Fix: handle labels with multiple sources

Also did some cleanup of the code to make it more clear
This commit is contained in:
Pierre Kraft 2015-10-05 12:58:45 +02:00
parent 223dd5e0db
commit 7ed92d2d00

View file

@ -1,12 +1,12 @@
/*! videojs-resolution-switcher - v0.0.0 - 2015-7-26 /*! videojs-resolution-switcher - v0.0.0 - 2015-7-26
* Copyright (c) 2015 Kasper Moskwiak * Copyright (c) 2015 Kasper Moskwiak
* Modified by Pierre Kraft
* Licensed under the Apache-2.0 license. */ * Licensed under the Apache-2.0 license. */
(function(window, videojs) { (function(window, videojs) {
'use strict'; 'use strict';
var defaults = {}, var defaults = {},
videoJsResolutionSwitcher, videoJsResolutionSwitcher;
groupedSrc;
/** /**
* Initialize the plugin. * Initialize the plugin.
@ -28,7 +28,6 @@
MenuItem.call(this, player, options); MenuItem.call(this, player, options);
this.src = options.src; this.src = options.src;
this.type = options.type;
this.on('click', this.onClick); this.on('click', this.onClick);
this.on('touchstart', this.onClick); this.on('touchstart', this.onClick);
@ -41,8 +40,10 @@
var isPaused = player.paused(); var isPaused = player.paused();
// Change menu button label // Change menu button label
label.innerHTML = this.options_.label; label.innerHTML = this.options_.label;
// Change player source and wait for loadedmetadata event, then play video // Change player source and wait for loadeddata event, then play video
player.src({src: this.src, type: this.type}).one( 'loadedmetadata', function() { // loadedmetadata doesn't work right now for flash.
// Probably because of https://github.com/videojs/video-js-swf/issues/124
setSourceSanitized(this.src).one( 'loadeddata', function() {
player.currentTime(currentTime); player.currentTime(currentTime);
if(!isPaused){ player.play(); } if(!isPaused){ player.play(); }
player.trigger('resolutionchange'); player.trigger('resolutionchange');
@ -50,6 +51,11 @@
} }
}); });
function setSourceSanitized(sources) {
return player.src(sources.map(function(src) {
return {src: src.src, type: src.type, res: src.res};
}));
}
/* /*
* Resolution menu button * Resolution menu button
@ -70,15 +76,16 @@
} }
}, },
createItems: function(){ createItems: function(){
var sources = this.sources;
var menuItems = []; var menuItems = [];
for(var i = 0; i < sources.length; i++){ var labels = (this.sources && this.sources.label) || {};
for (var key in labels) {
if (labels.hasOwnProperty(key)) {
menuItems.push(new ResolutionMenuItem(player, { menuItems.push(new ResolutionMenuItem(player, {
label: sources[i].label, label: key,
src: sources[i].src, src: labels[key]
type: sources[i].type
})); }));
} }
}
return menuItems; return menuItems;
} }
}); });
@ -94,13 +101,13 @@
} }
//Sort sources //Sort sources
src = src.sort(compareResolutions); src = src.sort(compareResolutions);
groupedSrc = bucketSources(src); var groupedSrc = bucketSources(src);
var menuButton = new ResolutionMenuButton(player, { sources: src }); var menuButton = new ResolutionMenuButton(player, { sources: groupedSrc });
menuButton.el().classList.add('vjs-resolution-button'); menuButton.el().classList.add('vjs-resolution-button');
player.controlBar.resolutionSwitcher = player.controlBar.addChild(menuButton); player.controlBar.resolutionSwitcher = player.controlBar.addChild(menuButton);
var newSource = chooseSrc(src); var newSource = chooseSrc(src, groupedSrc);
label.innerHTML = newSource.label; label.innerHTML = newSource.label;
player.src(newSource); return setSourceSanitized(newSource);
}; };
/** /**
@ -117,7 +124,7 @@
/** /**
* Group sources by label, resolution and type * Group sources by label, resolution and type
* @param {Array} src Array of sources * @param {Array} src Array of sources
* @returns {Object} grouped sources: { label: {}, res: {}, type: {} } * @returns {Object} grouped sources: { label: { key: [] }, res: { key: [] }, type: { key: [] } }
*/ */
function bucketSources(src){ function bucketSources(src){
var resolutions = { var resolutions = {
@ -125,27 +132,39 @@
res: {}, res: {},
type: {} type: {}
}; };
for(var i = 0; i<src.length; i++){ src.map(function(source) {
resolutions.label[src[i].label] = resolutions.label[src[i].label] || []; initResolutionKey(resolutions, 'label', source);
resolutions.res[src[i].res] = resolutions.res[src[i].res] || []; initResolutionKey(resolutions, 'res', source);
resolutions.type[src[i].type] = resolutions.type[src[i].type] || []; initResolutionKey(resolutions, 'type', source);
resolutions.label[src[i].label].push(src[i]);
resolutions.res[src[i].res].push(src[i]); appendSourceToKey(resolutions, 'label', source);
resolutions.type[src[i].type].push(src[i]); appendSourceToKey(resolutions, 'res', source);
} appendSourceToKey(resolutions, 'type', source);
});
return resolutions; 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 * Choose src if option.default is specified
* @param {Array} src Array of sources * @param {Array} src Array of sources
* @returns {Object} source object * @param {Object} groupedSrc {res: { key: [] }}
* @returns {Array} one or many source objects. As array for convenience
*/ */
function chooseSrc(src){ function chooseSrc(src, groupedSrc){
if(settings.default === 'low'){ return src[src.length - 1]; } if(settings.default === 'low'){ return [src[src.length - 1]]; }
if(settings.default === 'high'){ return src[0]; } if(settings.default === 'high'){ return [src[0]]; }
if(groupedSrc.res[settings.default]){ return groupedSrc.res[settings.default][0]; } if(groupedSrc.res[settings.default]){ return groupedSrc.res[settings.default]; }
return src[src.length - 1]; return [src[src.length - 1]];
} }
// Create resolution switcher for videos form <source> tag inside <video> // Create resolution switcher for videos form <source> tag inside <video>