Merge
This commit is contained in:
parent
1ad76800b0
commit
abd1182303
2
demo/dist/demo.css
vendored
2
demo/dist/demo.css
vendored
File diff suppressed because one or more lines are too long
110
demo/dist/demo.js
vendored
110
demo/dist/demo.js
vendored
@ -767,11 +767,12 @@ function getLocationOrigin() {
|
|||||||
|
|
||||||
// Oh dear IE10...
|
// Oh dear IE10...
|
||||||
if (!document.location.origin) {
|
if (!document.location.origin) {
|
||||||
document.location.origin =
|
return (
|
||||||
document.location.protocol +
|
document.location.protocol +
|
||||||
'//' +
|
'//' +
|
||||||
document.location.hostname +
|
document.location.hostname +
|
||||||
(document.location.port ? ':' + document.location.port : '');
|
(document.location.port ? ':' + document.location.port : '')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return document.location.origin;
|
return document.location.origin;
|
||||||
@ -1866,7 +1867,7 @@ Raven.prototype = {
|
|||||||
// webpack (using a build step causes webpack #1617). Grunt verifies that
|
// webpack (using a build step causes webpack #1617). Grunt verifies that
|
||||||
// this value matches package.json during build.
|
// this value matches package.json during build.
|
||||||
// See: https://github.com/getsentry/raven-js/issues/465
|
// See: https://github.com/getsentry/raven-js/issues/465
|
||||||
VERSION: '3.25.2',
|
VERSION: '3.26.1',
|
||||||
|
|
||||||
debug: false,
|
debug: false,
|
||||||
|
|
||||||
@ -2032,7 +2033,7 @@ Raven.prototype = {
|
|||||||
if (isFunction$1(options)) {
|
if (isFunction$1(options)) {
|
||||||
args = func || [];
|
args = func || [];
|
||||||
func = options;
|
func = options;
|
||||||
options = undefined;
|
options = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.wrap(options, func).apply(this, args);
|
return this.wrap(options, func).apply(this, args);
|
||||||
@ -2043,7 +2044,7 @@ Raven.prototype = {
|
|||||||
*
|
*
|
||||||
* @param {object} options A specific set of options for this context [optional]
|
* @param {object} options A specific set of options for this context [optional]
|
||||||
* @param {function} func The function to be wrapped in a new context
|
* @param {function} func The function to be wrapped in a new context
|
||||||
* @param {function} func A function to call before the try/catch wrapper [optional, private]
|
* @param {function} _before A function to call before the try/catch wrapper [optional, private]
|
||||||
* @return {function} The newly wrapped functions with a context
|
* @return {function} The newly wrapped functions with a context
|
||||||
*/
|
*/
|
||||||
wrap: function(options, func, _before) {
|
wrap: function(options, func, _before) {
|
||||||
@ -2156,8 +2157,9 @@ Raven.prototype = {
|
|||||||
_promiseRejectionHandler: function(event) {
|
_promiseRejectionHandler: function(event) {
|
||||||
this._logDebug('debug', 'Raven caught unhandled promise rejection:', event);
|
this._logDebug('debug', 'Raven caught unhandled promise rejection:', event);
|
||||||
this.captureException(event.reason, {
|
this.captureException(event.reason, {
|
||||||
extra: {
|
mechanism: {
|
||||||
unhandledPromiseRejection: true
|
type: 'onunhandledrejection',
|
||||||
|
handled: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -2834,7 +2836,15 @@ Raven.prototype = {
|
|||||||
}
|
}
|
||||||
var originalCallback = args[0];
|
var originalCallback = args[0];
|
||||||
if (isFunction$1(originalCallback)) {
|
if (isFunction$1(originalCallback)) {
|
||||||
args[0] = self.wrap(originalCallback);
|
args[0] = self.wrap(
|
||||||
|
{
|
||||||
|
mechanism: {
|
||||||
|
type: 'instrument',
|
||||||
|
data: {function: orig.name}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
originalCallback
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// IE < 9 doesn't support .call/.apply on setInterval/setTimeout, but it
|
// IE < 9 doesn't support .call/.apply on setInterval/setTimeout, but it
|
||||||
@ -2861,7 +2871,15 @@ Raven.prototype = {
|
|||||||
// preserve arity
|
// preserve arity
|
||||||
try {
|
try {
|
||||||
if (fn && fn.handleEvent) {
|
if (fn && fn.handleEvent) {
|
||||||
fn.handleEvent = self.wrap(fn.handleEvent);
|
fn.handleEvent = self.wrap(
|
||||||
|
{
|
||||||
|
mechanism: {
|
||||||
|
type: 'instrument',
|
||||||
|
data: {target: global, function: 'handleEvent', handler: fn.name}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fn.handleEvent
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// can sometimes get 'Permission denied to access property "handle Event'
|
// can sometimes get 'Permission denied to access property "handle Event'
|
||||||
@ -2901,7 +2919,20 @@ Raven.prototype = {
|
|||||||
return orig.call(
|
return orig.call(
|
||||||
this,
|
this,
|
||||||
evtName,
|
evtName,
|
||||||
self.wrap(fn, undefined, before),
|
self.wrap(
|
||||||
|
{
|
||||||
|
mechanism: {
|
||||||
|
type: 'instrument',
|
||||||
|
data: {
|
||||||
|
target: global,
|
||||||
|
function: 'addEventListener',
|
||||||
|
handler: fn.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fn,
|
||||||
|
before
|
||||||
|
),
|
||||||
capture,
|
capture,
|
||||||
secure
|
secure
|
||||||
);
|
);
|
||||||
@ -2935,7 +2966,17 @@ Raven.prototype = {
|
|||||||
'requestAnimationFrame',
|
'requestAnimationFrame',
|
||||||
function(orig) {
|
function(orig) {
|
||||||
return function(cb) {
|
return function(cb) {
|
||||||
return orig(self.wrap(cb));
|
return orig(
|
||||||
|
self.wrap(
|
||||||
|
{
|
||||||
|
mechanism: {
|
||||||
|
type: 'instrument',
|
||||||
|
data: {function: 'requestAnimationFrame', handler: orig.name}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cb
|
||||||
|
)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
wrappedBuiltIns
|
wrappedBuiltIns
|
||||||
@ -2998,7 +3039,15 @@ Raven.prototype = {
|
|||||||
function wrapProp(prop, xhr) {
|
function wrapProp(prop, xhr) {
|
||||||
if (prop in xhr && isFunction$1(xhr[prop])) {
|
if (prop in xhr && isFunction$1(xhr[prop])) {
|
||||||
fill$1(xhr, prop, function(orig) {
|
fill$1(xhr, prop, function(orig) {
|
||||||
return self.wrap(orig);
|
return self.wrap(
|
||||||
|
{
|
||||||
|
mechanism: {
|
||||||
|
type: 'instrument',
|
||||||
|
data: {function: prop, handler: orig.name}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
orig
|
||||||
|
);
|
||||||
}); // intentionally don't track filled methods on XHR instances
|
}); // intentionally don't track filled methods on XHR instances
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3063,7 +3112,19 @@ Raven.prototype = {
|
|||||||
xhr,
|
xhr,
|
||||||
'onreadystatechange',
|
'onreadystatechange',
|
||||||
function(orig) {
|
function(orig) {
|
||||||
return self.wrap(orig, undefined, onreadystatechangeHandler);
|
return self.wrap(
|
||||||
|
{
|
||||||
|
mechanism: {
|
||||||
|
type: 'instrument',
|
||||||
|
data: {
|
||||||
|
function: 'onreadystatechange',
|
||||||
|
handler: orig.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
orig,
|
||||||
|
onreadystatechangeHandler
|
||||||
|
);
|
||||||
} /* intentionally don't track this instrumentation */
|
} /* intentionally don't track this instrumentation */
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -3287,10 +3348,16 @@ Raven.prototype = {
|
|||||||
return globalServer;
|
return globalServer;
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleOnErrorStackInfo: function() {
|
_handleOnErrorStackInfo: function(stackInfo, options) {
|
||||||
|
options = options || {};
|
||||||
|
options.mechanism = options.mechanism || {
|
||||||
|
type: 'onerror',
|
||||||
|
handled: false
|
||||||
|
};
|
||||||
|
|
||||||
// if we are intentionally ignoring errors via onerror, bail out
|
// if we are intentionally ignoring errors via onerror, bail out
|
||||||
if (!this._ignoreOnError) {
|
if (!this._ignoreOnError) {
|
||||||
this._handleStackInfo.apply(this, arguments);
|
this._handleStackInfo(stackInfo, options);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -3427,6 +3494,19 @@ Raven.prototype = {
|
|||||||
options
|
options
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Move mechanism from options to exception interface
|
||||||
|
// We do this, as requiring user to pass `{exception:{mechanism:{ ... }}}` would be
|
||||||
|
// too much
|
||||||
|
if (!data.exception.mechanism && data.mechanism) {
|
||||||
|
data.exception.mechanism = data.mechanism;
|
||||||
|
delete data.mechanism;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.exception.mechanism = objectMerge$1(data.exception.mechanism || {}, {
|
||||||
|
type: 'generic',
|
||||||
|
handled: true
|
||||||
|
});
|
||||||
|
|
||||||
// Fire away!
|
// Fire away!
|
||||||
this._send(data);
|
this._send(data);
|
||||||
},
|
},
|
||||||
|
2
demo/dist/demo.js.map
vendored
2
demo/dist/demo.js.map
vendored
File diff suppressed because one or more lines are too long
2
demo/dist/demo.min.js
vendored
2
demo/dist/demo.min.js
vendored
File diff suppressed because one or more lines are too long
2
demo/dist/demo.min.js.map
vendored
2
demo/dist/demo.min.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.css
vendored
2
dist/plyr.css
vendored
File diff suppressed because one or more lines are too long
585
dist/plyr.js
vendored
585
dist/plyr.js
vendored
@ -493,61 +493,63 @@ var utils = {
|
|||||||
// Check variable types
|
// Check variable types
|
||||||
is: {
|
is: {
|
||||||
object: function object(input) {
|
object: function object(input) {
|
||||||
return this.getConstructor(input) === Object;
|
return utils.getConstructor(input) === Object;
|
||||||
},
|
},
|
||||||
number: function number(input) {
|
number: function number(input) {
|
||||||
return this.getConstructor(input) === Number && !Number.isNaN(input);
|
return utils.getConstructor(input) === Number && !Number.isNaN(input);
|
||||||
},
|
},
|
||||||
string: function string(input) {
|
string: function string(input) {
|
||||||
return this.getConstructor(input) === String;
|
return utils.getConstructor(input) === String;
|
||||||
},
|
},
|
||||||
boolean: function boolean(input) {
|
boolean: function boolean(input) {
|
||||||
return this.getConstructor(input) === Boolean;
|
return utils.getConstructor(input) === Boolean;
|
||||||
},
|
},
|
||||||
function: function _function(input) {
|
function: function _function(input) {
|
||||||
return this.getConstructor(input) === Function;
|
return utils.getConstructor(input) === Function;
|
||||||
},
|
},
|
||||||
array: function array(input) {
|
array: function array(input) {
|
||||||
return !this.nullOrUndefined(input) && Array.isArray(input);
|
return !utils.is.nullOrUndefined(input) && Array.isArray(input);
|
||||||
},
|
},
|
||||||
weakMap: function weakMap(input) {
|
weakMap: function weakMap(input) {
|
||||||
return this.instanceof(input, WeakMap);
|
return utils.is.instanceof(input, WeakMap);
|
||||||
},
|
},
|
||||||
nodeList: function nodeList(input) {
|
nodeList: function nodeList(input) {
|
||||||
return this.instanceof(input, NodeList);
|
return utils.is.instanceof(input, NodeList);
|
||||||
},
|
},
|
||||||
element: function element(input) {
|
element: function element(input) {
|
||||||
return this.instanceof(input, Element);
|
return utils.is.instanceof(input, Element);
|
||||||
},
|
},
|
||||||
textNode: function textNode(input) {
|
textNode: function textNode(input) {
|
||||||
return this.getConstructor(input) === Text;
|
return utils.getConstructor(input) === Text;
|
||||||
},
|
},
|
||||||
event: function event(input) {
|
event: function event(input) {
|
||||||
return this.instanceof(input, Event);
|
return utils.is.instanceof(input, Event);
|
||||||
},
|
},
|
||||||
cue: function cue(input) {
|
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) {
|
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) {
|
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) {
|
nullOrUndefined: function nullOrUndefined(input) {
|
||||||
return input === null || typeof input === 'undefined';
|
return input === null || typeof input === 'undefined';
|
||||||
},
|
},
|
||||||
empty: function empty(input) {
|
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) {
|
instanceof: function _instanceof$$1(input, constructor) {
|
||||||
return Boolean(input && constructor && input instanceof 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
|
// Unfortunately, due to mixed support, UA sniffing is required
|
||||||
getBrowser: function getBrowser() {
|
getBrowser: function getBrowser() {
|
||||||
return {
|
return {
|
||||||
@ -1167,7 +1169,7 @@ var utils = {
|
|||||||
|
|
||||||
// Bail if the value isn't a number
|
// Bail if the value isn't a number
|
||||||
if (!utils.is.number(time)) {
|
if (!utils.is.number(time)) {
|
||||||
return this.formatTime(null, displayHours, inverted);
|
return utils.formatTime(null, displayHours, inverted);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format time component to add leading zero
|
// Format time component to add leading zero
|
||||||
@ -1176,9 +1178,9 @@ var utils = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Breakdown to hours, mins, secs
|
// Breakdown to hours, mins, secs
|
||||||
var hours = this.getHours(time);
|
var hours = utils.getHours(time);
|
||||||
var mins = this.getMinutes(time);
|
var mins = utils.getMinutes(time);
|
||||||
var secs = this.getSeconds(time);
|
var secs = utils.getSeconds(time);
|
||||||
|
|
||||||
// Do we need to display hours?
|
// Do we need to display hours?
|
||||||
if (displayHours || hours > 0) {
|
if (displayHours || hours > 0) {
|
||||||
@ -1374,12 +1376,12 @@ var utils = {
|
|||||||
|
|
||||||
// Parse URL if needed
|
// Parse URL if needed
|
||||||
if (input.startsWith('http://') || input.startsWith('https://')) {
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1418,6 +1420,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
|
// Get aspect ratio for dimensions
|
||||||
getAspectRatio: function getAspectRatio(width, height) {
|
getAspectRatio: function getAspectRatio(width, height) {
|
||||||
var getRatio = function getRatio(w, h) {
|
var getRatio = function getRatio(w, h) {
|
||||||
@ -2159,9 +2169,15 @@ var controls = {
|
|||||||
|
|
||||||
|
|
||||||
// Create a settings menu item
|
// Create a settings menu item
|
||||||
createMenuItem: function createMenuItem(value, list, type, title) {
|
createMenuItem: function createMenuItem(_ref) {
|
||||||
var badge = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
var value = _ref.value,
|
||||||
var checked = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
|
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');
|
var item = utils.createElement('li');
|
||||||
|
|
||||||
@ -2477,8 +2493,13 @@ var controls = {
|
|||||||
var sorting = _this3.config.quality.options;
|
var sorting = _this3.config.quality.options;
|
||||||
return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;
|
return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;
|
||||||
}).forEach(function (quality) {
|
}).forEach(function (quality) {
|
||||||
var label = controls.getLabel.call(_this3, 'quality', quality);
|
controls.createMenuItem.call(_this3, {
|
||||||
controls.createMenuItem.call(_this3, quality, list, type, label, getBadge(quality));
|
value: quality,
|
||||||
|
list: list,
|
||||||
|
type: type,
|
||||||
|
title: controls.getLabel.call(_this3, 'quality', quality),
|
||||||
|
badge: getBadge(quality)
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
controls.updateSetting.call(this, type, list);
|
controls.updateSetting.call(this, type, list);
|
||||||
@ -2521,18 +2542,7 @@ var controls = {
|
|||||||
|
|
||||||
switch (setting) {
|
switch (setting) {
|
||||||
case 'captions':
|
case 'captions':
|
||||||
if (this.captions.active) {
|
value = this.currentTrack;
|
||||||
if (this.options.captions.length > 2 || !this.options.captions.some(function (lang) {
|
|
||||||
return lang === 'enabled';
|
|
||||||
})) {
|
|
||||||
value = this.captions.language;
|
|
||||||
} else {
|
|
||||||
value = 'enabled';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
value = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -2627,10 +2637,10 @@ var controls = {
|
|||||||
// TODO: Captions or language? Currently it's mixed
|
// TODO: Captions or language? Currently it's mixed
|
||||||
var type = 'captions';
|
var type = 'captions';
|
||||||
var list = this.elements.settings.panes.captions.querySelector('ul');
|
var list = this.elements.settings.panes.captions.querySelector('ul');
|
||||||
|
var tracks = captions.getTracks.call(this);
|
||||||
|
|
||||||
// Toggle the pane and tab
|
// Toggle the pane and tab
|
||||||
var toggle = captions.getTracks.call(this).length;
|
controls.toggleTab.call(this, type, tracks.length);
|
||||||
controls.toggleTab.call(this, type, toggle);
|
|
||||||
|
|
||||||
// Empty the menu
|
// Empty the menu
|
||||||
utils.emptyElement(list);
|
utils.emptyElement(list);
|
||||||
@ -2639,28 +2649,33 @@ var controls = {
|
|||||||
controls.checkMenu.call(this);
|
controls.checkMenu.call(this);
|
||||||
|
|
||||||
// If there's no captions, bail
|
// If there's no captions, bail
|
||||||
if (!toggle) {
|
if (!tracks.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-map the tracks into just the data we need
|
// Generate options data
|
||||||
var tracks = captions.getTracks.call(this).map(function (track) {
|
var options = tracks.map(function (track, value) {
|
||||||
return {
|
return {
|
||||||
language: !utils.is.empty(track.language) ? track.language : 'enabled',
|
value: value,
|
||||||
label: captions.getLabel.call(_this4, track)
|
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
|
// Add the "Disabled" option to turn off captions
|
||||||
tracks.unshift({
|
options.unshift({
|
||||||
language: '',
|
value: -1,
|
||||||
label: i18n.get('disabled', this.config)
|
checked: !this.captions.active,
|
||||||
|
title: i18n.get('disabled', this.config),
|
||||||
|
list: list,
|
||||||
|
type: 'language'
|
||||||
});
|
});
|
||||||
|
|
||||||
// Generate options
|
// Generate options
|
||||||
tracks.forEach(function (track) {
|
options.forEach(controls.createMenuItem.bind(this));
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
controls.updateSetting.call(this, type, list);
|
controls.updateSetting.call(this, type, list);
|
||||||
},
|
},
|
||||||
@ -2714,8 +2729,12 @@ var controls = {
|
|||||||
|
|
||||||
// Create items
|
// Create items
|
||||||
this.options.speed.forEach(function (speed) {
|
this.options.speed.forEach(function (speed) {
|
||||||
var label = controls.getLabel.call(_this5, 'speed', speed);
|
controls.createMenuItem.call(_this5, {
|
||||||
controls.createMenuItem.call(_this5, speed, list, type, label);
|
value: speed,
|
||||||
|
list: list,
|
||||||
|
type: type,
|
||||||
|
title: controls.getLabel.call(_this5, 'speed', speed)
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
controls.updateSetting.call(this, type, list);
|
controls.updateSetting.call(this, type, list);
|
||||||
@ -3189,10 +3208,10 @@ var controls = {
|
|||||||
var replace = function replace(input) {
|
var replace = function replace(input) {
|
||||||
var result = input;
|
var result = input;
|
||||||
|
|
||||||
Object.entries(props).forEach(function (_ref) {
|
Object.entries(props).forEach(function (_ref2) {
|
||||||
var _ref2 = slicedToArray(_ref, 2),
|
var _ref3 = slicedToArray(_ref2, 2),
|
||||||
key = _ref2[0],
|
key = _ref3[0],
|
||||||
value = _ref2[1];
|
value = _ref3[1];
|
||||||
|
|
||||||
result = utils.replaceAll(result, '{' + key + '}', value);
|
result = utils.replaceAll(result, '{' + key + '}', value);
|
||||||
});
|
});
|
||||||
@ -3309,91 +3328,168 @@ var captions = {
|
|||||||
active = this.config.captions.active;
|
active = this.config.captions.active;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set toggled state
|
// Get language from storage, fallback to config
|
||||||
this.toggleCaptions(active);
|
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
|
// Watch changes to textTracks and update captions menu
|
||||||
if (this.config.captions.update) {
|
if (this.isHTML5) {
|
||||||
utils.on(this.media.textTracks, 'addtrack removetrack', captions.update.bind(this));
|
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)
|
// Update available languages in list next tick (the event must not be triggered before the listeners)
|
||||||
setTimeout(captions.update.bind(this), 0);
|
setTimeout(captions.update.bind(this), 0);
|
||||||
},
|
},
|
||||||
update: function update() {
|
update: function update() {
|
||||||
// Update tracks
|
var _this = this;
|
||||||
var tracks = captions.getTracks.call(this);
|
|
||||||
this.options.captions = tracks.map(function (_ref) {
|
|
||||||
var language = _ref.language;
|
|
||||||
return language;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set language if it hasn't been set already
|
var tracks = captions.getTracks.call(this, true);
|
||||||
if (!this.language) {
|
// Get the wanted language
|
||||||
var language = this.config.captions.language;
|
var _captions = this.captions,
|
||||||
|
language = _captions.language,
|
||||||
|
meta = _captions.meta;
|
||||||
|
|
||||||
if (language === 'auto') {
|
// Handle tracks (add event listener and "pseudo"-default)
|
||||||
var _split = (navigator.language || navigator.userLanguage).split('-');
|
|
||||||
|
|
||||||
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];
|
// Turn off native caption rendering to avoid double captions
|
||||||
}
|
track.mode = 'hidden';
|
||||||
this.language = this.storage.get('language') || (language || '').toLowerCase();
|
|
||||||
|
// Add event listener for cue changes
|
||||||
|
utils.on(track, 'cuechange', function () {
|
||||||
|
return captions.updateCues.call(_this);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle the class hooks
|
var trackRemoved = !tracks.find(function (track) {
|
||||||
utils.toggleClass(this.elements.container, this.config.classNames.captions.enabled, !utils.is.empty(captions.getTracks.call(this)));
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
// Update available languages in list
|
||||||
if ((this.config.controls || []).includes('settings') && this.config.settings.includes('captions')) {
|
if ((this.config.controls || []).includes('settings') && this.config.settings.includes('captions')) {
|
||||||
controls.setCaptionsMenu.call(this);
|
controls.setCaptionsMenu.call(this);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
set: function set$$1(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
|
// Disable captions if setting to -1
|
||||||
setLanguage: function setLanguage() {
|
if (index === -1) {
|
||||||
var _this = this;
|
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Turn off native caption rendering to avoid double captions
|
|
||||||
// eslint-disable-next-line
|
|
||||||
track.mode = 'hidden';
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get current track
|
|
||||||
var currentTrack = 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (this.isVimeo && this.captions.active) {
|
|
||||||
this.embed.enableTextTrack(this.language);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!utils.is.number(index)) {
|
||||||
|
this.debug.warn('Invalid caption argument', index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(index in tracks)) {
|
||||||
|
this.debug.warn('Track not found', index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.captions.currentTrack !== index) {
|
||||||
|
this.captions.currentTrack = index;
|
||||||
|
var track = captions.getCurrentTrack.call(this);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show captions
|
||||||
|
if (show) {
|
||||||
|
this.toggleCaptions(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setLanguage: function setLanguage(language) {
|
||||||
|
var show = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
||||||
|
|
||||||
|
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 tracks
|
// 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() {
|
getTracks: function getTracks() {
|
||||||
// Return empty array at least
|
var _this2 = this;
|
||||||
if (utils.is.nullOrUndefined(this.media)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only get accepted kinds
|
var update = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
||||||
return Array.from(this.media.textTracks || []).filter(function (track) {
|
|
||||||
|
// 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);
|
return ['captions', 'subtitles'].includes(track.kind);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -3401,32 +3497,20 @@ var captions = {
|
|||||||
|
|
||||||
// Get the current track for the current language
|
// Get the current track for the current language
|
||||||
getCurrentTrack: function getCurrentTrack() {
|
getCurrentTrack: function getCurrentTrack() {
|
||||||
var _this2 = this;
|
var _this3 = this;
|
||||||
|
|
||||||
|
var fromLanguage = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
||||||
|
|
||||||
var tracks = captions.getTracks.call(this);
|
var tracks = captions.getTracks.call(this);
|
||||||
|
var sortIsDefault = function sortIsDefault(track) {
|
||||||
if (!tracks.length) {
|
return Number((_this3.captions.meta.get(track) || {}).default);
|
||||||
return null;
|
};
|
||||||
}
|
var sorted = Array.from(tracks).sort(function (a, b) {
|
||||||
|
return sortIsDefault(b) - sortIsDefault(a);
|
||||||
// Get track based on current language
|
|
||||||
var track = tracks.find(function (track) {
|
|
||||||
return track.language.toLowerCase() === _this2.language;
|
|
||||||
});
|
});
|
||||||
|
return !fromLanguage && tracks[this.currentTrack] || sorted.find(function (track) {
|
||||||
// Get the <track> with default attribute
|
return track.language === _this3.captions.language;
|
||||||
if (!track) {
|
}) || sorted[0];
|
||||||
track = utils.getElement.call(this, 'track[default]');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the first track
|
|
||||||
if (!track) {
|
|
||||||
var _tracks = slicedToArray(tracks, 1);
|
|
||||||
|
|
||||||
track = _tracks[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return track;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -3454,58 +3538,50 @@ var captions = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
// Display active caption if it contains text
|
// Update captions using current track's active cues
|
||||||
setCue: function setCue(input) {
|
// Also optional array argument in case there isn't any track (ex: vimeo)
|
||||||
// Get the track from the event if needed
|
updateCues: function updateCues(input) {
|
||||||
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) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.dispatchEvent.call(this, this.media, 'cuechange');
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// Set the current caption
|
|
||||||
setText: function setText(input) {
|
|
||||||
// Requires UI
|
// Requires UI
|
||||||
if (!this.supported.ui) {
|
if (!this.supported.ui) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utils.is.element(this.elements.captions)) {
|
if (!utils.is.element(this.elements.captions)) {
|
||||||
var content = utils.createElement('span');
|
|
||||||
|
|
||||||
// Empty the container
|
|
||||||
utils.emptyElement(this.elements.captions);
|
|
||||||
|
|
||||||
// Default to empty
|
|
||||||
var caption = !utils.is.nullOrUndefined(input) ? input : '';
|
|
||||||
|
|
||||||
// Set the span content
|
|
||||||
if (utils.is.string(caption)) {
|
|
||||||
content.innerText = caption.trim();
|
|
||||||
} else {
|
|
||||||
content.appendChild(caption);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set new caption text
|
|
||||||
this.elements.captions.appendChild(content);
|
|
||||||
} else {
|
|
||||||
this.debug.warn('No captions element to render to');
|
this.debug.warn('No captions element to render to');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only accept array or empty input
|
||||||
|
if (!utils.is.nullOrUndefined(input) && !Array.isArray(input)) {
|
||||||
|
this.debug.warn('updateCues: Invalid input', input);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cues = input;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set new caption text
|
||||||
|
var content = cues.map(function (cueText) {
|
||||||
|
return cueText.trim();
|
||||||
|
}).join('\n');
|
||||||
|
var changed = content !== this.elements.captions.innerHTML;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Trigger event
|
||||||
|
utils.dispatchEvent.call(this, this.media, 'cuechange');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -3809,6 +3885,7 @@ var defaults$1 = {
|
|||||||
},
|
},
|
||||||
progress: '.plyr__progress',
|
progress: '.plyr__progress',
|
||||||
captions: '.plyr__captions',
|
captions: '.plyr__captions',
|
||||||
|
caption: '.plyr__caption',
|
||||||
menu: {
|
menu: {
|
||||||
quality: '.js-plyr__menu__list--quality'
|
quality: '.js-plyr__menu__list--quality'
|
||||||
}
|
}
|
||||||
@ -4787,9 +4864,11 @@ var Listeners = function () {
|
|||||||
// Proxy events to container
|
// Proxy events to container
|
||||||
// Bubble up key events for Edge
|
// Bubble up key events for Edge
|
||||||
utils.on(this.player.media, this.player.config.events.concat(['keyup', 'keydown']).join(' '), function (event) {
|
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
|
// Get error details from media
|
||||||
|
|
||||||
if (event.type === 'error') {
|
if (event.type === 'error') {
|
||||||
detail = _this3.player.media.error;
|
detail = _this3.player.media.error;
|
||||||
}
|
}
|
||||||
@ -4888,7 +4967,7 @@ var Listeners = function () {
|
|||||||
// Settings menu items - use event delegation as items are added/removed
|
// Settings menu items - use event delegation as items are added/removed
|
||||||
if (utils.matches(event.target, _this4.player.config.selectors.inputs.language)) {
|
if (utils.matches(event.target, _this4.player.config.selectors.inputs.language)) {
|
||||||
proxy(event, function () {
|
proxy(event, function () {
|
||||||
_this4.player.language = event.target.value;
|
_this4.player.currentTrack = Number(event.target.value);
|
||||||
showHomeTab();
|
showHomeTab();
|
||||||
}, 'language');
|
}, 'language');
|
||||||
} else if (utils.matches(event.target, _this4.player.config.selectors.inputs.quality)) {
|
} else if (utils.matches(event.target, _this4.player.config.selectors.inputs.quality)) {
|
||||||
@ -5083,6 +5162,9 @@ var Listeners = function () {
|
|||||||
|
|
||||||
// Set playback state and trigger change (only on actual change)
|
// Set playback state and trigger change (only on actual change)
|
||||||
function assurePlaybackState(play) {
|
function assurePlaybackState(play) {
|
||||||
|
if (play && !this.embed.hasPlayed) {
|
||||||
|
this.embed.hasPlayed = true;
|
||||||
|
}
|
||||||
if (this.media.paused === play) {
|
if (this.media.paused === play) {
|
||||||
this.media.paused = !play;
|
this.media.paused = !play;
|
||||||
utils.dispatchEvent.call(this, this.media, play ? 'play' : 'pause');
|
utils.dispatchEvent.call(this, this.media, play ? 'play' : 'pause');
|
||||||
@ -5235,24 +5317,25 @@ var vimeo = {
|
|||||||
paused = player.paused,
|
paused = player.paused,
|
||||||
volume = player.volume;
|
volume = player.volume;
|
||||||
|
|
||||||
// Set seeking state and trigger event
|
var restorePause = paused && !embed.hasPlayed;
|
||||||
|
|
||||||
|
// Set seeking state and trigger event
|
||||||
media.seeking = true;
|
media.seeking = true;
|
||||||
utils.dispatchEvent.call(player, media, 'seeking');
|
utils.dispatchEvent.call(player, media, 'seeking');
|
||||||
|
|
||||||
// If paused, mute until seek is complete
|
// If paused, mute until seek is complete
|
||||||
Promise.resolve(paused && embed.setVolume(0))
|
Promise.resolve(restorePause && embed.setVolume(0))
|
||||||
// Seek
|
// Seek
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return embed.setCurrentTime(time);
|
return embed.setCurrentTime(time);
|
||||||
})
|
})
|
||||||
// Restore paused
|
// Restore paused
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return paused && embed.pause();
|
return restorePause && embed.pause();
|
||||||
})
|
})
|
||||||
// Restore volume
|
// Restore volume
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return paused && embed.setVolume(volume);
|
return restorePause && embed.setVolume(volume);
|
||||||
}).catch(function () {
|
}).catch(function () {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
});
|
});
|
||||||
@ -5382,17 +5465,25 @@ var vimeo = {
|
|||||||
captions.setup.call(player);
|
captions.setup.call(player);
|
||||||
});
|
});
|
||||||
|
|
||||||
player.embed.on('cuechange', function (data) {
|
player.embed.on('cuechange', function (_ref) {
|
||||||
var cue = null;
|
var _ref$cues = _ref.cues,
|
||||||
|
cues = _ref$cues === undefined ? [] : _ref$cues;
|
||||||
|
|
||||||
if (data.cues.length) {
|
var strippedCues = cues.map(function (cue) {
|
||||||
cue = utils.stripHTML(data.cues[0].text);
|
return utils.stripHTML(cue.text);
|
||||||
}
|
});
|
||||||
|
captions.updateCues.call(player, strippedCues);
|
||||||
captions.setText.call(player, cue);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
player.embed.on('loaded', function () {
|
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) {
|
if (utils.is.element(player.embed.element) && player.supported.ui) {
|
||||||
var frame = player.embed.element;
|
var frame = player.embed.element;
|
||||||
|
|
||||||
@ -5522,6 +5613,9 @@ function mapQualityUnits(levels) {
|
|||||||
|
|
||||||
// Set playback state and trigger change (only on actual change)
|
// Set playback state and trigger change (only on actual change)
|
||||||
function assurePlaybackState$1(play) {
|
function assurePlaybackState$1(play) {
|
||||||
|
if (play && !this.embed.hasPlayed) {
|
||||||
|
this.embed.hasPlayed = true;
|
||||||
|
}
|
||||||
if (this.media.paused === play) {
|
if (this.media.paused === play) {
|
||||||
this.media.paused = !play;
|
this.media.paused = !play;
|
||||||
utils.dispatchEvent.call(this, this.media, play ? 'play' : 'pause');
|
utils.dispatchEvent.call(this, this.media, play ? 'play' : 'pause');
|
||||||
@ -5935,7 +6029,7 @@ var youtube = {
|
|||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// Restore paused state (YouTube starts playing on seek if the video hasn't been played yet)
|
// 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();
|
player.media.pause();
|
||||||
} else {
|
} else {
|
||||||
assurePlaybackState$1.call(player, true);
|
assurePlaybackState$1.call(player, true);
|
||||||
@ -6926,7 +7020,8 @@ var Plyr = function () {
|
|||||||
// Captions
|
// Captions
|
||||||
this.captions = {
|
this.captions = {
|
||||||
active: null,
|
active: null,
|
||||||
currentTrack: null
|
currentTrack: -1,
|
||||||
|
meta: new WeakMap()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fullscreen
|
// Fullscreen
|
||||||
@ -6937,8 +7032,7 @@ var Plyr = function () {
|
|||||||
// Options
|
// Options
|
||||||
this.options = {
|
this.options = {
|
||||||
speed: [],
|
speed: [],
|
||||||
quality: [],
|
quality: []
|
||||||
captions: []
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
@ -7314,8 +7408,8 @@ var Plyr = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the captions language
|
* Set the caption track by index
|
||||||
* @param {string} - Two character ISO language code (e.g. EN, FR, PT, etc)
|
* @param {number} - Caption index
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
@ -8006,60 +8100,41 @@ var Plyr = function () {
|
|||||||
return Boolean(this.config.autoplay);
|
return Boolean(this.config.autoplay);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'language',
|
key: 'currentTrack',
|
||||||
set: function set$$1(input) {
|
set: function set$$1(input) {
|
||||||
// Nothing specified
|
captions.set.call(this, input);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update config
|
|
||||||
this.captions.language = language;
|
|
||||||
|
|
||||||
// Clear caption
|
|
||||||
captions.setText.call(this, null);
|
|
||||||
|
|
||||||
// Update captions
|
|
||||||
captions.setLanguage.call(this);
|
|
||||||
|
|
||||||
// Trigger an event
|
|
||||||
utils.dispatchEvent.call(this, this.media, 'languagechange');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current captions language
|
* Get the current caption track index (-1 if disabled)
|
||||||
*/
|
*/
|
||||||
,
|
,
|
||||||
get: function get$$1() {
|
get: function get$$1() {
|
||||||
return this.captions.language;
|
var _captions = this.captions,
|
||||||
|
active = _captions.active,
|
||||||
|
currentTrack = _captions.currentTrack;
|
||||||
|
|
||||||
|
return active ? currentTrack : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
*/
|
||||||
|
|
||||||
|
}, {
|
||||||
|
key: 'language',
|
||||||
|
set: function set$$1(input) {
|
||||||
|
captions.setLanguage.call(this, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current track's language
|
||||||
|
*/
|
||||||
|
,
|
||||||
|
get: function get$$1() {
|
||||||
|
return (captions.getCurrentTrack.call(this) || {}).language;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -8135,9 +8210,7 @@ var Plyr = function () {
|
|||||||
} else if (utils.is.nodeList(selector)) {
|
} else if (utils.is.nodeList(selector)) {
|
||||||
targets = Array.from(selector);
|
targets = Array.from(selector);
|
||||||
} else if (utils.is.array(selector)) {
|
} else if (utils.is.array(selector)) {
|
||||||
targets = selector.filter(function (i) {
|
targets = selector.filter(utils.is.element);
|
||||||
return utils.is.element(i);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utils.is.empty(targets)) {
|
if (utils.is.empty(targets)) {
|
||||||
|
2
dist/plyr.js.map
vendored
2
dist/plyr.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.min.js
vendored
2
dist/plyr.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.min.js.map
vendored
2
dist/plyr.min.js.map
vendored
File diff suppressed because one or more lines are too long
585
dist/plyr.polyfilled.js
vendored
585
dist/plyr.polyfilled.js
vendored
@ -5876,61 +5876,63 @@ var utils = {
|
|||||||
// Check variable types
|
// Check variable types
|
||||||
is: {
|
is: {
|
||||||
object: function object(input) {
|
object: function object(input) {
|
||||||
return this.getConstructor(input) === Object;
|
return utils.getConstructor(input) === Object;
|
||||||
},
|
},
|
||||||
number: function number(input) {
|
number: function number(input) {
|
||||||
return this.getConstructor(input) === Number && !Number.isNaN(input);
|
return utils.getConstructor(input) === Number && !Number.isNaN(input);
|
||||||
},
|
},
|
||||||
string: function string(input) {
|
string: function string(input) {
|
||||||
return this.getConstructor(input) === String;
|
return utils.getConstructor(input) === String;
|
||||||
},
|
},
|
||||||
boolean: function boolean(input) {
|
boolean: function boolean(input) {
|
||||||
return this.getConstructor(input) === Boolean;
|
return utils.getConstructor(input) === Boolean;
|
||||||
},
|
},
|
||||||
function: function _function(input) {
|
function: function _function(input) {
|
||||||
return this.getConstructor(input) === Function;
|
return utils.getConstructor(input) === Function;
|
||||||
},
|
},
|
||||||
array: function array(input) {
|
array: function array(input) {
|
||||||
return !this.nullOrUndefined(input) && Array.isArray(input);
|
return !utils.is.nullOrUndefined(input) && Array.isArray(input);
|
||||||
},
|
},
|
||||||
weakMap: function weakMap(input) {
|
weakMap: function weakMap(input) {
|
||||||
return this.instanceof(input, WeakMap);
|
return utils.is.instanceof(input, WeakMap);
|
||||||
},
|
},
|
||||||
nodeList: function nodeList(input) {
|
nodeList: function nodeList(input) {
|
||||||
return this.instanceof(input, NodeList);
|
return utils.is.instanceof(input, NodeList);
|
||||||
},
|
},
|
||||||
element: function element(input) {
|
element: function element(input) {
|
||||||
return this.instanceof(input, Element);
|
return utils.is.instanceof(input, Element);
|
||||||
},
|
},
|
||||||
textNode: function textNode(input) {
|
textNode: function textNode(input) {
|
||||||
return this.getConstructor(input) === Text;
|
return utils.getConstructor(input) === Text;
|
||||||
},
|
},
|
||||||
event: function event(input) {
|
event: function event(input) {
|
||||||
return this.instanceof(input, Event);
|
return utils.is.instanceof(input, Event);
|
||||||
},
|
},
|
||||||
cue: function cue(input) {
|
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) {
|
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) {
|
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) {
|
nullOrUndefined: function nullOrUndefined(input) {
|
||||||
return input === null || typeof input === 'undefined';
|
return input === null || typeof input === 'undefined';
|
||||||
},
|
},
|
||||||
empty: function empty(input) {
|
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) {
|
instanceof: function _instanceof$$1(input, constructor) {
|
||||||
return Boolean(input && constructor && input instanceof 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
|
// Unfortunately, due to mixed support, UA sniffing is required
|
||||||
getBrowser: function getBrowser() {
|
getBrowser: function getBrowser() {
|
||||||
return {
|
return {
|
||||||
@ -6550,7 +6552,7 @@ var utils = {
|
|||||||
|
|
||||||
// Bail if the value isn't a number
|
// Bail if the value isn't a number
|
||||||
if (!utils.is.number(time)) {
|
if (!utils.is.number(time)) {
|
||||||
return this.formatTime(null, displayHours, inverted);
|
return utils.formatTime(null, displayHours, inverted);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format time component to add leading zero
|
// Format time component to add leading zero
|
||||||
@ -6559,9 +6561,9 @@ var utils = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Breakdown to hours, mins, secs
|
// Breakdown to hours, mins, secs
|
||||||
var hours = this.getHours(time);
|
var hours = utils.getHours(time);
|
||||||
var mins = this.getMinutes(time);
|
var mins = utils.getMinutes(time);
|
||||||
var secs = this.getSeconds(time);
|
var secs = utils.getSeconds(time);
|
||||||
|
|
||||||
// Do we need to display hours?
|
// Do we need to display hours?
|
||||||
if (displayHours || hours > 0) {
|
if (displayHours || hours > 0) {
|
||||||
@ -6757,12 +6759,12 @@ var utils = {
|
|||||||
|
|
||||||
// Parse URL if needed
|
// Parse URL if needed
|
||||||
if (input.startsWith('http://') || input.startsWith('https://')) {
|
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;
|
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
|
// Get aspect ratio for dimensions
|
||||||
getAspectRatio: function getAspectRatio(width, height) {
|
getAspectRatio: function getAspectRatio(width, height) {
|
||||||
var getRatio = function getRatio(w, h) {
|
var getRatio = function getRatio(w, h) {
|
||||||
@ -7542,9 +7552,15 @@ var controls = {
|
|||||||
|
|
||||||
|
|
||||||
// Create a settings menu item
|
// Create a settings menu item
|
||||||
createMenuItem: function createMenuItem(value, list, type, title) {
|
createMenuItem: function createMenuItem(_ref) {
|
||||||
var badge = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
var value = _ref.value,
|
||||||
var checked = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
|
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');
|
var item = utils.createElement('li');
|
||||||
|
|
||||||
@ -7860,8 +7876,13 @@ var controls = {
|
|||||||
var sorting = _this3.config.quality.options;
|
var sorting = _this3.config.quality.options;
|
||||||
return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;
|
return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;
|
||||||
}).forEach(function (quality) {
|
}).forEach(function (quality) {
|
||||||
var label = controls.getLabel.call(_this3, 'quality', quality);
|
controls.createMenuItem.call(_this3, {
|
||||||
controls.createMenuItem.call(_this3, quality, list, type, label, getBadge(quality));
|
value: quality,
|
||||||
|
list: list,
|
||||||
|
type: type,
|
||||||
|
title: controls.getLabel.call(_this3, 'quality', quality),
|
||||||
|
badge: getBadge(quality)
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
controls.updateSetting.call(this, type, list);
|
controls.updateSetting.call(this, type, list);
|
||||||
@ -7904,18 +7925,7 @@ var controls = {
|
|||||||
|
|
||||||
switch (setting) {
|
switch (setting) {
|
||||||
case 'captions':
|
case 'captions':
|
||||||
if (this.captions.active) {
|
value = this.currentTrack;
|
||||||
if (this.options.captions.length > 2 || !this.options.captions.some(function (lang) {
|
|
||||||
return lang === 'enabled';
|
|
||||||
})) {
|
|
||||||
value = this.captions.language;
|
|
||||||
} else {
|
|
||||||
value = 'enabled';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
value = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -8010,10 +8020,10 @@ var controls = {
|
|||||||
// TODO: Captions or language? Currently it's mixed
|
// TODO: Captions or language? Currently it's mixed
|
||||||
var type = 'captions';
|
var type = 'captions';
|
||||||
var list = this.elements.settings.panes.captions.querySelector('ul');
|
var list = this.elements.settings.panes.captions.querySelector('ul');
|
||||||
|
var tracks = captions.getTracks.call(this);
|
||||||
|
|
||||||
// Toggle the pane and tab
|
// Toggle the pane and tab
|
||||||
var toggle = captions.getTracks.call(this).length;
|
controls.toggleTab.call(this, type, tracks.length);
|
||||||
controls.toggleTab.call(this, type, toggle);
|
|
||||||
|
|
||||||
// Empty the menu
|
// Empty the menu
|
||||||
utils.emptyElement(list);
|
utils.emptyElement(list);
|
||||||
@ -8022,28 +8032,33 @@ var controls = {
|
|||||||
controls.checkMenu.call(this);
|
controls.checkMenu.call(this);
|
||||||
|
|
||||||
// If there's no captions, bail
|
// If there's no captions, bail
|
||||||
if (!toggle) {
|
if (!tracks.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-map the tracks into just the data we need
|
// Generate options data
|
||||||
var tracks = captions.getTracks.call(this).map(function (track) {
|
var options = tracks.map(function (track, value) {
|
||||||
return {
|
return {
|
||||||
language: !utils.is.empty(track.language) ? track.language : 'enabled',
|
value: value,
|
||||||
label: captions.getLabel.call(_this4, track)
|
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
|
// Add the "Disabled" option to turn off captions
|
||||||
tracks.unshift({
|
options.unshift({
|
||||||
language: '',
|
value: -1,
|
||||||
label: i18n.get('disabled', this.config)
|
checked: !this.captions.active,
|
||||||
|
title: i18n.get('disabled', this.config),
|
||||||
|
list: list,
|
||||||
|
type: 'language'
|
||||||
});
|
});
|
||||||
|
|
||||||
// Generate options
|
// Generate options
|
||||||
tracks.forEach(function (track) {
|
options.forEach(controls.createMenuItem.bind(this));
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
controls.updateSetting.call(this, type, list);
|
controls.updateSetting.call(this, type, list);
|
||||||
},
|
},
|
||||||
@ -8097,8 +8112,12 @@ var controls = {
|
|||||||
|
|
||||||
// Create items
|
// Create items
|
||||||
this.options.speed.forEach(function (speed) {
|
this.options.speed.forEach(function (speed) {
|
||||||
var label = controls.getLabel.call(_this5, 'speed', speed);
|
controls.createMenuItem.call(_this5, {
|
||||||
controls.createMenuItem.call(_this5, speed, list, type, label);
|
value: speed,
|
||||||
|
list: list,
|
||||||
|
type: type,
|
||||||
|
title: controls.getLabel.call(_this5, 'speed', speed)
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
controls.updateSetting.call(this, type, list);
|
controls.updateSetting.call(this, type, list);
|
||||||
@ -8572,10 +8591,10 @@ var controls = {
|
|||||||
var replace = function replace(input) {
|
var replace = function replace(input) {
|
||||||
var result = input;
|
var result = input;
|
||||||
|
|
||||||
Object.entries(props).forEach(function (_ref) {
|
Object.entries(props).forEach(function (_ref2) {
|
||||||
var _ref2 = slicedToArray(_ref, 2),
|
var _ref3 = slicedToArray(_ref2, 2),
|
||||||
key = _ref2[0],
|
key = _ref3[0],
|
||||||
value = _ref2[1];
|
value = _ref3[1];
|
||||||
|
|
||||||
result = utils.replaceAll(result, '{' + key + '}', value);
|
result = utils.replaceAll(result, '{' + key + '}', value);
|
||||||
});
|
});
|
||||||
@ -8692,91 +8711,168 @@ var captions = {
|
|||||||
active = this.config.captions.active;
|
active = this.config.captions.active;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set toggled state
|
// Get language from storage, fallback to config
|
||||||
this.toggleCaptions(active);
|
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
|
// Watch changes to textTracks and update captions menu
|
||||||
if (this.config.captions.update) {
|
if (this.isHTML5) {
|
||||||
utils.on(this.media.textTracks, 'addtrack removetrack', captions.update.bind(this));
|
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)
|
// Update available languages in list next tick (the event must not be triggered before the listeners)
|
||||||
setTimeout(captions.update.bind(this), 0);
|
setTimeout(captions.update.bind(this), 0);
|
||||||
},
|
},
|
||||||
update: function update() {
|
update: function update() {
|
||||||
// Update tracks
|
var _this = this;
|
||||||
var tracks = captions.getTracks.call(this);
|
|
||||||
this.options.captions = tracks.map(function (_ref) {
|
|
||||||
var language = _ref.language;
|
|
||||||
return language;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set language if it hasn't been set already
|
var tracks = captions.getTracks.call(this, true);
|
||||||
if (!this.language) {
|
// Get the wanted language
|
||||||
var language = this.config.captions.language;
|
var _captions = this.captions,
|
||||||
|
language = _captions.language,
|
||||||
|
meta = _captions.meta;
|
||||||
|
|
||||||
if (language === 'auto') {
|
// Handle tracks (add event listener and "pseudo"-default)
|
||||||
var _split = (navigator.language || navigator.userLanguage).split('-');
|
|
||||||
|
|
||||||
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];
|
// Turn off native caption rendering to avoid double captions
|
||||||
}
|
track.mode = 'hidden';
|
||||||
this.language = this.storage.get('language') || (language || '').toLowerCase();
|
|
||||||
|
// Add event listener for cue changes
|
||||||
|
utils.on(track, 'cuechange', function () {
|
||||||
|
return captions.updateCues.call(_this);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle the class hooks
|
var trackRemoved = !tracks.find(function (track) {
|
||||||
utils.toggleClass(this.elements.container, this.config.classNames.captions.enabled, !utils.is.empty(captions.getTracks.call(this)));
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
// Update available languages in list
|
||||||
if ((this.config.controls || []).includes('settings') && this.config.settings.includes('captions')) {
|
if ((this.config.controls || []).includes('settings') && this.config.settings.includes('captions')) {
|
||||||
controls.setCaptionsMenu.call(this);
|
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
|
// Disable captions if setting to -1
|
||||||
setLanguage: function setLanguage() {
|
if (index === -1) {
|
||||||
var _this = this;
|
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Turn off native caption rendering to avoid double captions
|
|
||||||
// eslint-disable-next-line
|
|
||||||
track.mode = 'hidden';
|
|
||||||
});
|
|
||||||
|
|
||||||
// Get current track
|
|
||||||
var currentTrack = 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (this.isVimeo && this.captions.active) {
|
|
||||||
this.embed.enableTextTrack(this.language);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!utils.is.number(index)) {
|
||||||
|
this.debug.warn('Invalid caption argument', index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(index in tracks)) {
|
||||||
|
this.debug.warn('Track not found', index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.captions.currentTrack !== index) {
|
||||||
|
this.captions.currentTrack = index;
|
||||||
|
var track = captions.getCurrentTrack.call(this);
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show captions
|
||||||
|
if (show) {
|
||||||
|
this.toggleCaptions(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setLanguage: function setLanguage(language) {
|
||||||
|
var show = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
||||||
|
|
||||||
|
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 tracks
|
// 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() {
|
getTracks: function getTracks() {
|
||||||
// Return empty array at least
|
var _this2 = this;
|
||||||
if (utils.is.nullOrUndefined(this.media)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only get accepted kinds
|
var update = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
||||||
return Array.from(this.media.textTracks || []).filter(function (track) {
|
|
||||||
|
// 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);
|
return ['captions', 'subtitles'].includes(track.kind);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -8784,32 +8880,20 @@ var captions = {
|
|||||||
|
|
||||||
// Get the current track for the current language
|
// Get the current track for the current language
|
||||||
getCurrentTrack: function getCurrentTrack() {
|
getCurrentTrack: function getCurrentTrack() {
|
||||||
var _this2 = this;
|
var _this3 = this;
|
||||||
|
|
||||||
|
var fromLanguage = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
||||||
|
|
||||||
var tracks = captions.getTracks.call(this);
|
var tracks = captions.getTracks.call(this);
|
||||||
|
var sortIsDefault = function sortIsDefault(track) {
|
||||||
if (!tracks.length) {
|
return Number((_this3.captions.meta.get(track) || {}).default);
|
||||||
return null;
|
};
|
||||||
}
|
var sorted = Array.from(tracks).sort(function (a, b) {
|
||||||
|
return sortIsDefault(b) - sortIsDefault(a);
|
||||||
// Get track based on current language
|
|
||||||
var track = tracks.find(function (track) {
|
|
||||||
return track.language.toLowerCase() === _this2.language;
|
|
||||||
});
|
});
|
||||||
|
return !fromLanguage && tracks[this.currentTrack] || sorted.find(function (track) {
|
||||||
// Get the <track> with default attribute
|
return track.language === _this3.captions.language;
|
||||||
if (!track) {
|
}) || sorted[0];
|
||||||
track = utils.getElement.call(this, 'track[default]');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the first track
|
|
||||||
if (!track) {
|
|
||||||
var _tracks = slicedToArray(tracks, 1);
|
|
||||||
|
|
||||||
track = _tracks[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return track;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -8837,58 +8921,50 @@ var captions = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
// Display active caption if it contains text
|
// Update captions using current track's active cues
|
||||||
setCue: function setCue(input) {
|
// Also optional array argument in case there isn't any track (ex: vimeo)
|
||||||
// Get the track from the event if needed
|
updateCues: function updateCues(input) {
|
||||||
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) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.dispatchEvent.call(this, this.media, 'cuechange');
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// Set the current caption
|
|
||||||
setText: function setText(input) {
|
|
||||||
// Requires UI
|
// Requires UI
|
||||||
if (!this.supported.ui) {
|
if (!this.supported.ui) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utils.is.element(this.elements.captions)) {
|
if (!utils.is.element(this.elements.captions)) {
|
||||||
var content = utils.createElement('span');
|
|
||||||
|
|
||||||
// Empty the container
|
|
||||||
utils.emptyElement(this.elements.captions);
|
|
||||||
|
|
||||||
// Default to empty
|
|
||||||
var caption = !utils.is.nullOrUndefined(input) ? input : '';
|
|
||||||
|
|
||||||
// Set the span content
|
|
||||||
if (utils.is.string(caption)) {
|
|
||||||
content.innerText = caption.trim();
|
|
||||||
} else {
|
|
||||||
content.appendChild(caption);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set new caption text
|
|
||||||
this.elements.captions.appendChild(content);
|
|
||||||
} else {
|
|
||||||
this.debug.warn('No captions element to render to');
|
this.debug.warn('No captions element to render to');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only accept array or empty input
|
||||||
|
if (!utils.is.nullOrUndefined(input) && !Array.isArray(input)) {
|
||||||
|
this.debug.warn('updateCues: Invalid input', input);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cues = input;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set new caption text
|
||||||
|
var content = cues.map(function (cueText) {
|
||||||
|
return cueText.trim();
|
||||||
|
}).join('\n');
|
||||||
|
var changed = content !== this.elements.captions.innerHTML;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Trigger event
|
||||||
|
utils.dispatchEvent.call(this, this.media, 'cuechange');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -9192,6 +9268,7 @@ var defaults$1 = {
|
|||||||
},
|
},
|
||||||
progress: '.plyr__progress',
|
progress: '.plyr__progress',
|
||||||
captions: '.plyr__captions',
|
captions: '.plyr__captions',
|
||||||
|
caption: '.plyr__caption',
|
||||||
menu: {
|
menu: {
|
||||||
quality: '.js-plyr__menu__list--quality'
|
quality: '.js-plyr__menu__list--quality'
|
||||||
}
|
}
|
||||||
@ -10170,9 +10247,11 @@ var Listeners = function () {
|
|||||||
// Proxy events to container
|
// Proxy events to container
|
||||||
// Bubble up key events for Edge
|
// Bubble up key events for Edge
|
||||||
utils.on(this.player.media, this.player.config.events.concat(['keyup', 'keydown']).join(' '), function (event) {
|
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
|
// Get error details from media
|
||||||
|
|
||||||
if (event.type === 'error') {
|
if (event.type === 'error') {
|
||||||
detail = _this3.player.media.error;
|
detail = _this3.player.media.error;
|
||||||
}
|
}
|
||||||
@ -10271,7 +10350,7 @@ var Listeners = function () {
|
|||||||
// Settings menu items - use event delegation as items are added/removed
|
// Settings menu items - use event delegation as items are added/removed
|
||||||
if (utils.matches(event.target, _this4.player.config.selectors.inputs.language)) {
|
if (utils.matches(event.target, _this4.player.config.selectors.inputs.language)) {
|
||||||
proxy(event, function () {
|
proxy(event, function () {
|
||||||
_this4.player.language = event.target.value;
|
_this4.player.currentTrack = Number(event.target.value);
|
||||||
showHomeTab();
|
showHomeTab();
|
||||||
}, 'language');
|
}, 'language');
|
||||||
} else if (utils.matches(event.target, _this4.player.config.selectors.inputs.quality)) {
|
} 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)
|
// Set playback state and trigger change (only on actual change)
|
||||||
function assurePlaybackState(play) {
|
function assurePlaybackState(play) {
|
||||||
|
if (play && !this.embed.hasPlayed) {
|
||||||
|
this.embed.hasPlayed = true;
|
||||||
|
}
|
||||||
if (this.media.paused === play) {
|
if (this.media.paused === play) {
|
||||||
this.media.paused = !play;
|
this.media.paused = !play;
|
||||||
utils.dispatchEvent.call(this, this.media, play ? 'play' : 'pause');
|
utils.dispatchEvent.call(this, this.media, play ? 'play' : 'pause');
|
||||||
@ -10618,24 +10700,25 @@ var vimeo = {
|
|||||||
paused = player.paused,
|
paused = player.paused,
|
||||||
volume = player.volume;
|
volume = player.volume;
|
||||||
|
|
||||||
// Set seeking state and trigger event
|
var restorePause = paused && !embed.hasPlayed;
|
||||||
|
|
||||||
|
// Set seeking state and trigger event
|
||||||
media.seeking = true;
|
media.seeking = true;
|
||||||
utils.dispatchEvent.call(player, media, 'seeking');
|
utils.dispatchEvent.call(player, media, 'seeking');
|
||||||
|
|
||||||
// If paused, mute until seek is complete
|
// If paused, mute until seek is complete
|
||||||
Promise.resolve(paused && embed.setVolume(0))
|
Promise.resolve(restorePause && embed.setVolume(0))
|
||||||
// Seek
|
// Seek
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return embed.setCurrentTime(time);
|
return embed.setCurrentTime(time);
|
||||||
})
|
})
|
||||||
// Restore paused
|
// Restore paused
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return paused && embed.pause();
|
return restorePause && embed.pause();
|
||||||
})
|
})
|
||||||
// Restore volume
|
// Restore volume
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return paused && embed.setVolume(volume);
|
return restorePause && embed.setVolume(volume);
|
||||||
}).catch(function () {
|
}).catch(function () {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
});
|
});
|
||||||
@ -10765,17 +10848,25 @@ var vimeo = {
|
|||||||
captions.setup.call(player);
|
captions.setup.call(player);
|
||||||
});
|
});
|
||||||
|
|
||||||
player.embed.on('cuechange', function (data) {
|
player.embed.on('cuechange', function (_ref) {
|
||||||
var cue = null;
|
var _ref$cues = _ref.cues,
|
||||||
|
cues = _ref$cues === undefined ? [] : _ref$cues;
|
||||||
|
|
||||||
if (data.cues.length) {
|
var strippedCues = cues.map(function (cue) {
|
||||||
cue = utils.stripHTML(data.cues[0].text);
|
return utils.stripHTML(cue.text);
|
||||||
}
|
});
|
||||||
|
captions.updateCues.call(player, strippedCues);
|
||||||
captions.setText.call(player, cue);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
player.embed.on('loaded', function () {
|
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) {
|
if (utils.is.element(player.embed.element) && player.supported.ui) {
|
||||||
var frame = player.embed.element;
|
var frame = player.embed.element;
|
||||||
|
|
||||||
@ -10905,6 +10996,9 @@ function mapQualityUnits(levels) {
|
|||||||
|
|
||||||
// Set playback state and trigger change (only on actual change)
|
// Set playback state and trigger change (only on actual change)
|
||||||
function assurePlaybackState$1(play) {
|
function assurePlaybackState$1(play) {
|
||||||
|
if (play && !this.embed.hasPlayed) {
|
||||||
|
this.embed.hasPlayed = true;
|
||||||
|
}
|
||||||
if (this.media.paused === play) {
|
if (this.media.paused === play) {
|
||||||
this.media.paused = !play;
|
this.media.paused = !play;
|
||||||
utils.dispatchEvent.call(this, this.media, play ? 'play' : 'pause');
|
utils.dispatchEvent.call(this, this.media, play ? 'play' : 'pause');
|
||||||
@ -11318,7 +11412,7 @@ var youtube = {
|
|||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
// Restore paused state (YouTube starts playing on seek if the video hasn't been played yet)
|
// 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();
|
player.media.pause();
|
||||||
} else {
|
} else {
|
||||||
assurePlaybackState$1.call(player, true);
|
assurePlaybackState$1.call(player, true);
|
||||||
@ -12309,7 +12403,8 @@ var Plyr = function () {
|
|||||||
// Captions
|
// Captions
|
||||||
this.captions = {
|
this.captions = {
|
||||||
active: null,
|
active: null,
|
||||||
currentTrack: null
|
currentTrack: -1,
|
||||||
|
meta: new WeakMap()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Fullscreen
|
// Fullscreen
|
||||||
@ -12320,8 +12415,7 @@ var Plyr = function () {
|
|||||||
// Options
|
// Options
|
||||||
this.options = {
|
this.options = {
|
||||||
speed: [],
|
speed: [],
|
||||||
quality: [],
|
quality: []
|
||||||
captions: []
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
@ -12697,8 +12791,8 @@ var Plyr = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the captions language
|
* Set the caption track by index
|
||||||
* @param {string} - Two character ISO language code (e.g. EN, FR, PT, etc)
|
* @param {number} - Caption index
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
@ -13389,60 +13483,41 @@ var Plyr = function () {
|
|||||||
return Boolean(this.config.autoplay);
|
return Boolean(this.config.autoplay);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'language',
|
key: 'currentTrack',
|
||||||
set: function set(input) {
|
set: function set(input) {
|
||||||
// Nothing specified
|
captions.set.call(this, input);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update config
|
|
||||||
this.captions.language = language;
|
|
||||||
|
|
||||||
// Clear caption
|
|
||||||
captions.setText.call(this, null);
|
|
||||||
|
|
||||||
// Update captions
|
|
||||||
captions.setLanguage.call(this);
|
|
||||||
|
|
||||||
// Trigger an event
|
|
||||||
utils.dispatchEvent.call(this, this.media, 'languagechange');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current captions language
|
* Get the current caption track index (-1 if disabled)
|
||||||
*/
|
*/
|
||||||
,
|
,
|
||||||
get: function get() {
|
get: function get() {
|
||||||
return this.captions.language;
|
var _captions = this.captions,
|
||||||
|
active = _captions.active,
|
||||||
|
currentTrack = _captions.currentTrack;
|
||||||
|
|
||||||
|
return active ? currentTrack : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
*/
|
||||||
|
|
||||||
|
}, {
|
||||||
|
key: 'language',
|
||||||
|
set: function set(input) {
|
||||||
|
captions.setLanguage.call(this, input);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current track's language
|
||||||
|
*/
|
||||||
|
,
|
||||||
|
get: function get() {
|
||||||
|
return (captions.getCurrentTrack.call(this) || {}).language;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13518,9 +13593,7 @@ var Plyr = function () {
|
|||||||
} else if (utils.is.nodeList(selector)) {
|
} else if (utils.is.nodeList(selector)) {
|
||||||
targets = Array.from(selector);
|
targets = Array.from(selector);
|
||||||
} else if (utils.is.array(selector)) {
|
} else if (utils.is.array(selector)) {
|
||||||
targets = selector.filter(function (i) {
|
targets = selector.filter(utils.is.element);
|
||||||
return utils.is.element(i);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utils.is.empty(targets)) {
|
if (utils.is.empty(targets)) {
|
||||||
|
2
dist/plyr.polyfilled.js.map
vendored
2
dist/plyr.polyfilled.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.polyfilled.min.js
vendored
2
dist/plyr.polyfilled.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.polyfilled.min.js.map
vendored
2
dist/plyr.polyfilled.min.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user