Add video-resolution-switcher (v0.4.2) plugin
authorvijeth-aradhya <vijthaaa@gmail.com>
Tue, 18 Jul 2017 04:16:37 +0000 (09:46 +0530)
committervijeth-aradhya <vijthaaa@gmail.com>
Tue, 18 Jul 2017 04:16:37 +0000 (09:46 +0530)
16 files changed:
extlib/videojs-resolution-switcher/.brackets.json [new file with mode: 0644]
extlib/videojs-resolution-switcher/.editorconfig [new file with mode: 0644]
extlib/videojs-resolution-switcher/.jshintrc [new file with mode: 0644]
extlib/videojs-resolution-switcher/.npmignore [new file with mode: 0644]
extlib/videojs-resolution-switcher/.travis.yml [new file with mode: 0644]
extlib/videojs-resolution-switcher/Gruntfile.js [new file with mode: 0644]
extlib/videojs-resolution-switcher/LICENSE-Apache-2.0 [new file with mode: 0644]
extlib/videojs-resolution-switcher/README.md [new file with mode: 0644]
extlib/videojs-resolution-switcher/bower.json [new file with mode: 0644]
extlib/videojs-resolution-switcher/examples/flash.html [new file with mode: 0644]
extlib/videojs-resolution-switcher/examples/html5.html [new file with mode: 0644]
extlib/videojs-resolution-switcher/examples/youtube.html [new file with mode: 0644]
extlib/videojs-resolution-switcher/lib/videojs-resolution-switcher.css [new file with mode: 0644]
extlib/videojs-resolution-switcher/lib/videojs-resolution-switcher.js [new file with mode: 0644]
extlib/videojs-resolution-switcher/package.json [new file with mode: 0644]
mediagoblin/static/extlib/videojs-resolution-switcher [new symlink]

diff --git a/extlib/videojs-resolution-switcher/.brackets.json b/extlib/videojs-resolution-switcher/.brackets.json
new file mode 100644 (file)
index 0000000..bd079aa
--- /dev/null
@@ -0,0 +1,15 @@
+{
+  "language": {
+    "javascript": {
+      "linting.prefer": "JSHint",
+      "linting.usePreferredOnly": true
+    }
+  },
+  "jwolfe.file-tree-exclude.list": [
+        "node_modules",
+        "bower_components",
+        ".git",
+        "dist",
+        "vendor"
+    ]
+}
diff --git a/extlib/videojs-resolution-switcher/.editorconfig b/extlib/videojs-resolution-switcher/.editorconfig
new file mode 100644 (file)
index 0000000..e717f5e
--- /dev/null
@@ -0,0 +1,13 @@
+# http://editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/extlib/videojs-resolution-switcher/.jshintrc b/extlib/videojs-resolution-switcher/.jshintrc
new file mode 100644 (file)
index 0000000..9141dd6
--- /dev/null
@@ -0,0 +1,11 @@
+{
+    "browser"  : true,
+    "curly": true,
+    "eqeqeq": true,
+    "quotmark" : "single",
+    "trailing" : true,
+    "undef"    : true,
+    "predef"   : [
+        "videojs"
+    ]
+}
diff --git a/extlib/videojs-resolution-switcher/.npmignore b/extlib/videojs-resolution-switcher/.npmignore
new file mode 100644 (file)
index 0000000..6c17f82
--- /dev/null
@@ -0,0 +1,3 @@
+dist/
+test/
+*~
\ No newline at end of file
diff --git a/extlib/videojs-resolution-switcher/.travis.yml b/extlib/videojs-resolution-switcher/.travis.yml
new file mode 100644 (file)
index 0000000..41d37ae
--- /dev/null
@@ -0,0 +1,8 @@
+language: node_js
+node_js:
+  - 4
+  - 0.12
+  - 0.10
+before_install: npm install -g grunt-cli
+install: npm install
+sudo: false
diff --git a/extlib/videojs-resolution-switcher/Gruntfile.js b/extlib/videojs-resolution-switcher/Gruntfile.js
new file mode 100644 (file)
index 0000000..a0435f8
--- /dev/null
@@ -0,0 +1,88 @@
+'use strict';
+
+module.exports = function(grunt) {
+  grunt.initConfig({
+    pkg: grunt.file.readJSON('package.json'),
+    banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
+      '<%= grunt.template.today("yyyy-mm-dd") %>\n' +
+      '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>;' +
+      ' Licensed <%= pkg.license %> */\n',
+    clean: {
+      files: ['dist']
+    },
+    concat: {
+      options: {
+        banner: '<%= banner %>',
+        stripBanners: true
+      },
+      dist: {
+        src: 'lib/**/*.js',
+        dest: 'dist/<%= pkg.name %>.js'
+      }
+    },
+    uglify: {
+      options: {
+        banner: '<%= banner %>'
+      },
+      dist: {
+        src: '<%= concat.dist.dest %>',
+        dest: 'dist/<%= pkg.name %>.min.js'
+      }
+    },
+    qunit: {
+      files: 'test/**/*.html'
+    },
+    jshint: {
+      gruntfile: {
+        options: {
+          node: true
+        },
+        src: 'Gruntfile.js'
+      },
+      src: {
+        options: {
+          jshintrc: '.jshintrc'
+        },
+        src: ['lib/**/*.js']
+      },
+      test: {
+        options: {
+          jshintrc: '.jshintrc'
+        },
+        src: ['test/**/*.js']
+      }
+    },
+    watch: {
+      gruntfile: {
+        files: '<%= jshint.gruntfile.src %>',
+        tasks: ['jshint:gruntfile']
+      },
+      src: {
+        files: '<%= jshint.src.src %>',
+        tasks: ['jshint:src', 'qunit']
+      },
+      test: {
+        files: '<%= jshint.test.src %>',
+        tasks: ['jshint:test', 'qunit']
+      }
+    }
+  });
+
+  grunt.loadNpmTasks('grunt-contrib-clean');
+  grunt.loadNpmTasks('grunt-contrib-concat');
+  grunt.loadNpmTasks('grunt-contrib-uglify');
+  grunt.loadNpmTasks('grunt-contrib-qunit');
+  grunt.loadNpmTasks('grunt-contrib-jshint');
+  grunt.loadNpmTasks('grunt-contrib-watch');
+
+  grunt.registerTask('default',
+                     ['clean',
+                      'jshint',
+                      'qunit',
+                      'concat',
+                      'uglify']);
+  
+  grunt.registerTask('test', [
+    'jshint'
+  ]);
+};
diff --git a/extlib/videojs-resolution-switcher/LICENSE-Apache-2.0 b/extlib/videojs-resolution-switcher/LICENSE-Apache-2.0
new file mode 100644 (file)
index 0000000..d1bef84
--- /dev/null
@@ -0,0 +1,15 @@
+Copyright 2013 Kasper Moskwiak
+
+Modified by Pierre Kraft
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
\ No newline at end of file
diff --git a/extlib/videojs-resolution-switcher/README.md b/extlib/videojs-resolution-switcher/README.md
new file mode 100644 (file)
index 0000000..5a1493f
--- /dev/null
@@ -0,0 +1,240 @@
+# Video.js Resolution Switcher [![Build Status](https://travis-ci.org/kmoskwiak/videojs-resolution-switcher.svg?branch=master)](https://travis-ci.org/kmoskwiak/videojs-resolution-switcher) 
+
+Resolution switcher for [video.js v5](https://github.com/videojs/video.js)
+
+## Example
+
+[Working examples](examples) of the plugin you can check out if you're having trouble. Or check out this [demo](https://kmoskwiak.github.io/videojs-resolution-switcher/).
+
+## Getting Started
+
+Install plugin with
+
+**npm**
+```
+npm i videojs-resolution-switcher
+```
+
+or **bower**
+```
+bower install videojs-resolution-switcher
+```
+
+
+### Setup sources dynamically:
+
+```html
+<video id='video' class="video-js vjs-default-skin"></video>
+<script src="video.js"></script>
+<script src="videojs-resolution-switcher.js"></script>
+<script>
+  videojs('video', {
+    controls: true,
+    plugins: {
+        videoJsResolutionSwitcher: {
+          default: 'high',
+          dynamicLabel: true
+        }
+      }
+  }, function(){
+  
+    // Add dynamically sources via updateSrc method
+    player.updateSrc([
+        {
+          src: 'http://media.xiph.org/mango/tears_of_steel_1080p.webm',
+          type: 'video/webm',
+          label: '360'
+        },
+        {
+          src: 'http://mirrorblender.top-ix.org/movies/sintel-1024-surround.mp4',
+          type: 'video/mp4',
+          label: '720'
+        }
+      ])
+
+      player.on('resolutionchange', function(){
+        console.info('Source changed to %s', player.src())
+      })
+      
+  })
+</script>
+```
+
+### Or use `<source>` tags:
+
+```html
+
+<video id="video" class="video-js vjs-default-skin" width="1000" controls data-setup='{}'>
+   <source src="http://mirrorblender.top-ix.org/movies/sintel-1024-surround.mp4" type='video/mp4' label='SD' />
+   <source src="http://media.xiph.org/mango/tears_of_steel_1080p.webm" type='video/webm' label='HD'/>
+</video>
+<script>
+  videojs('video').videoJsResolutionSwitcher()
+</script>
+
+```
+
+
+### YouTube tech
+
+YouTube tech form https://github.com/eXon/videojs-youtube
+
+```html
+<video id='video' class="video-js vjs-default-skin"></video>
+<script src="../lib/videojs-resolution-switcher.js"></script>
+<script>
+       videojs('video', {
+               controls: true,
+               techOrder:  ["youtube"],
+               sources: [{ "type": "video/youtube", "src": "https://www.youtube.com/watch?v=iD_MyDbP_ZE"}],
+               plugins: {
+                       videoJsResolutionSwitcher: {
+                               default: 'low',
+                               dynamicLabel: true
+                       }
+               }
+       }, function(){
+               var player = this;
+               player.on('resolutionchange', function(){
+                       console.info('Source changed')
+               })
+       });
+
+</script>
+
+```
+
+### Flash tech
+
+When using flash tech `preload="auto"` is required.
+
+## Source options
+
+Sources can passed to player using `updateSrc` method or `<source>` tag as shown above. Avalible options for each source are:
+* label - `String` (required) is shown in menu (ex. 'SD' or '360p')
+* res - `Number` is resolution of video used for sorting (ex. 360 or 1080)
+
+## Plugin options
+
+You can pass options to plugin like this:
+
+```javascript
+
+videojs('video', {
+      controls: true,
+      muted: true,
+      width: 1000,
+      plugins: {
+        videoJsResolutionSwitcher: {
+          default: 'low'
+        }
+      }
+    }, function(){
+      // this is player
+    })
+```
+### Avalible options:
+* default - `{Number}|'low'|'high'` - default resolution. If any `Number` is passed plugin will try to choose source based on `res` parameter. If `low` or `high` is passed, plugin will choose respectively worse or best resolution (if `res` parameter is specified). If `res` parameter is not specified plugin assumes that sources array is sorted from best to worse.
+* dynamicLabel - `{Boolean}` - if `true` current label will be displayed in control bar. By default gear icon is displayed.
+* customSourcePicker - `{Function}` - custom function for selecting source.
+
+
+## Methods
+
+
+### updateSrc([source])
+Returns video.js player object if used as setter. If `source` is not passed it acts like [player.src()](http://docs.videojs.com/docs/api/player.html#Methodssrc)
+```javascript
+
+// Update video sources
+player.updateSrc([
+  { type: "video/mp4", src: "http://www.example.com/path/to/video.mp4", label: 'SD' },
+  { type: "video/mp4", src: "http://www.example.com/path/to/video.mp4", label: 'HD' },
+  { type: "video/mp4", src: "http://www.example.com/path/to/video.mp4", label: '4k' }
+])
+
+```
+#### PARAMETERS:
+| name | type | required | description |
+|:----:|:----:|:--------:|:-----------:|
+| source| array| no | array of sources |
+
+### currentResolution([label], [customSourcePicker])
+If used as getter returns current resolution object:
+```javascript
+  {
+    label: 'SD', // current label
+    sources: [
+      { type: "video/webm", src: "http://www.example.com/path/to/video.webm", label: 'SD' },
+      { type: "video/mp4", src: "http://www.example.com/path/to/video.mp4", label: 'SD' }
+    ] // array of sources with current label
+  }
+```
+
+If used as setter returns video.js player object.
+
+
+```javascript
+
+// Get current resolution
+player.currentResolution(); // returns object {label '', sources: []}
+
+// Set resolution
+player.currentResolution('SD'); // returns videojs player object
+```
+#### PARAMETERS:
+| name | type | required | description |
+|:----:|:----:|:--------:|:-----------:|
+| label| string| no | label name |
+| customSourcePicker | function | no | cutom function to choose source |
+
+#### customSourcePicker
+If there is more than one source with the same label, player will choose source automatically. This behavior can be changed if `customSourcePicker` is passed.
+
+`customSourcePicker` must return `player` object.
+```javascript
+player.currentResolution('SD', function(_player, _sources, _label){
+  return _player.src(_sources[0]); \\ Always select first source in array
+});
+```
+`customSourcePicker` accepst 3 arguments.
+
+| name | type | required | description |
+|:----:|:----:|:--------:|:-----------:|
+| player| Object | yes | videojs player object |
+| sources | Array | no | array of sources |
+| label | String | no | name of label |
+
+`customSourcePicker` may be passed in options when player is initialized:
+```javascript
+
+var myCustomSrcPicker = function(_p, _s, _l){
+  // select any source you want
+  return _p.src(selectedSource);
+}
+
+videojs('video', {
+      controls: true,
+      muted: true,
+      width: 1000,
+      plugins: {
+        videoJsResolutionSwitcher: {
+          default: 'low',
+          customSourcePicker: myCustomSrcPicker
+        }
+      }
+    }, function(){
+      // this is player
+    })
+```
+
+
+### getGroupedSrc()
+Returns sources grouped by label, resolution and type.
+
+
+## Events
+
+### resolutionchange `EVENT`
+
+> Fired when resolution is changed
diff --git a/extlib/videojs-resolution-switcher/bower.json b/extlib/videojs-resolution-switcher/bower.json
new file mode 100644 (file)
index 0000000..7e734d4
--- /dev/null
@@ -0,0 +1,35 @@
+{
+  "name": "vjs-resolution-switcher",
+  "version": "0.4.2",
+  "authors": [
+    "Kasper Moskwiak <kasper.moskwiak@gmail.com>"
+  ],
+  "description": "Resolution switcher for video.js 5",
+  "main": [
+    "lib/videojs-resolution-switcher.js",
+    "lib/videojs-resolution-switcher.css"
+  ],
+  "moduleType": [
+    "amd",
+    "globals",
+    "node"
+  ],
+  "keywords": [
+    "videojs",
+    "flash",
+    "video",
+    "player",
+    "resolution",
+    "sources",
+    "videojs-plugin"
+  ],
+  "license": "Apache-2.0",
+  "homepage": "https://github.com/kmoskwiak/videojs-resolution-switcher",
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "bower_components",
+    "test",
+    "tests"
+  ]
+}
diff --git a/extlib/videojs-resolution-switcher/examples/flash.html b/extlib/videojs-resolution-switcher/examples/flash.html
new file mode 100644 (file)
index 0000000..60dfb11
--- /dev/null
@@ -0,0 +1,81 @@
+<!doctype html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Video.js Resolution Switcher</title>
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <link href="../node_modules/video.js/dist/video-js.css" rel="stylesheet">
+  <link href="../lib/videojs-resolution-switcher.css" rel="stylesheet">
+  <style>
+    body {
+      font-family: Arial, sans-serif;
+      background: #777;
+    }
+    .info {
+      background-color: #eee;
+      border: thin solid #333;
+      border-radius: 3px;
+      padding: 0 5px;
+      text-align: center;
+    }
+    .video-js {
+      margin: 40px auto;
+    }
+  </style>
+</head>
+<body>
+  <div class="info">
+    <p>
+      Use flash
+    </p>
+  </div>
+
+  <video id='video_flash' class="video-js vjs-default-skin"></video>
+
+  <script src="../node_modules/video.js/dist/video.js"></script>
+  <script>
+    videojs.options.flash.swf = "../node_modules/video.js/dist/video-js.swf"
+  </script>
+  <script src="../lib/videojs-resolution-switcher.js"></script>
+  <script>
+
+    // Use flash
+    videojs('video_flash', {
+      controls: true,
+      techOrder: ['flash'],
+      preload: 'auto',
+      width: 1000,
+      plugins: {
+        videoJsResolutionSwitcher: {
+          default: 'low', // Default resolution [{Number}, 'low', 'high'],
+          dynamicLabel: true // Display dynamic labels or gear symbol
+        }
+      }
+    }, function(){
+      var player = this;
+      window.player = player
+
+      player.updateSrc([
+        {
+          src: 'https://vjs.zencdn.net/v/oceans.mp4?sd',
+          type: 'video/mp4',
+          label: 'SD',
+          res: 360
+        },
+        {
+          src: 'https://vjs.zencdn.net/v/oceans.mp4?hd',
+          type: 'video/mp4',
+          label: 'HD',
+          res: 720
+        }
+      ])
+
+      player.on('resolutionchange', function(){
+        console.info('Source changed to %s', player.src())
+      })
+
+    })
+    
+  </script>
+</body>
+</html>
diff --git a/extlib/videojs-resolution-switcher/examples/html5.html b/extlib/videojs-resolution-switcher/examples/html5.html
new file mode 100644 (file)
index 0000000..a987cc4
--- /dev/null
@@ -0,0 +1,97 @@
+<!doctype html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Video.js Resolution Switcher</title>
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <link href="../node_modules/video.js/dist/video-js.css" rel="stylesheet">
+  <link href="../lib/videojs-resolution-switcher.css" rel="stylesheet">
+  <style>
+    body {
+      font-family: Arial, sans-serif;
+      background: #777;
+    }
+    .info {
+      background-color: #eee;
+      border: thin solid #333;
+      border-radius: 3px;
+      padding: 0 5px;
+      text-align: center;
+    }
+    .video-js {
+      margin: 40px auto;
+    }
+  </style>
+</head>
+<body>
+  <div class="info">
+    <p>
+      Set sources dynamically
+    </p>
+  </div>
+
+  <video id='video' class="video-js vjs-default-skin"></video>
+
+  <div class="info">
+    <p>
+      Set sources inside <code>&ltvideo&gt</code> tag
+    </p>
+  </div>
+
+  <video id="video_1" class="video-js vjs-default-skin" width="1000" controls data-setup='{}' muted>
+    <source src="https://vjs.zencdn.net/v/oceans.mp4?480" type='video/mp4' label='SD' res='480' />
+    <source src="https://vjs.zencdn.net/v/oceans.mp4?1080" type='video/mp4' label='HD' res='1080'/>
+    <source src="https://vjs.zencdn.net/v/oceans.mp4?144" type='video/mp4' label='phone' res='144'/>
+    <source src="https://vjs.zencdn.net/v/oceans.mp4?2160" type='video/mp4' label='4k' res='2160'/>
+  </video>
+  
+
+  <script src="../node_modules/video.js/dist/video.js"></script>
+  <script>
+    videojs.options.flash.swf = "../node_modules/video.js/dist/video-js.swf"
+  </script>
+  <script src="../lib/videojs-resolution-switcher.js"></script>
+  <script>
+    // fire up the plugin
+    videojs('video', {
+      controls: true,
+      muted: true,
+      width: 1000,
+      plugins: {
+        videoJsResolutionSwitcher: {
+          default: 'low', // Default resolution [{Number}, 'low', 'high'],
+          dynamicLabel: true // Display dynamic labels or gear symbol
+        }
+      }
+    }, function(){
+      var player = this;
+      window.player = player
+
+      player.updateSrc([
+        {
+          src: 'https://vjs.zencdn.net/v/oceans.mp4?sd',
+          type: 'video/mp4',
+          label: 'SD',
+          res: 360
+        },
+        {
+          src: 'https://vjs.zencdn.net/v/oceans.mp4?hd',
+          type: 'video/mp4',
+          label: 'HD',
+          res: 720
+        }
+      ])
+
+      player.on('resolutionchange', function(){
+        console.info('Source changed to %s', player.src())
+      })
+
+    })
+  </script>
+
+
+  <script>
+    videojs('video_1').videoJsResolutionSwitcher()
+  </script>
+</body>
+</html>
diff --git a/extlib/videojs-resolution-switcher/examples/youtube.html b/extlib/videojs-resolution-switcher/examples/youtube.html
new file mode 100644 (file)
index 0000000..49b5ff9
--- /dev/null
@@ -0,0 +1,64 @@
+<!doctype html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Video.js Resolution Switcher</title>
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <link href="../node_modules/video.js/dist/video-js.css" rel="stylesheet">
+  <link href="../lib/videojs-resolution-switcher.css" rel="stylesheet">
+  <style>
+    body {
+      font-family: Arial, sans-serif;
+      background: #777;
+    }
+    .info {
+      background-color: #eee;
+      border: thin solid #333;
+      border-radius: 3px;
+      padding: 0 5px;
+      text-align: center;
+    }
+    .video-js {
+      margin: 40px auto;
+    }
+  </style>
+</head>
+<body>
+  <div class="info">
+    <p>
+      Youtube tech
+    </p>
+  </div>
+
+  <video id='video' class="video-js vjs-default-skin"></video>
+
+  <script src="../node_modules/video.js/dist/video.js"></script>
+  <script src="../node_modules/videojs-youtube/dist/Youtube.js"></script>
+  <script src="../lib/videojs-resolution-switcher.js"></script>
+  <script>
+    // fire up the plugin
+    videojs('video', {
+      controls: true,
+      muted: true,
+      techOrder:  ["youtube"],
+      width: 500,
+      sources: [{ "type": "video/youtube", "src": "https://www.youtube.com/watch?v=iD_MyDbP_ZE"}],
+      plugins: {
+        videoJsResolutionSwitcher: {
+          default: 'low',
+          dynamicLabel: true
+        }
+      }
+    }, function(){
+      var player = this;
+      window.player = player;
+      player.on('resolutionchange', function(){
+        console.info('Source changed')
+      })
+    });
+    
+  </script>
+
+
+</body>
+</html>
\ No newline at end of file
diff --git a/extlib/videojs-resolution-switcher/lib/videojs-resolution-switcher.css b/extlib/videojs-resolution-switcher/lib/videojs-resolution-switcher.css
new file mode 100644 (file)
index 0000000..aee4eac
--- /dev/null
@@ -0,0 +1,37 @@
+.vjs-resolution-button {
+  color: #ccc;
+  font-family: VideoJS;
+}
+
+.vjs-resolution-button .vjs-resolution-button-staticlabel:before {
+  content: '\f110';
+  font-size: 1.8em;
+  line-height: 1.67;
+}
+
+.vjs-resolution-button .vjs-resolution-button-label {
+    font-size: 1em;
+    line-height: 3em;
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    text-align: center;
+    box-sizing: inherit;
+               font-family: Arial, Helvetica, sans-serif;
+}
+
+.vjs-resolution-button ul.vjs-menu-content {
+  width: 4em !important;
+}
+
+.vjs-resolution-button .vjs-menu {
+  left: 0;
+}
+
+.vjs-resolution-button .vjs-menu li {
+  text-transform: none;
+       font-size: 1em;
+       font-family: Arial, Helvetica, sans-serif;
+}
diff --git a/extlib/videojs-resolution-switcher/lib/videojs-resolution-switcher.js b/extlib/videojs-resolution-switcher/lib/videojs-resolution-switcher.js
new file mode 100644 (file)
index 0000000..5b1448e
--- /dev/null
@@ -0,0 +1,358 @@
+/*! videojs-resolution-switcher - 2015-7-26
+ * Copyright (c) 2016 Kasper Moskwiak
+ * Modified by Pierre Kraft
+ * Licensed under the Apache-2.0 license. */
+
+(function() {
+  /* jshint eqnull: true*/
+  /* global require */
+  'use strict';
+  var videojs = null;
+  if(typeof window.videojs === 'undefined' && typeof require === 'function') {
+    videojs = require('video.js');
+  } else {
+    videojs = window.videojs;
+  }
+
+  (function(window, videojs) {
+
+
+    var defaults = {},
+        videoJsResolutionSwitcher,
+        currentResolution = {}, // stores current resolution
+        menuItemsHolder = {}; // stores menuItems
+
+    function setSourcesSanitized(player, sources, label, customSourcePicker) {
+      currentResolution = {
+        label: label,
+        sources: sources
+      };
+      if(typeof customSourcePicker === 'function'){
+        return customSourcePicker(player, sources, label);
+      }
+      return player.src(sources.map(function(src) {
+        return {src: src.src, type: src.type, res: src.res};
+      }));
+    }
+
+  /*
+   * Resolution menu item
+   */
+  var MenuItem = videojs.getComponent('MenuItem');
+  var ResolutionMenuItem = videojs.extend(MenuItem, {
+    constructor: function(player, options, onClickListener, label){
+      this.onClickListener = onClickListener;
+      this.label = label;
+      // Sets this.player_, this.options_ and initializes the component
+      MenuItem.call(this, player, options);
+      this.src = options.src;
+
+      this.on('click', this.onClick);
+      this.on('touchstart', this.onClick);
+
+      if (options.initialySelected) {
+        this.showAsLabel();
+        this.selected(true);
+
+        this.addClass('vjs-selected');
+      }
+    },
+    showAsLabel: function() {
+      // Change menu button label to the label of this item if the menu button label is provided
+      if(this.label) {
+        this.label.innerHTML = this.options_.label;
+      }
+    },
+    onClick: function(customSourcePicker){
+      this.onClickListener(this);
+      // Remember player state
+      var currentTime = this.player_.currentTime();
+      var isPaused = this.player_.paused();
+      this.showAsLabel();
+
+      // add .current class
+      this.addClass('vjs-selected');
+
+      // Hide bigPlayButton
+      if(!isPaused){
+        this.player_.bigPlayButton.hide();
+      }
+      if(typeof customSourcePicker !== 'function' &&
+        typeof this.options_.customSourcePicker === 'function'){
+        customSourcePicker = this.options_.customSourcePicker;
+      }
+      // Change player source and wait for loadeddata event, then play video
+      // loadedmetadata doesn't work right now for flash.
+      // Probably because of https://github.com/videojs/video-js-swf/issues/124
+      // If player preload is 'none' and then loadeddata not fired. So, we need timeupdate event for seek handle (timeupdate doesn't work properly with flash)
+      var handleSeekEvent = 'loadeddata';
+      if(this.player_.techName_ !== 'Youtube' && this.player_.preload() === 'none' && this.player_.techName_ !== 'Flash') {
+        handleSeekEvent = 'timeupdate';
+      }
+      setSourcesSanitized(this.player_, this.src, this.options_.label, customSourcePicker).one(handleSeekEvent, function() {
+        this.player_.currentTime(currentTime);
+        this.player_.handleTechSeeked_();
+        if(!isPaused){
+          // Start playing and hide loadingSpinner (flash issue ?)
+          this.player_.play().handleTechSeeked_();
+        }
+        this.player_.trigger('resolutionchange');
+        });
+      }
+    });
+
+
+    /*
+     * Resolution menu button
+     */
+     var MenuButton = videojs.getComponent('MenuButton');
+     var ResolutionMenuButton = videojs.extend(MenuButton, {
+       constructor: function(player, options, settings, label){
+        this.sources = options.sources;
+        this.label = label;
+        this.label.innerHTML = options.initialySelectedLabel;
+        // Sets this.player_, this.options_ and initializes the component
+        MenuButton.call(this, player, options, settings);
+        this.controlText('Quality');
+
+        if(settings.dynamicLabel){
+          this.el().appendChild(label);
+        }else{
+          var staticLabel = document.createElement('span');
+                                       videojs.addClass(staticLabel, 'vjs-resolution-button-staticlabel');
+          this.el().appendChild(staticLabel);
+        }
+       },
+       createItems: function(){
+         var menuItems = [];
+         var labels = (this.sources && this.sources.label) || {};
+         var onClickUnselectOthers = function(clickedItem) {
+          menuItems.map(function(item) {
+            item.selected(item === clickedItem);
+            item.removeClass('vjs-selected');
+          });
+         };
+
+         for (var key in labels) {
+           if (labels.hasOwnProperty(key)) {
+            menuItems.push(new ResolutionMenuItem(
+              this.player_,
+              {
+                label: key,
+                src: labels[key],
+                initialySelected: key === this.options_.initialySelectedLabel,
+                customSourcePicker: this.options_.customSourcePicker
+              },
+              onClickUnselectOthers,
+              this.label));
+             // Store menu item for API calls
+             menuItemsHolder[key] = menuItems[menuItems.length - 1];
+            }
+         }
+         return menuItems;
+       }
+     });
+
+    /**
+     * Initialize the plugin.
+     * @param {object} [options] configuration for the plugin
+     */
+    videoJsResolutionSwitcher = function(options) {
+      var settings = videojs.mergeOptions(defaults, options),
+          player = this,
+          label = document.createElement('span'),
+          groupedSrc = {};
+
+                       videojs.addClass(label, 'vjs-resolution-button-label');
+                       
+      /**
+       * Updates player sources or returns current source URL
+       * @param   {Array}  [src] array of sources [{src: '', type: '', label: '', res: ''}]
+       * @returns {Object|String|Array} videojs player object if used as setter or current source URL, object, or array of sources
+       */
+      player.updateSrc = function(src){
+        //Return current src if src is not given
+        if(!src){ return player.src(); }
+        // Dispose old resolution menu button before adding new sources
+        if(player.controlBar.resolutionSwitcher){
+          player.controlBar.resolutionSwitcher.dispose();
+          delete player.controlBar.resolutionSwitcher;
+        }
+        //Sort sources
+        src = src.sort(compareResolutions);
+        groupedSrc = bucketSources(src);
+        var choosen = chooseSrc(groupedSrc, src);
+        var menuButton = new ResolutionMenuButton(player, { sources: groupedSrc, initialySelectedLabel: choosen.label , initialySelectedRes: choosen.res , customSourcePicker: settings.customSourcePicker}, settings, label);
+                               videojs.addClass(menuButton.el(), 'vjs-resolution-button');
+        player.controlBar.resolutionSwitcher = player.controlBar.el_.insertBefore(menuButton.el_, player.controlBar.getChild('fullscreenToggle').el_);
+        player.controlBar.resolutionSwitcher.dispose = function(){
+          this.parentNode.removeChild(this);
+        };
+        return setSourcesSanitized(player, choosen.sources, choosen.label);
+      };
+
+      /**
+       * Returns current resolution or sets one when label is specified
+       * @param {String}   [label]         label name
+       * @param {Function} [customSourcePicker] custom function to choose source. Takes 3 arguments: player, sources, label. Must return player object.
+       * @returns {Object}   current resolution object {label: '', sources: []} if used as getter or player object if used as setter
+       */
+      player.currentResolution = function(label, customSourcePicker){
+        if(label == null) { return currentResolution; }
+        if(menuItemsHolder[label] != null){
+          menuItemsHolder[label].onClick(customSourcePicker);
+        }
+        return player;
+      };
+
+      /**
+       * Returns grouped sources by label, resolution and type
+       * @returns {Object} grouped sources: { label: { key: [] }, res: { key: [] }, type: { key: [] } }
+       */
+      player.getGroupedSrc = function(){
+        return groupedSrc;
+      };
+
+      /**
+       * Method used for sorting list of sources
+       * @param   {Object} a - source object with res property
+       * @param   {Object} b - source object with res property
+       * @returns {Number} result of comparation
+       */
+      function compareResolutions(a, b){
+        if(!a.res || !b.res){ return 0; }
+        return (+b.res)-(+a.res);
+      }
+
+      /**
+       * Group sources by label, resolution and type
+       * @param   {Array}  src Array of sources
+       * @returns {Object} grouped sources: { label: { key: [] }, res: { key: [] }, type: { key: [] } }
+       */
+      function bucketSources(src){
+        var resolutions = {
+          label: {},
+          res: {},
+          type: {}
+        };
+        src.map(function(source) {
+          initResolutionKey(resolutions, 'label', source);
+          initResolutionKey(resolutions, 'res', source);
+          initResolutionKey(resolutions, 'type', source);
+
+          appendSourceToKey(resolutions, 'label', source);
+          appendSourceToKey(resolutions, 'res', source);
+          appendSourceToKey(resolutions, 'type', source);
+        });
+        return resolutions;
+      }
+
+      function initResolutionKey(resolutions, key, source) {
+        if(resolutions[key][source[key]] == null) {
+          resolutions[key][source[key]] = [];
+        }
+      }
+
+      function appendSourceToKey(resolutions, key, source) {
+        resolutions[key][source[key]].push(source);
+      }
+
+      /**
+       * Choose src if option.default is specified
+       * @param   {Object} groupedSrc {res: { key: [] }}
+       * @param   {Array}  src Array of sources sorted by resolution used to find high and low res
+       * @returns {Object} {res: string, sources: []}
+       */
+      function chooseSrc(groupedSrc, src){
+        var selectedRes = settings['default']; // use array access as default is a reserved keyword
+        var selectedLabel = '';
+        if (selectedRes === 'high') {
+          selectedRes = src[0].res;
+          selectedLabel = src[0].label;
+        } else if (selectedRes === 'low' || selectedRes == null || !groupedSrc.res[selectedRes]) {
+          // Select low-res if default is low or not set
+          selectedRes = src[src.length - 1].res;
+          selectedLabel = src[src.length -1].label;
+        } else if (groupedSrc.res[selectedRes]) {
+          selectedLabel = groupedSrc.res[selectedRes][0].label;
+        }
+                               
+        return {res: selectedRes, label: selectedLabel, sources: groupedSrc.res[selectedRes]};
+      }
+                       
+                       function initResolutionForYt(player){
+                               // Init resolution
+                               player.tech_.ytPlayer.setPlaybackQuality('default');
+                               
+                               // Capture events
+                               player.tech_.ytPlayer.addEventListener('onPlaybackQualityChange', function(){
+                                       player.trigger('resolutionchange');
+                               });
+                               
+                               // We must wait for play event
+                               player.one('play', function(){
+                                       var qualities = player.tech_.ytPlayer.getAvailableQualityLevels();
+                                       // Map youtube qualities names
+                                       var _yts = {
+                                               highres: {res: 1080, label: '1080', yt: 'highres'},
+                                               hd1080: {res: 1080, label: '1080', yt: 'hd1080'}, 
+                                               hd720: {res: 720, label: '720', yt: 'hd720'}, 
+                                               large: {res: 480, label: '480', yt: 'large'},
+                                               medium: {res: 360, label: '360', yt: 'medium'}, 
+                                               small: {res: 240, label: '240', yt: 'small'},
+                                               tiny: {res: 144, label: '144', yt: 'tiny'},
+                                               auto: {res: 0, label: 'auto', yt: 'default'}
+                                       };
+
+                                       var _sources = [];
+
+                                       qualities.map(function(q){
+                                               _sources.push({
+                                                       src: player.src().src,
+                                                       type: player.src().type,
+                                                       label: _yts[q].label,
+                                                       res: _yts[q].res,
+                                                       _yt: _yts[q].yt
+                                               });
+                                       });
+
+                                       groupedSrc = bucketSources(_sources);
+
+                                       // Overwrite defualt sourcePicer function
+                                       var _customSourcePicker = function(_player, _sources, _label){
+                                               player.tech_.ytPlayer.setPlaybackQuality(_sources[0]._yt);
+                                               return player;
+                                       };
+
+                                       var choosen = {label: 'auto', res: 0, sources: groupedSrc.label.auto};
+                                       var menuButton = new ResolutionMenuButton(player, { 
+                                               sources: groupedSrc, 
+                                               initialySelectedLabel: choosen.label, 
+                                               initialySelectedRes: choosen.res, 
+                                               customSourcePicker: _customSourcePicker
+                                       }, settings, label);
+
+                                       menuButton.el().classList.add('vjs-resolution-button');
+                                       player.controlBar.resolutionSwitcher = player.controlBar.addChild(menuButton);
+                               });
+                       }
+                       
+                       player.ready(function(){
+                               if(player.options_.sources.length > 1){
+                                       // tech: Html5 and Flash
+                                       // Create resolution switcher for videos form <source> tag inside <video>
+                                       player.updateSrc(player.options_.sources);
+                               }
+                               
+                               if(player.techName_ === 'Youtube'){
+                                       // tech: YouTube
+                                       initResolutionForYt(player);
+                               }
+                       });
+
+    };
+
+    // register the plugin
+    videojs.plugin('videoJsResolutionSwitcher', videoJsResolutionSwitcher);
+  })(window, videojs);
+})();
diff --git a/extlib/videojs-resolution-switcher/package.json b/extlib/videojs-resolution-switcher/package.json
new file mode 100644 (file)
index 0000000..91cf9cb
--- /dev/null
@@ -0,0 +1,115 @@
+{
+  "_args": [
+    [
+      {
+        "raw": "videojs-resolution-switcher",
+        "scope": null,
+        "escapedName": "videojs-resolution-switcher",
+        "name": "videojs-resolution-switcher",
+        "rawSpec": "",
+        "spec": "latest",
+        "type": "tag"
+      },
+      "/home/vijeth"
+    ]
+  ],
+  "_from": "videojs-resolution-switcher@latest",
+  "_id": "videojs-resolution-switcher@0.4.2",
+  "_inCache": true,
+  "_installable": true,
+  "_location": "/videojs-resolution-switcher",
+  "_nodeVersion": "5.3.0",
+  "_npmOperationalInternal": {
+    "host": "packages-12-west.internal.npmjs.com",
+    "tmp": "tmp/videojs-resolution-switcher-0.4.2.tgz_1459876920307_0.39970111404545605"
+  },
+  "_npmUser": {
+    "name": "cosma",
+    "email": "kasper.moskwiak@gmail.com"
+  },
+  "_npmVersion": "3.5.2",
+  "_phantomChildren": {},
+  "_requested": {
+    "raw": "videojs-resolution-switcher",
+    "scope": null,
+    "escapedName": "videojs-resolution-switcher",
+    "name": "videojs-resolution-switcher",
+    "rawSpec": "",
+    "spec": "latest",
+    "type": "tag"
+  },
+  "_requiredBy": [
+    "#USER"
+  ],
+  "_resolved": "https://registry.npmjs.org/videojs-resolution-switcher/-/videojs-resolution-switcher-0.4.2.tgz",
+  "_shasum": "53ef38c58e95b90a61a7452de8177ee838a26405",
+  "_shrinkwrap": null,
+  "_spec": "videojs-resolution-switcher",
+  "_where": "/home/vijeth",
+  "author": {
+    "name": "Kasper Moskwiak",
+    "email": "kasper.moskwiak@gmail.com",
+    "url": "http://kspr.pl"
+  },
+  "bugs": {
+    "url": "https://github.com/kmoskwiak/videojs-resolution-switcher/issues"
+  },
+  "contributors": [
+    {
+      "name": "Pierre Kraft"
+    }
+  ],
+  "dependencies": {},
+  "description": "Resolution switcher for video.js 5",
+  "devDependencies": {
+    "grunt": "^0.4.5",
+    "grunt-contrib-clean": "^1.0",
+    "grunt-contrib-concat": "^1.0",
+    "grunt-contrib-jshint": "^1.0",
+    "grunt-contrib-qunit": "^1.1",
+    "grunt-contrib-uglify": "^1.0",
+    "grunt-contrib-watch": "^1.0",
+    "qunitjs": "^1.22",
+    "video.js": "^5.8",
+    "videojs-youtube": "^2.0.8"
+  },
+  "directories": {},
+  "dist": {
+    "shasum": "53ef38c58e95b90a61a7452de8177ee838a26405",
+    "tarball": "https://registry.npmjs.org/videojs-resolution-switcher/-/videojs-resolution-switcher-0.4.2.tgz"
+  },
+  "gitHead": "56760f6314d6b7ac9bfa24c16dce33e736cd9a97",
+  "homepage": "https://github.com/kmoskwiak/videojs-resolution-switcher#readme",
+  "keywords": [
+    "videojs",
+    "html5",
+    "flash",
+    "video",
+    "player",
+    "resolution",
+    "source",
+    "videojs-plugin"
+  ],
+  "license": "Apache-2.0",
+  "main": "./lib/videojs-resolution-switcher.js",
+  "maintainers": [
+    {
+      "name": "cosma",
+      "email": "kasper.moskwiak@gmail.com"
+    }
+  ],
+  "name": "videojs-resolution-switcher",
+  "optionalDependencies": {},
+  "peerDependencies": {
+    "video.js": "^5.8"
+  },
+  "readme": "ERROR: No README data found!",
+  "repository": {
+    "type": "git",
+    "url": "git+ssh://git@github.com/kmoskwiak/videojs-resolution-switcher.git"
+  },
+  "scripts": {
+    "test": "grunt test"
+  },
+  "version": "0.4.2"
+}
diff --git a/mediagoblin/static/extlib/videojs-resolution-switcher b/mediagoblin/static/extlib/videojs-resolution-switcher
new file mode 120000 (symlink)
index 0000000..ace672d
--- /dev/null
@@ -0,0 +1 @@
+../../../extlib/videojs-resolution-switcher/lib/
\ No newline at end of file