diff options
Diffstat (limited to 'dist/plyr.polyfilled.js')
-rw-r--r-- | dist/plyr.polyfilled.js | 557 |
1 files changed, 315 insertions, 242 deletions
diff --git a/dist/plyr.polyfilled.js b/dist/plyr.polyfilled.js index b919a304..fa2e8b7b 100644 --- a/dist/plyr.polyfilled.js +++ b/dist/plyr.polyfilled.js @@ -5876,61 +5876,63 @@ var utils = { // Check variable types is: { object: function object(input) { - return this.getConstructor(input) === Object; + return utils.getConstructor(input) === Object; }, number: function number(input) { - return this.getConstructor(input) === Number && !Number.isNaN(input); + return utils.getConstructor(input) === Number && !Number.isNaN(input); }, string: function string(input) { - return this.getConstructor(input) === String; + return utils.getConstructor(input) === String; }, boolean: function boolean(input) { - return this.getConstructor(input) === Boolean; + return utils.getConstructor(input) === Boolean; }, function: function _function(input) { - return this.getConstructor(input) === Function; + return utils.getConstructor(input) === Function; }, array: function array(input) { - return !this.nullOrUndefined(input) && Array.isArray(input); + return !utils.is.nullOrUndefined(input) && Array.isArray(input); }, weakMap: function weakMap(input) { - return this.instanceof(input, WeakMap); + return utils.is.instanceof(input, WeakMap); }, nodeList: function nodeList(input) { - return this.instanceof(input, NodeList); + return utils.is.instanceof(input, NodeList); }, element: function element(input) { - return this.instanceof(input, Element); + return utils.is.instanceof(input, Element); }, textNode: function textNode(input) { - return this.getConstructor(input) === Text; + return utils.getConstructor(input) === Text; }, event: function event(input) { - return this.instanceof(input, Event); + return utils.is.instanceof(input, Event); }, cue: function cue(input) { - return this.instanceof(input, window.TextTrackCue) || this.instanceof(input, window.VTTCue); + return utils.is.instanceof(input, window.TextTrackCue) || utils.is.instanceof(input, window.VTTCue); }, track: function track(input) { - return this.instanceof(input, TextTrack) || !this.nullOrUndefined(input) && this.string(input.kind); + return utils.is.instanceof(input, TextTrack) || !utils.is.nullOrUndefined(input) && utils.is.string(input.kind); }, url: function url(input) { - return !this.nullOrUndefined(input) && /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-/]))?/.test(input); + return !utils.is.nullOrUndefined(input) && /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-/]))?/.test(input); }, nullOrUndefined: function nullOrUndefined(input) { return input === null || typeof input === 'undefined'; }, empty: function empty(input) { - return this.nullOrUndefined(input) || (this.string(input) || this.array(input) || this.nodeList(input)) && !input.length || this.object(input) && !Object.keys(input).length; + return utils.is.nullOrUndefined(input) || (utils.is.string(input) || utils.is.array(input) || utils.is.nodeList(input)) && !input.length || utils.is.object(input) && !Object.keys(input).length; }, instanceof: function _instanceof$$1(input, constructor) { return Boolean(input && constructor && input instanceof constructor); - }, - getConstructor: function getConstructor(input) { - return !this.nullOrUndefined(input) ? input.constructor : null; } }, + getConstructor: function getConstructor(input) { + return !utils.is.nullOrUndefined(input) ? input.constructor : null; + }, + + // Unfortunately, due to mixed support, UA sniffing is required getBrowser: function getBrowser() { return { @@ -6550,7 +6552,7 @@ var utils = { // Bail if the value isn't a number if (!utils.is.number(time)) { - return this.formatTime(null, displayHours, inverted); + return utils.formatTime(null, displayHours, inverted); } // Format time component to add leading zero @@ -6559,9 +6561,9 @@ var utils = { }; // Breakdown to hours, mins, secs - var hours = this.getHours(time); - var mins = this.getMinutes(time); - var secs = this.getSeconds(time); + var hours = utils.getHours(time); + var mins = utils.getMinutes(time); + var secs = utils.getSeconds(time); // Do we need to display hours? if (displayHours || hours > 0) { @@ -6757,12 +6759,12 @@ var utils = { // Parse URL if needed if (input.startsWith('http://') || input.startsWith('https://')) { - var _parseUrl = this.parseUrl(input); + var _utils$parseUrl = utils.parseUrl(input); - search = _parseUrl.search; + search = _utils$parseUrl.search; } - if (this.is.empty(search)) { + if (utils.is.empty(search)) { return null; } @@ -6801,6 +6803,14 @@ var utils = { }, + // Like outerHTML, but also works for DocumentFragment + getHTML: function getHTML(element) { + var wrapper = document.createElement('div'); + wrapper.appendChild(element); + return wrapper.innerHTML; + }, + + // Get aspect ratio for dimensions getAspectRatio: function getAspectRatio(width, height) { var getRatio = function getRatio(w, h) { @@ -7542,9 +7552,15 @@ var controls = { // Create a settings menu item - createMenuItem: function createMenuItem(value, list, type, title) { - var badge = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null; - var checked = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false; + createMenuItem: function createMenuItem(_ref) { + var value = _ref.value, + list = _ref.list, + type = _ref.type, + title = _ref.title, + _ref$badge = _ref.badge, + badge = _ref$badge === undefined ? null : _ref$badge, + _ref$checked = _ref.checked, + checked = _ref$checked === undefined ? false : _ref$checked; var item = utils.createElement('li'); @@ -7860,8 +7876,13 @@ var controls = { var sorting = _this3.config.quality.options; return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1; }).forEach(function (quality) { - var label = controls.getLabel.call(_this3, 'quality', quality); - controls.createMenuItem.call(_this3, quality, list, type, label, getBadge(quality)); + controls.createMenuItem.call(_this3, { + value: quality, + list: list, + type: type, + title: controls.getLabel.call(_this3, 'quality', quality), + badge: getBadge(quality) + }); }); controls.updateSetting.call(this, type, list); @@ -7904,18 +7925,7 @@ var controls = { switch (setting) { case 'captions': - if (this.captions.active) { - if (this.options.captions.length > 2 || !this.options.captions.some(function (lang) { - return lang === 'enabled'; - })) { - value = this.captions.language; - } else { - value = 'enabled'; - } - } else { - value = ''; - } - + value = this.currentTrack; break; default: @@ -8010,10 +8020,10 @@ var controls = { // TODO: Captions or language? Currently it's mixed var type = 'captions'; var list = this.elements.settings.panes.captions.querySelector('ul'); + var tracks = captions.getTracks.call(this); // Toggle the pane and tab - var toggle = captions.getTracks.call(this).length; - controls.toggleTab.call(this, type, toggle); + controls.toggleTab.call(this, type, tracks.length); // Empty the menu utils.emptyElement(list); @@ -8022,28 +8032,33 @@ var controls = { controls.checkMenu.call(this); // If there's no captions, bail - if (!toggle) { + if (!tracks.length) { return; } - // Re-map the tracks into just the data we need - var tracks = captions.getTracks.call(this).map(function (track) { + // Generate options data + var options = tracks.map(function (track, value) { return { - language: !utils.is.empty(track.language) ? track.language : 'enabled', - label: captions.getLabel.call(_this4, track) + value: value, + checked: _this4.captions.active && _this4.currentTrack === value, + title: captions.getLabel.call(_this4, track), + badge: track.language && controls.createBadge.call(_this4, track.language.toUpperCase()), + list: list, + type: 'language' }; }); // Add the "Disabled" option to turn off captions - tracks.unshift({ - language: '', - label: i18n.get('disabled', this.config) + options.unshift({ + value: -1, + checked: !this.captions.active, + title: i18n.get('disabled', this.config), + list: list, + type: 'language' }); // Generate options - tracks.forEach(function (track) { - controls.createMenuItem.call(_this4, track.language, list, 'language', track.label, track.language !== 'enabled' ? controls.createBadge.call(_this4, track.language.toUpperCase()) : null, track.language.toLowerCase() === _this4.language); - }); + options.forEach(controls.createMenuItem.bind(this)); controls.updateSetting.call(this, type, list); }, @@ -8097,8 +8112,12 @@ var controls = { // Create items this.options.speed.forEach(function (speed) { - var label = controls.getLabel.call(_this5, 'speed', speed); - controls.createMenuItem.call(_this5, speed, list, type, label); + controls.createMenuItem.call(_this5, { + value: speed, + list: list, + type: type, + title: controls.getLabel.call(_this5, 'speed', speed) + }); }); controls.updateSetting.call(this, type, list); @@ -8572,10 +8591,10 @@ var controls = { var replace = function replace(input) { var result = input; - Object.entries(props).forEach(function (_ref) { - var _ref2 = slicedToArray(_ref, 2), - key = _ref2[0], - value = _ref2[1]; + Object.entries(props).forEach(function (_ref2) { + var _ref3 = slicedToArray(_ref2, 2), + key = _ref3[0], + value = _ref3[1]; result = utils.replaceAll(result, '{' + key + '}', value); }); @@ -8692,124 +8711,189 @@ var captions = { active = this.config.captions.active; } - // Set toggled state - this.toggleCaptions(active); + // Get language from storage, fallback to config + var language = this.storage.get('language') || this.config.captions.language; + if (language === 'auto') { + var _split = (navigator.language || navigator.userLanguage).split('-'); + + var _split2 = slicedToArray(_split, 1); + + language = _split2[0]; + } + // Set language and show if active + captions.setLanguage.call(this, language, active); // Watch changes to textTracks and update captions menu - if (this.config.captions.update) { - utils.on(this.media.textTracks, 'addtrack removetrack', captions.update.bind(this)); + if (this.isHTML5) { + var trackEvents = this.config.captions.update ? 'addtrack removetrack' : 'removetrack'; + utils.on(this.media.textTracks, trackEvents, 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: function update() { - // Update tracks - var tracks = captions.getTracks.call(this); - this.options.captions = tracks.map(function (_ref) { - var language = _ref.language; - return language; - }); + var _this = this; - // Set language if it hasn't been set already - if (!this.language) { - var language = this.config.captions.language; + var tracks = captions.getTracks.call(this, true); + // Get the wanted language + var _captions = this.captions, + language = _captions.language, + meta = _captions.meta; - if (language === 'auto') { - var _split = (navigator.language || navigator.userLanguage).split('-'); + // Handle tracks (add event listener and "pseudo"-default) - var _split2 = slicedToArray(_split, 1); + if (this.isHTML5 && this.isVideo) { + tracks.filter(function (track) { + return !meta.get(track); + }).forEach(function (track) { + _this.debug.log('Track added', track); + // Attempt to store if the original dom element was "default" + meta.set(track, { + default: track.mode === 'showing' + }); - language = _split2[0]; - } - this.language = this.storage.get('language') || (language || '').toLowerCase(); + // Turn off native caption rendering to avoid double captions + track.mode = 'hidden'; + + // Add event listener for cue changes + utils.on(track, 'cuechange', function () { + return captions.updateCues.call(_this); + }); + }); + } + + var trackRemoved = !tracks.find(function (track) { + return track === _this.captions.currentTrackNode; + }); + var firstMatch = this.language !== language && tracks.find(function (track) { + return track.language === language; + }); + + // Update language if removed or first matching track added + if (trackRemoved || firstMatch) { + captions.setLanguage.call(this, language, this.config.captions.active); } - // Toggle the class hooks - utils.toggleClass(this.elements.container, this.config.classNames.captions.enabled, !utils.is.empty(captions.getTracks.call(this))); + // Enable or disable captions based on track length + utils.toggleClass(this.elements.container, this.config.classNames.captions.enabled, !utils.is.empty(tracks)); // Update available languages in list if ((this.config.controls || []).includes('settings') && this.config.settings.includes('captions')) { controls.setCaptionsMenu.call(this); } }, + set: function set(index) { + var setLanguage = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var show = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + var tracks = captions.getTracks.call(this); - // Set the captions language - setLanguage: function setLanguage() { - var _this = this; + // Disable captions if setting to -1 + if (index === -1) { + this.toggleCaptions(false); + return; + } - // Setup HTML5 track rendering - if (this.isHTML5 && this.isVideo) { - captions.getTracks.call(this).forEach(function (track) { - // Show track - utils.on(track, 'cuechange', function (event) { - return captions.setCue.call(_this, event); - }); + if (!utils.is.number(index)) { + this.debug.warn('Invalid caption argument', index); + return; + } - // Turn off native caption rendering to avoid double captions - // eslint-disable-next-line - track.mode = 'hidden'; - }); + if (!(index in tracks)) { + this.debug.warn('Track not found', index); + return; + } - // Get current track - var currentTrack = captions.getCurrentTrack.call(this); + if (this.captions.currentTrack !== index) { + this.captions.currentTrack = index; + var track = captions.getCurrentTrack.call(this); - // Check if suported kind - if (utils.is.track(currentTrack)) { - // If we change the active track while a cue is already displayed we need to update it - if (Array.from(currentTrack.activeCues || []).length) { - captions.setCue.call(this, currentTrack); - } + var _ref = track || {}, + language = _ref.language; + + // Store reference to node for invalidation on remove + + + this.captions.currentTrackNode = track; + + // Prevent setting language in some cases, since it can violate user's intentions + if (setLanguage) { + this.captions.language = language; } - } else if (this.isVimeo && this.captions.active) { - this.embed.enableTextTrack(this.language); + + // Handle Vimeo captions + if (this.isVimeo) { + this.embed.enableTextTrack(language); + } + + // Trigger event + utils.dispatchEvent.call(this, this.media, 'languagechange'); } - }, + if (this.isHTML5 && this.isVideo) { + // If we change the active track while a cue is already displayed we need to update it + captions.updateCues.call(this); + } - // Get the tracks - getTracks: function getTracks() { - // Return empty array at least - if (utils.is.nullOrUndefined(this.media)) { - return []; + // Show captions + if (show) { + this.toggleCaptions(true); } + }, + setLanguage: function setLanguage(language) { + var show = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - // Only get accepted kinds - return Array.from(this.media.textTracks || []).filter(function (track) { - return ['captions', 'subtitles'].includes(track.kind); - }); + if (!utils.is.string(language)) { + this.debug.warn('Invalid language argument', language); + return; + } + // Normalize + this.captions.language = language.toLowerCase(); + + // Set currentTrack + var tracks = captions.getTracks.call(this); + var track = captions.getCurrentTrack.call(this, true); + captions.set.call(this, tracks.indexOf(track), false, show); }, - // Get the current track for the current language - getCurrentTrack: function getCurrentTrack() { + // Get current valid caption tracks + // If update is false it will also ignore tracks without metadata + // This is used to "freeze" the language options when captions.update is false + getTracks: function getTracks() { var _this2 = this; - var tracks = captions.getTracks.call(this); + var update = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - if (!tracks.length) { - return null; - } - - // Get track based on current language - var track = tracks.find(function (track) { - return track.language.toLowerCase() === _this2.language; + // Handle media or textTracks missing or null + var tracks = Array.from((this.media || {}).textTracks || []); + // For HTML5, use cache instead of current tracks when it exists (if captions.update is false) + // Filter out removed tracks and tracks that aren't captions/subtitles (for example metadata) + return tracks.filter(function (track) { + return !_this2.isHTML5 || update || _this2.captions.meta.has(track); + }).filter(function (track) { + return ['captions', 'subtitles'].includes(track.kind); }); + }, - // Get the <track> with default attribute - if (!track) { - track = utils.getElement.call(this, 'track[default]'); - } - // Get the first track - if (!track) { - var _tracks = slicedToArray(tracks, 1); + // Get the current track for the current language + getCurrentTrack: function getCurrentTrack() { + var _this3 = this; - track = _tracks[0]; - } + var fromLanguage = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - return track; + var tracks = captions.getTracks.call(this); + var sortIsDefault = function sortIsDefault(track) { + return Number((_this3.captions.meta.get(track) || {}).default); + }; + var sorted = Array.from(tracks).sort(function (a, b) { + return sortIsDefault(b) - sortIsDefault(a); + }); + return !fromLanguage && tracks[this.currentTrack] || sorted.find(function (track) { + return track.language === _this3.captions.language; + }) || sorted[0]; }, @@ -8837,58 +8921,50 @@ var captions = { }, - // Display active caption if it contains text - setCue: function setCue(input) { - // Get the track from the event if needed - var track = utils.is.event(input) ? input.target : input; - var activeCues = track.activeCues; - - var active = activeCues.length && activeCues[0]; - var currentTrack = captions.getCurrentTrack.call(this); - - // Only display current track - if (track !== currentTrack) { + // Update captions using current track's active cues + // Also optional array argument in case there isn't any track (ex: vimeo) + updateCues: function updateCues(input) { + // Requires UI + if (!this.supported.ui) { return; } - // Display a cue, if there is one - if (utils.is.cue(active)) { - captions.setText.call(this, active.getCueAsHTML()); - } else { - captions.setText.call(this, null); + if (!utils.is.element(this.elements.captions)) { + this.debug.warn('No captions element to render to'); + return; } - utils.dispatchEvent.call(this, this.media, 'cuechange'); - }, - - - // Set the current caption - setText: function setText(input) { - // Requires UI - if (!this.supported.ui) { + // Only accept array or empty input + if (!utils.is.nullOrUndefined(input) && !Array.isArray(input)) { + this.debug.warn('updateCues: Invalid input', input); return; } - if (utils.is.element(this.elements.captions)) { - var content = utils.createElement('span'); + var cues = input; - // Empty the container - utils.emptyElement(this.elements.captions); + // Get cues from track + if (!cues) { + var track = captions.getCurrentTrack.call(this); + cues = Array.from((track || {}).activeCues || []).map(function (cue) { + return cue.getCueAsHTML(); + }).map(utils.getHTML); + } - // Default to empty - var caption = !utils.is.nullOrUndefined(input) ? input : ''; + // Set new caption text + var content = cues.map(function (cueText) { + return cueText.trim(); + }).join('\n'); + var changed = content !== this.elements.captions.innerHTML; - // Set the span content - if (utils.is.string(caption)) { - content.innerText = caption.trim(); - } else { - content.appendChild(caption); - } + if (changed) { + // Empty the container and create a new child element + utils.emptyElement(this.elements.captions); + var caption = utils.createElement('span', utils.getAttributesFromSelector(this.config.selectors.caption)); + caption.innerHTML = content; + this.elements.captions.appendChild(caption); - // Set new caption text - this.elements.captions.appendChild(content); - } else { - this.debug.warn('No captions element to render to'); + // Trigger event + utils.dispatchEvent.call(this, this.media, 'cuechange'); } } }; @@ -8991,7 +9067,7 @@ var defaults$1 = { // Sprite (for icons) loadSprite: true, iconPrefix: 'plyr', - iconUrl: 'https://cdn.plyr.io/3.3.10/plyr.svg', + iconUrl: 'https://cdn.plyr.io/3.3.12/plyr.svg', // Blank video (used to prevent errors on source change) blankVideo: 'https://cdn.plyr.io/static/blank.mp4', @@ -9192,6 +9268,7 @@ var defaults$1 = { }, progress: '.plyr__progress', captions: '.plyr__captions', + caption: '.plyr__caption', menu: { quality: '.js-plyr__menu__list--quality' } @@ -10170,9 +10247,11 @@ var Listeners = function () { // Proxy events to container // Bubble up key events for Edge utils.on(this.player.media, this.player.config.events.concat(['keyup', 'keydown']).join(' '), function (event) { - var detail = {}; + var _event$detail = event.detail, + detail = _event$detail === undefined ? {} : _event$detail; // Get error details from media + if (event.type === 'error') { detail = _this3.player.media.error; } @@ -10271,7 +10350,7 @@ var Listeners = function () { // Settings menu items - use event delegation as items are added/removed if (utils.matches(event.target, _this4.player.config.selectors.inputs.language)) { proxy(event, function () { - _this4.player.language = event.target.value; + _this4.player.currentTrack = Number(event.target.value); showHomeTab(); }, 'language'); } else if (utils.matches(event.target, _this4.player.config.selectors.inputs.quality)) { @@ -10466,6 +10545,9 @@ var Listeners = function () { // Set playback state and trigger change (only on actual change) function assurePlaybackState(play) { + if (play && !this.embed.hasPlayed) { + this.embed.hasPlayed = true; + } if (this.media.paused === play) { this.media.paused = !play; utils.dispatchEvent.call(this, this.media, play ? 'play' : 'pause'); @@ -10618,24 +10700,25 @@ var vimeo = { paused = player.paused, volume = player.volume; - // Set seeking state and trigger event + var restorePause = paused && !embed.hasPlayed; + // Set seeking state and trigger event media.seeking = true; utils.dispatchEvent.call(player, media, 'seeking'); // If paused, mute until seek is complete - Promise.resolve(paused && embed.setVolume(0)) + Promise.resolve(restorePause && embed.setVolume(0)) // Seek .then(function () { return embed.setCurrentTime(time); }) // Restore paused .then(function () { - return paused && embed.pause(); + return restorePause && embed.pause(); }) // Restore volume .then(function () { - return paused && embed.setVolume(volume); + return restorePause && embed.setVolume(volume); }).catch(function () { // Do nothing }); @@ -10765,17 +10848,25 @@ var vimeo = { captions.setup.call(player); }); - player.embed.on('cuechange', function (data) { - var cue = null; - - if (data.cues.length) { - cue = utils.stripHTML(data.cues[0].text); - } + player.embed.on('cuechange', function (_ref) { + var _ref$cues = _ref.cues, + cues = _ref$cues === undefined ? [] : _ref$cues; - captions.setText.call(player, cue); + var strippedCues = cues.map(function (cue) { + return utils.stripHTML(cue.text); + }); + captions.updateCues.call(player, strippedCues); }); player.embed.on('loaded', function () { + // Assure state and events are updated on autoplay + player.embed.getPaused().then(function (paused) { + assurePlaybackState.call(player, !paused); + if (!paused) { + utils.dispatchEvent.call(player, player.media, 'playing'); + } + }); + if (utils.is.element(player.embed.element) && player.supported.ui) { var frame = player.embed.element; @@ -10905,6 +10996,9 @@ function mapQualityUnits(levels) { // Set playback state and trigger change (only on actual change) function assurePlaybackState$1(play) { + if (play && !this.embed.hasPlayed) { + this.embed.hasPlayed = true; + } if (this.media.paused === play) { this.media.paused = !play; utils.dispatchEvent.call(this, this.media, play ? 'play' : 'pause'); @@ -11318,7 +11412,7 @@ var youtube = { case 1: // Restore paused state (YouTube starts playing on seek if the video hasn't been played yet) - if (player.media.paused) { + if (player.media.paused && !player.embed.hasPlayed) { player.media.pause(); } else { assurePlaybackState$1.call(player, true); @@ -12309,7 +12403,8 @@ var Plyr = function () { // Captions this.captions = { active: null, - currentTrack: null + currentTrack: -1, + meta: new WeakMap() }; // Fullscreen @@ -12320,8 +12415,7 @@ var Plyr = function () { // Options this.options = { speed: [], - quality: [], - captions: [] + quality: [] }; // Debugging @@ -12697,8 +12791,8 @@ var Plyr = function () { } /** - * Set the captions language - * @param {string} - Two character ISO language code (e.g. EN, FR, PT, etc) + * Set the caption track by index + * @param {number} - Caption index */ }, { @@ -13389,60 +13483,41 @@ var Plyr = function () { return Boolean(this.config.autoplay); } }, { - key: 'language', + key: 'currentTrack', set: function set(input) { - // Nothing specified - if (!utils.is.string(input)) { - return; - } - - // If empty string is passed, assume disable captions - if (utils.is.empty(input)) { - this.toggleCaptions(false); - return; - } - - // Normalize - var language = input.toLowerCase(); - - // Check for support - if (!this.options.captions.includes(language)) { - this.debug.warn('Unsupported language option: ' + language); - return; - } - - // Ensure captions are enabled - this.toggleCaptions(true); - - // Enabled only - if (language === 'enabled') { - return; - } - - // If nothing to change, bail - if (this.language === language) { - return; - } + captions.set.call(this, input); + } - // Update config - this.captions.language = language; + /** + * Get the current caption track index (-1 if disabled) + */ + , + get: function get() { + var _captions = this.captions, + active = _captions.active, + currentTrack = _captions.currentTrack; - // Clear caption - captions.setText.call(this, null); + return active ? currentTrack : -1; + } - // Update captions - captions.setLanguage.call(this); + /** + * Set the wanted language for captions + * Since tracks can be added later it won't update the actual caption track until there is a matching track + * @param {string} - Two character ISO language code (e.g. EN, FR, PT, etc) + */ - // Trigger an event - utils.dispatchEvent.call(this, this.media, 'languagechange'); + }, { + key: 'language', + set: function set(input) { + captions.setLanguage.call(this, input); } /** - * Get the current captions language + * Get the current track's language */ , get: function get() { - return this.captions.language; + return (captions.getCurrentTrack.call(this) || {}).language; } /** @@ -13518,9 +13593,7 @@ var Plyr = function () { } else if (utils.is.nodeList(selector)) { targets = Array.from(selector); } else if (utils.is.array(selector)) { - targets = selector.filter(function (i) { - return utils.is.element(i); - }); + targets = selector.filter(utils.is.element); } if (utils.is.empty(targets)) { |