Add video-resolution-switcher (v0.4.2) plugin

This commit is contained in:
vijeth-aradhya 2017-07-18 09:46:37 +05:30
parent 0e49df65fe
commit 19d7c45070
16 changed files with 1181 additions and 0 deletions

View File

@ -0,0 +1,15 @@
{
"language": {
"javascript": {
"linting.prefer": "JSHint",
"linting.usePreferredOnly": true
}
},
"jwolfe.file-tree-exclude.list": [
"node_modules",
"bower_components",
".git",
"dist",
"vendor"
]
}

View File

@ -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

View File

@ -0,0 +1,11 @@
{
"browser" : true,
"curly": true,
"eqeqeq": true,
"quotmark" : "single",
"trailing" : true,
"undef" : true,
"predef" : [
"videojs"
]
}

View File

@ -0,0 +1,3 @@
dist/
test/
*~

View File

@ -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

View File

@ -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'
]);
};

View File

@ -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.

View File

@ -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

View File

@ -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"
]
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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;
}

View File

@ -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);
})();

View File

@ -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"
}

View File

@ -0,0 +1 @@
../../../extlib/videojs-resolution-switcher/lib/