diff options
author | Sam Potts <sam@potts.es> | 2018-05-30 21:44:42 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-30 21:44:42 +1000 |
commit | 450958c2904ad9e2d0c4f283af96f9bf69eeb250 (patch) | |
tree | e24e9cd14704959b52eb0528541bc72f490f845d /src/js | |
parent | ce199e4b6bb40899d69ad6d67aab9f0a8be66517 (diff) | |
parent | 963fe11ad66fcbf28d93b0c6d2a20f3cd77b83cf (diff) | |
download | plyr-450958c2904ad9e2d0c4f283af96f9bf69eeb250.tar.lz plyr-450958c2904ad9e2d0c4f283af96f9bf69eeb250.tar.xz plyr-450958c2904ad9e2d0c4f283af96f9bf69eeb250.zip |
Merge pull request #981 from friday/hls-captions
Improve captions handling for streaming
Diffstat (limited to 'src/js')
-rw-r--r-- | src/js/captions.js | 94 | ||||
-rw-r--r-- | src/js/controls.js | 5 | ||||
-rw-r--r-- | src/js/defaults.js | 5 | ||||
-rw-r--r-- | src/js/plyr.js | 21 | ||||
-rw-r--r-- | src/js/ui.js | 6 |
5 files changed, 54 insertions, 77 deletions
diff --git a/src/js/captions.js b/src/js/captions.js index df717351..30c4bc74 100644 --- a/src/js/captions.js +++ b/src/js/captions.js @@ -16,28 +16,6 @@ const captions = { return; } - // Set default language if not set - const stored = this.storage.get('language'); - - if (!utils.is.empty(stored)) { - this.captions.language = stored; - } - - if (utils.is.empty(this.captions.language)) { - this.captions.language = this.config.captions.language.toLowerCase(); - } - - // Set captions enabled state if not set - if (!utils.is.boolean(this.captions.active)) { - const active = this.storage.get('captions'); - - if (utils.is.boolean(active)) { - this.captions.active = active; - } else { - this.captions.active = this.config.captions.active; - } - } - // Only Vimeo and HTML5 video supported at this point if (!this.isVideo || this.isYouTube || (this.isHTML5 && !support.textTracks)) { // Clear menu and hide @@ -55,17 +33,6 @@ const captions = { utils.insertAfter(this.elements.captions, this.elements.wrapper); } - // Set the class hook - utils.toggleClass(this.elements.container, this.config.classNames.captions.enabled, !utils.is.empty(captions.getTracks.call(this))); - - // Get tracks - const tracks = captions.getTracks.call(this); - - // If no caption file exists, hide container for caption text - if (utils.is.empty(tracks)) { - return; - } - // Get browser info const browser = utils.getBrowser(); @@ -94,14 +61,45 @@ const captions = { }); } - // Set language - captions.setLanguage.call(this); + // Try to load the value from storage + let active = this.storage.get('captions'); + + // Otherwise fall back to the default config + if (!utils.is.boolean(active)) { + ({ active } = this.config.captions); + } - // Enable UI - captions.show.call(this); + // Set toggled state + this.toggleCaptions(active); - // Set available languages in list - if (utils.is.array(this.config.controls) && this.config.controls.includes('settings') && this.config.settings.includes('captions')) { + // Watch changes to textTracks and update captions menu + if (this.config.captions.update) { + utils.on(this.media.textTracks, 'addtrack removetrack', captions.update.bind(this)); + } + + // Update available languages in list next tick (the event must not be triggered before the listeners) + setTimeout(captions.update.bind(this), 0); + }, + + update() { + // Update tracks + const tracks = captions.getTracks.call(this); + this.options.captions = tracks.map(({language}) => language); + + // Set language if it hasn't been set already + if (!this.language) { + let { language } = this.config.captions; + if (language === 'auto') { + [ language ] = (navigator.language || navigator.userLanguage).split('-'); + } + this.language = this.storage.get('language') || (language || '').toLowerCase(); + } + + // Toggle the class hooks + utils.toggleClass(this.elements.container, this.config.classNames.captions.enabled, !utils.is.empty(captions.getTracks.call(this))); + + // Update available languages in list + if ((this.config.controls || []).includes('settings') && this.config.settings.includes('captions')) { controls.setCaptionsMenu.call(this); } }, @@ -247,24 +245,6 @@ const captions = { this.debug.warn('No captions element to render to'); } }, - - // Display captions container and button (for initialization) - show() { - // Try to load the value from storage - let active = this.storage.get('captions'); - - // Otherwise fall back to the default config - if (!utils.is.boolean(active)) { - ({ active } = this.config.captions); - } else { - this.captions.active = active; - } - - if (active) { - utils.toggleClass(this.elements.container, this.config.classNames.captions.active, true); - utils.toggleState(this.elements.buttons.captions, true); - } - }, }; export default captions; diff --git a/src/js/controls.js b/src/js/controls.js index c76bd66b..32e82f78 100644 --- a/src/js/controls.js +++ b/src/js/controls.js @@ -883,13 +883,10 @@ const controls = { 'language', track.label, track.language !== 'enabled' ? controls.createBadge.call(this, track.language.toUpperCase()) : null, - track.language.toLowerCase() === this.captions.language.toLowerCase(), + track.language.toLowerCase() === this.language, ); }); - // Store reference - this.options.captions = tracks.map(track => track.language); - controls.updateSetting.call(this, type, list); }, diff --git a/src/js/defaults.js b/src/js/defaults.js index 505520a5..6a88e73f 100644 --- a/src/js/defaults.js +++ b/src/js/defaults.js @@ -115,7 +115,10 @@ const defaults = { // Captions settings captions: { active: false, - language: (navigator.language || navigator.userLanguage).split('-')[0], + language: 'auto', + // Listen to new tracks added after Plyr is initialized. + // This is needed for streaming captions, but may result in unselectable options + update: false, }, // Fullscreen settings diff --git a/src/js/plyr.js b/src/js/plyr.js index 4a064e09..557291d9 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -838,24 +838,19 @@ class Plyr { } // If the method is called without parameter, toggle based on current value - const show = utils.is.boolean(input) ? input : !this.elements.container.classList.contains(this.config.classNames.captions.active); - - // Nothing to change... - if (this.captions.active === show) { - return; - } - - // Set global - this.captions.active = show; + const active = utils.is.boolean(input) ? input : !this.elements.container.classList.contains(this.config.classNames.captions.active); // Toggle state - utils.toggleState(this.elements.buttons.captions, this.captions.active); + utils.toggleState(this.elements.buttons.captions, active); // Add class hook - utils.toggleClass(this.elements.container, this.config.classNames.captions.active, this.captions.active); + utils.toggleClass(this.elements.container, this.config.classNames.captions.active, active); - // Trigger an event - utils.dispatchEvent.call(this, this.media, this.captions.active ? 'captionsenabled' : 'captionsdisabled'); + // Update state and trigger event + if (active !== this.captions.active) { + this.captions.active = active; + utils.dispatchEvent.call(this, this.media, this.captions.active ? 'captionsenabled' : 'captionsdisabled'); + } } /** diff --git a/src/js/ui.js b/src/js/ui.js index aa398e3a..d6ab0e59 100644 --- a/src/js/ui.js +++ b/src/js/ui.js @@ -55,8 +55,10 @@ const ui = { // Remove native controls ui.toggleNativeControls.call(this); - // Captions - captions.setup.call(this); + // Setup captions for HTML5 + if (this.isHTML5) { + captions.setup.call(this); + } // Reset volume this.volume = null; |