Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2bd08cdc28 | |||
| 5fefabe3bd | |||
| e281078441 | |||
| 9bb75f6f52 | |||
| 3b7a24456d | |||
| c885d59270 | |||
| 9f30d54963 | |||
| b247093495 | |||
| 9ca7b861a9 | |||
| 2eccf0dd05 | |||
| 566b957e65 | |||
| a8456f4ca7 | |||
| 0f3098040d | |||
| 21539be3f2 | |||
| c22f5c4b39 | |||
| f4b47a9275 | |||
| 266b70d9d0 | |||
| 6e68ad6d15 | |||
| c202551e6d | |||
| 5b7a025d26 | |||
| 26bcf83960 | |||
| e4acff4f8d | |||
| 568ddf2390 | |||
| ce91945544 | |||
| 11fed8d1b5 |
@@ -1,3 +1,11 @@
|
|||||||
|
## v3.5.3
|
||||||
|
|
||||||
|
- Improved the usage of the `ratio` config option; it now works as expected and for all video types. The default has not changed, it is to dynamically, where possible (except YouTube where 16:9 is used) determine the ratio from the media source so this is not a breaking change.
|
||||||
|
- Added new `ratio` getter and setter
|
||||||
|
- Fix: Properly clear all timeouts on destroy
|
||||||
|
- Fix: Allow absolute paths in preview thumbnails
|
||||||
|
- Improvement: Allow optional hours and ms in VTT parser in preview thumbnails
|
||||||
|
|
||||||
## v3.5.2
|
## v3.5.2
|
||||||
|
|
||||||
- Fixed issue where the preview thumbnail was present while scrubbing
|
- Fixed issue where the preview thumbnail was present while scrubbing
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+225
-112
@@ -1,7 +1,7 @@
|
|||||||
typeof navigator === "object" && (function () {
|
typeof navigator === "object" && (function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
||||||
|
|
||||||
function createCommonjsModule(fn, module) {
|
function createCommonjsModule(fn, module) {
|
||||||
return module = { exports: {} }, fn(module, module.exports), module.exports;
|
return module = { exports: {} }, fn(module, module.exports), module.exports;
|
||||||
@@ -4951,6 +4951,83 @@ typeof navigator === "object" && (function () {
|
|||||||
reducedMotion: 'matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches
|
reducedMotion: 'matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function validateRatio(input) {
|
||||||
|
if (!is$1.array(input) && (!is$1.string(input) || !input.includes(':'))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ratio = is$1.array(input) ? input : input.split(':');
|
||||||
|
return ratio.map(Number).every(is$1.number);
|
||||||
|
}
|
||||||
|
function reduceAspectRatio(ratio) {
|
||||||
|
if (!is$1.array(ratio) || !ratio.every(is$1.number)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ratio = _slicedToArray(ratio, 2),
|
||||||
|
width = _ratio[0],
|
||||||
|
height = _ratio[1];
|
||||||
|
|
||||||
|
var getDivider = function getDivider(w, h) {
|
||||||
|
return h === 0 ? w : getDivider(h, w % h);
|
||||||
|
};
|
||||||
|
|
||||||
|
var divider = getDivider(width, height);
|
||||||
|
return [width / divider, height / divider];
|
||||||
|
}
|
||||||
|
function getAspectRatio(input) {
|
||||||
|
var parse = function parse(ratio) {
|
||||||
|
if (!validateRatio(ratio)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ratio.split(':').map(Number);
|
||||||
|
}; // Provided ratio
|
||||||
|
|
||||||
|
|
||||||
|
var ratio = parse(input); // Get from config
|
||||||
|
|
||||||
|
if (ratio === null) {
|
||||||
|
ratio = parse(this.config.ratio);
|
||||||
|
} // Get from embed
|
||||||
|
|
||||||
|
|
||||||
|
if (ratio === null && !is$1.empty(this.embed) && is$1.string(this.embed.ratio)) {
|
||||||
|
ratio = parse(this.embed.ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ratio;
|
||||||
|
} // Set aspect ratio for responsive container
|
||||||
|
|
||||||
|
function setAspectRatio(input) {
|
||||||
|
if (!this.isVideo) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
var ratio = getAspectRatio.call(this, input);
|
||||||
|
|
||||||
|
var _ref = is$1.array(ratio) ? ratio : [0, 0],
|
||||||
|
_ref2 = _slicedToArray(_ref, 2),
|
||||||
|
w = _ref2[0],
|
||||||
|
h = _ref2[1];
|
||||||
|
|
||||||
|
var padding = 100 / w * h;
|
||||||
|
this.elements.wrapper.style.paddingBottom = "".concat(padding, "%"); // For Vimeo we have an extra <div> to hide the standard controls and UI
|
||||||
|
|
||||||
|
if (this.isVimeo && this.supported.ui) {
|
||||||
|
var height = 240;
|
||||||
|
var offset = (height - padding) / (height / 50);
|
||||||
|
this.media.style.transform = "translateY(-".concat(offset, "%)");
|
||||||
|
} else if (this.isHTML5) {
|
||||||
|
this.elements.wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
padding: padding,
|
||||||
|
ratio: ratio
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
var html5 = {
|
var html5 = {
|
||||||
getSources: function getSources() {
|
getSources: function getSources() {
|
||||||
@@ -4984,7 +5061,9 @@ typeof navigator === "object" && (function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var player = this; // Quality
|
var player = this; // Set aspect ratio if set
|
||||||
|
|
||||||
|
setAspectRatio.call(player); // Quality
|
||||||
|
|
||||||
Object.defineProperty(player.media, 'quality', {
|
Object.defineProperty(player.media, 'quality', {
|
||||||
get: function get() {
|
get: function get() {
|
||||||
@@ -5883,7 +5962,7 @@ typeof navigator === "object" && (function () {
|
|||||||
list.appendChild(menuItem);
|
list.appendChild(menuItem);
|
||||||
},
|
},
|
||||||
// Format a time for display
|
// Format a time for display
|
||||||
formatTime: function formatTime$$1() {
|
formatTime: function formatTime$1() {
|
||||||
var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
||||||
var inverted = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
var inverted = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
||||||
|
|
||||||
@@ -6003,8 +6082,8 @@ typeof navigator === "object" && (function () {
|
|||||||
range.setAttribute('aria-valuenow', this.currentTime);
|
range.setAttribute('aria-valuenow', this.currentTime);
|
||||||
var currentTime = controls.formatTime(this.currentTime);
|
var currentTime = controls.formatTime(this.currentTime);
|
||||||
var duration = controls.formatTime(this.duration);
|
var duration = controls.formatTime(this.duration);
|
||||||
var format$$1 = i18n.get('seekLabel', this.config);
|
var format = i18n.get('seekLabel', this.config);
|
||||||
range.setAttribute('aria-valuetext', format$$1.replace('{currentTime}', currentTime).replace('{duration}', duration));
|
range.setAttribute('aria-valuetext', format.replace('{currentTime}', currentTime).replace('{duration}', duration));
|
||||||
} else if (matches$1(range, this.config.selectors.inputs.volume)) {
|
} else if (matches$1(range, this.config.selectors.inputs.volume)) {
|
||||||
var percent = range.value * 100;
|
var percent = range.value * 100;
|
||||||
range.setAttribute('aria-valuenow', percent);
|
range.setAttribute('aria-valuenow', percent);
|
||||||
@@ -7358,8 +7437,9 @@ typeof navigator === "object" && (function () {
|
|||||||
invertTime: true,
|
invertTime: true,
|
||||||
// Clicking the currentTime inverts it's value to show time left rather than elapsed
|
// Clicking the currentTime inverts it's value to show time left rather than elapsed
|
||||||
toggleInvert: true,
|
toggleInvert: true,
|
||||||
// Aspect ratio (for embeds)
|
// Force an aspect ratio
|
||||||
ratio: '16:9',
|
// The format must be `'w:h'` (e.g. `'16:9'`)
|
||||||
|
ratio: null,
|
||||||
// Click video container to play/pause
|
// Click video container to play/pause
|
||||||
clickToPlay: true,
|
clickToPlay: true,
|
||||||
// Auto hide the controls
|
// Auto hide the controls
|
||||||
@@ -7371,7 +7451,7 @@ typeof navigator === "object" && (function () {
|
|||||||
// Sprite (for icons)
|
// Sprite (for icons)
|
||||||
loadSprite: true,
|
loadSprite: true,
|
||||||
iconPrefix: 'plyr',
|
iconPrefix: 'plyr',
|
||||||
iconUrl: 'https://cdn.plyr.io/3.5.2/plyr.svg',
|
iconUrl: 'https://cdn.plyr.io/3.5.3/plyr.svg',
|
||||||
// Blank video (used to prevent errors on source change)
|
// Blank video (used to prevent errors on source change)
|
||||||
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
||||||
// Quality default
|
// Quality default
|
||||||
@@ -7571,6 +7651,7 @@ typeof navigator === "object" && (function () {
|
|||||||
provider: 'plyr--{0}',
|
provider: 'plyr--{0}',
|
||||||
video: 'plyr__video-wrapper',
|
video: 'plyr__video-wrapper',
|
||||||
embed: 'plyr__video-embed',
|
embed: 'plyr__video-embed',
|
||||||
|
videoFixedRatio: 'plyr__video-wrapper--fixed-ratio',
|
||||||
embedContainer: 'plyr__video-embed__container',
|
embedContainer: 'plyr__video-embed__container',
|
||||||
poster: 'plyr__poster',
|
poster: 'plyr__poster',
|
||||||
posterEnabled: 'plyr__poster-enabled',
|
posterEnabled: 'plyr__poster-enabled',
|
||||||
@@ -8236,55 +8317,17 @@ typeof navigator === "object" && (function () {
|
|||||||
},
|
},
|
||||||
// Toggle controls based on state and `force` argument
|
// Toggle controls based on state and `force` argument
|
||||||
toggleControls: function toggleControls(force) {
|
toggleControls: function toggleControls(force) {
|
||||||
var controls$$1 = this.elements.controls;
|
var controls = this.elements.controls;
|
||||||
|
|
||||||
if (controls$$1 && this.config.hideControls) {
|
if (controls && this.config.hideControls) {
|
||||||
// Don't hide controls if a touch-device user recently seeked. (Must be limited to touch devices, or it occasionally prevents desktop controls from hiding.)
|
// Don't hide controls if a touch-device user recently seeked. (Must be limited to touch devices, or it occasionally prevents desktop controls from hiding.)
|
||||||
var recentTouchSeek = this.touch && this.lastSeekTime + 2000 > Date.now(); // Show controls if force, loading, paused, button interaction, or recent seek, otherwise hide
|
var recentTouchSeek = this.touch && this.lastSeekTime + 2000 > Date.now(); // Show controls if force, loading, paused, button interaction, or recent seek, otherwise hide
|
||||||
|
|
||||||
this.toggleControls(Boolean(force || this.loading || this.paused || controls$$1.pressed || controls$$1.hover || recentTouchSeek));
|
this.toggleControls(Boolean(force || this.loading || this.paused || controls.pressed || controls.hover || recentTouchSeek));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* function reduceAspectRatio(width, height) {
|
|
||||||
const getRatio = (w, h) => (h === 0 ? w : getRatio(h, w % h));
|
|
||||||
const ratio = getRatio(width, height);
|
|
||||||
return `${width / ratio}:${height / ratio}`;
|
|
||||||
} */
|
|
||||||
// Set aspect ratio for responsive container
|
|
||||||
|
|
||||||
function setAspectRatio(input) {
|
|
||||||
var ratio = input;
|
|
||||||
|
|
||||||
if (!is$1.string(ratio) && !is$1.nullOrUndefined(this.embed)) {
|
|
||||||
ratio = this.embed.ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is$1.string(ratio)) {
|
|
||||||
ratio = this.config.ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ratio$split$map = ratio.split(':').map(Number),
|
|
||||||
_ratio$split$map2 = _slicedToArray(_ratio$split$map, 2),
|
|
||||||
x = _ratio$split$map2[0],
|
|
||||||
y = _ratio$split$map2[1];
|
|
||||||
|
|
||||||
var padding = 100 / x * y;
|
|
||||||
this.elements.wrapper.style.paddingBottom = "".concat(padding, "%"); // For Vimeo we have an extra <div> to hide the standard controls and UI
|
|
||||||
|
|
||||||
if (this.isVimeo && this.supported.ui) {
|
|
||||||
var height = 240;
|
|
||||||
var offset = (height - padding) / (height / 50);
|
|
||||||
this.media.style.transform = "translateY(-".concat(offset, "%)");
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
padding: padding,
|
|
||||||
ratio: ratio
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var Listeners =
|
var Listeners =
|
||||||
/*#__PURE__*/
|
/*#__PURE__*/
|
||||||
function () {
|
function () {
|
||||||
@@ -8537,6 +8580,8 @@ typeof navigator === "object" && (function () {
|
|||||||
}, {
|
}, {
|
||||||
key: "container",
|
key: "container",
|
||||||
value: function container() {
|
value: function container() {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
var config = player.config,
|
var config = player.config,
|
||||||
elements = player.elements,
|
elements = player.elements,
|
||||||
@@ -8548,11 +8593,11 @@ typeof navigator === "object" && (function () {
|
|||||||
|
|
||||||
|
|
||||||
on.call(player, elements.container, 'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen', function (event) {
|
on.call(player, elements.container, 'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen', function (event) {
|
||||||
var controls$$1 = elements.controls; // Remove button states for fullscreen
|
var controls = elements.controls; // Remove button states for fullscreen
|
||||||
|
|
||||||
if (controls$$1 && event.type === 'enterfullscreen') {
|
if (controls && event.type === 'enterfullscreen') {
|
||||||
controls$$1.pressed = false;
|
controls.pressed = false;
|
||||||
controls$$1.hover = false;
|
controls.hover = false;
|
||||||
} // Show, then hide after a timeout unless another control event occurs
|
} // Show, then hide after a timeout unless another control event occurs
|
||||||
|
|
||||||
|
|
||||||
@@ -8588,16 +8633,15 @@ typeof navigator === "object" && (function () {
|
|||||||
|
|
||||||
var target = player.elements.wrapper.firstChild;
|
var target = player.elements.wrapper.firstChild;
|
||||||
|
|
||||||
var _ratio$split$map = ratio.split(':').map(Number),
|
var _ratio = _slicedToArray(ratio, 2),
|
||||||
_ratio$split$map2 = _slicedToArray(_ratio$split$map, 2),
|
y = _ratio[1];
|
||||||
height = _ratio$split$map2[1];
|
|
||||||
|
|
||||||
var _player$embed$ratio$s = player.embed.ratio.split(':').map(Number),
|
var _getAspectRatio$call = getAspectRatio.call(_this),
|
||||||
_player$embed$ratio$s2 = _slicedToArray(_player$embed$ratio$s, 2),
|
_getAspectRatio$call2 = _slicedToArray(_getAspectRatio$call, 2),
|
||||||
videoWidth = _player$embed$ratio$s2[0],
|
videoX = _getAspectRatio$call2[0],
|
||||||
videoHeight = _player$embed$ratio$s2[1];
|
videoY = _getAspectRatio$call2[1];
|
||||||
|
|
||||||
target.style.maxWidth = toggle ? "".concat(height / videoHeight * videoWidth, "px") : null;
|
target.style.maxWidth = toggle ? "".concat(y / videoY * videoX, "px") : null;
|
||||||
target.style.margin = toggle ? '0 auto' : null;
|
target.style.margin = toggle ? '0 auto' : null;
|
||||||
}; // Resize on fullscreen change
|
}; // Resize on fullscreen change
|
||||||
|
|
||||||
@@ -8650,7 +8694,7 @@ typeof navigator === "object" && (function () {
|
|||||||
}, {
|
}, {
|
||||||
key: "media",
|
key: "media",
|
||||||
value: function media() {
|
value: function media() {
|
||||||
var _this = this;
|
var _this2 = this;
|
||||||
|
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
var elements = player.elements; // Time change on media
|
var elements = player.elements; // Time change on media
|
||||||
@@ -8715,11 +8759,11 @@ typeof navigator === "object" && (function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (player.ended) {
|
if (player.ended) {
|
||||||
_this.proxy(event, player.restart, 'restart');
|
_this2.proxy(event, player.restart, 'restart');
|
||||||
|
|
||||||
_this.proxy(event, player.play, 'play');
|
_this2.proxy(event, player.play, 'play');
|
||||||
} else {
|
} else {
|
||||||
_this.proxy(event, player.togglePlay, 'play');
|
_this2.proxy(event, player.togglePlay, 'play');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} // Disable right click
|
} // Disable right click
|
||||||
@@ -8794,21 +8838,21 @@ typeof navigator === "object" && (function () {
|
|||||||
}, {
|
}, {
|
||||||
key: "bind",
|
key: "bind",
|
||||||
value: function bind(element, type, defaultHandler, customHandlerKey) {
|
value: function bind(element, type, defaultHandler, customHandlerKey) {
|
||||||
var _this2 = this;
|
var _this3 = this;
|
||||||
|
|
||||||
var passive = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
|
var passive = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
var customHandler = player.config.listeners[customHandlerKey];
|
var customHandler = player.config.listeners[customHandlerKey];
|
||||||
var hasCustomHandler = is$1.function(customHandler);
|
var hasCustomHandler = is$1.function(customHandler);
|
||||||
on.call(player, element, type, function (event) {
|
on.call(player, element, type, function (event) {
|
||||||
return _this2.proxy(event, defaultHandler, customHandlerKey);
|
return _this3.proxy(event, defaultHandler, customHandlerKey);
|
||||||
}, passive && !hasCustomHandler);
|
}, passive && !hasCustomHandler);
|
||||||
} // Listen for control events
|
} // Listen for control events
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "controls",
|
key: "controls",
|
||||||
value: function controls$$1() {
|
value: function controls$1() {
|
||||||
var _this3 = this;
|
var _this4 = this;
|
||||||
|
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
var elements = player.elements; // IE doesn't support input event, so we fallback to change
|
var elements = player.elements; // IE doesn't support input event, so we fallback to change
|
||||||
@@ -8817,7 +8861,7 @@ typeof navigator === "object" && (function () {
|
|||||||
|
|
||||||
if (elements.buttons.play) {
|
if (elements.buttons.play) {
|
||||||
Array.from(elements.buttons.play).forEach(function (button) {
|
Array.from(elements.buttons.play).forEach(function (button) {
|
||||||
_this3.bind(button, 'click', player.togglePlay, 'play');
|
_this4.bind(button, 'click', player.togglePlay, 'play');
|
||||||
});
|
});
|
||||||
} // Pause
|
} // Pause
|
||||||
|
|
||||||
@@ -8924,7 +8968,7 @@ typeof navigator === "object" && (function () {
|
|||||||
if (browser.isIos) {
|
if (browser.isIos) {
|
||||||
var inputs = getElements.call(player, 'input[type="range"]');
|
var inputs = getElements.call(player, 'input[type="range"]');
|
||||||
Array.from(inputs).forEach(function (input) {
|
Array.from(inputs).forEach(function (input) {
|
||||||
return _this3.bind(input, inputEvent, function (event) {
|
return _this4.bind(input, inputEvent, function (event) {
|
||||||
return repaint(event.target);
|
return repaint(event.target);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -8982,7 +9026,7 @@ typeof navigator === "object" && (function () {
|
|||||||
|
|
||||||
if (browser.isWebkit) {
|
if (browser.isWebkit) {
|
||||||
Array.from(getElements.call(player, 'input[type="range"]')).forEach(function (element) {
|
Array.from(getElements.call(player, 'input[type="range"]')).forEach(function (element) {
|
||||||
_this3.bind(element, 'input', function (event) {
|
_this4.bind(element, 'input', function (event) {
|
||||||
return controls.updateRangeFill.call(player, event.target);
|
return controls.updateRangeFill.call(player, event.target);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -9029,7 +9073,7 @@ typeof navigator === "object" && (function () {
|
|||||||
toggleClass(elements.controls, config.classNames.noTransition, false);
|
toggleClass(elements.controls, config.classNames.noTransition, false);
|
||||||
}, 0); // Delay a little more for mouse users
|
}, 0); // Delay a little more for mouse users
|
||||||
|
|
||||||
var delay = _this3.touch ? 3000 : 4000; // Clear timer
|
var delay = _this4.touch ? 3000 : 4000; // Clear timer
|
||||||
|
|
||||||
clearTimeout(timers.controls); // Hide again after delay
|
clearTimeout(timers.controls); // Hide again after delay
|
||||||
|
|
||||||
@@ -9170,16 +9214,23 @@ typeof navigator === "object" && (function () {
|
|||||||
maxTries = (args.numRetries || 0) + 1,
|
maxTries = (args.numRetries || 0) + 1,
|
||||||
beforeCallbackFn = args.before || devnull,
|
beforeCallbackFn = args.before || devnull,
|
||||||
pathStripped = path.replace(/^(css|img)!/, ''),
|
pathStripped = path.replace(/^(css|img)!/, ''),
|
||||||
isCss,
|
isLegacyIECss,
|
||||||
e;
|
e;
|
||||||
numTries = numTries || 0;
|
numTries = numTries || 0;
|
||||||
|
|
||||||
if (/(^css!|\.css$)/.test(path)) {
|
if (/(^css!|\.css$)/.test(path)) {
|
||||||
isCss = true; // css
|
// css
|
||||||
|
|
||||||
e = doc.createElement('link');
|
e = doc.createElement('link');
|
||||||
e.rel = 'stylesheet';
|
e.rel = 'stylesheet';
|
||||||
e.href = pathStripped; //.replace(/^css!/, ''); // remove "css!" prefix
|
e.href = pathStripped; // tag IE9+
|
||||||
|
|
||||||
|
isLegacyIECss = 'hideFocus' in e; // use preload in IE Edge (to detect load errors)
|
||||||
|
|
||||||
|
if (isLegacyIECss && e.relList) {
|
||||||
|
isLegacyIECss = 0;
|
||||||
|
e.rel = 'preload';
|
||||||
|
e.as = 'style';
|
||||||
|
}
|
||||||
} else if (/(^img!|\.(png|gif|jpg|svg)$)/.test(path)) {
|
} else if (/(^img!|\.(png|gif|jpg|svg)$)/.test(path)) {
|
||||||
// image
|
// image
|
||||||
e = doc.createElement('img');
|
e = doc.createElement('img');
|
||||||
@@ -9192,10 +9243,10 @@ typeof navigator === "object" && (function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
e.onload = e.onerror = e.onbeforeload = function (ev) {
|
e.onload = e.onerror = e.onbeforeload = function (ev) {
|
||||||
var result = ev.type[0]; // Note: The following code isolates IE using `hideFocus` and treats empty
|
var result = ev.type[0]; // treat empty stylesheets as failures to get around lack of onerror
|
||||||
// stylesheets as failures to get around lack of onerror support
|
// support in IE9-11
|
||||||
|
|
||||||
if (isCss && 'hideFocus' in e) {
|
if (isLegacyIECss) {
|
||||||
try {
|
try {
|
||||||
if (!e.sheet.cssText.length) result = 'e';
|
if (!e.sheet.cssText.length) result = 'e';
|
||||||
} catch (x) {
|
} catch (x) {
|
||||||
@@ -9213,6 +9264,9 @@ typeof navigator === "object" && (function () {
|
|||||||
if (numTries < maxTries) {
|
if (numTries < maxTries) {
|
||||||
return loadFile(path, callbackFn, args, numTries);
|
return loadFile(path, callbackFn, args, numTries);
|
||||||
}
|
}
|
||||||
|
} else if (e.rel == 'preload' && e.as == 'style') {
|
||||||
|
// activate preloaded stylesheets
|
||||||
|
return e.rel = 'stylesheet'; // jshint ignore:line
|
||||||
} // execute callback
|
} // execute callback
|
||||||
|
|
||||||
|
|
||||||
@@ -9259,9 +9313,11 @@ typeof navigator === "object" && (function () {
|
|||||||
/**
|
/**
|
||||||
* Initiate script load and register bundle.
|
* Initiate script load and register bundle.
|
||||||
* @param {(string|string[])} paths - The file paths
|
* @param {(string|string[])} paths - The file paths
|
||||||
* @param {(string|Function)} [arg1] - The bundleId or success callback
|
* @param {(string|Function|Object)} [arg1] - The (1) bundleId or (2) success
|
||||||
* @param {Function} [arg2] - The success or error callback
|
* callback or (3) object literal with success/error arguments, numRetries,
|
||||||
* @param {Function} [arg3] - The error callback
|
* etc.
|
||||||
|
* @param {(Function|Object)} [arg2] - The (1) success callback or (2) object
|
||||||
|
* literal with success/error arguments, numRetries, etc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -9278,15 +9334,26 @@ typeof navigator === "object" && (function () {
|
|||||||
} else {
|
} else {
|
||||||
bundleIdCache[bundleId] = true;
|
bundleIdCache[bundleId] = true;
|
||||||
}
|
}
|
||||||
} // load scripts
|
}
|
||||||
|
|
||||||
|
function loadFn(resolve, reject) {
|
||||||
|
loadFiles(paths, function (pathsNotFound) {
|
||||||
|
// execute callbacks
|
||||||
|
executeCallbacks(args, pathsNotFound); // resolve Promise
|
||||||
|
|
||||||
|
if (resolve) {
|
||||||
|
executeCallbacks({
|
||||||
|
success: resolve,
|
||||||
|
error: reject
|
||||||
|
}, pathsNotFound);
|
||||||
|
} // publish bundle load event
|
||||||
|
|
||||||
|
|
||||||
loadFiles(paths, function (pathsNotFound) {
|
publish(bundleId, pathsNotFound);
|
||||||
// execute callbacks
|
}, args);
|
||||||
executeCallbacks(args, pathsNotFound); // publish bundle load event
|
}
|
||||||
|
|
||||||
publish(bundleId, pathsNotFound);
|
if (args.returnPromise) return new Promise(loadFn);else loadFn();
|
||||||
}, args);
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Execute callbacks when dependencies have been satisfied.
|
* Execute callbacks when dependencies have been satisfied.
|
||||||
@@ -9392,7 +9459,7 @@ typeof navigator === "object" && (function () {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// API Ready
|
// API Ready
|
||||||
ready: function ready$$1() {
|
ready: function ready() {
|
||||||
var _this2 = this;
|
var _this2 = this;
|
||||||
|
|
||||||
var player = this;
|
var player = this;
|
||||||
@@ -9586,7 +9653,7 @@ typeof navigator === "object" && (function () {
|
|||||||
height = _dimensions[1];
|
height = _dimensions[1];
|
||||||
|
|
||||||
player.embed.ratio = "".concat(width, ":").concat(height);
|
player.embed.ratio = "".concat(width, ":").concat(height);
|
||||||
setAspectRatio.call(_this2, player.embed.ratio);
|
setAspectRatio.call(_this2);
|
||||||
}); // Set autopause
|
}); // Set autopause
|
||||||
|
|
||||||
player.embed.setAutopause(player.config.autopause).then(function (state) {
|
player.embed.setAutopause(player.config.autopause).then(function (state) {
|
||||||
@@ -9708,6 +9775,19 @@ typeof navigator === "object" && (function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getHost(config) {
|
||||||
|
if (config.noCookie) {
|
||||||
|
return 'https://www.youtube-nocookie.com';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.location.protocol === 'http:') {
|
||||||
|
return 'http://www.youtube.com';
|
||||||
|
} // Use YouTube's default
|
||||||
|
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
var youtube = {
|
var youtube = {
|
||||||
setup: function setup() {
|
setup: function setup() {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
@@ -9771,7 +9851,7 @@ typeof navigator === "object" && (function () {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// API ready
|
// API ready
|
||||||
ready: function ready$$1() {
|
ready: function ready() {
|
||||||
var player = this; // Ignore already setup (race condition)
|
var player = this; // Ignore already setup (race condition)
|
||||||
|
|
||||||
var currentId = player.media.getAttribute('id');
|
var currentId = player.media.getAttribute('id');
|
||||||
@@ -9799,8 +9879,8 @@ typeof navigator === "object" && (function () {
|
|||||||
});
|
});
|
||||||
player.media = replaceElement(container, player.media); // Id to poster wrapper
|
player.media = replaceElement(container, player.media); // Id to poster wrapper
|
||||||
|
|
||||||
var posterSrc = function posterSrc(format$$1) {
|
var posterSrc = function posterSrc(format) {
|
||||||
return "https://img.youtube.com/vi/".concat(videoId, "/").concat(format$$1, "default.jpg");
|
return "https://i.ytimg.com/vi/".concat(videoId, "/").concat(format, "default.jpg");
|
||||||
}; // Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide)
|
}; // Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide)
|
||||||
|
|
||||||
|
|
||||||
@@ -9824,7 +9904,7 @@ typeof navigator === "object" && (function () {
|
|||||||
|
|
||||||
player.embed = new window.YT.Player(id, {
|
player.embed = new window.YT.Player(id, {
|
||||||
videoId: videoId,
|
videoId: videoId,
|
||||||
host: config.noCookie ? 'https://www.youtube-nocookie.com' : undefined,
|
host: getHost(config),
|
||||||
playerVars: extend({}, {
|
playerVars: extend({}, {
|
||||||
autoplay: player.config.autoplay ? 1 : 0,
|
autoplay: player.config.autoplay ? 1 : 0,
|
||||||
// Autoplay
|
// Autoplay
|
||||||
@@ -10039,7 +10119,7 @@ typeof navigator === "object" && (function () {
|
|||||||
|
|
||||||
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 && !player.embed.hasPlayed) {
|
if (!player.config.autoplay && player.media.paused && !player.embed.hasPlayed) {
|
||||||
player.media.pause();
|
player.media.pause();
|
||||||
} else {
|
} else {
|
||||||
assurePlaybackState$1.call(player, true);
|
assurePlaybackState$1.call(player, true);
|
||||||
@@ -10193,7 +10273,7 @@ typeof navigator === "object" && (function () {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "ready",
|
key: "ready",
|
||||||
value: function ready$$1() {
|
value: function ready() {
|
||||||
var _this3 = this;
|
var _this3 = this;
|
||||||
|
|
||||||
// Start ticking our safety timer. If the whole advertisement
|
// Start ticking our safety timer. If the whole advertisement
|
||||||
@@ -10677,7 +10757,7 @@ typeof navigator === "object" && (function () {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "on",
|
key: "on",
|
||||||
value: function on$$1(event, callback) {
|
value: function on(event, callback) {
|
||||||
if (!is$1.array(this.events[event])) {
|
if (!is$1.array(this.events[event])) {
|
||||||
this.events[event] = [];
|
this.events[event] = [];
|
||||||
}
|
}
|
||||||
@@ -10761,11 +10841,11 @@ typeof navigator === "object" && (function () {
|
|||||||
lines.forEach(function (line) {
|
lines.forEach(function (line) {
|
||||||
if (!is$1.number(result.startTime)) {
|
if (!is$1.number(result.startTime)) {
|
||||||
// The line with start and end times on it is the first line of interest
|
// The line with start and end times on it is the first line of interest
|
||||||
var matchTimes = line.match(/([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{2,3})( ?--> ?)([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{2,3})/); // Note that this currently ignores caption formatting directives that are optionally on the end of this line - fine for non-captions VTT
|
var matchTimes = line.match(/([0-9]{2})?:?([0-9]{2}):([0-9]{2}).([0-9]{2,3})( ?--> ?)([0-9]{2})?:?([0-9]{2}):([0-9]{2}).([0-9]{2,3})/); // Note that this currently ignores caption formatting directives that are optionally on the end of this line - fine for non-captions VTT
|
||||||
|
|
||||||
if (matchTimes) {
|
if (matchTimes) {
|
||||||
result.startTime = Number(matchTimes[1]) * 60 * 60 + Number(matchTimes[2]) * 60 + Number(matchTimes[3]) + Number("0.".concat(matchTimes[4]));
|
result.startTime = Number(matchTimes[1] || 0) * 60 * 60 + Number(matchTimes[2]) * 60 + Number(matchTimes[3]) + Number("0.".concat(matchTimes[4]));
|
||||||
result.endTime = Number(matchTimes[6]) * 60 * 60 + Number(matchTimes[7]) * 60 + Number(matchTimes[8]) + Number("0.".concat(matchTimes[9]));
|
result.endTime = Number(matchTimes[6] || 0) * 60 * 60 + Number(matchTimes[7]) * 60 + Number(matchTimes[8]) + Number("0.".concat(matchTimes[9]));
|
||||||
}
|
}
|
||||||
} else if (!is$1.empty(line.trim()) && is$1.empty(result.text)) {
|
} else if (!is$1.empty(line.trim()) && is$1.empty(result.text)) {
|
||||||
// If we already have the startTime, then we're definitely up to the text line(s)
|
// If we already have the startTime, then we're definitely up to the text line(s)
|
||||||
@@ -10900,8 +10980,9 @@ typeof navigator === "object" && (function () {
|
|||||||
urlPrefix: ''
|
urlPrefix: ''
|
||||||
}; // If the URLs don't start with '/', then we need to set their relative path to be the location of the VTT file
|
}; // If the URLs don't start with '/', then we need to set their relative path to be the location of the VTT file
|
||||||
// If the URLs do start with '/', then they obviously don't need a prefix, so it will remain blank
|
// If the URLs do start with '/', then they obviously don't need a prefix, so it will remain blank
|
||||||
|
// If the thumbnail URLs start with with none of '/', 'http://' or 'https://', then we need to set their relative path to be the location of the VTT file
|
||||||
|
|
||||||
if (!thumbnail.frames[0].text.startsWith('/')) {
|
if (!thumbnail.frames[0].text.startsWith('/') && !thumbnail.frames[0].text.startsWith('http://') && !thumbnail.frames[0].text.startsWith('https://')) {
|
||||||
thumbnail.urlPrefix = url.substring(0, url.lastIndexOf('/') + 1);
|
thumbnail.urlPrefix = url.substring(0, url.lastIndexOf('/') + 1);
|
||||||
} // Download the first frame, so that we can determine/set the height of this thumbnailsDef
|
} // Download the first frame, so that we can determine/set the height of this thumbnailsDef
|
||||||
|
|
||||||
@@ -11805,8 +11886,10 @@ typeof navigator === "object" && (function () {
|
|||||||
} // Autoplay if required
|
} // Autoplay if required
|
||||||
|
|
||||||
|
|
||||||
if (this.config.autoplay) {
|
if (this.isHTML5 && this.config.autoplay) {
|
||||||
this.play();
|
setTimeout(function () {
|
||||||
|
return _this.play();
|
||||||
|
}, 10);
|
||||||
} // Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek
|
} // Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek
|
||||||
|
|
||||||
|
|
||||||
@@ -12025,7 +12108,7 @@ typeof navigator === "object" && (function () {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "on",
|
key: "on",
|
||||||
value: function on$$1(event, callback) {
|
value: function on$1(event, callback) {
|
||||||
on.call(this, this.elements.container, event, callback);
|
on.call(this, this.elements.container, event, callback);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -12036,7 +12119,7 @@ typeof navigator === "object" && (function () {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "once",
|
key: "once",
|
||||||
value: function once$$1(event, callback) {
|
value: function once$1(event, callback) {
|
||||||
once.call(this, this.elements.container, event, callback);
|
once.call(this, this.elements.container, event, callback);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -12047,7 +12130,7 @@ typeof navigator === "object" && (function () {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "off",
|
key: "off",
|
||||||
value: function off$$1(event, callback) {
|
value: function off$1(event, callback) {
|
||||||
off(this.elements.container, event, callback);
|
off(this.elements.container, event, callback);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -12116,12 +12199,14 @@ typeof navigator === "object" && (function () {
|
|||||||
}; // Stop playback
|
}; // Stop playback
|
||||||
|
|
||||||
|
|
||||||
this.stop(); // Provider specific stuff
|
this.stop(); // Clear timeouts
|
||||||
|
|
||||||
|
clearTimeout(this.timers.loading);
|
||||||
|
clearTimeout(this.timers.controls);
|
||||||
|
clearTimeout(this.timers.resized); // Provider specific stuff
|
||||||
|
|
||||||
if (this.isHTML5) {
|
if (this.isHTML5) {
|
||||||
// Clear timeout
|
// Restore native video controls
|
||||||
clearTimeout(this.timers.loading); // Restore native video controls
|
|
||||||
|
|
||||||
ui.toggleNativeControls.call(this, true); // Clean up
|
ui.toggleNativeControls.call(this, true); // Clean up
|
||||||
|
|
||||||
done();
|
done();
|
||||||
@@ -12594,6 +12679,34 @@ typeof navigator === "object" && (function () {
|
|||||||
|
|
||||||
return this.media.getAttribute('poster');
|
return this.media.getAttribute('poster');
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Get the current aspect ratio in use
|
||||||
|
*/
|
||||||
|
|
||||||
|
}, {
|
||||||
|
key: "ratio",
|
||||||
|
get: function get() {
|
||||||
|
var ratio = reduceAspectRatio(getAspectRatio.call(this));
|
||||||
|
return is$1.array(ratio) ? ratio.join(':') : ratio;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Set video aspect ratio
|
||||||
|
*/
|
||||||
|
,
|
||||||
|
set: function set(input) {
|
||||||
|
if (!this.isVideo) {
|
||||||
|
this.debug.warn('Aspect ratio can only be set for video');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is$1.string(input) || !validateRatio(input)) {
|
||||||
|
this.debug.error("Invalid aspect ratio specified (".concat(input, ")"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.config.ratio = input;
|
||||||
|
setAspectRatio.call(this);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Set the autoplay state
|
* Set the autoplay state
|
||||||
* @param {Boolean} input - Whether to autoplay or not
|
* @param {Boolean} input - Whether to autoplay or not
|
||||||
@@ -12706,7 +12819,7 @@ typeof navigator === "object" && (function () {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "loadSprite",
|
key: "loadSprite",
|
||||||
value: function loadSprite$$1(url, id) {
|
value: function loadSprite$1(url, id) {
|
||||||
return loadSprite(url, id);
|
return loadSprite(url, id);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+228
-115
@@ -1,8 +1,8 @@
|
|||||||
typeof navigator === "object" && (function (global, factory) {
|
typeof navigator === "object" && (function (global, factory) {
|
||||||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
||||||
typeof define === 'function' && define.amd ? define('Plyr', factory) :
|
typeof define === 'function' && define.amd ? define('Plyr', factory) :
|
||||||
(global.Plyr = factory());
|
(global = global || self, global.Plyr = factory());
|
||||||
}(this, (function () { 'use strict';
|
}(this, function () { 'use strict';
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) {
|
function _classCallCheck(instance, Constructor) {
|
||||||
if (!(instance instanceof Constructor)) {
|
if (!(instance instanceof Constructor)) {
|
||||||
@@ -1101,6 +1101,83 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
reducedMotion: 'matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches
|
reducedMotion: 'matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function validateRatio(input) {
|
||||||
|
if (!is$1.array(input) && (!is$1.string(input) || !input.includes(':'))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ratio = is$1.array(input) ? input : input.split(':');
|
||||||
|
return ratio.map(Number).every(is$1.number);
|
||||||
|
}
|
||||||
|
function reduceAspectRatio(ratio) {
|
||||||
|
if (!is$1.array(ratio) || !ratio.every(is$1.number)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ratio = _slicedToArray(ratio, 2),
|
||||||
|
width = _ratio[0],
|
||||||
|
height = _ratio[1];
|
||||||
|
|
||||||
|
var getDivider = function getDivider(w, h) {
|
||||||
|
return h === 0 ? w : getDivider(h, w % h);
|
||||||
|
};
|
||||||
|
|
||||||
|
var divider = getDivider(width, height);
|
||||||
|
return [width / divider, height / divider];
|
||||||
|
}
|
||||||
|
function getAspectRatio(input) {
|
||||||
|
var parse = function parse(ratio) {
|
||||||
|
if (!validateRatio(ratio)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ratio.split(':').map(Number);
|
||||||
|
}; // Provided ratio
|
||||||
|
|
||||||
|
|
||||||
|
var ratio = parse(input); // Get from config
|
||||||
|
|
||||||
|
if (ratio === null) {
|
||||||
|
ratio = parse(this.config.ratio);
|
||||||
|
} // Get from embed
|
||||||
|
|
||||||
|
|
||||||
|
if (ratio === null && !is$1.empty(this.embed) && is$1.string(this.embed.ratio)) {
|
||||||
|
ratio = parse(this.embed.ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ratio;
|
||||||
|
} // Set aspect ratio for responsive container
|
||||||
|
|
||||||
|
function setAspectRatio(input) {
|
||||||
|
if (!this.isVideo) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
var ratio = getAspectRatio.call(this, input);
|
||||||
|
|
||||||
|
var _ref = is$1.array(ratio) ? ratio : [0, 0],
|
||||||
|
_ref2 = _slicedToArray(_ref, 2),
|
||||||
|
w = _ref2[0],
|
||||||
|
h = _ref2[1];
|
||||||
|
|
||||||
|
var padding = 100 / w * h;
|
||||||
|
this.elements.wrapper.style.paddingBottom = "".concat(padding, "%"); // For Vimeo we have an extra <div> to hide the standard controls and UI
|
||||||
|
|
||||||
|
if (this.isVimeo && this.supported.ui) {
|
||||||
|
var height = 240;
|
||||||
|
var offset = (height - padding) / (height / 50);
|
||||||
|
this.media.style.transform = "translateY(-".concat(offset, "%)");
|
||||||
|
} else if (this.isHTML5) {
|
||||||
|
this.elements.wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
padding: padding,
|
||||||
|
ratio: ratio
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
var html5 = {
|
var html5 = {
|
||||||
getSources: function getSources() {
|
getSources: function getSources() {
|
||||||
@@ -1134,7 +1211,9 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var player = this; // Quality
|
var player = this; // Set aspect ratio if set
|
||||||
|
|
||||||
|
setAspectRatio.call(player); // Quality
|
||||||
|
|
||||||
Object.defineProperty(player.media, 'quality', {
|
Object.defineProperty(player.media, 'quality', {
|
||||||
get: function get() {
|
get: function get() {
|
||||||
@@ -2033,7 +2112,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
list.appendChild(menuItem);
|
list.appendChild(menuItem);
|
||||||
},
|
},
|
||||||
// Format a time for display
|
// Format a time for display
|
||||||
formatTime: function formatTime$$1() {
|
formatTime: function formatTime$1() {
|
||||||
var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
||||||
var inverted = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
var inverted = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
||||||
|
|
||||||
@@ -2153,8 +2232,8 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
range.setAttribute('aria-valuenow', this.currentTime);
|
range.setAttribute('aria-valuenow', this.currentTime);
|
||||||
var currentTime = controls.formatTime(this.currentTime);
|
var currentTime = controls.formatTime(this.currentTime);
|
||||||
var duration = controls.formatTime(this.duration);
|
var duration = controls.formatTime(this.duration);
|
||||||
var format$$1 = i18n.get('seekLabel', this.config);
|
var format = i18n.get('seekLabel', this.config);
|
||||||
range.setAttribute('aria-valuetext', format$$1.replace('{currentTime}', currentTime).replace('{duration}', duration));
|
range.setAttribute('aria-valuetext', format.replace('{currentTime}', currentTime).replace('{duration}', duration));
|
||||||
} else if (matches$1(range, this.config.selectors.inputs.volume)) {
|
} else if (matches$1(range, this.config.selectors.inputs.volume)) {
|
||||||
var percent = range.value * 100;
|
var percent = range.value * 100;
|
||||||
range.setAttribute('aria-valuenow', percent);
|
range.setAttribute('aria-valuenow', percent);
|
||||||
@@ -3508,8 +3587,9 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
invertTime: true,
|
invertTime: true,
|
||||||
// Clicking the currentTime inverts it's value to show time left rather than elapsed
|
// Clicking the currentTime inverts it's value to show time left rather than elapsed
|
||||||
toggleInvert: true,
|
toggleInvert: true,
|
||||||
// Aspect ratio (for embeds)
|
// Force an aspect ratio
|
||||||
ratio: '16:9',
|
// The format must be `'w:h'` (e.g. `'16:9'`)
|
||||||
|
ratio: null,
|
||||||
// Click video container to play/pause
|
// Click video container to play/pause
|
||||||
clickToPlay: true,
|
clickToPlay: true,
|
||||||
// Auto hide the controls
|
// Auto hide the controls
|
||||||
@@ -3521,7 +3601,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
// Sprite (for icons)
|
// Sprite (for icons)
|
||||||
loadSprite: true,
|
loadSprite: true,
|
||||||
iconPrefix: 'plyr',
|
iconPrefix: 'plyr',
|
||||||
iconUrl: 'https://cdn.plyr.io/3.5.2/plyr.svg',
|
iconUrl: 'https://cdn.plyr.io/3.5.3/plyr.svg',
|
||||||
// Blank video (used to prevent errors on source change)
|
// Blank video (used to prevent errors on source change)
|
||||||
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
||||||
// Quality default
|
// Quality default
|
||||||
@@ -3721,6 +3801,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
provider: 'plyr--{0}',
|
provider: 'plyr--{0}',
|
||||||
video: 'plyr__video-wrapper',
|
video: 'plyr__video-wrapper',
|
||||||
embed: 'plyr__video-embed',
|
embed: 'plyr__video-embed',
|
||||||
|
videoFixedRatio: 'plyr__video-wrapper--fixed-ratio',
|
||||||
embedContainer: 'plyr__video-embed__container',
|
embedContainer: 'plyr__video-embed__container',
|
||||||
poster: 'plyr__poster',
|
poster: 'plyr__poster',
|
||||||
posterEnabled: 'plyr__poster-enabled',
|
posterEnabled: 'plyr__poster-enabled',
|
||||||
@@ -4386,55 +4467,17 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
},
|
},
|
||||||
// Toggle controls based on state and `force` argument
|
// Toggle controls based on state and `force` argument
|
||||||
toggleControls: function toggleControls(force) {
|
toggleControls: function toggleControls(force) {
|
||||||
var controls$$1 = this.elements.controls;
|
var controls = this.elements.controls;
|
||||||
|
|
||||||
if (controls$$1 && this.config.hideControls) {
|
if (controls && this.config.hideControls) {
|
||||||
// Don't hide controls if a touch-device user recently seeked. (Must be limited to touch devices, or it occasionally prevents desktop controls from hiding.)
|
// Don't hide controls if a touch-device user recently seeked. (Must be limited to touch devices, or it occasionally prevents desktop controls from hiding.)
|
||||||
var recentTouchSeek = this.touch && this.lastSeekTime + 2000 > Date.now(); // Show controls if force, loading, paused, button interaction, or recent seek, otherwise hide
|
var recentTouchSeek = this.touch && this.lastSeekTime + 2000 > Date.now(); // Show controls if force, loading, paused, button interaction, or recent seek, otherwise hide
|
||||||
|
|
||||||
this.toggleControls(Boolean(force || this.loading || this.paused || controls$$1.pressed || controls$$1.hover || recentTouchSeek));
|
this.toggleControls(Boolean(force || this.loading || this.paused || controls.pressed || controls.hover || recentTouchSeek));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* function reduceAspectRatio(width, height) {
|
|
||||||
const getRatio = (w, h) => (h === 0 ? w : getRatio(h, w % h));
|
|
||||||
const ratio = getRatio(width, height);
|
|
||||||
return `${width / ratio}:${height / ratio}`;
|
|
||||||
} */
|
|
||||||
// Set aspect ratio for responsive container
|
|
||||||
|
|
||||||
function setAspectRatio(input) {
|
|
||||||
var ratio = input;
|
|
||||||
|
|
||||||
if (!is$1.string(ratio) && !is$1.nullOrUndefined(this.embed)) {
|
|
||||||
ratio = this.embed.ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is$1.string(ratio)) {
|
|
||||||
ratio = this.config.ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ratio$split$map = ratio.split(':').map(Number),
|
|
||||||
_ratio$split$map2 = _slicedToArray(_ratio$split$map, 2),
|
|
||||||
x = _ratio$split$map2[0],
|
|
||||||
y = _ratio$split$map2[1];
|
|
||||||
|
|
||||||
var padding = 100 / x * y;
|
|
||||||
this.elements.wrapper.style.paddingBottom = "".concat(padding, "%"); // For Vimeo we have an extra <div> to hide the standard controls and UI
|
|
||||||
|
|
||||||
if (this.isVimeo && this.supported.ui) {
|
|
||||||
var height = 240;
|
|
||||||
var offset = (height - padding) / (height / 50);
|
|
||||||
this.media.style.transform = "translateY(-".concat(offset, "%)");
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
padding: padding,
|
|
||||||
ratio: ratio
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var Listeners =
|
var Listeners =
|
||||||
/*#__PURE__*/
|
/*#__PURE__*/
|
||||||
function () {
|
function () {
|
||||||
@@ -4687,6 +4730,8 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}, {
|
}, {
|
||||||
key: "container",
|
key: "container",
|
||||||
value: function container() {
|
value: function container() {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
var config = player.config,
|
var config = player.config,
|
||||||
elements = player.elements,
|
elements = player.elements,
|
||||||
@@ -4698,11 +4743,11 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
|
|
||||||
on.call(player, elements.container, 'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen', function (event) {
|
on.call(player, elements.container, 'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen', function (event) {
|
||||||
var controls$$1 = elements.controls; // Remove button states for fullscreen
|
var controls = elements.controls; // Remove button states for fullscreen
|
||||||
|
|
||||||
if (controls$$1 && event.type === 'enterfullscreen') {
|
if (controls && event.type === 'enterfullscreen') {
|
||||||
controls$$1.pressed = false;
|
controls.pressed = false;
|
||||||
controls$$1.hover = false;
|
controls.hover = false;
|
||||||
} // Show, then hide after a timeout unless another control event occurs
|
} // Show, then hide after a timeout unless another control event occurs
|
||||||
|
|
||||||
|
|
||||||
@@ -4738,16 +4783,15 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
var target = player.elements.wrapper.firstChild;
|
var target = player.elements.wrapper.firstChild;
|
||||||
|
|
||||||
var _ratio$split$map = ratio.split(':').map(Number),
|
var _ratio = _slicedToArray(ratio, 2),
|
||||||
_ratio$split$map2 = _slicedToArray(_ratio$split$map, 2),
|
y = _ratio[1];
|
||||||
height = _ratio$split$map2[1];
|
|
||||||
|
|
||||||
var _player$embed$ratio$s = player.embed.ratio.split(':').map(Number),
|
var _getAspectRatio$call = getAspectRatio.call(_this),
|
||||||
_player$embed$ratio$s2 = _slicedToArray(_player$embed$ratio$s, 2),
|
_getAspectRatio$call2 = _slicedToArray(_getAspectRatio$call, 2),
|
||||||
videoWidth = _player$embed$ratio$s2[0],
|
videoX = _getAspectRatio$call2[0],
|
||||||
videoHeight = _player$embed$ratio$s2[1];
|
videoY = _getAspectRatio$call2[1];
|
||||||
|
|
||||||
target.style.maxWidth = toggle ? "".concat(height / videoHeight * videoWidth, "px") : null;
|
target.style.maxWidth = toggle ? "".concat(y / videoY * videoX, "px") : null;
|
||||||
target.style.margin = toggle ? '0 auto' : null;
|
target.style.margin = toggle ? '0 auto' : null;
|
||||||
}; // Resize on fullscreen change
|
}; // Resize on fullscreen change
|
||||||
|
|
||||||
@@ -4800,7 +4844,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}, {
|
}, {
|
||||||
key: "media",
|
key: "media",
|
||||||
value: function media() {
|
value: function media() {
|
||||||
var _this = this;
|
var _this2 = this;
|
||||||
|
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
var elements = player.elements; // Time change on media
|
var elements = player.elements; // Time change on media
|
||||||
@@ -4865,11 +4909,11 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (player.ended) {
|
if (player.ended) {
|
||||||
_this.proxy(event, player.restart, 'restart');
|
_this2.proxy(event, player.restart, 'restart');
|
||||||
|
|
||||||
_this.proxy(event, player.play, 'play');
|
_this2.proxy(event, player.play, 'play');
|
||||||
} else {
|
} else {
|
||||||
_this.proxy(event, player.togglePlay, 'play');
|
_this2.proxy(event, player.togglePlay, 'play');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} // Disable right click
|
} // Disable right click
|
||||||
@@ -4944,21 +4988,21 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}, {
|
}, {
|
||||||
key: "bind",
|
key: "bind",
|
||||||
value: function bind(element, type, defaultHandler, customHandlerKey) {
|
value: function bind(element, type, defaultHandler, customHandlerKey) {
|
||||||
var _this2 = this;
|
var _this3 = this;
|
||||||
|
|
||||||
var passive = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
|
var passive = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
var customHandler = player.config.listeners[customHandlerKey];
|
var customHandler = player.config.listeners[customHandlerKey];
|
||||||
var hasCustomHandler = is$1.function(customHandler);
|
var hasCustomHandler = is$1.function(customHandler);
|
||||||
on.call(player, element, type, function (event) {
|
on.call(player, element, type, function (event) {
|
||||||
return _this2.proxy(event, defaultHandler, customHandlerKey);
|
return _this3.proxy(event, defaultHandler, customHandlerKey);
|
||||||
}, passive && !hasCustomHandler);
|
}, passive && !hasCustomHandler);
|
||||||
} // Listen for control events
|
} // Listen for control events
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "controls",
|
key: "controls",
|
||||||
value: function controls$$1() {
|
value: function controls$1() {
|
||||||
var _this3 = this;
|
var _this4 = this;
|
||||||
|
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
var elements = player.elements; // IE doesn't support input event, so we fallback to change
|
var elements = player.elements; // IE doesn't support input event, so we fallback to change
|
||||||
@@ -4967,7 +5011,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
if (elements.buttons.play) {
|
if (elements.buttons.play) {
|
||||||
Array.from(elements.buttons.play).forEach(function (button) {
|
Array.from(elements.buttons.play).forEach(function (button) {
|
||||||
_this3.bind(button, 'click', player.togglePlay, 'play');
|
_this4.bind(button, 'click', player.togglePlay, 'play');
|
||||||
});
|
});
|
||||||
} // Pause
|
} // Pause
|
||||||
|
|
||||||
@@ -5074,7 +5118,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
if (browser.isIos) {
|
if (browser.isIos) {
|
||||||
var inputs = getElements.call(player, 'input[type="range"]');
|
var inputs = getElements.call(player, 'input[type="range"]');
|
||||||
Array.from(inputs).forEach(function (input) {
|
Array.from(inputs).forEach(function (input) {
|
||||||
return _this3.bind(input, inputEvent, function (event) {
|
return _this4.bind(input, inputEvent, function (event) {
|
||||||
return repaint(event.target);
|
return repaint(event.target);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -5132,7 +5176,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
if (browser.isWebkit) {
|
if (browser.isWebkit) {
|
||||||
Array.from(getElements.call(player, 'input[type="range"]')).forEach(function (element) {
|
Array.from(getElements.call(player, 'input[type="range"]')).forEach(function (element) {
|
||||||
_this3.bind(element, 'input', function (event) {
|
_this4.bind(element, 'input', function (event) {
|
||||||
return controls.updateRangeFill.call(player, event.target);
|
return controls.updateRangeFill.call(player, event.target);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -5179,7 +5223,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
toggleClass(elements.controls, config.classNames.noTransition, false);
|
toggleClass(elements.controls, config.classNames.noTransition, false);
|
||||||
}, 0); // Delay a little more for mouse users
|
}, 0); // Delay a little more for mouse users
|
||||||
|
|
||||||
var delay = _this3.touch ? 3000 : 4000; // Clear timer
|
var delay = _this4.touch ? 3000 : 4000; // Clear timer
|
||||||
|
|
||||||
clearTimeout(timers.controls); // Hide again after delay
|
clearTimeout(timers.controls); // Hide again after delay
|
||||||
|
|
||||||
@@ -5217,7 +5261,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
return Listeners;
|
return Listeners;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
||||||
|
|
||||||
function createCommonjsModule(fn, module) {
|
function createCommonjsModule(fn, module) {
|
||||||
return module = { exports: {} }, fn(module, module.exports), module.exports;
|
return module = { exports: {} }, fn(module, module.exports), module.exports;
|
||||||
@@ -5326,16 +5370,23 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
maxTries = (args.numRetries || 0) + 1,
|
maxTries = (args.numRetries || 0) + 1,
|
||||||
beforeCallbackFn = args.before || devnull,
|
beforeCallbackFn = args.before || devnull,
|
||||||
pathStripped = path.replace(/^(css|img)!/, ''),
|
pathStripped = path.replace(/^(css|img)!/, ''),
|
||||||
isCss,
|
isLegacyIECss,
|
||||||
e;
|
e;
|
||||||
numTries = numTries || 0;
|
numTries = numTries || 0;
|
||||||
|
|
||||||
if (/(^css!|\.css$)/.test(path)) {
|
if (/(^css!|\.css$)/.test(path)) {
|
||||||
isCss = true; // css
|
// css
|
||||||
|
|
||||||
e = doc.createElement('link');
|
e = doc.createElement('link');
|
||||||
e.rel = 'stylesheet';
|
e.rel = 'stylesheet';
|
||||||
e.href = pathStripped; //.replace(/^css!/, ''); // remove "css!" prefix
|
e.href = pathStripped; // tag IE9+
|
||||||
|
|
||||||
|
isLegacyIECss = 'hideFocus' in e; // use preload in IE Edge (to detect load errors)
|
||||||
|
|
||||||
|
if (isLegacyIECss && e.relList) {
|
||||||
|
isLegacyIECss = 0;
|
||||||
|
e.rel = 'preload';
|
||||||
|
e.as = 'style';
|
||||||
|
}
|
||||||
} else if (/(^img!|\.(png|gif|jpg|svg)$)/.test(path)) {
|
} else if (/(^img!|\.(png|gif|jpg|svg)$)/.test(path)) {
|
||||||
// image
|
// image
|
||||||
e = doc.createElement('img');
|
e = doc.createElement('img');
|
||||||
@@ -5348,10 +5399,10 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
e.onload = e.onerror = e.onbeforeload = function (ev) {
|
e.onload = e.onerror = e.onbeforeload = function (ev) {
|
||||||
var result = ev.type[0]; // Note: The following code isolates IE using `hideFocus` and treats empty
|
var result = ev.type[0]; // treat empty stylesheets as failures to get around lack of onerror
|
||||||
// stylesheets as failures to get around lack of onerror support
|
// support in IE9-11
|
||||||
|
|
||||||
if (isCss && 'hideFocus' in e) {
|
if (isLegacyIECss) {
|
||||||
try {
|
try {
|
||||||
if (!e.sheet.cssText.length) result = 'e';
|
if (!e.sheet.cssText.length) result = 'e';
|
||||||
} catch (x) {
|
} catch (x) {
|
||||||
@@ -5369,6 +5420,9 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
if (numTries < maxTries) {
|
if (numTries < maxTries) {
|
||||||
return loadFile(path, callbackFn, args, numTries);
|
return loadFile(path, callbackFn, args, numTries);
|
||||||
}
|
}
|
||||||
|
} else if (e.rel == 'preload' && e.as == 'style') {
|
||||||
|
// activate preloaded stylesheets
|
||||||
|
return e.rel = 'stylesheet'; // jshint ignore:line
|
||||||
} // execute callback
|
} // execute callback
|
||||||
|
|
||||||
|
|
||||||
@@ -5415,9 +5469,11 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
/**
|
/**
|
||||||
* Initiate script load and register bundle.
|
* Initiate script load and register bundle.
|
||||||
* @param {(string|string[])} paths - The file paths
|
* @param {(string|string[])} paths - The file paths
|
||||||
* @param {(string|Function)} [arg1] - The bundleId or success callback
|
* @param {(string|Function|Object)} [arg1] - The (1) bundleId or (2) success
|
||||||
* @param {Function} [arg2] - The success or error callback
|
* callback or (3) object literal with success/error arguments, numRetries,
|
||||||
* @param {Function} [arg3] - The error callback
|
* etc.
|
||||||
|
* @param {(Function|Object)} [arg2] - The (1) success callback or (2) object
|
||||||
|
* literal with success/error arguments, numRetries, etc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -5434,15 +5490,26 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
} else {
|
} else {
|
||||||
bundleIdCache[bundleId] = true;
|
bundleIdCache[bundleId] = true;
|
||||||
}
|
}
|
||||||
} // load scripts
|
}
|
||||||
|
|
||||||
|
function loadFn(resolve, reject) {
|
||||||
|
loadFiles(paths, function (pathsNotFound) {
|
||||||
|
// execute callbacks
|
||||||
|
executeCallbacks(args, pathsNotFound); // resolve Promise
|
||||||
|
|
||||||
|
if (resolve) {
|
||||||
|
executeCallbacks({
|
||||||
|
success: resolve,
|
||||||
|
error: reject
|
||||||
|
}, pathsNotFound);
|
||||||
|
} // publish bundle load event
|
||||||
|
|
||||||
|
|
||||||
loadFiles(paths, function (pathsNotFound) {
|
publish(bundleId, pathsNotFound);
|
||||||
// execute callbacks
|
}, args);
|
||||||
executeCallbacks(args, pathsNotFound); // publish bundle load event
|
}
|
||||||
|
|
||||||
publish(bundleId, pathsNotFound);
|
if (args.returnPromise) return new Promise(loadFn);else loadFn();
|
||||||
}, args);
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Execute callbacks when dependencies have been satisfied.
|
* Execute callbacks when dependencies have been satisfied.
|
||||||
@@ -5548,7 +5615,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// API Ready
|
// API Ready
|
||||||
ready: function ready$$1() {
|
ready: function ready() {
|
||||||
var _this2 = this;
|
var _this2 = this;
|
||||||
|
|
||||||
var player = this;
|
var player = this;
|
||||||
@@ -5742,7 +5809,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
height = _dimensions[1];
|
height = _dimensions[1];
|
||||||
|
|
||||||
player.embed.ratio = "".concat(width, ":").concat(height);
|
player.embed.ratio = "".concat(width, ":").concat(height);
|
||||||
setAspectRatio.call(_this2, player.embed.ratio);
|
setAspectRatio.call(_this2);
|
||||||
}); // Set autopause
|
}); // Set autopause
|
||||||
|
|
||||||
player.embed.setAutopause(player.config.autopause).then(function (state) {
|
player.embed.setAutopause(player.config.autopause).then(function (state) {
|
||||||
@@ -5864,6 +5931,19 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getHost(config) {
|
||||||
|
if (config.noCookie) {
|
||||||
|
return 'https://www.youtube-nocookie.com';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.location.protocol === 'http:') {
|
||||||
|
return 'http://www.youtube.com';
|
||||||
|
} // Use YouTube's default
|
||||||
|
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
var youtube = {
|
var youtube = {
|
||||||
setup: function setup() {
|
setup: function setup() {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
@@ -5927,7 +6007,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// API ready
|
// API ready
|
||||||
ready: function ready$$1() {
|
ready: function ready() {
|
||||||
var player = this; // Ignore already setup (race condition)
|
var player = this; // Ignore already setup (race condition)
|
||||||
|
|
||||||
var currentId = player.media.getAttribute('id');
|
var currentId = player.media.getAttribute('id');
|
||||||
@@ -5955,8 +6035,8 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
});
|
});
|
||||||
player.media = replaceElement(container, player.media); // Id to poster wrapper
|
player.media = replaceElement(container, player.media); // Id to poster wrapper
|
||||||
|
|
||||||
var posterSrc = function posterSrc(format$$1) {
|
var posterSrc = function posterSrc(format) {
|
||||||
return "https://img.youtube.com/vi/".concat(videoId, "/").concat(format$$1, "default.jpg");
|
return "https://i.ytimg.com/vi/".concat(videoId, "/").concat(format, "default.jpg");
|
||||||
}; // Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide)
|
}; // Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide)
|
||||||
|
|
||||||
|
|
||||||
@@ -5980,7 +6060,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
player.embed = new window.YT.Player(id, {
|
player.embed = new window.YT.Player(id, {
|
||||||
videoId: videoId,
|
videoId: videoId,
|
||||||
host: config.noCookie ? 'https://www.youtube-nocookie.com' : undefined,
|
host: getHost(config),
|
||||||
playerVars: extend({}, {
|
playerVars: extend({}, {
|
||||||
autoplay: player.config.autoplay ? 1 : 0,
|
autoplay: player.config.autoplay ? 1 : 0,
|
||||||
// Autoplay
|
// Autoplay
|
||||||
@@ -6195,7 +6275,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
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 && !player.embed.hasPlayed) {
|
if (!player.config.autoplay && player.media.paused && !player.embed.hasPlayed) {
|
||||||
player.media.pause();
|
player.media.pause();
|
||||||
} else {
|
} else {
|
||||||
assurePlaybackState$1.call(player, true);
|
assurePlaybackState$1.call(player, true);
|
||||||
@@ -6349,7 +6429,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "ready",
|
key: "ready",
|
||||||
value: function ready$$1() {
|
value: function ready() {
|
||||||
var _this3 = this;
|
var _this3 = this;
|
||||||
|
|
||||||
// Start ticking our safety timer. If the whole advertisement
|
// Start ticking our safety timer. If the whole advertisement
|
||||||
@@ -6833,7 +6913,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "on",
|
key: "on",
|
||||||
value: function on$$1(event, callback) {
|
value: function on(event, callback) {
|
||||||
if (!is$1.array(this.events[event])) {
|
if (!is$1.array(this.events[event])) {
|
||||||
this.events[event] = [];
|
this.events[event] = [];
|
||||||
}
|
}
|
||||||
@@ -6917,11 +6997,11 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
lines.forEach(function (line) {
|
lines.forEach(function (line) {
|
||||||
if (!is$1.number(result.startTime)) {
|
if (!is$1.number(result.startTime)) {
|
||||||
// The line with start and end times on it is the first line of interest
|
// The line with start and end times on it is the first line of interest
|
||||||
var matchTimes = line.match(/([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{2,3})( ?--> ?)([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{2,3})/); // Note that this currently ignores caption formatting directives that are optionally on the end of this line - fine for non-captions VTT
|
var matchTimes = line.match(/([0-9]{2})?:?([0-9]{2}):([0-9]{2}).([0-9]{2,3})( ?--> ?)([0-9]{2})?:?([0-9]{2}):([0-9]{2}).([0-9]{2,3})/); // Note that this currently ignores caption formatting directives that are optionally on the end of this line - fine for non-captions VTT
|
||||||
|
|
||||||
if (matchTimes) {
|
if (matchTimes) {
|
||||||
result.startTime = Number(matchTimes[1]) * 60 * 60 + Number(matchTimes[2]) * 60 + Number(matchTimes[3]) + Number("0.".concat(matchTimes[4]));
|
result.startTime = Number(matchTimes[1] || 0) * 60 * 60 + Number(matchTimes[2]) * 60 + Number(matchTimes[3]) + Number("0.".concat(matchTimes[4]));
|
||||||
result.endTime = Number(matchTimes[6]) * 60 * 60 + Number(matchTimes[7]) * 60 + Number(matchTimes[8]) + Number("0.".concat(matchTimes[9]));
|
result.endTime = Number(matchTimes[6] || 0) * 60 * 60 + Number(matchTimes[7]) * 60 + Number(matchTimes[8]) + Number("0.".concat(matchTimes[9]));
|
||||||
}
|
}
|
||||||
} else if (!is$1.empty(line.trim()) && is$1.empty(result.text)) {
|
} else if (!is$1.empty(line.trim()) && is$1.empty(result.text)) {
|
||||||
// If we already have the startTime, then we're definitely up to the text line(s)
|
// If we already have the startTime, then we're definitely up to the text line(s)
|
||||||
@@ -7056,8 +7136,9 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
urlPrefix: ''
|
urlPrefix: ''
|
||||||
}; // If the URLs don't start with '/', then we need to set their relative path to be the location of the VTT file
|
}; // If the URLs don't start with '/', then we need to set their relative path to be the location of the VTT file
|
||||||
// If the URLs do start with '/', then they obviously don't need a prefix, so it will remain blank
|
// If the URLs do start with '/', then they obviously don't need a prefix, so it will remain blank
|
||||||
|
// If the thumbnail URLs start with with none of '/', 'http://' or 'https://', then we need to set their relative path to be the location of the VTT file
|
||||||
|
|
||||||
if (!thumbnail.frames[0].text.startsWith('/')) {
|
if (!thumbnail.frames[0].text.startsWith('/') && !thumbnail.frames[0].text.startsWith('http://') && !thumbnail.frames[0].text.startsWith('https://')) {
|
||||||
thumbnail.urlPrefix = url.substring(0, url.lastIndexOf('/') + 1);
|
thumbnail.urlPrefix = url.substring(0, url.lastIndexOf('/') + 1);
|
||||||
} // Download the first frame, so that we can determine/set the height of this thumbnailsDef
|
} // Download the first frame, so that we can determine/set the height of this thumbnailsDef
|
||||||
|
|
||||||
@@ -7961,8 +8042,10 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
} // Autoplay if required
|
} // Autoplay if required
|
||||||
|
|
||||||
|
|
||||||
if (this.config.autoplay) {
|
if (this.isHTML5 && this.config.autoplay) {
|
||||||
this.play();
|
setTimeout(function () {
|
||||||
|
return _this.play();
|
||||||
|
}, 10);
|
||||||
} // Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek
|
} // Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek
|
||||||
|
|
||||||
|
|
||||||
@@ -8181,7 +8264,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "on",
|
key: "on",
|
||||||
value: function on$$1(event, callback) {
|
value: function on$1(event, callback) {
|
||||||
on.call(this, this.elements.container, event, callback);
|
on.call(this, this.elements.container, event, callback);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -8192,7 +8275,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "once",
|
key: "once",
|
||||||
value: function once$$1(event, callback) {
|
value: function once$1(event, callback) {
|
||||||
once.call(this, this.elements.container, event, callback);
|
once.call(this, this.elements.container, event, callback);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -8203,7 +8286,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "off",
|
key: "off",
|
||||||
value: function off$$1(event, callback) {
|
value: function off$1(event, callback) {
|
||||||
off(this.elements.container, event, callback);
|
off(this.elements.container, event, callback);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -8272,12 +8355,14 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}; // Stop playback
|
}; // Stop playback
|
||||||
|
|
||||||
|
|
||||||
this.stop(); // Provider specific stuff
|
this.stop(); // Clear timeouts
|
||||||
|
|
||||||
|
clearTimeout(this.timers.loading);
|
||||||
|
clearTimeout(this.timers.controls);
|
||||||
|
clearTimeout(this.timers.resized); // Provider specific stuff
|
||||||
|
|
||||||
if (this.isHTML5) {
|
if (this.isHTML5) {
|
||||||
// Clear timeout
|
// Restore native video controls
|
||||||
clearTimeout(this.timers.loading); // Restore native video controls
|
|
||||||
|
|
||||||
ui.toggleNativeControls.call(this, true); // Clean up
|
ui.toggleNativeControls.call(this, true); // Clean up
|
||||||
|
|
||||||
done();
|
done();
|
||||||
@@ -8750,6 +8835,34 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
return this.media.getAttribute('poster');
|
return this.media.getAttribute('poster');
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Get the current aspect ratio in use
|
||||||
|
*/
|
||||||
|
|
||||||
|
}, {
|
||||||
|
key: "ratio",
|
||||||
|
get: function get() {
|
||||||
|
var ratio = reduceAspectRatio(getAspectRatio.call(this));
|
||||||
|
return is$1.array(ratio) ? ratio.join(':') : ratio;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Set video aspect ratio
|
||||||
|
*/
|
||||||
|
,
|
||||||
|
set: function set(input) {
|
||||||
|
if (!this.isVideo) {
|
||||||
|
this.debug.warn('Aspect ratio can only be set for video');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is$1.string(input) || !validateRatio(input)) {
|
||||||
|
this.debug.error("Invalid aspect ratio specified (".concat(input, ")"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.config.ratio = input;
|
||||||
|
setAspectRatio.call(this);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Set the autoplay state
|
* Set the autoplay state
|
||||||
* @param {Boolean} input - Whether to autoplay or not
|
* @param {Boolean} input - Whether to autoplay or not
|
||||||
@@ -8862,7 +8975,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "loadSprite",
|
key: "loadSprite",
|
||||||
value: function loadSprite$$1(url, id) {
|
value: function loadSprite$1(url, id) {
|
||||||
return loadSprite(url, id);
|
return loadSprite(url, id);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -8902,4 +9015,4 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
return Plyr;
|
return Plyr;
|
||||||
|
|
||||||
})));
|
}));
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+225
-112
@@ -1095,6 +1095,83 @@ var support = {
|
|||||||
reducedMotion: 'matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches
|
reducedMotion: 'matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function validateRatio(input) {
|
||||||
|
if (!is$1.array(input) && (!is$1.string(input) || !input.includes(':'))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ratio = is$1.array(input) ? input : input.split(':');
|
||||||
|
return ratio.map(Number).every(is$1.number);
|
||||||
|
}
|
||||||
|
function reduceAspectRatio(ratio) {
|
||||||
|
if (!is$1.array(ratio) || !ratio.every(is$1.number)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ratio = _slicedToArray(ratio, 2),
|
||||||
|
width = _ratio[0],
|
||||||
|
height = _ratio[1];
|
||||||
|
|
||||||
|
var getDivider = function getDivider(w, h) {
|
||||||
|
return h === 0 ? w : getDivider(h, w % h);
|
||||||
|
};
|
||||||
|
|
||||||
|
var divider = getDivider(width, height);
|
||||||
|
return [width / divider, height / divider];
|
||||||
|
}
|
||||||
|
function getAspectRatio(input) {
|
||||||
|
var parse = function parse(ratio) {
|
||||||
|
if (!validateRatio(ratio)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ratio.split(':').map(Number);
|
||||||
|
}; // Provided ratio
|
||||||
|
|
||||||
|
|
||||||
|
var ratio = parse(input); // Get from config
|
||||||
|
|
||||||
|
if (ratio === null) {
|
||||||
|
ratio = parse(this.config.ratio);
|
||||||
|
} // Get from embed
|
||||||
|
|
||||||
|
|
||||||
|
if (ratio === null && !is$1.empty(this.embed) && is$1.string(this.embed.ratio)) {
|
||||||
|
ratio = parse(this.embed.ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ratio;
|
||||||
|
} // Set aspect ratio for responsive container
|
||||||
|
|
||||||
|
function setAspectRatio(input) {
|
||||||
|
if (!this.isVideo) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
var ratio = getAspectRatio.call(this, input);
|
||||||
|
|
||||||
|
var _ref = is$1.array(ratio) ? ratio : [0, 0],
|
||||||
|
_ref2 = _slicedToArray(_ref, 2),
|
||||||
|
w = _ref2[0],
|
||||||
|
h = _ref2[1];
|
||||||
|
|
||||||
|
var padding = 100 / w * h;
|
||||||
|
this.elements.wrapper.style.paddingBottom = "".concat(padding, "%"); // For Vimeo we have an extra <div> to hide the standard controls and UI
|
||||||
|
|
||||||
|
if (this.isVimeo && this.supported.ui) {
|
||||||
|
var height = 240;
|
||||||
|
var offset = (height - padding) / (height / 50);
|
||||||
|
this.media.style.transform = "translateY(-".concat(offset, "%)");
|
||||||
|
} else if (this.isHTML5) {
|
||||||
|
this.elements.wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
padding: padding,
|
||||||
|
ratio: ratio
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
var html5 = {
|
var html5 = {
|
||||||
getSources: function getSources() {
|
getSources: function getSources() {
|
||||||
@@ -1128,7 +1205,9 @@ var html5 = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var player = this; // Quality
|
var player = this; // Set aspect ratio if set
|
||||||
|
|
||||||
|
setAspectRatio.call(player); // Quality
|
||||||
|
|
||||||
Object.defineProperty(player.media, 'quality', {
|
Object.defineProperty(player.media, 'quality', {
|
||||||
get: function get() {
|
get: function get() {
|
||||||
@@ -2027,7 +2106,7 @@ var controls = {
|
|||||||
list.appendChild(menuItem);
|
list.appendChild(menuItem);
|
||||||
},
|
},
|
||||||
// Format a time for display
|
// Format a time for display
|
||||||
formatTime: function formatTime$$1() {
|
formatTime: function formatTime$1() {
|
||||||
var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
var time = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
||||||
var inverted = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
var inverted = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
||||||
|
|
||||||
@@ -2147,8 +2226,8 @@ var controls = {
|
|||||||
range.setAttribute('aria-valuenow', this.currentTime);
|
range.setAttribute('aria-valuenow', this.currentTime);
|
||||||
var currentTime = controls.formatTime(this.currentTime);
|
var currentTime = controls.formatTime(this.currentTime);
|
||||||
var duration = controls.formatTime(this.duration);
|
var duration = controls.formatTime(this.duration);
|
||||||
var format$$1 = i18n.get('seekLabel', this.config);
|
var format = i18n.get('seekLabel', this.config);
|
||||||
range.setAttribute('aria-valuetext', format$$1.replace('{currentTime}', currentTime).replace('{duration}', duration));
|
range.setAttribute('aria-valuetext', format.replace('{currentTime}', currentTime).replace('{duration}', duration));
|
||||||
} else if (matches$1(range, this.config.selectors.inputs.volume)) {
|
} else if (matches$1(range, this.config.selectors.inputs.volume)) {
|
||||||
var percent = range.value * 100;
|
var percent = range.value * 100;
|
||||||
range.setAttribute('aria-valuenow', percent);
|
range.setAttribute('aria-valuenow', percent);
|
||||||
@@ -3502,8 +3581,9 @@ var defaults$1 = {
|
|||||||
invertTime: true,
|
invertTime: true,
|
||||||
// Clicking the currentTime inverts it's value to show time left rather than elapsed
|
// Clicking the currentTime inverts it's value to show time left rather than elapsed
|
||||||
toggleInvert: true,
|
toggleInvert: true,
|
||||||
// Aspect ratio (for embeds)
|
// Force an aspect ratio
|
||||||
ratio: '16:9',
|
// The format must be `'w:h'` (e.g. `'16:9'`)
|
||||||
|
ratio: null,
|
||||||
// Click video container to play/pause
|
// Click video container to play/pause
|
||||||
clickToPlay: true,
|
clickToPlay: true,
|
||||||
// Auto hide the controls
|
// Auto hide the controls
|
||||||
@@ -3515,7 +3595,7 @@ var defaults$1 = {
|
|||||||
// Sprite (for icons)
|
// Sprite (for icons)
|
||||||
loadSprite: true,
|
loadSprite: true,
|
||||||
iconPrefix: 'plyr',
|
iconPrefix: 'plyr',
|
||||||
iconUrl: 'https://cdn.plyr.io/3.5.2/plyr.svg',
|
iconUrl: 'https://cdn.plyr.io/3.5.3/plyr.svg',
|
||||||
// Blank video (used to prevent errors on source change)
|
// Blank video (used to prevent errors on source change)
|
||||||
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
||||||
// Quality default
|
// Quality default
|
||||||
@@ -3715,6 +3795,7 @@ var defaults$1 = {
|
|||||||
provider: 'plyr--{0}',
|
provider: 'plyr--{0}',
|
||||||
video: 'plyr__video-wrapper',
|
video: 'plyr__video-wrapper',
|
||||||
embed: 'plyr__video-embed',
|
embed: 'plyr__video-embed',
|
||||||
|
videoFixedRatio: 'plyr__video-wrapper--fixed-ratio',
|
||||||
embedContainer: 'plyr__video-embed__container',
|
embedContainer: 'plyr__video-embed__container',
|
||||||
poster: 'plyr__poster',
|
poster: 'plyr__poster',
|
||||||
posterEnabled: 'plyr__poster-enabled',
|
posterEnabled: 'plyr__poster-enabled',
|
||||||
@@ -4380,55 +4461,17 @@ var ui = {
|
|||||||
},
|
},
|
||||||
// Toggle controls based on state and `force` argument
|
// Toggle controls based on state and `force` argument
|
||||||
toggleControls: function toggleControls(force) {
|
toggleControls: function toggleControls(force) {
|
||||||
var controls$$1 = this.elements.controls;
|
var controls = this.elements.controls;
|
||||||
|
|
||||||
if (controls$$1 && this.config.hideControls) {
|
if (controls && this.config.hideControls) {
|
||||||
// Don't hide controls if a touch-device user recently seeked. (Must be limited to touch devices, or it occasionally prevents desktop controls from hiding.)
|
// Don't hide controls if a touch-device user recently seeked. (Must be limited to touch devices, or it occasionally prevents desktop controls from hiding.)
|
||||||
var recentTouchSeek = this.touch && this.lastSeekTime + 2000 > Date.now(); // Show controls if force, loading, paused, button interaction, or recent seek, otherwise hide
|
var recentTouchSeek = this.touch && this.lastSeekTime + 2000 > Date.now(); // Show controls if force, loading, paused, button interaction, or recent seek, otherwise hide
|
||||||
|
|
||||||
this.toggleControls(Boolean(force || this.loading || this.paused || controls$$1.pressed || controls$$1.hover || recentTouchSeek));
|
this.toggleControls(Boolean(force || this.loading || this.paused || controls.pressed || controls.hover || recentTouchSeek));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* function reduceAspectRatio(width, height) {
|
|
||||||
const getRatio = (w, h) => (h === 0 ? w : getRatio(h, w % h));
|
|
||||||
const ratio = getRatio(width, height);
|
|
||||||
return `${width / ratio}:${height / ratio}`;
|
|
||||||
} */
|
|
||||||
// Set aspect ratio for responsive container
|
|
||||||
|
|
||||||
function setAspectRatio(input) {
|
|
||||||
var ratio = input;
|
|
||||||
|
|
||||||
if (!is$1.string(ratio) && !is$1.nullOrUndefined(this.embed)) {
|
|
||||||
ratio = this.embed.ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is$1.string(ratio)) {
|
|
||||||
ratio = this.config.ratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ratio$split$map = ratio.split(':').map(Number),
|
|
||||||
_ratio$split$map2 = _slicedToArray(_ratio$split$map, 2),
|
|
||||||
x = _ratio$split$map2[0],
|
|
||||||
y = _ratio$split$map2[1];
|
|
||||||
|
|
||||||
var padding = 100 / x * y;
|
|
||||||
this.elements.wrapper.style.paddingBottom = "".concat(padding, "%"); // For Vimeo we have an extra <div> to hide the standard controls and UI
|
|
||||||
|
|
||||||
if (this.isVimeo && this.supported.ui) {
|
|
||||||
var height = 240;
|
|
||||||
var offset = (height - padding) / (height / 50);
|
|
||||||
this.media.style.transform = "translateY(-".concat(offset, "%)");
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
padding: padding,
|
|
||||||
ratio: ratio
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var Listeners =
|
var Listeners =
|
||||||
/*#__PURE__*/
|
/*#__PURE__*/
|
||||||
function () {
|
function () {
|
||||||
@@ -4681,6 +4724,8 @@ function () {
|
|||||||
}, {
|
}, {
|
||||||
key: "container",
|
key: "container",
|
||||||
value: function container() {
|
value: function container() {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
var config = player.config,
|
var config = player.config,
|
||||||
elements = player.elements,
|
elements = player.elements,
|
||||||
@@ -4692,11 +4737,11 @@ function () {
|
|||||||
|
|
||||||
|
|
||||||
on.call(player, elements.container, 'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen', function (event) {
|
on.call(player, elements.container, 'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen', function (event) {
|
||||||
var controls$$1 = elements.controls; // Remove button states for fullscreen
|
var controls = elements.controls; // Remove button states for fullscreen
|
||||||
|
|
||||||
if (controls$$1 && event.type === 'enterfullscreen') {
|
if (controls && event.type === 'enterfullscreen') {
|
||||||
controls$$1.pressed = false;
|
controls.pressed = false;
|
||||||
controls$$1.hover = false;
|
controls.hover = false;
|
||||||
} // Show, then hide after a timeout unless another control event occurs
|
} // Show, then hide after a timeout unless another control event occurs
|
||||||
|
|
||||||
|
|
||||||
@@ -4732,16 +4777,15 @@ function () {
|
|||||||
|
|
||||||
var target = player.elements.wrapper.firstChild;
|
var target = player.elements.wrapper.firstChild;
|
||||||
|
|
||||||
var _ratio$split$map = ratio.split(':').map(Number),
|
var _ratio = _slicedToArray(ratio, 2),
|
||||||
_ratio$split$map2 = _slicedToArray(_ratio$split$map, 2),
|
y = _ratio[1];
|
||||||
height = _ratio$split$map2[1];
|
|
||||||
|
|
||||||
var _player$embed$ratio$s = player.embed.ratio.split(':').map(Number),
|
var _getAspectRatio$call = getAspectRatio.call(_this),
|
||||||
_player$embed$ratio$s2 = _slicedToArray(_player$embed$ratio$s, 2),
|
_getAspectRatio$call2 = _slicedToArray(_getAspectRatio$call, 2),
|
||||||
videoWidth = _player$embed$ratio$s2[0],
|
videoX = _getAspectRatio$call2[0],
|
||||||
videoHeight = _player$embed$ratio$s2[1];
|
videoY = _getAspectRatio$call2[1];
|
||||||
|
|
||||||
target.style.maxWidth = toggle ? "".concat(height / videoHeight * videoWidth, "px") : null;
|
target.style.maxWidth = toggle ? "".concat(y / videoY * videoX, "px") : null;
|
||||||
target.style.margin = toggle ? '0 auto' : null;
|
target.style.margin = toggle ? '0 auto' : null;
|
||||||
}; // Resize on fullscreen change
|
}; // Resize on fullscreen change
|
||||||
|
|
||||||
@@ -4794,7 +4838,7 @@ function () {
|
|||||||
}, {
|
}, {
|
||||||
key: "media",
|
key: "media",
|
||||||
value: function media() {
|
value: function media() {
|
||||||
var _this = this;
|
var _this2 = this;
|
||||||
|
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
var elements = player.elements; // Time change on media
|
var elements = player.elements; // Time change on media
|
||||||
@@ -4859,11 +4903,11 @@ function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (player.ended) {
|
if (player.ended) {
|
||||||
_this.proxy(event, player.restart, 'restart');
|
_this2.proxy(event, player.restart, 'restart');
|
||||||
|
|
||||||
_this.proxy(event, player.play, 'play');
|
_this2.proxy(event, player.play, 'play');
|
||||||
} else {
|
} else {
|
||||||
_this.proxy(event, player.togglePlay, 'play');
|
_this2.proxy(event, player.togglePlay, 'play');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} // Disable right click
|
} // Disable right click
|
||||||
@@ -4938,21 +4982,21 @@ function () {
|
|||||||
}, {
|
}, {
|
||||||
key: "bind",
|
key: "bind",
|
||||||
value: function bind(element, type, defaultHandler, customHandlerKey) {
|
value: function bind(element, type, defaultHandler, customHandlerKey) {
|
||||||
var _this2 = this;
|
var _this3 = this;
|
||||||
|
|
||||||
var passive = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
|
var passive = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
var customHandler = player.config.listeners[customHandlerKey];
|
var customHandler = player.config.listeners[customHandlerKey];
|
||||||
var hasCustomHandler = is$1.function(customHandler);
|
var hasCustomHandler = is$1.function(customHandler);
|
||||||
on.call(player, element, type, function (event) {
|
on.call(player, element, type, function (event) {
|
||||||
return _this2.proxy(event, defaultHandler, customHandlerKey);
|
return _this3.proxy(event, defaultHandler, customHandlerKey);
|
||||||
}, passive && !hasCustomHandler);
|
}, passive && !hasCustomHandler);
|
||||||
} // Listen for control events
|
} // Listen for control events
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "controls",
|
key: "controls",
|
||||||
value: function controls$$1() {
|
value: function controls$1() {
|
||||||
var _this3 = this;
|
var _this4 = this;
|
||||||
|
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
var elements = player.elements; // IE doesn't support input event, so we fallback to change
|
var elements = player.elements; // IE doesn't support input event, so we fallback to change
|
||||||
@@ -4961,7 +5005,7 @@ function () {
|
|||||||
|
|
||||||
if (elements.buttons.play) {
|
if (elements.buttons.play) {
|
||||||
Array.from(elements.buttons.play).forEach(function (button) {
|
Array.from(elements.buttons.play).forEach(function (button) {
|
||||||
_this3.bind(button, 'click', player.togglePlay, 'play');
|
_this4.bind(button, 'click', player.togglePlay, 'play');
|
||||||
});
|
});
|
||||||
} // Pause
|
} // Pause
|
||||||
|
|
||||||
@@ -5068,7 +5112,7 @@ function () {
|
|||||||
if (browser.isIos) {
|
if (browser.isIos) {
|
||||||
var inputs = getElements.call(player, 'input[type="range"]');
|
var inputs = getElements.call(player, 'input[type="range"]');
|
||||||
Array.from(inputs).forEach(function (input) {
|
Array.from(inputs).forEach(function (input) {
|
||||||
return _this3.bind(input, inputEvent, function (event) {
|
return _this4.bind(input, inputEvent, function (event) {
|
||||||
return repaint(event.target);
|
return repaint(event.target);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -5126,7 +5170,7 @@ function () {
|
|||||||
|
|
||||||
if (browser.isWebkit) {
|
if (browser.isWebkit) {
|
||||||
Array.from(getElements.call(player, 'input[type="range"]')).forEach(function (element) {
|
Array.from(getElements.call(player, 'input[type="range"]')).forEach(function (element) {
|
||||||
_this3.bind(element, 'input', function (event) {
|
_this4.bind(element, 'input', function (event) {
|
||||||
return controls.updateRangeFill.call(player, event.target);
|
return controls.updateRangeFill.call(player, event.target);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -5173,7 +5217,7 @@ function () {
|
|||||||
toggleClass(elements.controls, config.classNames.noTransition, false);
|
toggleClass(elements.controls, config.classNames.noTransition, false);
|
||||||
}, 0); // Delay a little more for mouse users
|
}, 0); // Delay a little more for mouse users
|
||||||
|
|
||||||
var delay = _this3.touch ? 3000 : 4000; // Clear timer
|
var delay = _this4.touch ? 3000 : 4000; // Clear timer
|
||||||
|
|
||||||
clearTimeout(timers.controls); // Hide again after delay
|
clearTimeout(timers.controls); // Hide again after delay
|
||||||
|
|
||||||
@@ -5211,7 +5255,7 @@ function () {
|
|||||||
return Listeners;
|
return Listeners;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
||||||
|
|
||||||
function createCommonjsModule(fn, module) {
|
function createCommonjsModule(fn, module) {
|
||||||
return module = { exports: {} }, fn(module, module.exports), module.exports;
|
return module = { exports: {} }, fn(module, module.exports), module.exports;
|
||||||
@@ -5320,16 +5364,23 @@ var loadjs_umd = createCommonjsModule(function (module, exports) {
|
|||||||
maxTries = (args.numRetries || 0) + 1,
|
maxTries = (args.numRetries || 0) + 1,
|
||||||
beforeCallbackFn = args.before || devnull,
|
beforeCallbackFn = args.before || devnull,
|
||||||
pathStripped = path.replace(/^(css|img)!/, ''),
|
pathStripped = path.replace(/^(css|img)!/, ''),
|
||||||
isCss,
|
isLegacyIECss,
|
||||||
e;
|
e;
|
||||||
numTries = numTries || 0;
|
numTries = numTries || 0;
|
||||||
|
|
||||||
if (/(^css!|\.css$)/.test(path)) {
|
if (/(^css!|\.css$)/.test(path)) {
|
||||||
isCss = true; // css
|
// css
|
||||||
|
|
||||||
e = doc.createElement('link');
|
e = doc.createElement('link');
|
||||||
e.rel = 'stylesheet';
|
e.rel = 'stylesheet';
|
||||||
e.href = pathStripped; //.replace(/^css!/, ''); // remove "css!" prefix
|
e.href = pathStripped; // tag IE9+
|
||||||
|
|
||||||
|
isLegacyIECss = 'hideFocus' in e; // use preload in IE Edge (to detect load errors)
|
||||||
|
|
||||||
|
if (isLegacyIECss && e.relList) {
|
||||||
|
isLegacyIECss = 0;
|
||||||
|
e.rel = 'preload';
|
||||||
|
e.as = 'style';
|
||||||
|
}
|
||||||
} else if (/(^img!|\.(png|gif|jpg|svg)$)/.test(path)) {
|
} else if (/(^img!|\.(png|gif|jpg|svg)$)/.test(path)) {
|
||||||
// image
|
// image
|
||||||
e = doc.createElement('img');
|
e = doc.createElement('img');
|
||||||
@@ -5342,10 +5393,10 @@ var loadjs_umd = createCommonjsModule(function (module, exports) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
e.onload = e.onerror = e.onbeforeload = function (ev) {
|
e.onload = e.onerror = e.onbeforeload = function (ev) {
|
||||||
var result = ev.type[0]; // Note: The following code isolates IE using `hideFocus` and treats empty
|
var result = ev.type[0]; // treat empty stylesheets as failures to get around lack of onerror
|
||||||
// stylesheets as failures to get around lack of onerror support
|
// support in IE9-11
|
||||||
|
|
||||||
if (isCss && 'hideFocus' in e) {
|
if (isLegacyIECss) {
|
||||||
try {
|
try {
|
||||||
if (!e.sheet.cssText.length) result = 'e';
|
if (!e.sheet.cssText.length) result = 'e';
|
||||||
} catch (x) {
|
} catch (x) {
|
||||||
@@ -5363,6 +5414,9 @@ var loadjs_umd = createCommonjsModule(function (module, exports) {
|
|||||||
if (numTries < maxTries) {
|
if (numTries < maxTries) {
|
||||||
return loadFile(path, callbackFn, args, numTries);
|
return loadFile(path, callbackFn, args, numTries);
|
||||||
}
|
}
|
||||||
|
} else if (e.rel == 'preload' && e.as == 'style') {
|
||||||
|
// activate preloaded stylesheets
|
||||||
|
return e.rel = 'stylesheet'; // jshint ignore:line
|
||||||
} // execute callback
|
} // execute callback
|
||||||
|
|
||||||
|
|
||||||
@@ -5409,9 +5463,11 @@ var loadjs_umd = createCommonjsModule(function (module, exports) {
|
|||||||
/**
|
/**
|
||||||
* Initiate script load and register bundle.
|
* Initiate script load and register bundle.
|
||||||
* @param {(string|string[])} paths - The file paths
|
* @param {(string|string[])} paths - The file paths
|
||||||
* @param {(string|Function)} [arg1] - The bundleId or success callback
|
* @param {(string|Function|Object)} [arg1] - The (1) bundleId or (2) success
|
||||||
* @param {Function} [arg2] - The success or error callback
|
* callback or (3) object literal with success/error arguments, numRetries,
|
||||||
* @param {Function} [arg3] - The error callback
|
* etc.
|
||||||
|
* @param {(Function|Object)} [arg2] - The (1) success callback or (2) object
|
||||||
|
* literal with success/error arguments, numRetries, etc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -5428,15 +5484,26 @@ var loadjs_umd = createCommonjsModule(function (module, exports) {
|
|||||||
} else {
|
} else {
|
||||||
bundleIdCache[bundleId] = true;
|
bundleIdCache[bundleId] = true;
|
||||||
}
|
}
|
||||||
} // load scripts
|
}
|
||||||
|
|
||||||
|
function loadFn(resolve, reject) {
|
||||||
|
loadFiles(paths, function (pathsNotFound) {
|
||||||
|
// execute callbacks
|
||||||
|
executeCallbacks(args, pathsNotFound); // resolve Promise
|
||||||
|
|
||||||
|
if (resolve) {
|
||||||
|
executeCallbacks({
|
||||||
|
success: resolve,
|
||||||
|
error: reject
|
||||||
|
}, pathsNotFound);
|
||||||
|
} // publish bundle load event
|
||||||
|
|
||||||
|
|
||||||
loadFiles(paths, function (pathsNotFound) {
|
publish(bundleId, pathsNotFound);
|
||||||
// execute callbacks
|
}, args);
|
||||||
executeCallbacks(args, pathsNotFound); // publish bundle load event
|
}
|
||||||
|
|
||||||
publish(bundleId, pathsNotFound);
|
if (args.returnPromise) return new Promise(loadFn);else loadFn();
|
||||||
}, args);
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Execute callbacks when dependencies have been satisfied.
|
* Execute callbacks when dependencies have been satisfied.
|
||||||
@@ -5542,7 +5609,7 @@ var vimeo = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// API Ready
|
// API Ready
|
||||||
ready: function ready$$1() {
|
ready: function ready() {
|
||||||
var _this2 = this;
|
var _this2 = this;
|
||||||
|
|
||||||
var player = this;
|
var player = this;
|
||||||
@@ -5736,7 +5803,7 @@ var vimeo = {
|
|||||||
height = _dimensions[1];
|
height = _dimensions[1];
|
||||||
|
|
||||||
player.embed.ratio = "".concat(width, ":").concat(height);
|
player.embed.ratio = "".concat(width, ":").concat(height);
|
||||||
setAspectRatio.call(_this2, player.embed.ratio);
|
setAspectRatio.call(_this2);
|
||||||
}); // Set autopause
|
}); // Set autopause
|
||||||
|
|
||||||
player.embed.setAutopause(player.config.autopause).then(function (state) {
|
player.embed.setAutopause(player.config.autopause).then(function (state) {
|
||||||
@@ -5858,6 +5925,19 @@ function assurePlaybackState$1(play) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getHost(config) {
|
||||||
|
if (config.noCookie) {
|
||||||
|
return 'https://www.youtube-nocookie.com';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.location.protocol === 'http:') {
|
||||||
|
return 'http://www.youtube.com';
|
||||||
|
} // Use YouTube's default
|
||||||
|
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
var youtube = {
|
var youtube = {
|
||||||
setup: function setup() {
|
setup: function setup() {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
@@ -5921,7 +6001,7 @@ var youtube = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// API ready
|
// API ready
|
||||||
ready: function ready$$1() {
|
ready: function ready() {
|
||||||
var player = this; // Ignore already setup (race condition)
|
var player = this; // Ignore already setup (race condition)
|
||||||
|
|
||||||
var currentId = player.media.getAttribute('id');
|
var currentId = player.media.getAttribute('id');
|
||||||
@@ -5949,8 +6029,8 @@ var youtube = {
|
|||||||
});
|
});
|
||||||
player.media = replaceElement(container, player.media); // Id to poster wrapper
|
player.media = replaceElement(container, player.media); // Id to poster wrapper
|
||||||
|
|
||||||
var posterSrc = function posterSrc(format$$1) {
|
var posterSrc = function posterSrc(format) {
|
||||||
return "https://img.youtube.com/vi/".concat(videoId, "/").concat(format$$1, "default.jpg");
|
return "https://i.ytimg.com/vi/".concat(videoId, "/").concat(format, "default.jpg");
|
||||||
}; // Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide)
|
}; // Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide)
|
||||||
|
|
||||||
|
|
||||||
@@ -5974,7 +6054,7 @@ var youtube = {
|
|||||||
|
|
||||||
player.embed = new window.YT.Player(id, {
|
player.embed = new window.YT.Player(id, {
|
||||||
videoId: videoId,
|
videoId: videoId,
|
||||||
host: config.noCookie ? 'https://www.youtube-nocookie.com' : undefined,
|
host: getHost(config),
|
||||||
playerVars: extend({}, {
|
playerVars: extend({}, {
|
||||||
autoplay: player.config.autoplay ? 1 : 0,
|
autoplay: player.config.autoplay ? 1 : 0,
|
||||||
// Autoplay
|
// Autoplay
|
||||||
@@ -6189,7 +6269,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 && !player.embed.hasPlayed) {
|
if (!player.config.autoplay && player.media.paused && !player.embed.hasPlayed) {
|
||||||
player.media.pause();
|
player.media.pause();
|
||||||
} else {
|
} else {
|
||||||
assurePlaybackState$1.call(player, true);
|
assurePlaybackState$1.call(player, true);
|
||||||
@@ -6343,7 +6423,7 @@ function () {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "ready",
|
key: "ready",
|
||||||
value: function ready$$1() {
|
value: function ready() {
|
||||||
var _this3 = this;
|
var _this3 = this;
|
||||||
|
|
||||||
// Start ticking our safety timer. If the whole advertisement
|
// Start ticking our safety timer. If the whole advertisement
|
||||||
@@ -6827,7 +6907,7 @@ function () {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "on",
|
key: "on",
|
||||||
value: function on$$1(event, callback) {
|
value: function on(event, callback) {
|
||||||
if (!is$1.array(this.events[event])) {
|
if (!is$1.array(this.events[event])) {
|
||||||
this.events[event] = [];
|
this.events[event] = [];
|
||||||
}
|
}
|
||||||
@@ -6911,11 +6991,11 @@ var parseVtt = function parseVtt(vttDataString) {
|
|||||||
lines.forEach(function (line) {
|
lines.forEach(function (line) {
|
||||||
if (!is$1.number(result.startTime)) {
|
if (!is$1.number(result.startTime)) {
|
||||||
// The line with start and end times on it is the first line of interest
|
// The line with start and end times on it is the first line of interest
|
||||||
var matchTimes = line.match(/([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{2,3})( ?--> ?)([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{2,3})/); // Note that this currently ignores caption formatting directives that are optionally on the end of this line - fine for non-captions VTT
|
var matchTimes = line.match(/([0-9]{2})?:?([0-9]{2}):([0-9]{2}).([0-9]{2,3})( ?--> ?)([0-9]{2})?:?([0-9]{2}):([0-9]{2}).([0-9]{2,3})/); // Note that this currently ignores caption formatting directives that are optionally on the end of this line - fine for non-captions VTT
|
||||||
|
|
||||||
if (matchTimes) {
|
if (matchTimes) {
|
||||||
result.startTime = Number(matchTimes[1]) * 60 * 60 + Number(matchTimes[2]) * 60 + Number(matchTimes[3]) + Number("0.".concat(matchTimes[4]));
|
result.startTime = Number(matchTimes[1] || 0) * 60 * 60 + Number(matchTimes[2]) * 60 + Number(matchTimes[3]) + Number("0.".concat(matchTimes[4]));
|
||||||
result.endTime = Number(matchTimes[6]) * 60 * 60 + Number(matchTimes[7]) * 60 + Number(matchTimes[8]) + Number("0.".concat(matchTimes[9]));
|
result.endTime = Number(matchTimes[6] || 0) * 60 * 60 + Number(matchTimes[7]) * 60 + Number(matchTimes[8]) + Number("0.".concat(matchTimes[9]));
|
||||||
}
|
}
|
||||||
} else if (!is$1.empty(line.trim()) && is$1.empty(result.text)) {
|
} else if (!is$1.empty(line.trim()) && is$1.empty(result.text)) {
|
||||||
// If we already have the startTime, then we're definitely up to the text line(s)
|
// If we already have the startTime, then we're definitely up to the text line(s)
|
||||||
@@ -7050,8 +7130,9 @@ function () {
|
|||||||
urlPrefix: ''
|
urlPrefix: ''
|
||||||
}; // If the URLs don't start with '/', then we need to set their relative path to be the location of the VTT file
|
}; // If the URLs don't start with '/', then we need to set their relative path to be the location of the VTT file
|
||||||
// If the URLs do start with '/', then they obviously don't need a prefix, so it will remain blank
|
// If the URLs do start with '/', then they obviously don't need a prefix, so it will remain blank
|
||||||
|
// If the thumbnail URLs start with with none of '/', 'http://' or 'https://', then we need to set their relative path to be the location of the VTT file
|
||||||
|
|
||||||
if (!thumbnail.frames[0].text.startsWith('/')) {
|
if (!thumbnail.frames[0].text.startsWith('/') && !thumbnail.frames[0].text.startsWith('http://') && !thumbnail.frames[0].text.startsWith('https://')) {
|
||||||
thumbnail.urlPrefix = url.substring(0, url.lastIndexOf('/') + 1);
|
thumbnail.urlPrefix = url.substring(0, url.lastIndexOf('/') + 1);
|
||||||
} // Download the first frame, so that we can determine/set the height of this thumbnailsDef
|
} // Download the first frame, so that we can determine/set the height of this thumbnailsDef
|
||||||
|
|
||||||
@@ -7955,8 +8036,10 @@ function () {
|
|||||||
} // Autoplay if required
|
} // Autoplay if required
|
||||||
|
|
||||||
|
|
||||||
if (this.config.autoplay) {
|
if (this.isHTML5 && this.config.autoplay) {
|
||||||
this.play();
|
setTimeout(function () {
|
||||||
|
return _this.play();
|
||||||
|
}, 10);
|
||||||
} // Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek
|
} // Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek
|
||||||
|
|
||||||
|
|
||||||
@@ -8175,7 +8258,7 @@ function () {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "on",
|
key: "on",
|
||||||
value: function on$$1(event, callback) {
|
value: function on$1(event, callback) {
|
||||||
on.call(this, this.elements.container, event, callback);
|
on.call(this, this.elements.container, event, callback);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -8186,7 +8269,7 @@ function () {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "once",
|
key: "once",
|
||||||
value: function once$$1(event, callback) {
|
value: function once$1(event, callback) {
|
||||||
once.call(this, this.elements.container, event, callback);
|
once.call(this, this.elements.container, event, callback);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -8197,7 +8280,7 @@ function () {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "off",
|
key: "off",
|
||||||
value: function off$$1(event, callback) {
|
value: function off$1(event, callback) {
|
||||||
off(this.elements.container, event, callback);
|
off(this.elements.container, event, callback);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -8266,12 +8349,14 @@ function () {
|
|||||||
}; // Stop playback
|
}; // Stop playback
|
||||||
|
|
||||||
|
|
||||||
this.stop(); // Provider specific stuff
|
this.stop(); // Clear timeouts
|
||||||
|
|
||||||
|
clearTimeout(this.timers.loading);
|
||||||
|
clearTimeout(this.timers.controls);
|
||||||
|
clearTimeout(this.timers.resized); // Provider specific stuff
|
||||||
|
|
||||||
if (this.isHTML5) {
|
if (this.isHTML5) {
|
||||||
// Clear timeout
|
// Restore native video controls
|
||||||
clearTimeout(this.timers.loading); // Restore native video controls
|
|
||||||
|
|
||||||
ui.toggleNativeControls.call(this, true); // Clean up
|
ui.toggleNativeControls.call(this, true); // Clean up
|
||||||
|
|
||||||
done();
|
done();
|
||||||
@@ -8744,6 +8829,34 @@ function () {
|
|||||||
|
|
||||||
return this.media.getAttribute('poster');
|
return this.media.getAttribute('poster');
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Get the current aspect ratio in use
|
||||||
|
*/
|
||||||
|
|
||||||
|
}, {
|
||||||
|
key: "ratio",
|
||||||
|
get: function get() {
|
||||||
|
var ratio = reduceAspectRatio(getAspectRatio.call(this));
|
||||||
|
return is$1.array(ratio) ? ratio.join(':') : ratio;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Set video aspect ratio
|
||||||
|
*/
|
||||||
|
,
|
||||||
|
set: function set(input) {
|
||||||
|
if (!this.isVideo) {
|
||||||
|
this.debug.warn('Aspect ratio can only be set for video');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is$1.string(input) || !validateRatio(input)) {
|
||||||
|
this.debug.error("Invalid aspect ratio specified (".concat(input, ")"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.config.ratio = input;
|
||||||
|
setAspectRatio.call(this);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Set the autoplay state
|
* Set the autoplay state
|
||||||
* @param {Boolean} input - Whether to autoplay or not
|
* @param {Boolean} input - Whether to autoplay or not
|
||||||
@@ -8856,7 +8969,7 @@ function () {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: "loadSprite",
|
key: "loadSprite",
|
||||||
value: function loadSprite$$1(url, id) {
|
value: function loadSprite$1(url, id) {
|
||||||
return loadSprite(url, id);
|
return loadSprite(url, id);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
Vendored
+5050
-2524
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+5047
-2521
File diff suppressed because it is too large
Load Diff
@@ -149,6 +149,7 @@ Object.entries(build.js).forEach(([filename, entry]) => {
|
|||||||
{
|
{
|
||||||
// debug: true,
|
// debug: true,
|
||||||
useBuiltIns: polyfill ? 'usage' : false,
|
useBuiltIns: polyfill ? 'usage' : false,
|
||||||
|
corejs: polyfill ? 3 : undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|||||||
+21
-20
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "plyr",
|
"name": "plyr",
|
||||||
"version": "3.5.2",
|
"version": "3.5.3",
|
||||||
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
||||||
"homepage": "https://plyr.io",
|
"homepage": "https://plyr.io",
|
||||||
"author": "Sam Potts <sam@potts.es>",
|
"author": "Sam Potts <sam@potts.es>",
|
||||||
@@ -35,15 +35,15 @@
|
|||||||
"deploy": "yarn lint && gulp deploy"
|
"deploy": "yarn lint && gulp deploy"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"ansi-colors": "^3.2.3",
|
"ansi-colors": "^3.2.4",
|
||||||
"aws-sdk": "^2.409.0",
|
"aws-sdk": "^2.437.0",
|
||||||
"@babel/core": "^7.3.3",
|
"@babel/core": "^7.4.3",
|
||||||
"@babel/preset-env": "^7.3.1",
|
"@babel/preset-env": "^7.4.3",
|
||||||
"babel-eslint": "^10.0.1",
|
"babel-eslint": "^10.0.1",
|
||||||
"del": "^3.0.0",
|
"del": "^4.1.0",
|
||||||
"eslint": "^5.14.1",
|
"eslint": "^5.16.0",
|
||||||
"eslint-config-airbnb-base": "^13.1.0",
|
"eslint-config-airbnb-base": "^13.1.0",
|
||||||
"eslint-config-prettier": "^4.0.0",
|
"eslint-config-prettier": "^4.1.0",
|
||||||
"eslint-plugin-import": "^2.16.0",
|
"eslint-plugin-import": "^2.16.0",
|
||||||
"fancy-log": "^1.3.3",
|
"fancy-log": "^1.3.3",
|
||||||
"fastly-purge": "^1.0.1",
|
"fastly-purge": "^1.0.1",
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
"gulp": "^4.0.0",
|
"gulp": "^4.0.0",
|
||||||
"gulp-autoprefixer": "^6.0.0",
|
"gulp-autoprefixer": "^6.0.0",
|
||||||
"gulp-awspublish": "^4.0.0",
|
"gulp-awspublish": "^4.0.0",
|
||||||
"gulp-better-rollup": "^3.4.0",
|
"gulp-better-rollup": "^4.0.1",
|
||||||
"gulp-clean-css": "^4.0.0",
|
"gulp-clean-css": "^4.0.0",
|
||||||
"gulp-filter": "^5.1.0",
|
"gulp-filter": "^5.1.0",
|
||||||
"gulp-header": "^2.0.7",
|
"gulp-header": "^2.0.7",
|
||||||
@@ -66,29 +66,30 @@
|
|||||||
"gulp-sourcemaps": "^2.6.5",
|
"gulp-sourcemaps": "^2.6.5",
|
||||||
"gulp-svgstore": "^7.0.1",
|
"gulp-svgstore": "^7.0.1",
|
||||||
"gulp-terser": "^1.1.7",
|
"gulp-terser": "^1.1.7",
|
||||||
"postcss-custom-properties": "^8.0.9",
|
"postcss-custom-properties": "^8.0.10",
|
||||||
"prettier-eslint": "^8.8.2",
|
"prettier-eslint": "^8.8.2",
|
||||||
"prettier-stylelint": "^0.4.2",
|
"prettier-stylelint": "^0.4.2",
|
||||||
"remark-cli": "^6.0.1",
|
"remark-cli": "^6.0.1",
|
||||||
"remark-validate-links": "^8.0.0",
|
"remark-validate-links": "^8.0.2",
|
||||||
|
"rollup": "^1.10.0",
|
||||||
"rollup-plugin-babel": "^4.3.2",
|
"rollup-plugin-babel": "^4.3.2",
|
||||||
"rollup-plugin-commonjs": "^9.2.1",
|
"rollup-plugin-commonjs": "^9.3.4",
|
||||||
"rollup-plugin-node-resolve": "^4.0.1",
|
"rollup-plugin-node-resolve": "^4.2.3",
|
||||||
"stylelint": "^9.10.1",
|
"stylelint": "^9.10.1",
|
||||||
"stylelint-config-prettier": "^5.0.0",
|
"stylelint-config-prettier": "^5.0.0",
|
||||||
"stylelint-config-recommended": "^2.1.0",
|
"stylelint-config-recommended": "^2.1.0",
|
||||||
"stylelint-config-sass-guidelines": "^5.3.0",
|
"stylelint-config-sass-guidelines": "^5.3.0",
|
||||||
"stylelint-order": "^2.0.0",
|
"stylelint-order": "^2.2.1",
|
||||||
"stylelint-scss": "^3.5.4",
|
"stylelint-scss": "^3.5.4",
|
||||||
"stylelint-selector-bem-pattern": "^2.0.0",
|
"stylelint-selector-bem-pattern": "^2.1.0",
|
||||||
"through2": "^3.0.0"
|
"through2": "^3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"core-js": "^2.6.5",
|
"core-js": "^3.0.1",
|
||||||
"custom-event-polyfill": "^1.0.6",
|
"custom-event-polyfill": "^1.0.7",
|
||||||
"loadjs": "^3.5.5",
|
"loadjs": "^3.6.1",
|
||||||
"rangetouch": "^2.0.0",
|
"rangetouch": "^2.0.0",
|
||||||
"raven-js": "^3.27.0",
|
"raven-js": "^3.27.0",
|
||||||
"url-polyfill": "^1.1.3"
|
"url-polyfill": "^1.1.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,10 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"settings": {
|
"settings": {
|
||||||
|
"search.exclude": {
|
||||||
|
"**/node_modules": true,
|
||||||
|
"**/dist": true
|
||||||
|
},
|
||||||
// Linting
|
// Linting
|
||||||
"stylelint.enable": true,
|
"stylelint.enable": true,
|
||||||
"css.validate": false,
|
"css.validate": false,
|
||||||
|
|||||||
@@ -123,13 +123,13 @@ See [initialising](#initialising) for more information on advanced setups.
|
|||||||
You can use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript. There's 2 versions; one with and one without [polyfills](#polyfills). My recommendation would be to manage polyfills seperately as part of your application but to make life easier you can use the polyfilled build.
|
You can use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript. There's 2 versions; one with and one without [polyfills](#polyfills). My recommendation would be to manage polyfills seperately as part of your application but to make life easier you can use the polyfilled build.
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script src="https://cdn.plyr.io/3.5.2/plyr.js"></script>
|
<script src="https://cdn.plyr.io/3.5.3/plyr.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
...or...
|
...or...
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script src="https://cdn.plyr.io/3.5.2/plyr.polyfilled.js"></script>
|
<script src="https://cdn.plyr.io/3.5.3/plyr.polyfilled.js"></script>
|
||||||
```
|
```
|
||||||
|
|
||||||
## CSS
|
## CSS
|
||||||
@@ -143,13 +143,13 @@ Include the `plyr.css` stylsheet into your `<head>`
|
|||||||
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following:
|
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<link rel="stylesheet" href="https://cdn.plyr.io/3.5.2/plyr.css" />
|
<link rel="stylesheet" href="https://cdn.plyr.io/3.5.3/plyr.css" />
|
||||||
```
|
```
|
||||||
|
|
||||||
## SVG Sprite
|
## SVG Sprite
|
||||||
|
|
||||||
The SVG sprite is loaded automatically from our CDN (provided by [Fastly](https://www.fastly.com/)). To change this, see the [options](#options) below. For
|
The SVG sprite is loaded automatically from our CDN (provided by [Fastly](https://www.fastly.com/)). To change this, see the [options](#options) below. For
|
||||||
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.5.2/plyr.svg`.
|
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.5.3/plyr.svg`.
|
||||||
|
|
||||||
# Ads
|
# Ads
|
||||||
|
|
||||||
@@ -293,10 +293,10 @@ Note the single quotes encapsulating the JSON and double quotes on the object ke
|
|||||||
| `listeners` | Object | `null` | Allows binding of event listeners to the controls before the default handlers. See the `defaults.js` for available listeners. If your handler prevents default on the event (`event.preventDefault()`), the default handler will not fire. |
|
| `listeners` | Object | `null` | Allows binding of event listeners to the controls before the default handlers. See the `defaults.js` for available listeners. If your handler prevents default on the event (`event.preventDefault()`), the default handler will not fire. |
|
||||||
| `captions` | Object | `{ active: false, language: 'auto', update: false }` | `active`: Toggles if captions should be active by default. `language`: Sets the default language to load (if available). 'auto' uses the browser language. `update`: Listen to changes to tracks and update menu. This is needed for some streaming libraries, but can result in unselectable language options). |
|
| `captions` | Object | `{ active: false, language: 'auto', update: false }` | `active`: Toggles if captions should be active by default. `language`: Sets the default language to load (if available). 'auto' uses the browser language. `update`: Listen to changes to tracks and update menu. This is needed for some streaming libraries, but can result in unselectable language options). |
|
||||||
| `fullscreen` | Object | `{ enabled: true, fallback: true, iosNative: false }` | `enabled`: Toggles whether fullscreen should be enabled. `fallback`: Allow fallback to a full-window solution (`true`/`false`/`'force'`). `iosNative`: whether to use native iOS fullscreen when entering fullscreen (no custom controls) |
|
| `fullscreen` | Object | `{ enabled: true, fallback: true, iosNative: false }` | `enabled`: Toggles whether fullscreen should be enabled. `fallback`: Allow fallback to a full-window solution (`true`/`false`/`'force'`). `iosNative`: whether to use native iOS fullscreen when entering fullscreen (no custom controls) |
|
||||||
| `ratio` | String | `16:9` | The aspect ratio you want to use for embedded players. |
|
| `ratio` | String | `null` | Force an aspect ratio for all videos. The format is `'w:h'` - e.g. `'16:9'` or `'4:3'`. If this is not specified then the default for HTML5 and Vimeo is to use the native resolution of the video. As dimensions are not available from YouTube via SDK, 16:9 is forced as a sensible default. |
|
||||||
| `storage` | Object | `{ enabled: true, key: 'plyr' }` | `enabled`: Allow use of local storage to store user settings. `key`: The key name to use. |
|
| `storage` | Object | `{ enabled: true, key: 'plyr' }` | `enabled`: Allow use of local storage to store user settings. `key`: The key name to use. |
|
||||||
| `speed` | Object | `{ selected: 1, options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] }` | `selected`: The default speed for playback. `options`: Options to display in the menu. Most browsers will refuse to play slower than 0.5. |
|
| `speed` | Object | `{ selected: 1, options: [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] }` | `selected`: The default speed for playback. `options`: Options to display in the menu. Most browsers will refuse to play slower than 0.5. |
|
||||||
| `quality` | Object | `{ default: 'default', options: ['hd2160', 'hd1440', 'hd1080', 'hd720', 'large', 'medium', 'small', 'tiny', 'default'] }` | Currently only supported by YouTube. `default` is the default quality level, determined by YouTube. `options` are the options to display. |
|
| `quality` | Object | `{ default: 576, options: [4320, 2880, 2160, 1440, 1080, 720, 576, 480, 360, 240] }` | `default` is the default quality level (if it exists in your sources). `options` are the options to display. This is used to filter the available sources. |
|
||||||
| `loop` | Object | `{ active: false }` | `active`: Whether to loop the current video. If the `loop` attribute is present on a `<video>` or `<audio>` element, this will be automatically set to true This is an object to support future functionality. |
|
| `loop` | Object | `{ active: false }` | `active`: Whether to loop the current video. If the `loop` attribute is present on a `<video>` or `<audio>` element, this will be automatically set to true This is an object to support future functionality. |
|
||||||
| `ads` | Object | `{ enabled: false, publisherId: '' }` | `enabled`: Whether to enable advertisements. `publisherId`: Your unique [vi.ai](https://vi.ai/publisher-video-monetization/?aid=plyrio) publisher ID. |
|
| `ads` | Object | `{ enabled: false, publisherId: '' }` | `enabled`: Whether to enable advertisements. `publisherId`: Your unique [vi.ai](https://vi.ai/publisher-video-monetization/?aid=plyrio) publisher ID. |
|
||||||
| `urls` | Object | See source. | If you wish to override any API URLs then you can do so here. You can also set a custom download URL for the download button. |
|
| `urls` | Object | See source. | If you wish to override any API URLs then you can do so here. You can also set a custom download URL for the download button. |
|
||||||
@@ -404,10 +404,10 @@ player.fullscreen.active; // false;
|
|||||||
| `language` | ✓ | ✓ | Gets or sets the preferred captions language for the player. The setter accepts an ISO two-letter language code. Support for the languages is dependent on the captions you include. If your captions don't have any language data, or if you have multiple tracks with the same language, you may want to use `currentTrack` instead. |
|
| `language` | ✓ | ✓ | Gets or sets the preferred captions language for the player. The setter accepts an ISO two-letter language code. Support for the languages is dependent on the captions you include. If your captions don't have any language data, or if you have multiple tracks with the same language, you may want to use `currentTrack` instead. |
|
||||||
| `fullscreen.active` | ✓ | - | Returns a boolean indicating if the current player is in fullscreen mode. |
|
| `fullscreen.active` | ✓ | - | Returns a boolean indicating if the current player is in fullscreen mode. |
|
||||||
| `fullscreen.enabled` | ✓ | - | Returns a boolean indicating if the current player has fullscreen enabled. |
|
| `fullscreen.enabled` | ✓ | - | Returns a boolean indicating if the current player has fullscreen enabled. |
|
||||||
| `pip`² | ✓ | ✓ | Gets or sets the picture-in-picture state of the player. The setter accepts a boolean. This currently only supported on Safari 10+ (on MacOS Sierra+ and iOS 10+) and Chrome 70+. |
|
| `pip`¹ | ✓ | ✓ | Gets or sets the picture-in-picture state of the player. The setter accepts a boolean. This currently only supported on Safari 10+ (on MacOS Sierra+ and iOS 10+) and Chrome 70+. |
|
||||||
|
| `ratio` | ✓ | ✓ | Gets or sets the video aspect ratio. The setter accepts a string in the same format as the `ratio` option. |
|
||||||
|
|
||||||
1. YouTube only. HTML5 will follow.
|
1. HTML5 only
|
||||||
2. HTML5 only
|
|
||||||
|
|
||||||
### The `.source` setter
|
### The `.source` setter
|
||||||
|
|
||||||
|
|||||||
@@ -42,8 +42,9 @@ const defaults = {
|
|||||||
// Clicking the currentTime inverts it's value to show time left rather than elapsed
|
// Clicking the currentTime inverts it's value to show time left rather than elapsed
|
||||||
toggleInvert: true,
|
toggleInvert: true,
|
||||||
|
|
||||||
// Aspect ratio (for embeds)
|
// Force an aspect ratio
|
||||||
ratio: '16:9',
|
// The format must be `'w:h'` (e.g. `'16:9'`)
|
||||||
|
ratio: null,
|
||||||
|
|
||||||
// Click video container to play/pause
|
// Click video container to play/pause
|
||||||
clickToPlay: true,
|
clickToPlay: true,
|
||||||
@@ -60,7 +61,7 @@ const defaults = {
|
|||||||
// Sprite (for icons)
|
// Sprite (for icons)
|
||||||
loadSprite: true,
|
loadSprite: true,
|
||||||
iconPrefix: 'plyr',
|
iconPrefix: 'plyr',
|
||||||
iconUrl: 'https://cdn.plyr.io/3.5.2/plyr.svg',
|
iconUrl: 'https://cdn.plyr.io/3.5.3/plyr.svg',
|
||||||
|
|
||||||
// Blank video (used to prevent errors on source change)
|
// Blank video (used to prevent errors on source change)
|
||||||
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
||||||
@@ -330,6 +331,7 @@ const defaults = {
|
|||||||
provider: 'plyr--{0}',
|
provider: 'plyr--{0}',
|
||||||
video: 'plyr__video-wrapper',
|
video: 'plyr__video-wrapper',
|
||||||
embed: 'plyr__video-embed',
|
embed: 'plyr__video-embed',
|
||||||
|
videoFixedRatio: 'plyr__video-wrapper--fixed-ratio',
|
||||||
embedContainer: 'plyr__video-embed__container',
|
embedContainer: 'plyr__video-embed__container',
|
||||||
poster: 'plyr__poster',
|
poster: 'plyr__poster',
|
||||||
posterEnabled: 'plyr__poster-enabled',
|
posterEnabled: 'plyr__poster-enabled',
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import support from './support';
|
|||||||
import { removeElement } from './utils/elements';
|
import { removeElement } from './utils/elements';
|
||||||
import { triggerEvent } from './utils/events';
|
import { triggerEvent } from './utils/events';
|
||||||
import is from './utils/is';
|
import is from './utils/is';
|
||||||
|
import { setAspectRatio } from './utils/style';
|
||||||
|
|
||||||
const html5 = {
|
const html5 = {
|
||||||
getSources() {
|
getSources() {
|
||||||
@@ -43,6 +44,9 @@ const html5 = {
|
|||||||
|
|
||||||
const player = this;
|
const player = this;
|
||||||
|
|
||||||
|
// Set aspect ratio if set
|
||||||
|
setAspectRatio.call(player);
|
||||||
|
|
||||||
// Quality
|
// Quality
|
||||||
Object.defineProperty(player.media, 'quality', {
|
Object.defineProperty(player.media, 'quality', {
|
||||||
get() {
|
get() {
|
||||||
|
|||||||
+4
-4
@@ -9,7 +9,7 @@ import browser from './utils/browser';
|
|||||||
import { getElement, getElements, matches, toggleClass, toggleHidden } from './utils/elements';
|
import { getElement, getElements, matches, toggleClass, toggleHidden } from './utils/elements';
|
||||||
import { off, on, once, toggleListener, triggerEvent } from './utils/events';
|
import { off, on, once, toggleListener, triggerEvent } from './utils/events';
|
||||||
import is from './utils/is';
|
import is from './utils/is';
|
||||||
import { setAspectRatio } from './utils/style';
|
import { getAspectRatio, setAspectRatio } from './utils/style';
|
||||||
|
|
||||||
class Listeners {
|
class Listeners {
|
||||||
constructor(player) {
|
constructor(player) {
|
||||||
@@ -317,10 +317,10 @@ class Listeners {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const target = player.elements.wrapper.firstChild;
|
const target = player.elements.wrapper.firstChild;
|
||||||
const [, height] = ratio.split(':').map(Number);
|
const [, y] = ratio;
|
||||||
const [videoWidth, videoHeight] = player.embed.ratio.split(':').map(Number);
|
const [videoX, videoY] = getAspectRatio.call(this);
|
||||||
|
|
||||||
target.style.maxWidth = toggle ? `${(height / videoHeight) * videoWidth}px` : null;
|
target.style.maxWidth = toggle ? `${(y / videoY) * videoX}px` : null;
|
||||||
target.style.margin = toggle ? '0 auto' : null;
|
target.style.margin = toggle ? '0 auto' : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -17,17 +17,17 @@ const parseVtt = vttDataString => {
|
|||||||
if (!is.number(result.startTime)) {
|
if (!is.number(result.startTime)) {
|
||||||
// The line with start and end times on it is the first line of interest
|
// The line with start and end times on it is the first line of interest
|
||||||
const matchTimes = line.match(
|
const matchTimes = line.match(
|
||||||
/([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{2,3})( ?--> ?)([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{2,3})/,
|
/([0-9]{2})?:?([0-9]{2}):([0-9]{2}).([0-9]{2,3})( ?--> ?)([0-9]{2})?:?([0-9]{2}):([0-9]{2}).([0-9]{2,3})/,
|
||||||
); // Note that this currently ignores caption formatting directives that are optionally on the end of this line - fine for non-captions VTT
|
); // Note that this currently ignores caption formatting directives that are optionally on the end of this line - fine for non-captions VTT
|
||||||
|
|
||||||
if (matchTimes) {
|
if (matchTimes) {
|
||||||
result.startTime =
|
result.startTime =
|
||||||
Number(matchTimes[1]) * 60 * 60 +
|
Number(matchTimes[1] || 0) * 60 * 60 +
|
||||||
Number(matchTimes[2]) * 60 +
|
Number(matchTimes[2]) * 60 +
|
||||||
Number(matchTimes[3]) +
|
Number(matchTimes[3]) +
|
||||||
Number(`0.${matchTimes[4]}`);
|
Number(`0.${matchTimes[4]}`);
|
||||||
result.endTime =
|
result.endTime =
|
||||||
Number(matchTimes[6]) * 60 * 60 +
|
Number(matchTimes[6] || 0) * 60 * 60 +
|
||||||
Number(matchTimes[7]) * 60 +
|
Number(matchTimes[7]) * 60 +
|
||||||
Number(matchTimes[8]) +
|
Number(matchTimes[8]) +
|
||||||
Number(`0.${matchTimes[9]}`);
|
Number(`0.${matchTimes[9]}`);
|
||||||
@@ -148,7 +148,10 @@ class PreviewThumbnails {
|
|||||||
|
|
||||||
// If the URLs don't start with '/', then we need to set their relative path to be the location of the VTT file
|
// If the URLs don't start with '/', then we need to set their relative path to be the location of the VTT file
|
||||||
// If the URLs do start with '/', then they obviously don't need a prefix, so it will remain blank
|
// If the URLs do start with '/', then they obviously don't need a prefix, so it will remain blank
|
||||||
if (!thumbnail.frames[0].text.startsWith('/')) {
|
// If the thumbnail URLs start with with none of '/', 'http://' or 'https://', then we need to set their relative path to be the location of the VTT file
|
||||||
|
if (!thumbnail.frames[0].text.startsWith('/') &&
|
||||||
|
!thumbnail.frames[0].text.startsWith('http://') &&
|
||||||
|
!thumbnail.frames[0].text.startsWith('https://')) {
|
||||||
thumbnail.urlPrefix = url.substring(0, url.lastIndexOf('/') + 1);
|
thumbnail.urlPrefix = url.substring(0, url.lastIndexOf('/') + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ const vimeo = {
|
|||||||
Promise.all([player.embed.getVideoWidth(), player.embed.getVideoHeight()]).then(dimensions => {
|
Promise.all([player.embed.getVideoWidth(), player.embed.getVideoHeight()]).then(dimensions => {
|
||||||
const [width, height] = dimensions;
|
const [width, height] = dimensions;
|
||||||
player.embed.ratio = `${width}:${height}`;
|
player.embed.ratio = `${width}:${height}`;
|
||||||
setAspectRatio.call(this, player.embed.ratio);
|
setAspectRatio.call(this);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set autopause
|
// Set autopause
|
||||||
|
|||||||
@@ -34,6 +34,19 @@ function assurePlaybackState(play) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getHost(config) {
|
||||||
|
if (config.noCookie) {
|
||||||
|
return 'https://www.youtube-nocookie.com';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.location.protocol === 'http:') {
|
||||||
|
return 'http://www.youtube.com';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use YouTube's default
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const youtube = {
|
const youtube = {
|
||||||
setup() {
|
setup() {
|
||||||
// Add embed class for responsive
|
// Add embed class for responsive
|
||||||
@@ -130,7 +143,7 @@ const youtube = {
|
|||||||
player.media = replaceElement(container, player.media);
|
player.media = replaceElement(container, player.media);
|
||||||
|
|
||||||
// Id to poster wrapper
|
// Id to poster wrapper
|
||||||
const posterSrc = format => `https://img.youtube.com/vi/${videoId}/${format}default.jpg`;
|
const posterSrc = format => `https://i.ytimg.com/vi/${videoId}/${format}default.jpg`;
|
||||||
|
|
||||||
// Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide)
|
// Check thumbnail images in order of quality, but reject fallback thumbnails (120px wide)
|
||||||
loadImage(posterSrc('maxres'), 121) // Higest quality and unpadded
|
loadImage(posterSrc('maxres'), 121) // Higest quality and unpadded
|
||||||
@@ -151,7 +164,7 @@ const youtube = {
|
|||||||
// https://developers.google.com/youtube/iframe_api_reference
|
// https://developers.google.com/youtube/iframe_api_reference
|
||||||
player.embed = new window.YT.Player(id, {
|
player.embed = new window.YT.Player(id, {
|
||||||
videoId,
|
videoId,
|
||||||
host: config.noCookie ? 'https://www.youtube-nocookie.com' : undefined,
|
host: getHost(config),
|
||||||
playerVars: extend(
|
playerVars: extend(
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
@@ -386,7 +399,7 @@ const 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 && !player.embed.hasPlayed) {
|
if (!player.config.autoplay && player.media.paused && !player.embed.hasPlayed) {
|
||||||
player.media.pause();
|
player.media.pause();
|
||||||
} else {
|
} else {
|
||||||
assurePlaybackState.call(player, true);
|
assurePlaybackState.call(player, true);
|
||||||
|
|||||||
+37
-6
@@ -1,6 +1,6 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Plyr
|
// Plyr
|
||||||
// plyr.js v3.5.2
|
// plyr.js v3.5.3
|
||||||
// https://github.com/sampotts/plyr
|
// https://github.com/sampotts/plyr
|
||||||
// License: The MIT License (MIT)
|
// License: The MIT License (MIT)
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
@@ -26,6 +26,7 @@ import { off, on, once, triggerEvent, unbindListeners } from './utils/events';
|
|||||||
import is from './utils/is';
|
import is from './utils/is';
|
||||||
import loadSprite from './utils/loadSprite';
|
import loadSprite from './utils/loadSprite';
|
||||||
import { cloneDeep, extend } from './utils/objects';
|
import { cloneDeep, extend } from './utils/objects';
|
||||||
|
import { getAspectRatio, reduceAspectRatio, setAspectRatio, validateRatio } from './utils/style';
|
||||||
import { parseUrl } from './utils/urls';
|
import { parseUrl } from './utils/urls';
|
||||||
|
|
||||||
// Private properties
|
// Private properties
|
||||||
@@ -301,8 +302,8 @@ class Plyr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Autoplay if required
|
// Autoplay if required
|
||||||
if (this.config.autoplay) {
|
if (this.isHTML5 && this.config.autoplay) {
|
||||||
this.play();
|
setTimeout(() => this.play(), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek
|
// Seek time will be recorded (in listeners.js) so we can prevent hiding controls for a few seconds after seek
|
||||||
@@ -846,6 +847,34 @@ class Plyr {
|
|||||||
return this.media.getAttribute('poster');
|
return this.media.getAttribute('poster');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current aspect ratio in use
|
||||||
|
*/
|
||||||
|
get ratio() {
|
||||||
|
const ratio = reduceAspectRatio(getAspectRatio.call(this));
|
||||||
|
|
||||||
|
return is.array(ratio) ? ratio.join(':') : ratio;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set video aspect ratio
|
||||||
|
*/
|
||||||
|
set ratio(input) {
|
||||||
|
if (!this.isVideo) {
|
||||||
|
this.debug.warn('Aspect ratio can only be set for video');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is.string(input) || !validateRatio(input)) {
|
||||||
|
this.debug.error(`Invalid aspect ratio specified (${input})`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.config.ratio = input;
|
||||||
|
|
||||||
|
setAspectRatio.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the autoplay state
|
* Set the autoplay state
|
||||||
* @param {Boolean} input - Whether to autoplay or not
|
* @param {Boolean} input - Whether to autoplay or not
|
||||||
@@ -1088,11 +1117,13 @@ class Plyr {
|
|||||||
// Stop playback
|
// Stop playback
|
||||||
this.stop();
|
this.stop();
|
||||||
|
|
||||||
|
// Clear timeouts
|
||||||
|
clearTimeout(this.timers.loading);
|
||||||
|
clearTimeout(this.timers.controls);
|
||||||
|
clearTimeout(this.timers.resized);
|
||||||
|
|
||||||
// Provider specific stuff
|
// Provider specific stuff
|
||||||
if (this.isHTML5) {
|
if (this.isHTML5) {
|
||||||
// Clear timeout
|
|
||||||
clearTimeout(this.timers.loading);
|
|
||||||
|
|
||||||
// Restore native video controls
|
// Restore native video controls
|
||||||
ui.toggleNativeControls.call(this, true);
|
ui.toggleNativeControls.call(this, true);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Plyr Polyfilled Build
|
// Plyr Polyfilled Build
|
||||||
// plyr.js v3.5.2
|
// plyr.js v3.5.3
|
||||||
// https://github.com/sampotts/plyr
|
// https://github.com/sampotts/plyr
|
||||||
// License: The MIT License (MIT)
|
// License: The MIT License (MIT)
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|||||||
+53
-14
@@ -4,26 +4,63 @@
|
|||||||
|
|
||||||
import is from './is';
|
import is from './is';
|
||||||
|
|
||||||
/* function reduceAspectRatio(width, height) {
|
export function validateRatio(input) {
|
||||||
const getRatio = (w, h) => (h === 0 ? w : getRatio(h, w % h));
|
if (!is.array(input) && (!is.string(input) || !input.includes(':'))) {
|
||||||
const ratio = getRatio(width, height);
|
return false;
|
||||||
return `${width / ratio}:${height / ratio}`;
|
}
|
||||||
} */
|
|
||||||
|
const ratio = is.array(input) ? input : input.split(':');
|
||||||
|
|
||||||
|
return ratio.map(Number).every(is.number);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function reduceAspectRatio(ratio) {
|
||||||
|
if (!is.array(ratio) || !ratio.every(is.number)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [width, height] = ratio;
|
||||||
|
const getDivider = (w, h) => (h === 0 ? w : getDivider(h, w % h));
|
||||||
|
const divider = getDivider(width, height);
|
||||||
|
|
||||||
|
return [width / divider, height / divider];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAspectRatio(input) {
|
||||||
|
const parse = ratio => {
|
||||||
|
if (!validateRatio(ratio)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ratio.split(':').map(Number);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Provided ratio
|
||||||
|
let ratio = parse(input);
|
||||||
|
|
||||||
|
// Get from config
|
||||||
|
if (ratio === null) {
|
||||||
|
ratio = parse(this.config.ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get from embed
|
||||||
|
if (ratio === null && !is.empty(this.embed) && is.string(this.embed.ratio)) {
|
||||||
|
ratio = parse(this.embed.ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ratio;
|
||||||
|
}
|
||||||
|
|
||||||
// Set aspect ratio for responsive container
|
// Set aspect ratio for responsive container
|
||||||
export function setAspectRatio(input) {
|
export function setAspectRatio(input) {
|
||||||
let ratio = input;
|
if (!this.isVideo) {
|
||||||
|
return {};
|
||||||
if (!is.string(ratio) && !is.nullOrUndefined(this.embed)) {
|
|
||||||
({ ratio } = this.embed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is.string(ratio)) {
|
const ratio = getAspectRatio.call(this, input);
|
||||||
({ ratio } = this.config);
|
|
||||||
}
|
|
||||||
|
|
||||||
const [x, y] = ratio.split(':').map(Number);
|
const [w, h] = is.array(ratio) ? ratio : [0, 0];
|
||||||
const padding = (100 / x) * y;
|
const padding = (100 / w) * h;
|
||||||
|
|
||||||
this.elements.wrapper.style.paddingBottom = `${padding}%`;
|
this.elements.wrapper.style.paddingBottom = `${padding}%`;
|
||||||
|
|
||||||
@@ -32,6 +69,8 @@ export function setAspectRatio(input) {
|
|||||||
const height = 240;
|
const height = 240;
|
||||||
const offset = (height - padding) / (height / 50);
|
const offset = (height - padding) / (height / 50);
|
||||||
this.media.style.transform = `translateY(-${offset}%)`;
|
this.media.style.transform = `translateY(-${offset}%)`;
|
||||||
|
} else if (this.isHTML5) {
|
||||||
|
this.elements.wrapper.classList.toggle(this.config.classNames.videoFixedRatio, ratio !== null);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { padding, ratio };
|
return { padding, ratio };
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
// --------------------------------------------------------------
|
|
||||||
// Embedded players
|
|
||||||
// YouTube, Vimeo, etc
|
|
||||||
// --------------------------------------------------------------
|
|
||||||
|
|
||||||
// Default to 16:9 ratio but this is set by JavaScript based on config
|
|
||||||
$embed-padding: ((100 / 16) * 9);
|
|
||||||
|
|
||||||
.plyr__video-embed {
|
|
||||||
height: 0;
|
|
||||||
padding-bottom: to-percentage($embed-padding);
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
iframe {
|
|
||||||
border: 0;
|
|
||||||
height: 100%;
|
|
||||||
left: 0;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
user-select: none;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the full custom UI is supported
|
|
||||||
.plyr--full-ui .plyr__video-embed {
|
|
||||||
$height: 240;
|
|
||||||
$offset: to-percentage(($height - $embed-padding) / ($height / 50));
|
|
||||||
|
|
||||||
// Only used for Vimeo
|
|
||||||
> .plyr__video-embed__container {
|
|
||||||
padding-bottom: to-percentage($height);
|
|
||||||
position: relative;
|
|
||||||
transform: translateY(-$offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -20,3 +20,36 @@
|
|||||||
// Require z-index to force border-radius
|
// Require z-index to force border-radius
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default to 16:9 ratio but this is set by JavaScript based on config
|
||||||
|
$embed-padding: ((100 / 16) * 9);
|
||||||
|
|
||||||
|
.plyr__video-embed,
|
||||||
|
.plyr__video-wrapper--fixed-ratio {
|
||||||
|
height: 0;
|
||||||
|
padding-bottom: to-percentage($embed-padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
.plyr__video-embed iframe,
|
||||||
|
.plyr__video-wrapper--fixed-ratio video {
|
||||||
|
border: 0;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
user-select: none;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the full custom UI is supported
|
||||||
|
.plyr--full-ui .plyr__video-embed {
|
||||||
|
$height: 240;
|
||||||
|
$offset: to-percentage(($height - $embed-padding) / ($height / 50));
|
||||||
|
|
||||||
|
// Only used for Vimeo
|
||||||
|
> .plyr__video-embed__container {
|
||||||
|
padding-bottom: to-percentage($height);
|
||||||
|
position: relative;
|
||||||
|
transform: translateY(-$offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
@import 'components/captions';
|
@import 'components/captions';
|
||||||
@import 'components/control';
|
@import 'components/control';
|
||||||
@import 'components/controls';
|
@import 'components/controls';
|
||||||
@import 'components/embed';
|
|
||||||
@import 'components/menus';
|
@import 'components/menus';
|
||||||
@import 'components/sliders';
|
@import 'components/sliders';
|
||||||
@import 'components/poster';
|
@import 'components/poster';
|
||||||
|
|||||||
Reference in New Issue
Block a user