Compare commits

..

2 Commits

Author SHA1 Message Date
cce143a7da v3.0.11 2018-03-30 23:14:07 +11:00
d593005b32 Muted and autoplay fixes, small bug fixes 2018-03-30 23:09:17 +11:00
19 changed files with 288 additions and 148 deletions

15
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Launch Chrome against localhost",
"url": "http://localhost/dev/plyr/demo",
"webRoot": "${workspaceFolder}"
}
]
}

View File

@ -1,3 +1,8 @@
## v3.0.11
* Muted and autoplay fixes
* Small bug fixes from Sentry logs
## v3.0.10 ## v3.0.10
* Docs fix * Docs fix

View File

@ -169,7 +169,8 @@
</aside> </aside>
<!-- Polyfills --> <!-- Polyfills -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=es6,Array.prototype.includes,CustomEvent" crossorigin="anonymous"></script> <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=es6,Array.prototype.includes,CustomEvent,Object.entries"
crossorigin="anonymous"></script>
<!-- Plyr core script --> <!-- Plyr core script -->
<script src="../dist/plyr.js" crossorigin="anonymous"></script> <script src="../dist/plyr.js" crossorigin="anonymous"></script>

127
dist/plyr.js vendored
View File

@ -77,7 +77,7 @@ var defaults = {
// Sprite (for icons) // Sprite (for icons)
loadSprite: true, loadSprite: true,
iconPrefix: 'plyr', iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/3.0.9/plyr.svg', iconUrl: 'https://cdn.plyr.io/3.0.10/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',
@ -2430,6 +2430,9 @@ var ui = {
// Reset quality options // Reset quality options
this.options.quality = []; this.options.quality = [];
// Reset volume display
ui.updateVolume.call(this);
// Reset time display // Reset time display
ui.timeUpdate.call(this); ui.timeUpdate.call(this);
@ -4200,17 +4203,17 @@ var Listeners = function () {
return ui.updateProgress.call(_this3.player, event); return ui.updateProgress.call(_this3.player, event);
}); });
// Handle native mute // Handle volume changes
utils.on(this.player.media, 'volumechange', function (event) { utils.on(this.player.media, 'volumechange', function (event) {
return ui.updateVolume.call(_this3.player, event); return ui.updateVolume.call(_this3.player, event);
}); });
// Handle native play/pause // Handle play/pause
utils.on(this.player.media, 'playing play pause ended emptied', function (event) { utils.on(this.player.media, 'playing play pause ended emptied', function (event) {
return ui.checkPlaying.call(_this3.player, event); return ui.checkPlaying.call(_this3.player, event);
}); });
// Loading // Loading state
utils.on(this.player.media, 'waiting canplay seeked playing', function (event) { utils.on(this.player.media, 'waiting canplay seeked playing', function (event) {
return ui.checkLoading.call(_this3.player, event); return ui.checkLoading.call(_this3.player, event);
}); });
@ -4218,6 +4221,20 @@ var Listeners = function () {
// Check if media failed to load // Check if media failed to load
// utils.on(this.player.media, 'play', event => ui.checkFailed.call(this.player, event)); // utils.on(this.player.media, 'play', event => ui.checkFailed.call(this.player, event));
// If autoplay, then load advertisement if required
// TODO: Show some sort of loading state while the ad manager loads else there's a delay before ad shows
utils.on(this.player.media, 'playing', function () {
// If ads are enabled, wait for them first
if (_this3.player.ads.enabled && !_this3.player.ads.initialized) {
// Wait for manager response
_this3.player.ads.managerPromise.then(function () {
return _this3.player.ads.play();
}).catch(function () {
return _this3.player.play();
});
}
});
// Click video // Click video
if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) { if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) {
// Re-fetch the wrapper // Re-fetch the wrapper
@ -4813,11 +4830,12 @@ var Ads = function () {
this.cuePoints = this.manager.getCuePoints(); this.cuePoints = this.manager.getCuePoints();
// Add advertisement cue's within the time line if available // Add advertisement cue's within the time line if available
if (!utils.is.empty(this.cuePoints)) {
this.cuePoints.forEach(function (cuePoint) { this.cuePoints.forEach(function (cuePoint) {
if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < _this6.player.duration) { if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < _this6.player.duration) {
var seekElement = _this6.player.elements.progress; var seekElement = _this6.player.elements.progress;
if (seekElement) { if (utils.is.element(seekElement)) {
var cuePercentage = 100 / _this6.player.duration * cuePoint; var cuePercentage = 100 / _this6.player.duration * cuePoint;
var cue = utils.createElement('span', { var cue = utils.createElement('span', {
class: _this6.player.config.classNames.cues class: _this6.player.config.classNames.cues
@ -4828,6 +4846,7 @@ var Ads = function () {
} }
} }
}); });
}
// Get skippable state // Get skippable state
// TODO: Skip button // TODO: Skip button
@ -5011,6 +5030,10 @@ var Ads = function () {
this.player.on('seeked', function () { this.player.on('seeked', function () {
var seekedTime = _this8.player.currentTime; var seekedTime = _this8.player.currentTime;
if (utils.is.empty(_this8.cuePoints)) {
return;
}
_this8.cuePoints.forEach(function (cuePoint, index) { _this8.cuePoints.forEach(function (cuePoint, index) {
if (time < cuePoint && cuePoint < seekedTime) { if (time < cuePoint && cuePoint < seekedTime) {
_this8.manager.discardAdBreak(); _this8.manager.discardAdBreak();
@ -5022,7 +5045,9 @@ var Ads = function () {
// Listen to the resizing of the window. And resize ad accordingly // Listen to the resizing of the window. And resize ad accordingly
// TODO: eventually implement ResizeObserver // TODO: eventually implement ResizeObserver
window.addEventListener('resize', function () { window.addEventListener('resize', function () {
if (_this8.manager) {
_this8.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL); _this8.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);
}
}); });
} }
@ -6360,7 +6385,17 @@ var Plyr = function () {
} }
// Cache original element state for .destroy() // Cache original element state for .destroy()
this.elements.original = this.media.cloneNode(true); // TODO: Investigate a better solution as I suspect this causes reported double load issues?
setTimeout(function () {
var clone = _this.media.cloneNode(true);
// Prevent the clone autoplaying
if (clone.getAttribute('autoplay')) {
clone.pause();
}
_this.elements.original = clone;
}, 0);
// Set media type based on tag or data attribute // Set media type based on tag or data attribute
// Supported: video, audio, vimeo, youtube // Supported: video, audio, vimeo, youtube
@ -6510,6 +6545,11 @@ var Plyr = function () {
// Setup ads if provided // Setup ads if provided
this.ads = new Ads(this); this.ads = new Ads(this);
// Autoplay if required
if (this.config.autoplay) {
this.play();
}
} }
// --------------------------------------- // ---------------------------------------
@ -6529,20 +6569,14 @@ var Plyr = function () {
* Play the media, or play the advertisement (if they are not blocked) * Play the media, or play the advertisement (if they are not blocked)
*/ */
value: function play() { value: function play() {
var _this2 = this;
if (!utils.is.function(this.media.play)) { if (!utils.is.function(this.media.play)) {
return null; return null;
} }
// If ads are enabled, wait for them first // If ads are enabled, wait for them first
if (this.ads.enabled && !this.ads.initialized) { /* if (this.ads.enabled && !this.ads.initialized) {
return this.ads.managerPromise.then(function () { return this.ads.managerPromise.then(() => this.ads.play()).catch(() => this.media.play());
return _this2.ads.play(); } */
}).catch(function () {
return _this2.media.play();
});
}
// Return the promise (for HTML5) // Return the promise (for HTML5)
return this.media.play(); return this.media.play();
@ -6594,7 +6628,7 @@ var Plyr = function () {
value: function stop() { value: function stop() {
if (this.isHTML5) { if (this.isHTML5) {
this.media.load(); this.media.load();
} else { } else if (utils.is.function(this.media.stop)) {
this.media.stop(); this.media.stop();
} }
} }
@ -6729,7 +6763,7 @@ var Plyr = function () {
}, { }, {
key: 'toggleControls', key: 'toggleControls',
value: function toggleControls(toggle) { value: function toggleControls(toggle) {
var _this3 = this; var _this2 = this;
// We need controls of course... // We need controls of course...
if (!utils.is.element(this.elements.controls)) { if (!utils.is.element(this.elements.controls)) {
@ -6803,25 +6837,30 @@ var Plyr = function () {
// then set the timer to hide the controls // then set the timer to hide the controls
if (!show || this.playing) { if (!show || this.playing) {
this.timers.controls = setTimeout(function () { this.timers.controls = setTimeout(function () {
// We need controls of course...
if (!utils.is.element(_this2.elements.controls)) {
return;
}
// If the mouse is over the controls (and not entering fullscreen), bail // If the mouse is over the controls (and not entering fullscreen), bail
if ((_this3.elements.controls.pressed || _this3.elements.controls.hover) && !isEnterFullscreen) { if ((_this2.elements.controls.pressed || _this2.elements.controls.hover) && !isEnterFullscreen) {
return; return;
} }
// Restore transition behaviour // Restore transition behaviour
if (!utils.hasClass(_this3.elements.container, _this3.config.classNames.hideControls)) { if (!utils.hasClass(_this2.elements.container, _this2.config.classNames.hideControls)) {
utils.toggleClass(_this3.elements.controls, _this3.config.classNames.noTransition, false); utils.toggleClass(_this2.elements.controls, _this2.config.classNames.noTransition, false);
} }
// Check if controls toggled // Check if controls toggled
var toggled = utils.toggleClass(_this3.elements.container, _this3.config.classNames.hideControls, true); var toggled = utils.toggleClass(_this2.elements.container, _this2.config.classNames.hideControls, true);
// Trigger event and close menu // Trigger event and close menu
if (toggled) { if (toggled) {
utils.dispatchEvent.call(_this3, _this3.media, 'controlshidden'); utils.dispatchEvent.call(_this2, _this2.media, 'controlshidden');
if (_this3.config.controls.includes('settings') && !utils.is.empty(_this3.config.settings)) { if (_this2.config.controls.includes('settings') && !utils.is.empty(_this2.config.settings)) {
controls.toggleMenu.call(_this3, false); controls.toggleMenu.call(_this2, false);
} }
} }
}, delay); }, delay);
@ -6863,7 +6902,7 @@ var Plyr = function () {
}, { }, {
key: 'destroy', key: 'destroy',
value: function destroy(callback) { value: function destroy(callback) {
var _this4 = this; var _this3 = this;
var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@ -6876,22 +6915,22 @@ var Plyr = function () {
document.body.style.overflow = ''; document.body.style.overflow = '';
// GC for embed // GC for embed
_this4.embed = null; _this3.embed = null;
// If it's a soft destroy, make minimal changes // If it's a soft destroy, make minimal changes
if (soft) { if (soft) {
if (Object.keys(_this4.elements).length) { if (Object.keys(_this3.elements).length) {
// Remove elements // Remove elements
utils.removeElement(_this4.elements.buttons.play); utils.removeElement(_this3.elements.buttons.play);
utils.removeElement(_this4.elements.captions); utils.removeElement(_this3.elements.captions);
utils.removeElement(_this4.elements.controls); utils.removeElement(_this3.elements.controls);
utils.removeElement(_this4.elements.wrapper); utils.removeElement(_this3.elements.wrapper);
// Clear for GC // Clear for GC
_this4.elements.buttons.play = null; _this3.elements.buttons.play = null;
_this4.elements.captions = null; _this3.elements.captions = null;
_this4.elements.controls = null; _this3.elements.controls = null;
_this4.elements.wrapper = null; _this3.elements.wrapper = null;
} }
// Callback // Callback
@ -6900,26 +6939,26 @@ var Plyr = function () {
} }
} else { } else {
// Unbind listeners // Unbind listeners
_this4.listeners.clear(); _this3.listeners.clear();
// Replace the container with the original element provided // Replace the container with the original element provided
utils.replaceElement(_this4.elements.original, _this4.elements.container); utils.replaceElement(_this3.elements.original, _this3.elements.container);
// Event // Event
utils.dispatchEvent.call(_this4, _this4.elements.original, 'destroyed', true); utils.dispatchEvent.call(_this3, _this3.elements.original, 'destroyed', true);
// Callback // Callback
if (utils.is.function(callback)) { if (utils.is.function(callback)) {
callback.call(_this4.elements.original); callback.call(_this3.elements.original);
} }
// Reset state // Reset state
_this4.ready = false; _this3.ready = false;
// Clear for garbage collection // Clear for garbage collection
setTimeout(function () { setTimeout(function () {
_this4.elements = null; _this3.elements = null;
_this4.media = null; _this3.media = null;
}, 200); }, 200);
} }
}; };
@ -7171,8 +7210,8 @@ var Plyr = function () {
// Set the player volume // Set the player volume
this.media.volume = volume; this.media.volume = volume;
// If muted, and we're increasing volume, reset muted state // If muted, and we're increasing volume manually, reset muted state
if (this.muted && volume > 0) { if (!utils.is.empty(value) && this.muted && volume > 0) {
this.muted = false; this.muted = false;
} }
} }

2
dist/plyr.js.map vendored

File diff suppressed because one or more lines are too long

2
dist/plyr.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5117,7 +5117,7 @@ var defaults = {
// Sprite (for icons) // Sprite (for icons)
loadSprite: true, loadSprite: true,
iconPrefix: 'plyr', iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/3.0.10/plyr.svg', iconUrl: 'https://cdn.plyr.io/3.0.11/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',
@ -7464,6 +7464,9 @@ var ui = {
// Reset quality options // Reset quality options
this.options.quality = []; this.options.quality = [];
// Reset volume display
ui.updateVolume.call(this);
// Reset time display // Reset time display
ui.timeUpdate.call(this); ui.timeUpdate.call(this);
@ -9234,17 +9237,17 @@ var Listeners = function () {
return ui.updateProgress.call(_this3.player, event); return ui.updateProgress.call(_this3.player, event);
}); });
// Handle native mute // Handle volume changes
utils.on(this.player.media, 'volumechange', function (event) { utils.on(this.player.media, 'volumechange', function (event) {
return ui.updateVolume.call(_this3.player, event); return ui.updateVolume.call(_this3.player, event);
}); });
// Handle native play/pause // Handle play/pause
utils.on(this.player.media, 'playing play pause ended emptied', function (event) { utils.on(this.player.media, 'playing play pause ended emptied', function (event) {
return ui.checkPlaying.call(_this3.player, event); return ui.checkPlaying.call(_this3.player, event);
}); });
// Loading // Loading state
utils.on(this.player.media, 'waiting canplay seeked playing', function (event) { utils.on(this.player.media, 'waiting canplay seeked playing', function (event) {
return ui.checkLoading.call(_this3.player, event); return ui.checkLoading.call(_this3.player, event);
}); });
@ -9252,6 +9255,20 @@ var Listeners = function () {
// Check if media failed to load // Check if media failed to load
// utils.on(this.player.media, 'play', event => ui.checkFailed.call(this.player, event)); // utils.on(this.player.media, 'play', event => ui.checkFailed.call(this.player, event));
// If autoplay, then load advertisement if required
// TODO: Show some sort of loading state while the ad manager loads else there's a delay before ad shows
utils.on(this.player.media, 'playing', function () {
// If ads are enabled, wait for them first
if (_this3.player.ads.enabled && !_this3.player.ads.initialized) {
// Wait for manager response
_this3.player.ads.managerPromise.then(function () {
return _this3.player.ads.play();
}).catch(function () {
return _this3.player.play();
});
}
});
// Click video // Click video
if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) { if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) {
// Re-fetch the wrapper // Re-fetch the wrapper
@ -9847,11 +9864,12 @@ var Ads = function () {
this.cuePoints = this.manager.getCuePoints(); this.cuePoints = this.manager.getCuePoints();
// Add advertisement cue's within the time line if available // Add advertisement cue's within the time line if available
if (!utils.is.empty(this.cuePoints)) {
this.cuePoints.forEach(function (cuePoint) { this.cuePoints.forEach(function (cuePoint) {
if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < _this6.player.duration) { if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < _this6.player.duration) {
var seekElement = _this6.player.elements.progress; var seekElement = _this6.player.elements.progress;
if (seekElement) { if (utils.is.element(seekElement)) {
var cuePercentage = 100 / _this6.player.duration * cuePoint; var cuePercentage = 100 / _this6.player.duration * cuePoint;
var cue = utils.createElement('span', { var cue = utils.createElement('span', {
class: _this6.player.config.classNames.cues class: _this6.player.config.classNames.cues
@ -9862,6 +9880,7 @@ var Ads = function () {
} }
} }
}); });
}
// Get skippable state // Get skippable state
// TODO: Skip button // TODO: Skip button
@ -10045,6 +10064,10 @@ var Ads = function () {
this.player.on('seeked', function () { this.player.on('seeked', function () {
var seekedTime = _this8.player.currentTime; var seekedTime = _this8.player.currentTime;
if (utils.is.empty(_this8.cuePoints)) {
return;
}
_this8.cuePoints.forEach(function (cuePoint, index) { _this8.cuePoints.forEach(function (cuePoint, index) {
if (time < cuePoint && cuePoint < seekedTime) { if (time < cuePoint && cuePoint < seekedTime) {
_this8.manager.discardAdBreak(); _this8.manager.discardAdBreak();
@ -10056,7 +10079,9 @@ var Ads = function () {
// Listen to the resizing of the window. And resize ad accordingly // Listen to the resizing of the window. And resize ad accordingly
// TODO: eventually implement ResizeObserver // TODO: eventually implement ResizeObserver
window.addEventListener('resize', function () { window.addEventListener('resize', function () {
if (_this8.manager) {
_this8.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL); _this8.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);
}
}); });
} }
@ -11394,7 +11419,17 @@ var Plyr = function () {
} }
// Cache original element state for .destroy() // Cache original element state for .destroy()
this.elements.original = this.media.cloneNode(true); // TODO: Investigate a better solution as I suspect this causes reported double load issues?
setTimeout(function () {
var clone = _this.media.cloneNode(true);
// Prevent the clone autoplaying
if (clone.getAttribute('autoplay')) {
clone.pause();
}
_this.elements.original = clone;
}, 0);
// Set media type based on tag or data attribute // Set media type based on tag or data attribute
// Supported: video, audio, vimeo, youtube // Supported: video, audio, vimeo, youtube
@ -11544,6 +11579,11 @@ var Plyr = function () {
// Setup ads if provided // Setup ads if provided
this.ads = new Ads(this); this.ads = new Ads(this);
// Autoplay if required
if (this.config.autoplay) {
this.play();
}
} }
// --------------------------------------- // ---------------------------------------
@ -11563,20 +11603,14 @@ var Plyr = function () {
* Play the media, or play the advertisement (if they are not blocked) * Play the media, or play the advertisement (if they are not blocked)
*/ */
value: function play() { value: function play() {
var _this2 = this;
if (!utils.is.function(this.media.play)) { if (!utils.is.function(this.media.play)) {
return null; return null;
} }
// If ads are enabled, wait for them first // If ads are enabled, wait for them first
if (this.ads.enabled && !this.ads.initialized) { /* if (this.ads.enabled && !this.ads.initialized) {
return this.ads.managerPromise.then(function () { return this.ads.managerPromise.then(() => this.ads.play()).catch(() => this.media.play());
return _this2.ads.play(); } */
}).catch(function () {
return _this2.media.play();
});
}
// Return the promise (for HTML5) // Return the promise (for HTML5)
return this.media.play(); return this.media.play();
@ -11628,7 +11662,7 @@ var Plyr = function () {
value: function stop() { value: function stop() {
if (this.isHTML5) { if (this.isHTML5) {
this.media.load(); this.media.load();
} else { } else if (utils.is.function(this.media.stop)) {
this.media.stop(); this.media.stop();
} }
} }
@ -11763,7 +11797,7 @@ var Plyr = function () {
}, { }, {
key: 'toggleControls', key: 'toggleControls',
value: function toggleControls(toggle) { value: function toggleControls(toggle) {
var _this3 = this; var _this2 = this;
// We need controls of course... // We need controls of course...
if (!utils.is.element(this.elements.controls)) { if (!utils.is.element(this.elements.controls)) {
@ -11837,25 +11871,30 @@ var Plyr = function () {
// then set the timer to hide the controls // then set the timer to hide the controls
if (!show || this.playing) { if (!show || this.playing) {
this.timers.controls = setTimeout(function () { this.timers.controls = setTimeout(function () {
// We need controls of course...
if (!utils.is.element(_this2.elements.controls)) {
return;
}
// If the mouse is over the controls (and not entering fullscreen), bail // If the mouse is over the controls (and not entering fullscreen), bail
if ((_this3.elements.controls.pressed || _this3.elements.controls.hover) && !isEnterFullscreen) { if ((_this2.elements.controls.pressed || _this2.elements.controls.hover) && !isEnterFullscreen) {
return; return;
} }
// Restore transition behaviour // Restore transition behaviour
if (!utils.hasClass(_this3.elements.container, _this3.config.classNames.hideControls)) { if (!utils.hasClass(_this2.elements.container, _this2.config.classNames.hideControls)) {
utils.toggleClass(_this3.elements.controls, _this3.config.classNames.noTransition, false); utils.toggleClass(_this2.elements.controls, _this2.config.classNames.noTransition, false);
} }
// Check if controls toggled // Check if controls toggled
var toggled = utils.toggleClass(_this3.elements.container, _this3.config.classNames.hideControls, true); var toggled = utils.toggleClass(_this2.elements.container, _this2.config.classNames.hideControls, true);
// Trigger event and close menu // Trigger event and close menu
if (toggled) { if (toggled) {
utils.dispatchEvent.call(_this3, _this3.media, 'controlshidden'); utils.dispatchEvent.call(_this2, _this2.media, 'controlshidden');
if (_this3.config.controls.includes('settings') && !utils.is.empty(_this3.config.settings)) { if (_this2.config.controls.includes('settings') && !utils.is.empty(_this2.config.settings)) {
controls.toggleMenu.call(_this3, false); controls.toggleMenu.call(_this2, false);
} }
} }
}, delay); }, delay);
@ -11897,7 +11936,7 @@ var Plyr = function () {
}, { }, {
key: 'destroy', key: 'destroy',
value: function destroy(callback) { value: function destroy(callback) {
var _this4 = this; var _this3 = this;
var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@ -11910,22 +11949,22 @@ var Plyr = function () {
document.body.style.overflow = ''; document.body.style.overflow = '';
// GC for embed // GC for embed
_this4.embed = null; _this3.embed = null;
// If it's a soft destroy, make minimal changes // If it's a soft destroy, make minimal changes
if (soft) { if (soft) {
if (Object.keys(_this4.elements).length) { if (Object.keys(_this3.elements).length) {
// Remove elements // Remove elements
utils.removeElement(_this4.elements.buttons.play); utils.removeElement(_this3.elements.buttons.play);
utils.removeElement(_this4.elements.captions); utils.removeElement(_this3.elements.captions);
utils.removeElement(_this4.elements.controls); utils.removeElement(_this3.elements.controls);
utils.removeElement(_this4.elements.wrapper); utils.removeElement(_this3.elements.wrapper);
// Clear for GC // Clear for GC
_this4.elements.buttons.play = null; _this3.elements.buttons.play = null;
_this4.elements.captions = null; _this3.elements.captions = null;
_this4.elements.controls = null; _this3.elements.controls = null;
_this4.elements.wrapper = null; _this3.elements.wrapper = null;
} }
// Callback // Callback
@ -11934,26 +11973,26 @@ var Plyr = function () {
} }
} else { } else {
// Unbind listeners // Unbind listeners
_this4.listeners.clear(); _this3.listeners.clear();
// Replace the container with the original element provided // Replace the container with the original element provided
utils.replaceElement(_this4.elements.original, _this4.elements.container); utils.replaceElement(_this3.elements.original, _this3.elements.container);
// Event // Event
utils.dispatchEvent.call(_this4, _this4.elements.original, 'destroyed', true); utils.dispatchEvent.call(_this3, _this3.elements.original, 'destroyed', true);
// Callback // Callback
if (utils.is.function(callback)) { if (utils.is.function(callback)) {
callback.call(_this4.elements.original); callback.call(_this3.elements.original);
} }
// Reset state // Reset state
_this4.ready = false; _this3.ready = false;
// Clear for garbage collection // Clear for garbage collection
setTimeout(function () { setTimeout(function () {
_this4.elements = null; _this3.elements = null;
_this4.media = null; _this3.media = null;
}, 200); }, 200);
} }
}; };
@ -12205,8 +12244,8 @@ var Plyr = function () {
// Set the player volume // Set the player volume
this.media.volume = volume; this.media.volume = volume;
// If muted, and we're increasing volume, reset muted state // If muted, and we're increasing volume manually, reset muted state
if (this.muted && volume > 0) { if (!utils.is.empty(value) && this.muted && volume > 0) {
this.muted = false; this.muted = false;
} }
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{ {
"name": "plyr", "name": "plyr",
"version": "3.0.10", "version": "3.0.11",
"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",
"main": "./dist/plyr.js", "main": "./dist/plyr.js",

View File

@ -128,7 +128,7 @@ See [initialising](#initialising) for more information on advanced setups.
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript, you can use the following: If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript, you can use the following:
```html ```html
<script src="https://cdn.plyr.io/3.0.10/plyr.js"></script> <script src="https://cdn.plyr.io/3.0.11/plyr.js"></script>
``` ```
_Note_: Be sure to read the [polyfills](#polyfills) section below about browser compatibility _Note_: Be sure to read the [polyfills](#polyfills) section below about browser compatibility
@ -144,13 +144,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.0.10/plyr.css"> <link rel="stylesheet" href="https://cdn.plyr.io/3.0.11/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.0.10/plyr.svg`. reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.0.11/plyr.svg`.
## Ads ## Ads

View File

@ -56,7 +56,7 @@ const defaults = {
// Sprite (for icons) // Sprite (for icons)
loadSprite: true, loadSprite: true,
iconPrefix: 'plyr', iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/3.0.10/plyr.svg', iconUrl: 'https://cdn.plyr.io/3.0.11/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',

View File

@ -278,18 +278,28 @@ class Listeners {
// Check for buffer progress // Check for buffer progress
utils.on(this.player.media, 'progress playing', event => ui.updateProgress.call(this.player, event)); utils.on(this.player.media, 'progress playing', event => ui.updateProgress.call(this.player, event));
// Handle native mute // Handle volume changes
utils.on(this.player.media, 'volumechange', event => ui.updateVolume.call(this.player, event)); utils.on(this.player.media, 'volumechange', event => ui.updateVolume.call(this.player, event));
// Handle native play/pause // Handle play/pause
utils.on(this.player.media, 'playing play pause ended emptied', event => ui.checkPlaying.call(this.player, event)); utils.on(this.player.media, 'playing play pause ended emptied', event => ui.checkPlaying.call(this.player, event));
// Loading // Loading state
utils.on(this.player.media, 'waiting canplay seeked playing', event => ui.checkLoading.call(this.player, event)); utils.on(this.player.media, 'waiting canplay seeked playing', event => ui.checkLoading.call(this.player, event));
// Check if media failed to load // Check if media failed to load
// utils.on(this.player.media, 'play', event => ui.checkFailed.call(this.player, event)); // utils.on(this.player.media, 'play', event => ui.checkFailed.call(this.player, event));
// If autoplay, then load advertisement if required
// TODO: Show some sort of loading state while the ad manager loads else there's a delay before ad shows
utils.on(this.player.media, 'playing', () => {
// If ads are enabled, wait for them first
if (this.player.ads.enabled && !this.player.ads.initialized) {
// Wait for manager response
this.player.ads.managerPromise.then(() => this.player.ads.play()).catch(() => this.player.play());
}
});
// Click video // Click video
if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) { if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) {
// Re-fetch the wrapper // Re-fetch the wrapper

View File

@ -206,11 +206,12 @@ class Ads {
this.cuePoints = this.manager.getCuePoints(); this.cuePoints = this.manager.getCuePoints();
// Add advertisement cue's within the time line if available // Add advertisement cue's within the time line if available
if (!utils.is.empty(this.cuePoints)) {
this.cuePoints.forEach(cuePoint => { this.cuePoints.forEach(cuePoint => {
if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < this.player.duration) { if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < this.player.duration) {
const seekElement = this.player.elements.progress; const seekElement = this.player.elements.progress;
if (seekElement) { if (utils.is.element(seekElement)) {
const cuePercentage = 100 / this.player.duration * cuePoint; const cuePercentage = 100 / this.player.duration * cuePoint;
const cue = utils.createElement('span', { const cue = utils.createElement('span', {
class: this.player.config.classNames.cues, class: this.player.config.classNames.cues,
@ -221,6 +222,7 @@ class Ads {
} }
} }
}); });
}
// Get skippable state // Get skippable state
// TODO: Skip button // TODO: Skip button
@ -385,6 +387,10 @@ class Ads {
this.player.on('seeked', () => { this.player.on('seeked', () => {
const seekedTime = this.player.currentTime; const seekedTime = this.player.currentTime;
if (utils.is.empty(this.cuePoints)) {
return;
}
this.cuePoints.forEach((cuePoint, index) => { this.cuePoints.forEach((cuePoint, index) => {
if (time < cuePoint && cuePoint < seekedTime) { if (time < cuePoint && cuePoint < seekedTime) {
this.manager.discardAdBreak(); this.manager.discardAdBreak();
@ -396,7 +402,9 @@ class Ads {
// Listen to the resizing of the window. And resize ad accordingly // Listen to the resizing of the window. And resize ad accordingly
// TODO: eventually implement ResizeObserver // TODO: eventually implement ResizeObserver
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
if (this.manager) {
this.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL); this.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);
}
}); });
} }

View File

@ -1,6 +1,6 @@
// ========================================================================== // ==========================================================================
// Plyr // Plyr
// plyr.js v3.0.10 // plyr.js v3.0.11
// https://github.com/sampotts/plyr // https://github.com/sampotts/plyr
// License: The MIT License (MIT) // License: The MIT License (MIT)
// ========================================================================== // ==========================================================================
@ -133,7 +133,17 @@ class Plyr {
} }
// Cache original element state for .destroy() // Cache original element state for .destroy()
this.elements.original = this.media.cloneNode(true); // TODO: Investigate a better solution as I suspect this causes reported double load issues?
setTimeout(() => {
const clone = this.media.cloneNode(true);
// Prevent the clone autoplaying
if (clone.getAttribute('autoplay')) {
clone.pause();
}
this.elements.original = clone;
}, 0);
// Set media type based on tag or data attribute // Set media type based on tag or data attribute
// Supported: video, audio, vimeo, youtube // Supported: video, audio, vimeo, youtube
@ -286,6 +296,11 @@ class Plyr {
// Setup ads if provided // Setup ads if provided
this.ads = new Ads(this); this.ads = new Ads(this);
// Autoplay if required
if (this.config.autoplay) {
this.play();
}
} }
// --------------------------------------- // ---------------------------------------
@ -323,9 +338,9 @@ class Plyr {
} }
// If ads are enabled, wait for them first // If ads are enabled, wait for them first
if (this.ads.enabled && !this.ads.initialized) { /* if (this.ads.enabled && !this.ads.initialized) {
return this.ads.managerPromise.then(() => this.ads.play()).catch(() => this.media.play()); return this.ads.managerPromise.then(() => this.ads.play()).catch(() => this.media.play());
} } */
// Return the promise (for HTML5) // Return the promise (for HTML5)
return this.media.play(); return this.media.play();
@ -384,7 +399,7 @@ class Plyr {
stop() { stop() {
if (this.isHTML5) { if (this.isHTML5) {
this.media.load(); this.media.load();
} else { } else if (utils.is.function(this.media.stop)) {
this.media.stop(); this.media.stop();
} }
} }
@ -524,8 +539,8 @@ class Plyr {
// Set the player volume // Set the player volume
this.media.volume = volume; this.media.volume = volume;
// If muted, and we're increasing volume, reset muted state // If muted, and we're increasing volume manually, reset muted state
if (this.muted && volume > 0) { if (!utils.is.empty(value) && this.muted && volume > 0) {
this.muted = false; this.muted = false;
} }
} }
@ -1019,6 +1034,11 @@ class Plyr {
// then set the timer to hide the controls // then set the timer to hide the controls
if (!show || this.playing) { if (!show || this.playing) {
this.timers.controls = setTimeout(() => { this.timers.controls = setTimeout(() => {
// We need controls of course...
if (!utils.is.element(this.elements.controls)) {
return;
}
// If the mouse is over the controls (and not entering fullscreen), bail // If the mouse is over the controls (and not entering fullscreen), bail
if ((this.elements.controls.pressed || this.elements.controls.hover) && !isEnterFullscreen) { if ((this.elements.controls.pressed || this.elements.controls.hover) && !isEnterFullscreen) {
return; return;

View File

@ -1,6 +1,6 @@
// ========================================================================== // ==========================================================================
// Plyr Polyfilled Build // Plyr Polyfilled Build
// plyr.js v3.0.10 // plyr.js v3.0.11
// https://github.com/sampotts/plyr // https://github.com/sampotts/plyr
// License: The MIT License (MIT) // License: The MIT License (MIT)
// ========================================================================== // ==========================================================================

View File

@ -74,6 +74,9 @@ const ui = {
// Reset quality options // Reset quality options
this.options.quality = []; this.options.quality = [];
// Reset volume display
ui.updateVolume.call(this);
// Reset time display // Reset time display
ui.timeUpdate.call(this); ui.timeUpdate.call(this);