Merge pull request #988 from kim-company/translate-qualities
Translate quality badges and quality names
This commit is contained in:
@ -32,6 +32,7 @@
|
|||||||
"message": "Use local parameter instead."
|
"message": "Use local parameter instead."
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"no-param-reassign": [2, { "props": false }],
|
||||||
"array-bracket-newline": [2, { "minItems": 2 }],
|
"array-bracket-newline": [2, { "minItems": 2 }],
|
||||||
"array-element-newline": [2, { "minItems": 2 }]
|
"array-element-newline": [2, { "minItems": 2 }]
|
||||||
},
|
},
|
||||||
|
200
dist/plyr.js
vendored
200
dist/plyr.js
vendored
@ -1300,6 +1300,14 @@ var utils = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// Get a nested value in an object
|
||||||
|
getDeep: function getDeep(object, path) {
|
||||||
|
return path.split('.').reduce(function (obj, key) {
|
||||||
|
return obj && obj[key] || undefined;
|
||||||
|
}, object);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
// Get the closest value in an array
|
// Get the closest value in an array
|
||||||
closest: function closest(array, value) {
|
closest: function closest(array, value) {
|
||||||
if (!utils.is.array(array) || !array.length) {
|
if (!utils.is.array(array) || !array.length) {
|
||||||
@ -1771,11 +1779,15 @@ var i18n = {
|
|||||||
var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
||||||
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||||
|
|
||||||
if (utils.is.empty(key) || utils.is.empty(config) || !Object.keys(config.i18n).includes(key)) {
|
if (utils.is.empty(key) || utils.is.empty(config)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
var string = config.i18n[key];
|
var string = utils.getDeep(config.i18n, key);
|
||||||
|
|
||||||
|
if (utils.is.empty(string)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
var replace = {
|
var replace = {
|
||||||
'{seektime}': config.seekTime,
|
'{seektime}': config.seekTime,
|
||||||
@ -2449,27 +2461,7 @@ var controls = {
|
|||||||
|
|
||||||
// Get the badge HTML for HD, 4K etc
|
// Get the badge HTML for HD, 4K etc
|
||||||
var getBadge = function getBadge(quality) {
|
var getBadge = function getBadge(quality) {
|
||||||
var label = '';
|
var label = i18n.get('qualityBadge.' + quality, _this3.config);
|
||||||
|
|
||||||
switch (quality) {
|
|
||||||
case 2160:
|
|
||||||
label = '4K';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1440:
|
|
||||||
case 1080:
|
|
||||||
case 720:
|
|
||||||
label = 'HD';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 576:
|
|
||||||
case 480:
|
|
||||||
label = 'SD';
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!label.length) {
|
if (!label.length) {
|
||||||
return null;
|
return null;
|
||||||
@ -2492,7 +2484,6 @@ var controls = {
|
|||||||
|
|
||||||
|
|
||||||
// Translate a value into a nice label
|
// Translate a value into a nice label
|
||||||
// TODO: Localisation
|
|
||||||
getLabel: function getLabel(setting, value) {
|
getLabel: function getLabel(setting, value) {
|
||||||
switch (setting) {
|
switch (setting) {
|
||||||
case 'speed':
|
case 'speed':
|
||||||
@ -2500,9 +2491,15 @@ var controls = {
|
|||||||
|
|
||||||
case 'quality':
|
case 'quality':
|
||||||
if (utils.is.number(value)) {
|
if (utils.is.number(value)) {
|
||||||
|
var qualityName = i18n.get('qualityName.' + value, this.config);
|
||||||
|
|
||||||
|
if (!qualityName.length) {
|
||||||
return value + 'p';
|
return value + 'p';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return qualityName;
|
||||||
|
}
|
||||||
|
|
||||||
return utils.toTitleCase(value);
|
return utils.toTitleCase(value);
|
||||||
|
|
||||||
case 'captions':
|
case 'captions':
|
||||||
@ -2660,12 +2657,7 @@ var controls = {
|
|||||||
|
|
||||||
// Generate options
|
// Generate options
|
||||||
tracks.forEach(function (track) {
|
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.captions.language.toLowerCase());
|
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);
|
||||||
});
|
|
||||||
|
|
||||||
// Store reference
|
|
||||||
this.options.captions = tracks.map(function (track) {
|
|
||||||
return track.language;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
controls.updateSetting.call(this, type, list);
|
controls.updateSetting.call(this, type, list);
|
||||||
@ -3268,28 +3260,6 @@ var captions = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set default language if not set
|
|
||||||
var stored = this.storage.get('language');
|
|
||||||
|
|
||||||
if (!utils.is.empty(stored)) {
|
|
||||||
this.captions.language = stored;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (utils.is.empty(this.captions.language)) {
|
|
||||||
this.captions.language = this.config.captions.language.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set captions enabled state if not set
|
|
||||||
if (!utils.is.boolean(this.captions.active)) {
|
|
||||||
var active = this.storage.get('captions');
|
|
||||||
|
|
||||||
if (utils.is.boolean(active)) {
|
|
||||||
this.captions.active = active;
|
|
||||||
} else {
|
|
||||||
this.captions.active = this.config.captions.active;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only Vimeo and HTML5 video supported at this point
|
// Only Vimeo and HTML5 video supported at this point
|
||||||
if (!this.isVideo || this.isYouTube || this.isHTML5 && !support.textTracks) {
|
if (!this.isVideo || this.isYouTube || this.isHTML5 && !support.textTracks) {
|
||||||
// Clear menu and hide
|
// Clear menu and hide
|
||||||
@ -3307,17 +3277,6 @@ var captions = {
|
|||||||
utils.insertAfter(this.elements.captions, this.elements.wrapper);
|
utils.insertAfter(this.elements.captions, this.elements.wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the class hook
|
|
||||||
utils.toggleClass(this.elements.container, this.config.classNames.captions.enabled, !utils.is.empty(captions.getTracks.call(this)));
|
|
||||||
|
|
||||||
// Get tracks
|
|
||||||
var tracks = captions.getTracks.call(this);
|
|
||||||
|
|
||||||
// If no caption file exists, hide container for caption text
|
|
||||||
if (utils.is.empty(tracks)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get browser info
|
// Get browser info
|
||||||
var browser = utils.getBrowser();
|
var browser = utils.getBrowser();
|
||||||
|
|
||||||
@ -3340,14 +3299,52 @@ var captions = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set language
|
// Try to load the value from storage
|
||||||
captions.setLanguage.call(this);
|
var active = this.storage.get('captions');
|
||||||
|
|
||||||
// Enable UI
|
// Otherwise fall back to the default config
|
||||||
captions.show.call(this);
|
if (!utils.is.boolean(active)) {
|
||||||
|
active = this.config.captions.active;
|
||||||
|
}
|
||||||
|
|
||||||
// Set available languages in list
|
// Set toggled state
|
||||||
if (utils.is.array(this.config.controls) && this.config.controls.includes('settings') && this.config.settings.includes('captions')) {
|
this.toggleCaptions(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));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set language if it hasn't been set already
|
||||||
|
if (!this.language) {
|
||||||
|
var language = this.config.captions.language;
|
||||||
|
|
||||||
|
if (language === 'auto') {
|
||||||
|
var _split = (navigator.language || navigator.userLanguage).split('-');
|
||||||
|
|
||||||
|
var _split2 = slicedToArray(_split, 1);
|
||||||
|
|
||||||
|
language = _split2[0];
|
||||||
|
}
|
||||||
|
this.language = this.storage.get('language') || (language || '').toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle the class hooks
|
||||||
|
utils.toggleClass(this.elements.container, this.config.classNames.captions.enabled, !utils.is.empty(captions.getTracks.call(this)));
|
||||||
|
|
||||||
|
// Update available languages in list
|
||||||
|
if ((this.config.controls || []).includes('settings') && this.config.settings.includes('captions')) {
|
||||||
controls.setCaptionsMenu.call(this);
|
controls.setCaptionsMenu.call(this);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -3508,25 +3505,6 @@ var captions = {
|
|||||||
} else {
|
} else {
|
||||||
this.debug.warn('No captions element to render to');
|
this.debug.warn('No captions element to render to');
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// Display captions container and button (for initialization)
|
|
||||||
show: function show() {
|
|
||||||
// Try to load the value from storage
|
|
||||||
var active = this.storage.get('captions');
|
|
||||||
|
|
||||||
// Otherwise fall back to the default config
|
|
||||||
if (!utils.is.boolean(active)) {
|
|
||||||
active = this.config.captions.active;
|
|
||||||
} else {
|
|
||||||
this.captions.active = active;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (active) {
|
|
||||||
utils.toggleClass(this.elements.container, this.config.classNames.captions.active, true);
|
|
||||||
utils.toggleState(this.elements.buttons.captions, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3667,7 +3645,10 @@ var defaults$1 = {
|
|||||||
// Captions settings
|
// Captions settings
|
||||||
captions: {
|
captions: {
|
||||||
active: false,
|
active: false,
|
||||||
language: (navigator.language || navigator.userLanguage).split('-')[0]
|
language: 'auto',
|
||||||
|
// Listen to new tracks added after Plyr is initialized.
|
||||||
|
// This is needed for streaming captions, but may result in unselectable options
|
||||||
|
update: false
|
||||||
},
|
},
|
||||||
|
|
||||||
// Fullscreen settings
|
// Fullscreen settings
|
||||||
@ -3724,7 +3705,15 @@ var defaults$1 = {
|
|||||||
reset: 'Reset',
|
reset: 'Reset',
|
||||||
disabled: 'Disabled',
|
disabled: 'Disabled',
|
||||||
enabled: 'Enabled',
|
enabled: 'Enabled',
|
||||||
advertisement: 'Ad'
|
advertisement: 'Ad',
|
||||||
|
qualityBadge: {
|
||||||
|
2160: '4K',
|
||||||
|
1440: 'HD',
|
||||||
|
1080: 'HD',
|
||||||
|
720: 'HD',
|
||||||
|
576: 'SD',
|
||||||
|
480: 'SD'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// URLs
|
// URLs
|
||||||
@ -4183,8 +4172,10 @@ var ui = {
|
|||||||
// Remove native controls
|
// Remove native controls
|
||||||
ui.toggleNativeControls.call(this);
|
ui.toggleNativeControls.call(this);
|
||||||
|
|
||||||
// Captions
|
// Setup captions for HTML5
|
||||||
|
if (this.isHTML5) {
|
||||||
captions.setup.call(this);
|
captions.setup.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
// Reset volume
|
// Reset volume
|
||||||
this.volume = null;
|
this.volume = null;
|
||||||
@ -4237,6 +4228,12 @@ var ui = {
|
|||||||
if (this.poster && this.elements.poster && !this.elements.poster.style.backgroundImage) {
|
if (this.poster && this.elements.poster && !this.elements.poster.style.backgroundImage) {
|
||||||
ui.setPoster.call(this, this.poster);
|
ui.setPoster.call(this, this.poster);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Manually set the duration if user has overridden it.
|
||||||
|
// The event listeners for it doesn't get called if preload is disabled (#701)
|
||||||
|
if (this.config.duration) {
|
||||||
|
controls.durationUpdate.call(this);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -7294,25 +7291,20 @@ var Plyr = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the method is called without parameter, toggle based on current value
|
// If the method is called without parameter, toggle based on current value
|
||||||
var show = utils.is.boolean(input) ? input : !this.elements.container.classList.contains(this.config.classNames.captions.active);
|
var active = utils.is.boolean(input) ? input : !this.elements.container.classList.contains(this.config.classNames.captions.active);
|
||||||
|
|
||||||
// Nothing to change...
|
|
||||||
if (this.captions.active === show) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set global
|
|
||||||
this.captions.active = show;
|
|
||||||
|
|
||||||
// Toggle state
|
// Toggle state
|
||||||
utils.toggleState(this.elements.buttons.captions, this.captions.active);
|
utils.toggleState(this.elements.buttons.captions, active);
|
||||||
|
|
||||||
// Add class hook
|
// Add class hook
|
||||||
utils.toggleClass(this.elements.container, this.config.classNames.captions.active, this.captions.active);
|
utils.toggleClass(this.elements.container, this.config.classNames.captions.active, active);
|
||||||
|
|
||||||
// Trigger an event
|
// Update state and trigger event
|
||||||
|
if (active !== this.captions.active) {
|
||||||
|
this.captions.active = active;
|
||||||
utils.dispatchEvent.call(this, this.media, this.captions.active ? 'captionsenabled' : 'captionsdisabled');
|
utils.dispatchEvent.call(this, this.media, this.captions.active ? 'captionsenabled' : 'captionsdisabled');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the captions language
|
* Set the captions language
|
||||||
@ -7843,7 +7835,7 @@ var Plyr = function () {
|
|||||||
quality = Number(input);
|
quality = Number(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!utils.is.number(quality) || quality === 0) {
|
if (!utils.is.number(quality)) {
|
||||||
quality = this.storage.get('quality');
|
quality = this.storage.get('quality');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
237
dist/plyr.polyfilled.js
vendored
237
dist/plyr.polyfilled.js
vendored
@ -20,7 +20,7 @@ if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef
|
|||||||
});
|
});
|
||||||
|
|
||||||
var _core = createCommonjsModule(function (module) {
|
var _core = createCommonjsModule(function (module) {
|
||||||
var core = module.exports = { version: '2.5.6' };
|
var core = module.exports = { version: '2.5.5' };
|
||||||
if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
|
if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef
|
||||||
});
|
});
|
||||||
var _core_1 = _core.version;
|
var _core_1 = _core.version;
|
||||||
@ -333,18 +333,11 @@ var _arrayIncludes = function (IS_INCLUDES) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
var _shared = createCommonjsModule(function (module) {
|
|
||||||
var SHARED = '__core-js_shared__';
|
var SHARED = '__core-js_shared__';
|
||||||
var store = _global[SHARED] || (_global[SHARED] = {});
|
var store = _global[SHARED] || (_global[SHARED] = {});
|
||||||
|
var _shared = function (key) {
|
||||||
(module.exports = function (key, value) {
|
return store[key] || (store[key] = {});
|
||||||
return store[key] || (store[key] = value !== undefined ? value : {});
|
};
|
||||||
})('versions', []).push({
|
|
||||||
version: _core.version,
|
|
||||||
mode: _library ? 'pure' : 'global',
|
|
||||||
copyright: '© 2018 Denis Pushkarev (zloirock.ru)'
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var shared = _shared('keys');
|
var shared = _shared('keys');
|
||||||
|
|
||||||
@ -2652,8 +2645,7 @@ var _microtask = function () {
|
|||||||
};
|
};
|
||||||
// environments with maybe non-completely correct, but existent Promise
|
// environments with maybe non-completely correct, but existent Promise
|
||||||
} else if (Promise$1 && Promise$1.resolve) {
|
} else if (Promise$1 && Promise$1.resolve) {
|
||||||
// Promise.resolve without an argument throws an error in LG WebOS 2
|
var promise = Promise$1.resolve();
|
||||||
var promise = Promise$1.resolve(undefined);
|
|
||||||
notify = function () {
|
notify = function () {
|
||||||
promise.then(flush);
|
promise.then(flush);
|
||||||
};
|
};
|
||||||
@ -2710,10 +2702,6 @@ var _perform = function (exec) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var navigator$1 = _global.navigator;
|
|
||||||
|
|
||||||
var _userAgent = navigator$1 && navigator$1.userAgent || '';
|
|
||||||
|
|
||||||
var _promiseResolve = function (C, x) {
|
var _promiseResolve = function (C, x) {
|
||||||
_anObject(C);
|
_anObject(C);
|
||||||
if (_isObject(x) && x.constructor === C) return x;
|
if (_isObject(x) && x.constructor === C) return x;
|
||||||
@ -2728,12 +2716,9 @@ var microtask = _microtask();
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var PROMISE = 'Promise';
|
var PROMISE = 'Promise';
|
||||||
var TypeError$1 = _global.TypeError;
|
var TypeError$1 = _global.TypeError;
|
||||||
var process$2 = _global.process;
|
var process$2 = _global.process;
|
||||||
var versions = process$2 && process$2.versions;
|
|
||||||
var v8 = versions && versions.v8 || '';
|
|
||||||
var $Promise = _global[PROMISE];
|
var $Promise = _global[PROMISE];
|
||||||
var isNode$1 = _classof(process$2) == 'process';
|
var isNode$1 = _classof(process$2) == 'process';
|
||||||
var empty = function () { /* empty */ };
|
var empty = function () { /* empty */ };
|
||||||
@ -2748,13 +2733,7 @@ var USE_NATIVE = !!function () {
|
|||||||
exec(empty, empty);
|
exec(empty, empty);
|
||||||
};
|
};
|
||||||
// unhandled rejections tracking support, NodeJS Promise without it fails @@species test
|
// unhandled rejections tracking support, NodeJS Promise without it fails @@species test
|
||||||
return (isNode$1 || typeof PromiseRejectionEvent == 'function')
|
return (isNode$1 || typeof PromiseRejectionEvent == 'function') && promise.then(empty) instanceof FakePromise;
|
||||||
&& promise.then(empty) instanceof FakePromise
|
|
||||||
// v8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables
|
|
||||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=830565
|
|
||||||
// we can't detect it synchronously, so just check versions
|
|
||||||
&& v8.indexOf('6.6') !== 0
|
|
||||||
&& _userAgent.indexOf('Chrome/66') === -1;
|
|
||||||
} catch (e) { /* empty */ }
|
} catch (e) { /* empty */ }
|
||||||
}();
|
}();
|
||||||
|
|
||||||
@ -4182,6 +4161,10 @@ var _stringPad = function (that, maxLength, fillString, left) {
|
|||||||
return left ? stringFiller + S : S + stringFiller;
|
return left ? stringFiller + S : S + stringFiller;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var navigator$1 = _global.navigator;
|
||||||
|
|
||||||
|
var _userAgent = navigator$1 && navigator$1.userAgent || '';
|
||||||
|
|
||||||
// https://github.com/tc39/proposal-string-pad-start-end
|
// https://github.com/tc39/proposal-string-pad-start-end
|
||||||
|
|
||||||
|
|
||||||
@ -6706,6 +6689,14 @@ var utils = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// Get a nested value in an object
|
||||||
|
getDeep: function getDeep(object, path) {
|
||||||
|
return path.split('.').reduce(function (obj, key) {
|
||||||
|
return obj && obj[key] || undefined;
|
||||||
|
}, object);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
// Get the closest value in an array
|
// Get the closest value in an array
|
||||||
closest: function closest(array, value) {
|
closest: function closest(array, value) {
|
||||||
if (!utils.is.array(array) || !array.length) {
|
if (!utils.is.array(array) || !array.length) {
|
||||||
@ -7177,11 +7168,15 @@ var i18n = {
|
|||||||
var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
||||||
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||||
|
|
||||||
if (utils.is.empty(key) || utils.is.empty(config) || !Object.keys(config.i18n).includes(key)) {
|
if (utils.is.empty(key) || utils.is.empty(config)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
var string = config.i18n[key];
|
var string = utils.getDeep(config.i18n, key);
|
||||||
|
|
||||||
|
if (utils.is.empty(string)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
var replace = {
|
var replace = {
|
||||||
'{seektime}': config.seekTime,
|
'{seektime}': config.seekTime,
|
||||||
@ -7855,27 +7850,7 @@ var controls = {
|
|||||||
|
|
||||||
// Get the badge HTML for HD, 4K etc
|
// Get the badge HTML for HD, 4K etc
|
||||||
var getBadge = function getBadge(quality) {
|
var getBadge = function getBadge(quality) {
|
||||||
var label = '';
|
var label = i18n.get('qualityBadge.' + quality, _this3.config);
|
||||||
|
|
||||||
switch (quality) {
|
|
||||||
case 2160:
|
|
||||||
label = '4K';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1440:
|
|
||||||
case 1080:
|
|
||||||
case 720:
|
|
||||||
label = 'HD';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 576:
|
|
||||||
case 480:
|
|
||||||
label = 'SD';
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!label.length) {
|
if (!label.length) {
|
||||||
return null;
|
return null;
|
||||||
@ -7898,7 +7873,6 @@ var controls = {
|
|||||||
|
|
||||||
|
|
||||||
// Translate a value into a nice label
|
// Translate a value into a nice label
|
||||||
// TODO: Localisation
|
|
||||||
getLabel: function getLabel(setting, value) {
|
getLabel: function getLabel(setting, value) {
|
||||||
switch (setting) {
|
switch (setting) {
|
||||||
case 'speed':
|
case 'speed':
|
||||||
@ -7906,9 +7880,15 @@ var controls = {
|
|||||||
|
|
||||||
case 'quality':
|
case 'quality':
|
||||||
if (utils.is.number(value)) {
|
if (utils.is.number(value)) {
|
||||||
|
var qualityName = i18n.get('qualityName.' + value, this.config);
|
||||||
|
|
||||||
|
if (!qualityName.length) {
|
||||||
return value + 'p';
|
return value + 'p';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return qualityName;
|
||||||
|
}
|
||||||
|
|
||||||
return utils.toTitleCase(value);
|
return utils.toTitleCase(value);
|
||||||
|
|
||||||
case 'captions':
|
case 'captions':
|
||||||
@ -8066,12 +8046,7 @@ var controls = {
|
|||||||
|
|
||||||
// Generate options
|
// Generate options
|
||||||
tracks.forEach(function (track) {
|
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.captions.language.toLowerCase());
|
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);
|
||||||
});
|
|
||||||
|
|
||||||
// Store reference
|
|
||||||
this.options.captions = tracks.map(function (track) {
|
|
||||||
return track.language;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
controls.updateSetting.call(this, type, list);
|
controls.updateSetting.call(this, type, list);
|
||||||
@ -8674,28 +8649,6 @@ var captions = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set default language if not set
|
|
||||||
var stored = this.storage.get('language');
|
|
||||||
|
|
||||||
if (!utils.is.empty(stored)) {
|
|
||||||
this.captions.language = stored;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (utils.is.empty(this.captions.language)) {
|
|
||||||
this.captions.language = this.config.captions.language.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set captions enabled state if not set
|
|
||||||
if (!utils.is.boolean(this.captions.active)) {
|
|
||||||
var active = this.storage.get('captions');
|
|
||||||
|
|
||||||
if (utils.is.boolean(active)) {
|
|
||||||
this.captions.active = active;
|
|
||||||
} else {
|
|
||||||
this.captions.active = this.config.captions.active;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only Vimeo and HTML5 video supported at this point
|
// Only Vimeo and HTML5 video supported at this point
|
||||||
if (!this.isVideo || this.isYouTube || this.isHTML5 && !support.textTracks) {
|
if (!this.isVideo || this.isYouTube || this.isHTML5 && !support.textTracks) {
|
||||||
// Clear menu and hide
|
// Clear menu and hide
|
||||||
@ -8713,17 +8666,6 @@ var captions = {
|
|||||||
utils.insertAfter(this.elements.captions, this.elements.wrapper);
|
utils.insertAfter(this.elements.captions, this.elements.wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the class hook
|
|
||||||
utils.toggleClass(this.elements.container, this.config.classNames.captions.enabled, !utils.is.empty(captions.getTracks.call(this)));
|
|
||||||
|
|
||||||
// Get tracks
|
|
||||||
var tracks = captions.getTracks.call(this);
|
|
||||||
|
|
||||||
// If no caption file exists, hide container for caption text
|
|
||||||
if (utils.is.empty(tracks)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get browser info
|
// Get browser info
|
||||||
var browser = utils.getBrowser();
|
var browser = utils.getBrowser();
|
||||||
|
|
||||||
@ -8746,14 +8688,52 @@ var captions = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set language
|
// Try to load the value from storage
|
||||||
captions.setLanguage.call(this);
|
var active = this.storage.get('captions');
|
||||||
|
|
||||||
// Enable UI
|
// Otherwise fall back to the default config
|
||||||
captions.show.call(this);
|
if (!utils.is.boolean(active)) {
|
||||||
|
active = this.config.captions.active;
|
||||||
|
}
|
||||||
|
|
||||||
// Set available languages in list
|
// Set toggled state
|
||||||
if (utils.is.array(this.config.controls) && this.config.controls.includes('settings') && this.config.settings.includes('captions')) {
|
this.toggleCaptions(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));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set language if it hasn't been set already
|
||||||
|
if (!this.language) {
|
||||||
|
var language = this.config.captions.language;
|
||||||
|
|
||||||
|
if (language === 'auto') {
|
||||||
|
var _split = (navigator.language || navigator.userLanguage).split('-');
|
||||||
|
|
||||||
|
var _split2 = slicedToArray(_split, 1);
|
||||||
|
|
||||||
|
language = _split2[0];
|
||||||
|
}
|
||||||
|
this.language = this.storage.get('language') || (language || '').toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle the class hooks
|
||||||
|
utils.toggleClass(this.elements.container, this.config.classNames.captions.enabled, !utils.is.empty(captions.getTracks.call(this)));
|
||||||
|
|
||||||
|
// Update available languages in list
|
||||||
|
if ((this.config.controls || []).includes('settings') && this.config.settings.includes('captions')) {
|
||||||
controls.setCaptionsMenu.call(this);
|
controls.setCaptionsMenu.call(this);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -8914,25 +8894,6 @@ var captions = {
|
|||||||
} else {
|
} else {
|
||||||
this.debug.warn('No captions element to render to');
|
this.debug.warn('No captions element to render to');
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// Display captions container and button (for initialization)
|
|
||||||
show: function show() {
|
|
||||||
// Try to load the value from storage
|
|
||||||
var active = this.storage.get('captions');
|
|
||||||
|
|
||||||
// Otherwise fall back to the default config
|
|
||||||
if (!utils.is.boolean(active)) {
|
|
||||||
active = this.config.captions.active;
|
|
||||||
} else {
|
|
||||||
this.captions.active = active;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (active) {
|
|
||||||
utils.toggleClass(this.elements.container, this.config.classNames.captions.active, true);
|
|
||||||
utils.toggleState(this.elements.buttons.captions, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -9073,7 +9034,10 @@ var defaults$1 = {
|
|||||||
// Captions settings
|
// Captions settings
|
||||||
captions: {
|
captions: {
|
||||||
active: false,
|
active: false,
|
||||||
language: (navigator.language || navigator.userLanguage).split('-')[0]
|
language: 'auto',
|
||||||
|
// Listen to new tracks added after Plyr is initialized.
|
||||||
|
// This is needed for streaming captions, but may result in unselectable options
|
||||||
|
update: false
|
||||||
},
|
},
|
||||||
|
|
||||||
// Fullscreen settings
|
// Fullscreen settings
|
||||||
@ -9130,7 +9094,15 @@ var defaults$1 = {
|
|||||||
reset: 'Reset',
|
reset: 'Reset',
|
||||||
disabled: 'Disabled',
|
disabled: 'Disabled',
|
||||||
enabled: 'Enabled',
|
enabled: 'Enabled',
|
||||||
advertisement: 'Ad'
|
advertisement: 'Ad',
|
||||||
|
qualityBadge: {
|
||||||
|
2160: '4K',
|
||||||
|
1440: 'HD',
|
||||||
|
1080: 'HD',
|
||||||
|
720: 'HD',
|
||||||
|
576: 'SD',
|
||||||
|
480: 'SD'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// URLs
|
// URLs
|
||||||
@ -9589,8 +9561,10 @@ var ui = {
|
|||||||
// Remove native controls
|
// Remove native controls
|
||||||
ui.toggleNativeControls.call(this);
|
ui.toggleNativeControls.call(this);
|
||||||
|
|
||||||
// Captions
|
// Setup captions for HTML5
|
||||||
|
if (this.isHTML5) {
|
||||||
captions.setup.call(this);
|
captions.setup.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
// Reset volume
|
// Reset volume
|
||||||
this.volume = null;
|
this.volume = null;
|
||||||
@ -9643,6 +9617,12 @@ var ui = {
|
|||||||
if (this.poster && this.elements.poster && !this.elements.poster.style.backgroundImage) {
|
if (this.poster && this.elements.poster && !this.elements.poster.style.backgroundImage) {
|
||||||
ui.setPoster.call(this, this.poster);
|
ui.setPoster.call(this, this.poster);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Manually set the duration if user has overridden it.
|
||||||
|
// The event listeners for it doesn't get called if preload is disabled (#701)
|
||||||
|
if (this.config.duration) {
|
||||||
|
controls.durationUpdate.call(this);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -12700,25 +12680,20 @@ var Plyr = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the method is called without parameter, toggle based on current value
|
// If the method is called without parameter, toggle based on current value
|
||||||
var show = utils.is.boolean(input) ? input : !this.elements.container.classList.contains(this.config.classNames.captions.active);
|
var active = utils.is.boolean(input) ? input : !this.elements.container.classList.contains(this.config.classNames.captions.active);
|
||||||
|
|
||||||
// Nothing to change...
|
|
||||||
if (this.captions.active === show) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set global
|
|
||||||
this.captions.active = show;
|
|
||||||
|
|
||||||
// Toggle state
|
// Toggle state
|
||||||
utils.toggleState(this.elements.buttons.captions, this.captions.active);
|
utils.toggleState(this.elements.buttons.captions, active);
|
||||||
|
|
||||||
// Add class hook
|
// Add class hook
|
||||||
utils.toggleClass(this.elements.container, this.config.classNames.captions.active, this.captions.active);
|
utils.toggleClass(this.elements.container, this.config.classNames.captions.active, active);
|
||||||
|
|
||||||
// Trigger an event
|
// Update state and trigger event
|
||||||
|
if (active !== this.captions.active) {
|
||||||
|
this.captions.active = active;
|
||||||
utils.dispatchEvent.call(this, this.media, this.captions.active ? 'captionsenabled' : 'captionsdisabled');
|
utils.dispatchEvent.call(this, this.media, this.captions.active ? 'captionsenabled' : 'captionsdisabled');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the captions language
|
* Set the captions language
|
||||||
@ -13249,7 +13224,7 @@ var Plyr = function () {
|
|||||||
quality = Number(input);
|
quality = Number(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!utils.is.number(quality) || quality === 0) {
|
if (!utils.is.number(quality)) {
|
||||||
quality = this.storage.get('quality');
|
quality = this.storage.get('quality');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
29
src/js/controls.js
vendored
29
src/js/controls.js
vendored
@ -664,27 +664,7 @@ const controls = {
|
|||||||
|
|
||||||
// Get the badge HTML for HD, 4K etc
|
// Get the badge HTML for HD, 4K etc
|
||||||
const getBadge = quality => {
|
const getBadge = quality => {
|
||||||
let label = '';
|
const label = i18n.get(`qualityBadge.${quality}`, this.config);
|
||||||
|
|
||||||
switch (quality) {
|
|
||||||
case 2160:
|
|
||||||
label = '4K';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1440:
|
|
||||||
case 1080:
|
|
||||||
case 720:
|
|
||||||
label = 'HD';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 576:
|
|
||||||
case 480:
|
|
||||||
label = 'SD';
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!label.length) {
|
if (!label.length) {
|
||||||
return null;
|
return null;
|
||||||
@ -708,7 +688,6 @@ const controls = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Translate a value into a nice label
|
// Translate a value into a nice label
|
||||||
// TODO: Localisation
|
|
||||||
getLabel(setting, value) {
|
getLabel(setting, value) {
|
||||||
switch (setting) {
|
switch (setting) {
|
||||||
case 'speed':
|
case 'speed':
|
||||||
@ -716,9 +695,15 @@ const controls = {
|
|||||||
|
|
||||||
case 'quality':
|
case 'quality':
|
||||||
if (utils.is.number(value)) {
|
if (utils.is.number(value)) {
|
||||||
|
const label = i18n.get(`qualityLabel.${value}`, this.config);
|
||||||
|
|
||||||
|
if (!label.length) {
|
||||||
return `${value}p`;
|
return `${value}p`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
return utils.toTitleCase(value);
|
return utils.toTitleCase(value);
|
||||||
|
|
||||||
case 'captions':
|
case 'captions':
|
||||||
|
@ -190,6 +190,14 @@ const defaults = {
|
|||||||
disabled: 'Disabled',
|
disabled: 'Disabled',
|
||||||
enabled: 'Enabled',
|
enabled: 'Enabled',
|
||||||
advertisement: 'Ad',
|
advertisement: 'Ad',
|
||||||
|
qualityBadge: {
|
||||||
|
2160: '4K',
|
||||||
|
1440: 'HD',
|
||||||
|
1080: 'HD',
|
||||||
|
720: 'HD',
|
||||||
|
576: 'SD',
|
||||||
|
480: 'SD',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
// URLs
|
// URLs
|
||||||
|
@ -6,11 +6,15 @@ import utils from './utils';
|
|||||||
|
|
||||||
const i18n = {
|
const i18n = {
|
||||||
get(key = '', config = {}) {
|
get(key = '', config = {}) {
|
||||||
if (utils.is.empty(key) || utils.is.empty(config) || !Object.keys(config.i18n).includes(key)) {
|
if (utils.is.empty(key) || utils.is.empty(config)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
let string = config.i18n[key];
|
let string = utils.getDeep(config.i18n, key);
|
||||||
|
|
||||||
|
if (utils.is.empty(string)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
const replace = {
|
const replace = {
|
||||||
'{seektime}': config.seekTime,
|
'{seektime}': config.seekTime,
|
||||||
|
@ -675,7 +675,7 @@ class Plyr {
|
|||||||
quality = Number(input);
|
quality = Number(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!utils.is.number(quality) || quality === 0) {
|
if (!utils.is.number(quality)) {
|
||||||
quality = this.storage.get('quality');
|
quality = this.storage.get('quality');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -728,6 +728,11 @@ const utils = {
|
|||||||
return JSON.parse(JSON.stringify(object));
|
return JSON.parse(JSON.stringify(object));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Get a nested value in an object
|
||||||
|
getDeep(object, path) {
|
||||||
|
return path.split('.').reduce((obj, key) => obj && obj[key], object);
|
||||||
|
},
|
||||||
|
|
||||||
// Get the closest value in an array
|
// Get the closest value in an array
|
||||||
closest(array, value) {
|
closest(array, value) {
|
||||||
if (!utils.is.array(array) || !array.length) {
|
if (!utils.is.array(array) || !array.length) {
|
||||||
|
Reference in New Issue
Block a user