From 19d7c450706df1aae74003fcfcfa03d17ebd6f54 Mon Sep 17 00:00:00 2001 From: vijeth-aradhya Date: Tue, 18 Jul 2017 09:46:37 +0530 Subject: [PATCH] Add video-resolution-switcher (v0.4.2) plugin --- .../.brackets.json | 15 + .../videojs-resolution-switcher/.editorconfig | 13 + extlib/videojs-resolution-switcher/.jshintrc | 11 + extlib/videojs-resolution-switcher/.npmignore | 3 + .../videojs-resolution-switcher/.travis.yml | 8 + .../videojs-resolution-switcher/Gruntfile.js | 88 +++++ .../LICENSE-Apache-2.0 | 15 + extlib/videojs-resolution-switcher/README.md | 240 ++++++++++++ extlib/videojs-resolution-switcher/bower.json | 35 ++ .../examples/flash.html | 81 ++++ .../examples/html5.html | 97 +++++ .../examples/youtube.html | 64 ++++ .../lib/videojs-resolution-switcher.css | 37 ++ .../lib/videojs-resolution-switcher.js | 358 ++++++++++++++++++ .../videojs-resolution-switcher/package.json | 115 ++++++ .../static/extlib/videojs-resolution-switcher | 1 + 16 files changed, 1181 insertions(+) create mode 100644 extlib/videojs-resolution-switcher/.brackets.json create mode 100644 extlib/videojs-resolution-switcher/.editorconfig create mode 100644 extlib/videojs-resolution-switcher/.jshintrc create mode 100644 extlib/videojs-resolution-switcher/.npmignore create mode 100644 extlib/videojs-resolution-switcher/.travis.yml create mode 100644 extlib/videojs-resolution-switcher/Gruntfile.js create mode 100644 extlib/videojs-resolution-switcher/LICENSE-Apache-2.0 create mode 100644 extlib/videojs-resolution-switcher/README.md create mode 100644 extlib/videojs-resolution-switcher/bower.json create mode 100644 extlib/videojs-resolution-switcher/examples/flash.html create mode 100644 extlib/videojs-resolution-switcher/examples/html5.html create mode 100644 extlib/videojs-resolution-switcher/examples/youtube.html create mode 100644 extlib/videojs-resolution-switcher/lib/videojs-resolution-switcher.css create mode 100644 extlib/videojs-resolution-switcher/lib/videojs-resolution-switcher.js create mode 100644 extlib/videojs-resolution-switcher/package.json create mode 120000 mediagoblin/static/extlib/videojs-resolution-switcher diff --git a/extlib/videojs-resolution-switcher/.brackets.json b/extlib/videojs-resolution-switcher/.brackets.json new file mode 100644 index 00000000..bd079aa1 --- /dev/null +++ b/extlib/videojs-resolution-switcher/.brackets.json @@ -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 index 00000000..e717f5eb --- /dev/null +++ b/extlib/videojs-resolution-switcher/.editorconfig @@ -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 index 00000000..9141dd62 --- /dev/null +++ b/extlib/videojs-resolution-switcher/.jshintrc @@ -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 index 00000000..6c17f823 --- /dev/null +++ b/extlib/videojs-resolution-switcher/.npmignore @@ -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 index 00000000..41d37ae1 --- /dev/null +++ b/extlib/videojs-resolution-switcher/.travis.yml @@ -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 index 00000000..a0435f81 --- /dev/null +++ b/extlib/videojs-resolution-switcher/Gruntfile.js @@ -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 index 00000000..d1bef841 --- /dev/null +++ b/extlib/videojs-resolution-switcher/LICENSE-Apache-2.0 @@ -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 index 00000000..5a1493fb --- /dev/null +++ b/extlib/videojs-resolution-switcher/README.md @@ -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 + + + + +``` + +### Or use `` tags: + +```html + + + + +``` + + +### YouTube tech + +YouTube tech form https://github.com/eXon/videojs-youtube + +```html + + + + +``` + +### Flash tech + +When using flash tech `preload="auto"` is required. + +## Source options + +Sources can passed to player using `updateSrc` method or `` 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 index 00000000..7e734d44 --- /dev/null +++ b/extlib/videojs-resolution-switcher/bower.json @@ -0,0 +1,35 @@ +{ + "name": "vjs-resolution-switcher", + "version": "0.4.2", + "authors": [ + "Kasper Moskwiak " + ], + "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 index 00000000..60dfb11d --- /dev/null +++ b/extlib/videojs-resolution-switcher/examples/flash.html @@ -0,0 +1,81 @@ + + + + + Video.js Resolution Switcher + + + + + + +
+

+ Use flash +

+
+ + + + + + + + + diff --git a/extlib/videojs-resolution-switcher/examples/html5.html b/extlib/videojs-resolution-switcher/examples/html5.html new file mode 100644 index 00000000..a987cc42 --- /dev/null +++ b/extlib/videojs-resolution-switcher/examples/html5.html @@ -0,0 +1,97 @@ + + + + + Video.js Resolution Switcher + + + + + + +
+

+ Set sources dynamically +

+
+ + + +
+

+ Set sources inside <video> tag +

+
+ + + + + + + + + + + + + diff --git a/extlib/videojs-resolution-switcher/examples/youtube.html b/extlib/videojs-resolution-switcher/examples/youtube.html new file mode 100644 index 00000000..49b5ff97 --- /dev/null +++ b/extlib/videojs-resolution-switcher/examples/youtube.html @@ -0,0 +1,64 @@ + + + + + Video.js Resolution Switcher + + + + + + +
+

+ Youtube tech +

+
+ + + + + + + + + + + \ 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 index 00000000..aee4eacc --- /dev/null +++ b/extlib/videojs-resolution-switcher/lib/videojs-resolution-switcher.css @@ -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 index 00000000..5b1448ea --- /dev/null +++ b/extlib/videojs-resolution-switcher/lib/videojs-resolution-switcher.js @@ -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 tag inside