Refs #13 Support quality selector buttons anywhere in the player's component hierarchy

Previously, the SourceInterceptor made the assumption that the QualitySelector button component
is a direct child of the controlBar component. That may not always be true. Video.js allows you
to specify a nested hierarchy of components, and so when plugin users choose to move the
QualitySelector button elsewhere, the plugin does not work properly.

This commit introduces a new event type called QUALITY_REQUESTED to signal when the user is
requesting a quality change. The old QUALITY_SELECTED event is now used to denote when the
plugin actually uses a new quality source. This dichotomy eliminates the need for the
SourceInterceptor to have a reference to the QualitySelector button component.
This commit is contained in:
Matt Luedke 2017-12-01 18:25:45 -05:00 committed by Jeremy Thomerson
parent ec9e06196f
commit a682125480
5 changed files with 19 additions and 13 deletions

View File

@ -39,7 +39,7 @@ module.exports = function(videojs) {
*/ */
handleClick: function(event) { handleClick: function(event) {
MenuItem.prototype.handleClick.call(this, event); MenuItem.prototype.handleClick.call(this, event);
this.player().trigger(events.QUALITY_SELECTED, this.source); this.player().trigger(events.QUALITY_REQUESTED, this.source);
}, },
}); });

View File

@ -25,7 +25,7 @@ module.exports = function(videojs) {
MenuButton.call(this, player, options); MenuButton.call(this, player, options);
// Update interface instantly so the user's change is acknowledged // Update interface instantly so the user's change is acknowledged
player.on(events.QUALITY_SELECTED, function(event, newSource) { player.on(events.QUALITY_REQUESTED, function(event, newSource) {
this.setSelectedSource(newSource); this.setSelectedSource(newSource);
player.addClass(QUALITY_CHANGE_CLASS); player.addClass(QUALITY_CHANGE_CLASS);
@ -34,6 +34,11 @@ module.exports = function(videojs) {
}); });
}.bind(this)); }.bind(this));
player.on(events.QUALITY_SELECTED, function(event, newSource) {
// Update the selected source with the source that was actually selected
this.setSelectedSource(newSource);
}.bind(this));
// Since it's possible for the player to get a source before the selector is // Since it's possible for the player to get a source before the selector is
// created, make sure to update once we get a "ready" signal. // created, make sure to update once we get a "ready" signal.
player.one('ready', function() { player.one('ready', function() {
@ -50,8 +55,12 @@ module.exports = function(videojs) {
* @param source {object} player source to display as selected * @param source {object} player source to display as selected
*/ */
setSelectedSource: function(source) { setSelectedSource: function(source) {
this.selectedSrc = source ? source.src : undefined; var src = (source ? source.src : undefined);
this.update();
if (this.selectedSrc !== src) {
this.selectedSrc = src;
this.update();
}
}, },
/** /**

View File

@ -2,6 +2,7 @@
module.exports = { module.exports = {
QUALITY_REQUESTED: 'qualityRequested',
QUALITY_SELECTED: 'qualitySelected', QUALITY_SELECTED: 'qualitySelected',
}; };

View File

@ -13,7 +13,7 @@ module.exports = function(videojs) {
videojs.hook('setup', function(player) { videojs.hook('setup', function(player) {
// Add handler to switch sources when the user requests a change // Add handler to switch sources when the user requests a change
player.on(events.QUALITY_SELECTED, function(event, newSource) { player.on(events.QUALITY_REQUESTED, function(event, newSource) {
var sources = player.currentSources(), var sources = player.currentSources(),
currentTime = player.currentTime(), currentTime = player.currentTime(),
isPaused = player.paused(), isPaused = player.paused(),

View File

@ -1,6 +1,7 @@
'use strict'; 'use strict';
var _ = require('underscore'); var _ = require('underscore'),
events = require('../events');
module.exports = function(videojs) { module.exports = function(videojs) {
@ -10,8 +11,7 @@ module.exports = function(videojs) {
setSource: function(playerSelectedSource, next) { setSource: function(playerSelectedSource, next) {
var sources = player.currentSources(), var sources = player.currentSources(),
userSelectedSource, chosenSource, userSelectedSource, chosenSource;
qualitySelector;
// There are generally two source options, the one that videojs // There are generally two source options, the one that videojs
// auto-selects and the one that a "user" of this plugin has // auto-selects and the one that a "user" of this plugin has
@ -28,11 +28,7 @@ module.exports = function(videojs) {
chosenSource = userSelectedSource || playerSelectedSource; chosenSource = userSelectedSource || playerSelectedSource;
// Update the quality selector with the new source player.trigger(events.QUALITY_SELECTED, chosenSource);
qualitySelector = player.controlBar.getChild('qualitySelector');
if (qualitySelector) {
qualitySelector.setSelectedSource(chosenSource);
}
// Pass along the chosen source // Pass along the chosen source
next(null, chosenSource); next(null, chosenSource);