Ads bug fixes

This commit is contained in:
Sam Potts 2019-02-01 00:24:48 +11:00
parent d0e3c7c6d0
commit eb628c8e4f
27 changed files with 406 additions and 296 deletions

126
demo/dist/demo.js vendored
View File

@ -4255,6 +4255,10 @@ typeof navigator === "object" && (function () {
return instanceOf(input, TextTrack) || !isNullOrUndefined(input) && isString$2(input.kind);
};
var isPromise = function isPromise(input) {
return instanceOf(input, Promise);
};
var isEmpty = function isEmpty(input) {
return isNullOrUndefined(input) || (isString$2(input) || isArray$2(input) || isNodeList(input)) && !input.length || isObject$2(input) && !Object.keys(input).length;
};
@ -4300,6 +4304,7 @@ typeof navigator === "object" && (function () {
keyboardEvent: isKeyboardEvent,
cue: isCue,
track: isTrack,
promise: isPromise,
url: isUrl,
empty: isEmpty
};
@ -4791,6 +4796,28 @@ typeof navigator === "object" && (function () {
ui: ui
};
},
// Detect support for autoplay
/* autoplay: (() => {
const video = document.createElement('video');
video.src = 'https://cdn.plyr.io/static/blank.mp4';
const promise = video.play();
if (is.promise(promise)) {
console.warn('PROMISE', promise);
promise
.then(() => {
console.warn('supported');
return true;
})
.catch(() => {
console.warn('not supported');
return false;
});
} else {
console.warn('supported - no promise');
return true;
}
})(), */
// Picture-in-picture support
// Safari & Chrome only currently
pip: function () {
@ -7283,7 +7310,7 @@ typeof navigator === "object" && (function () {
// Sprite (for icons)
loadSprite: true,
iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/3.4.8/plyr.svg',
iconUrl: 'https://cdn.plyr.io/3.5.0-beta.3/plyr.svg',
// Blank video (used to prevent errors on source change)
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
// Quality default
@ -8603,23 +8630,6 @@ typeof navigator === "object" && (function () {
on.call(player, player.media, 'waiting canplay seeked playing', function (event) {
return ui.checkLoading.call(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
on.call(player, player.media, 'playing', function () {
if (!player.ads) {
return;
} // If ads are enabled, wait for them first
if (player.ads.enabled && !player.ads.initialized) {
// Wait for manager response
player.ads.managerPromise.then(function () {
return player.ads.play();
}).catch(function () {
return player.play();
});
}
}); // Click video
if (player.supported.ui && player.config.clickToPlay && !player.isAudio) {
@ -10180,10 +10190,11 @@ typeof navigator === "object" && (function () {
google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED); // Set language
google.ima.settings.setLocale(this.player.config.ads.language); // We assume the adContainer is the video container of the plyr element
// that will house the ads
google.ima.settings.setLocale(this.player.config.ads.language); // Set playback for iOS10+
this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container); // Request video ads to be pre-loaded
google.ima.settings.setDisableCustomPlaybackForIOS10Plus(this.player.config.playsinline); // We assume the adContainer is the video container of the plyr element that will house the ads
this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container, this.player.media); // Request video ads to be pre-loaded
this.requestAds();
}
@ -10523,11 +10534,9 @@ typeof navigator === "object" && (function () {
// Hide the advertisement container
this.elements.container.style.zIndex = ''; // Ad is stopped
this.playing = false; // Play our video
this.playing = false; // Play video
if (this.player.currentTime < this.player.duration) {
this.player.play();
}
this.player.media.play();
}
/**
* Pause our video
@ -10537,11 +10546,11 @@ typeof navigator === "object" && (function () {
key: "pauseContent",
value: function pauseContent() {
// Show the advertisement container
this.elements.container.style.zIndex = 3; // Ad is playing.
this.elements.container.style.zIndex = 3; // Ad is playing
this.playing = true; // Pause our video.
this.player.pause();
this.player.media.pause();
}
/**
* Destroy the adsManager so we can grab new ads after this. If we don't then we're not
@ -10930,8 +10939,8 @@ typeof navigator === "object" && (function () {
}
}
}, {
key: "finishScrubbing",
value: function finishScrubbing() {
key: "endScrubbing",
value: function endScrubbing() {
var _this4 = this;
this.mouseDown = false; // Hide scrubbing preview. But wait until the video has successfully seeked before hiding the scrubbing preview
@ -11773,8 +11782,19 @@ typeof navigator === "object" && (function () {
* Play the media, or play the advertisement (if they are not blocked)
*/
value: function play() {
var _this2 = this;
if (!is.function(this.media.play)) {
return null;
} // Intecept play with ads
if (this.ads && this.ads.enabled) {
this.ads.managerPromise.then(function () {
return _this2.ads.play();
}).catch(function () {
return _this2.media.play();
});
} // Return the promise (for HTML5)
@ -11992,7 +12012,7 @@ typeof navigator === "object" && (function () {
}, {
key: "destroy",
value: function destroy(callback) {
var _this2 = this;
var _this3 = this;
var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@ -12004,20 +12024,20 @@ typeof navigator === "object" && (function () {
// Reset overflow (incase destroyed while in fullscreen)
document.body.style.overflow = ''; // GC for embed
_this2.embed = null; // If it's a soft destroy, make minimal changes
_this3.embed = null; // If it's a soft destroy, make minimal changes
if (soft) {
if (Object.keys(_this2.elements).length) {
if (Object.keys(_this3.elements).length) {
// Remove elements
removeElement(_this2.elements.buttons.play);
removeElement(_this2.elements.captions);
removeElement(_this2.elements.controls);
removeElement(_this2.elements.wrapper); // Clear for GC
removeElement(_this3.elements.buttons.play);
removeElement(_this3.elements.captions);
removeElement(_this3.elements.controls);
removeElement(_this3.elements.wrapper); // Clear for GC
_this2.elements.buttons.play = null;
_this2.elements.captions = null;
_this2.elements.controls = null;
_this2.elements.wrapper = null;
_this3.elements.buttons.play = null;
_this3.elements.captions = null;
_this3.elements.controls = null;
_this3.elements.wrapper = null;
} // Callback
@ -12026,22 +12046,22 @@ typeof navigator === "object" && (function () {
}
} else {
// Unbind listeners
unbindListeners.call(_this2); // Replace the container with the original element provided
unbindListeners.call(_this3); // Replace the container with the original element provided
replaceElement(_this2.elements.original, _this2.elements.container); // Event
replaceElement(_this3.elements.original, _this3.elements.container); // Event
triggerEvent.call(_this2, _this2.elements.original, 'destroyed', true); // Callback
triggerEvent.call(_this3, _this3.elements.original, 'destroyed', true); // Callback
if (is.function(callback)) {
callback.call(_this2.elements.original);
callback.call(_this3.elements.original);
} // Reset state
_this2.ready = false; // Clear for garbage collection
_this3.ready = false; // Clear for garbage collection
setTimeout(function () {
_this2.elements = null;
_this2.media = null;
_this3.elements = null;
_this3.media = null;
}, 200);
}
}; // Stop playback
@ -12723,7 +12743,12 @@ typeof navigator === "object" && (function () {
focused.classList.add(tabClassName);
}, 10);
}); // Setup the player
});
var userType = 'annon';
var contentType = 'on-demand';
var cmsid = 2490180;
var vid = 3788;
var tagUrl = "https://pubads.g.doubleclick.net/gampad/live/ads?sz=640x360&iu=/21736521837/ovo/web&impl=s&gdfp_req=1&env=vp&output=vast&cust_params=usergroup%3D".concat(userType, "%26content-type%3D").concat(contentType, "&cmsid=").concat(cmsid, "&vid=").concat(vid); // Setup the player
var player = new Plyr(selector, {
debug: true,
@ -12742,8 +12767,9 @@ typeof navigator === "object" && (function () {
google: 'AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c'
},
ads: {
enabled: env.prod || env.dev,
publisherId: '918848828995742'
enabled: true,
// env.prod || env.dev,
tagUrl: tagUrl
},
previewThumbnails: {
enabled: true,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -58,6 +58,13 @@ import Plyr from '../../../src/js/plyr';
}, 10);
});
const userType = 'annon';
const contentType = 'on-demand';
const cmsid = 2490180;
const vid = 3788;
const tagUrl = `https://pubads.g.doubleclick.net/gampad/live/ads?sz=640x360&iu=/21736521837/ovo/web&impl=s&gdfp_req=1&env=vp&output=vast&cust_params=usergroup%3D${userType}%26content-type%3D${contentType}&cmsid=${cmsid}&vid=${vid}`;
// Setup the player
const player = new Plyr(selector, {
debug: true,
@ -76,8 +83,8 @@ import Plyr from '../../../src/js/plyr';
google: 'AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c',
},
ads: {
enabled: env.prod || env.dev,
publisherId: '918848828995742',
enabled: true, // env.prod || env.dev,
tagUrl,
},
previewThumbnails: {
enabled: true,

114
dist/plyr.js vendored
View File

@ -170,6 +170,10 @@ typeof navigator === "object" && (function (global, factory) {
return instanceOf(input, TextTrack) || !isNullOrUndefined(input) && isString(input.kind);
};
var isPromise = function isPromise(input) {
return instanceOf(input, Promise);
};
var isEmpty = function isEmpty(input) {
return isNullOrUndefined(input) || (isString(input) || isArray(input) || isNodeList(input)) && !input.length || isObject(input) && !Object.keys(input).length;
};
@ -215,6 +219,7 @@ typeof navigator === "object" && (function (global, factory) {
keyboardEvent: isKeyboardEvent,
cue: isCue,
track: isTrack,
promise: isPromise,
url: isUrl,
empty: isEmpty
};
@ -706,6 +711,28 @@ typeof navigator === "object" && (function (global, factory) {
ui: ui
};
},
// Detect support for autoplay
/* autoplay: (() => {
const video = document.createElement('video');
video.src = 'https://cdn.plyr.io/static/blank.mp4';
const promise = video.play();
if (is.promise(promise)) {
console.warn('PROMISE', promise);
promise
.then(() => {
console.warn('supported');
return true;
})
.catch(() => {
console.warn('not supported');
return false;
});
} else {
console.warn('supported - no promise');
return true;
}
})(), */
// Picture-in-picture support
// Safari & Chrome only currently
pip: function () {
@ -3198,7 +3225,7 @@ typeof navigator === "object" && (function (global, factory) {
// Sprite (for icons)
loadSprite: true,
iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/3.4.8/plyr.svg',
iconUrl: 'https://cdn.plyr.io/3.5.0-beta.3/plyr.svg',
// Blank video (used to prevent errors on source change)
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
// Quality default
@ -4518,23 +4545,6 @@ typeof navigator === "object" && (function (global, factory) {
on.call(player, player.media, 'waiting canplay seeked playing', function (event) {
return ui.checkLoading.call(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
on.call(player, player.media, 'playing', function () {
if (!player.ads) {
return;
} // If ads are enabled, wait for them first
if (player.ads.enabled && !player.ads.initialized) {
// Wait for manager response
player.ads.managerPromise.then(function () {
return player.ads.play();
}).catch(function () {
return player.play();
});
}
}); // Click video
if (player.supported.ui && player.config.clickToPlay && !player.isAudio) {
@ -6101,10 +6111,11 @@ typeof navigator === "object" && (function (global, factory) {
google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED); // Set language
google.ima.settings.setLocale(this.player.config.ads.language); // We assume the adContainer is the video container of the plyr element
// that will house the ads
google.ima.settings.setLocale(this.player.config.ads.language); // Set playback for iOS10+
this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container); // Request video ads to be pre-loaded
google.ima.settings.setDisableCustomPlaybackForIOS10Plus(this.player.config.playsinline); // We assume the adContainer is the video container of the plyr element that will house the ads
this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container, this.player.media); // Request video ads to be pre-loaded
this.requestAds();
}
@ -6444,11 +6455,9 @@ typeof navigator === "object" && (function (global, factory) {
// Hide the advertisement container
this.elements.container.style.zIndex = ''; // Ad is stopped
this.playing = false; // Play our video
this.playing = false; // Play video
if (this.player.currentTime < this.player.duration) {
this.player.play();
}
this.player.media.play();
}
/**
* Pause our video
@ -6458,11 +6467,11 @@ typeof navigator === "object" && (function (global, factory) {
key: "pauseContent",
value: function pauseContent() {
// Show the advertisement container
this.elements.container.style.zIndex = 3; // Ad is playing.
this.elements.container.style.zIndex = 3; // Ad is playing
this.playing = true; // Pause our video.
this.player.pause();
this.player.media.pause();
}
/**
* Destroy the adsManager so we can grab new ads after this. If we don't then we're not
@ -6851,8 +6860,8 @@ typeof navigator === "object" && (function (global, factory) {
}
}
}, {
key: "finishScrubbing",
value: function finishScrubbing() {
key: "endScrubbing",
value: function endScrubbing() {
var _this4 = this;
this.mouseDown = false; // Hide scrubbing preview. But wait until the video has successfully seeked before hiding the scrubbing preview
@ -7694,8 +7703,19 @@ typeof navigator === "object" && (function (global, factory) {
* Play the media, or play the advertisement (if they are not blocked)
*/
value: function play() {
var _this2 = this;
if (!is.function(this.media.play)) {
return null;
} // Intecept play with ads
if (this.ads && this.ads.enabled) {
this.ads.managerPromise.then(function () {
return _this2.ads.play();
}).catch(function () {
return _this2.media.play();
});
} // Return the promise (for HTML5)
@ -7913,7 +7933,7 @@ typeof navigator === "object" && (function (global, factory) {
}, {
key: "destroy",
value: function destroy(callback) {
var _this2 = this;
var _this3 = this;
var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@ -7925,20 +7945,20 @@ typeof navigator === "object" && (function (global, factory) {
// Reset overflow (incase destroyed while in fullscreen)
document.body.style.overflow = ''; // GC for embed
_this2.embed = null; // If it's a soft destroy, make minimal changes
_this3.embed = null; // If it's a soft destroy, make minimal changes
if (soft) {
if (Object.keys(_this2.elements).length) {
if (Object.keys(_this3.elements).length) {
// Remove elements
removeElement(_this2.elements.buttons.play);
removeElement(_this2.elements.captions);
removeElement(_this2.elements.controls);
removeElement(_this2.elements.wrapper); // Clear for GC
removeElement(_this3.elements.buttons.play);
removeElement(_this3.elements.captions);
removeElement(_this3.elements.controls);
removeElement(_this3.elements.wrapper); // Clear for GC
_this2.elements.buttons.play = null;
_this2.elements.captions = null;
_this2.elements.controls = null;
_this2.elements.wrapper = null;
_this3.elements.buttons.play = null;
_this3.elements.captions = null;
_this3.elements.controls = null;
_this3.elements.wrapper = null;
} // Callback
@ -7947,22 +7967,22 @@ typeof navigator === "object" && (function (global, factory) {
}
} else {
// Unbind listeners
unbindListeners.call(_this2); // Replace the container with the original element provided
unbindListeners.call(_this3); // Replace the container with the original element provided
replaceElement(_this2.elements.original, _this2.elements.container); // Event
replaceElement(_this3.elements.original, _this3.elements.container); // Event
triggerEvent.call(_this2, _this2.elements.original, 'destroyed', true); // Callback
triggerEvent.call(_this3, _this3.elements.original, 'destroyed', true); // Callback
if (is.function(callback)) {
callback.call(_this2.elements.original);
callback.call(_this3.elements.original);
} // Reset state
_this2.ready = false; // Clear for garbage collection
_this3.ready = false; // Clear for garbage collection
setTimeout(function () {
_this2.elements = null;
_this2.media = null;
_this3.elements = null;
_this3.media = null;
}, 200);
}
}; // Stop playback

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

2
dist/plyr.min.mjs vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

114
dist/plyr.mjs vendored
View File

@ -164,6 +164,10 @@ var isTrack = function isTrack(input) {
return instanceOf(input, TextTrack) || !isNullOrUndefined(input) && isString(input.kind);
};
var isPromise = function isPromise(input) {
return instanceOf(input, Promise);
};
var isEmpty = function isEmpty(input) {
return isNullOrUndefined(input) || (isString(input) || isArray(input) || isNodeList(input)) && !input.length || isObject(input) && !Object.keys(input).length;
};
@ -209,6 +213,7 @@ var is = {
keyboardEvent: isKeyboardEvent,
cue: isCue,
track: isTrack,
promise: isPromise,
url: isUrl,
empty: isEmpty
};
@ -700,6 +705,28 @@ var support = {
ui: ui
};
},
// Detect support for autoplay
/* autoplay: (() => {
const video = document.createElement('video');
video.src = 'https://cdn.plyr.io/static/blank.mp4';
const promise = video.play();
if (is.promise(promise)) {
console.warn('PROMISE', promise);
promise
.then(() => {
console.warn('supported');
return true;
})
.catch(() => {
console.warn('not supported');
return false;
});
} else {
console.warn('supported - no promise');
return true;
}
})(), */
// Picture-in-picture support
// Safari & Chrome only currently
pip: function () {
@ -3192,7 +3219,7 @@ var defaults = {
// Sprite (for icons)
loadSprite: true,
iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/3.4.8/plyr.svg',
iconUrl: 'https://cdn.plyr.io/3.5.0-beta.3/plyr.svg',
// Blank video (used to prevent errors on source change)
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
// Quality default
@ -4512,23 +4539,6 @@ function () {
on.call(player, player.media, 'waiting canplay seeked playing', function (event) {
return ui.checkLoading.call(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
on.call(player, player.media, 'playing', function () {
if (!player.ads) {
return;
} // If ads are enabled, wait for them first
if (player.ads.enabled && !player.ads.initialized) {
// Wait for manager response
player.ads.managerPromise.then(function () {
return player.ads.play();
}).catch(function () {
return player.play();
});
}
}); // Click video
if (player.supported.ui && player.config.clickToPlay && !player.isAudio) {
@ -6095,10 +6105,11 @@ function () {
google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED); // Set language
google.ima.settings.setLocale(this.player.config.ads.language); // We assume the adContainer is the video container of the plyr element
// that will house the ads
google.ima.settings.setLocale(this.player.config.ads.language); // Set playback for iOS10+
this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container); // Request video ads to be pre-loaded
google.ima.settings.setDisableCustomPlaybackForIOS10Plus(this.player.config.playsinline); // We assume the adContainer is the video container of the plyr element that will house the ads
this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container, this.player.media); // Request video ads to be pre-loaded
this.requestAds();
}
@ -6438,11 +6449,9 @@ function () {
// Hide the advertisement container
this.elements.container.style.zIndex = ''; // Ad is stopped
this.playing = false; // Play our video
this.playing = false; // Play video
if (this.player.currentTime < this.player.duration) {
this.player.play();
}
this.player.media.play();
}
/**
* Pause our video
@ -6452,11 +6461,11 @@ function () {
key: "pauseContent",
value: function pauseContent() {
// Show the advertisement container
this.elements.container.style.zIndex = 3; // Ad is playing.
this.elements.container.style.zIndex = 3; // Ad is playing
this.playing = true; // Pause our video.
this.player.pause();
this.player.media.pause();
}
/**
* Destroy the adsManager so we can grab new ads after this. If we don't then we're not
@ -6845,8 +6854,8 @@ function () {
}
}
}, {
key: "finishScrubbing",
value: function finishScrubbing() {
key: "endScrubbing",
value: function endScrubbing() {
var _this4 = this;
this.mouseDown = false; // Hide scrubbing preview. But wait until the video has successfully seeked before hiding the scrubbing preview
@ -7688,8 +7697,19 @@ function () {
* Play the media, or play the advertisement (if they are not blocked)
*/
value: function play() {
var _this2 = this;
if (!is.function(this.media.play)) {
return null;
} // Intecept play with ads
if (this.ads && this.ads.enabled) {
this.ads.managerPromise.then(function () {
return _this2.ads.play();
}).catch(function () {
return _this2.media.play();
});
} // Return the promise (for HTML5)
@ -7907,7 +7927,7 @@ function () {
}, {
key: "destroy",
value: function destroy(callback) {
var _this2 = this;
var _this3 = this;
var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@ -7919,20 +7939,20 @@ function () {
// Reset overflow (incase destroyed while in fullscreen)
document.body.style.overflow = ''; // GC for embed
_this2.embed = null; // If it's a soft destroy, make minimal changes
_this3.embed = null; // If it's a soft destroy, make minimal changes
if (soft) {
if (Object.keys(_this2.elements).length) {
if (Object.keys(_this3.elements).length) {
// Remove elements
removeElement(_this2.elements.buttons.play);
removeElement(_this2.elements.captions);
removeElement(_this2.elements.controls);
removeElement(_this2.elements.wrapper); // Clear for GC
removeElement(_this3.elements.buttons.play);
removeElement(_this3.elements.captions);
removeElement(_this3.elements.controls);
removeElement(_this3.elements.wrapper); // Clear for GC
_this2.elements.buttons.play = null;
_this2.elements.captions = null;
_this2.elements.controls = null;
_this2.elements.wrapper = null;
_this3.elements.buttons.play = null;
_this3.elements.captions = null;
_this3.elements.controls = null;
_this3.elements.wrapper = null;
} // Callback
@ -7941,22 +7961,22 @@ function () {
}
} else {
// Unbind listeners
unbindListeners.call(_this2); // Replace the container with the original element provided
unbindListeners.call(_this3); // Replace the container with the original element provided
replaceElement(_this2.elements.original, _this2.elements.container); // Event
replaceElement(_this3.elements.original, _this3.elements.container); // Event
triggerEvent.call(_this2, _this2.elements.original, 'destroyed', true); // Callback
triggerEvent.call(_this3, _this3.elements.original, 'destroyed', true); // Callback
if (is.function(callback)) {
callback.call(_this2.elements.original);
callback.call(_this3.elements.original);
} // Reset state
_this2.ready = false; // Clear for garbage collection
_this3.ready = false; // Clear for garbage collection
setTimeout(function () {
_this2.elements = null;
_this2.media = null;
_this3.elements = null;
_this3.media = null;
}, 200);
}
}; // Stop playback

View File

@ -3189,6 +3189,10 @@ typeof navigator === "object" && (function (global, factory) {
return instanceOf(input, TextTrack) || !isNullOrUndefined(input) && isString(input.kind);
};
var isPromise = function isPromise(input) {
return instanceOf(input, Promise);
};
var isEmpty = function isEmpty(input) {
return isNullOrUndefined(input) || (isString(input) || isArray(input) || isNodeList(input)) && !input.length || isObject(input) && !Object.keys(input).length;
};
@ -3234,6 +3238,7 @@ typeof navigator === "object" && (function (global, factory) {
keyboardEvent: isKeyboardEvent,
cue: isCue,
track: isTrack,
promise: isPromise,
url: isUrl,
empty: isEmpty
};
@ -3723,6 +3728,28 @@ typeof navigator === "object" && (function (global, factory) {
ui: ui
};
},
// Detect support for autoplay
/* autoplay: (() => {
const video = document.createElement('video');
video.src = 'https://cdn.plyr.io/static/blank.mp4';
const promise = video.play();
if (is.promise(promise)) {
console.warn('PROMISE', promise);
promise
.then(() => {
console.warn('supported');
return true;
})
.catch(() => {
console.warn('not supported');
return false;
});
} else {
console.warn('supported - no promise');
return true;
}
})(), */
// Picture-in-picture support
// Safari & Chrome only currently
pip: function () {
@ -6261,7 +6288,7 @@ typeof navigator === "object" && (function (global, factory) {
// Sprite (for icons)
loadSprite: true,
iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/3.4.8/plyr.svg',
iconUrl: 'https://cdn.plyr.io/3.5.0-beta.3/plyr.svg',
// Blank video (used to prevent errors on source change)
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
// Quality default
@ -7591,23 +7618,6 @@ typeof navigator === "object" && (function (global, factory) {
on.call(player, player.media, 'waiting canplay seeked playing', function (event) {
return ui.checkLoading.call(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
on.call(player, player.media, 'playing', function () {
if (!player.ads) {
return;
} // If ads are enabled, wait for them first
if (player.ads.enabled && !player.ads.initialized) {
// Wait for manager response
player.ads.managerPromise.then(function () {
return player.ads.play();
}).catch(function () {
return player.play();
});
}
}); // Click video
if (player.supported.ui && player.config.clickToPlay && !player.isAudio) {
@ -9215,10 +9225,11 @@ typeof navigator === "object" && (function (global, factory) {
google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED); // Set language
google.ima.settings.setLocale(this.player.config.ads.language); // We assume the adContainer is the video container of the plyr element
// that will house the ads
google.ima.settings.setLocale(this.player.config.ads.language); // Set playback for iOS10+
this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container); // Request video ads to be pre-loaded
google.ima.settings.setDisableCustomPlaybackForIOS10Plus(this.player.config.playsinline); // We assume the adContainer is the video container of the plyr element that will house the ads
this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container, this.player.media); // Request video ads to be pre-loaded
this.requestAds();
}
@ -9558,11 +9569,9 @@ typeof navigator === "object" && (function (global, factory) {
// Hide the advertisement container
this.elements.container.style.zIndex = ''; // Ad is stopped
this.playing = false; // Play our video
this.playing = false; // Play video
if (this.player.currentTime < this.player.duration) {
this.player.play();
}
this.player.media.play();
}
/**
* Pause our video
@ -9572,11 +9581,11 @@ typeof navigator === "object" && (function (global, factory) {
key: "pauseContent",
value: function pauseContent() {
// Show the advertisement container
this.elements.container.style.zIndex = 3; // Ad is playing.
this.elements.container.style.zIndex = 3; // Ad is playing
this.playing = true; // Pause our video.
this.player.pause();
this.player.media.pause();
}
/**
* Destroy the adsManager so we can grab new ads after this. If we don't then we're not
@ -9979,8 +9988,8 @@ typeof navigator === "object" && (function (global, factory) {
}
}
}, {
key: "finishScrubbing",
value: function finishScrubbing() {
key: "endScrubbing",
value: function endScrubbing() {
var _this4 = this;
this.mouseDown = false; // Hide scrubbing preview. But wait until the video has successfully seeked before hiding the scrubbing preview
@ -10822,8 +10831,19 @@ typeof navigator === "object" && (function (global, factory) {
* Play the media, or play the advertisement (if they are not blocked)
*/
value: function play() {
var _this2 = this;
if (!is$1.function(this.media.play)) {
return null;
} // Intecept play with ads
if (this.ads && this.ads.enabled) {
this.ads.managerPromise.then(function () {
return _this2.ads.play();
}).catch(function () {
return _this2.media.play();
});
} // Return the promise (for HTML5)
@ -11041,7 +11061,7 @@ typeof navigator === "object" && (function (global, factory) {
}, {
key: "destroy",
value: function destroy(callback) {
var _this2 = this;
var _this3 = this;
var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@ -11053,20 +11073,20 @@ typeof navigator === "object" && (function (global, factory) {
// Reset overflow (incase destroyed while in fullscreen)
document.body.style.overflow = ''; // GC for embed
_this2.embed = null; // If it's a soft destroy, make minimal changes
_this3.embed = null; // If it's a soft destroy, make minimal changes
if (soft) {
if (Object.keys(_this2.elements).length) {
if (Object.keys(_this3.elements).length) {
// Remove elements
removeElement(_this2.elements.buttons.play);
removeElement(_this2.elements.captions);
removeElement(_this2.elements.controls);
removeElement(_this2.elements.wrapper); // Clear for GC
removeElement(_this3.elements.buttons.play);
removeElement(_this3.elements.captions);
removeElement(_this3.elements.controls);
removeElement(_this3.elements.wrapper); // Clear for GC
_this2.elements.buttons.play = null;
_this2.elements.captions = null;
_this2.elements.controls = null;
_this2.elements.wrapper = null;
_this3.elements.buttons.play = null;
_this3.elements.captions = null;
_this3.elements.controls = null;
_this3.elements.wrapper = null;
} // Callback
@ -11075,22 +11095,22 @@ typeof navigator === "object" && (function (global, factory) {
}
} else {
// Unbind listeners
unbindListeners.call(_this2); // Replace the container with the original element provided
unbindListeners.call(_this3); // Replace the container with the original element provided
replaceElement(_this2.elements.original, _this2.elements.container); // Event
replaceElement(_this3.elements.original, _this3.elements.container); // Event
triggerEvent.call(_this2, _this2.elements.original, 'destroyed', true); // Callback
triggerEvent.call(_this3, _this3.elements.original, 'destroyed', true); // Callback
if (is$1.function(callback)) {
callback.call(_this2.elements.original);
callback.call(_this3.elements.original);
} // Reset state
_this2.ready = false; // Clear for garbage collection
_this3.ready = false; // Clear for garbage collection
setTimeout(function () {
_this2.elements = null;
_this2.media = null;
_this3.elements = null;
_this3.media = null;
}, 200);
}
}; // Stop playback

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

File diff suppressed because one or more lines are too long

View File

@ -3183,6 +3183,10 @@ var isTrack = function isTrack(input) {
return instanceOf(input, TextTrack) || !isNullOrUndefined(input) && isString(input.kind);
};
var isPromise = function isPromise(input) {
return instanceOf(input, Promise);
};
var isEmpty = function isEmpty(input) {
return isNullOrUndefined(input) || (isString(input) || isArray(input) || isNodeList(input)) && !input.length || isObject(input) && !Object.keys(input).length;
};
@ -3228,6 +3232,7 @@ var is$1 = {
keyboardEvent: isKeyboardEvent,
cue: isCue,
track: isTrack,
promise: isPromise,
url: isUrl,
empty: isEmpty
};
@ -3717,6 +3722,28 @@ var support = {
ui: ui
};
},
// Detect support for autoplay
/* autoplay: (() => {
const video = document.createElement('video');
video.src = 'https://cdn.plyr.io/static/blank.mp4';
const promise = video.play();
if (is.promise(promise)) {
console.warn('PROMISE', promise);
promise
.then(() => {
console.warn('supported');
return true;
})
.catch(() => {
console.warn('not supported');
return false;
});
} else {
console.warn('supported - no promise');
return true;
}
})(), */
// Picture-in-picture support
// Safari & Chrome only currently
pip: function () {
@ -6255,7 +6282,7 @@ var defaults = {
// Sprite (for icons)
loadSprite: true,
iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/3.4.8/plyr.svg',
iconUrl: 'https://cdn.plyr.io/3.5.0-beta.3/plyr.svg',
// Blank video (used to prevent errors on source change)
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
// Quality default
@ -7585,23 +7612,6 @@ function () {
on.call(player, player.media, 'waiting canplay seeked playing', function (event) {
return ui.checkLoading.call(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
on.call(player, player.media, 'playing', function () {
if (!player.ads) {
return;
} // If ads are enabled, wait for them first
if (player.ads.enabled && !player.ads.initialized) {
// Wait for manager response
player.ads.managerPromise.then(function () {
return player.ads.play();
}).catch(function () {
return player.play();
});
}
}); // Click video
if (player.supported.ui && player.config.clickToPlay && !player.isAudio) {
@ -9209,10 +9219,11 @@ function () {
google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED); // Set language
google.ima.settings.setLocale(this.player.config.ads.language); // We assume the adContainer is the video container of the plyr element
// that will house the ads
google.ima.settings.setLocale(this.player.config.ads.language); // Set playback for iOS10+
this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container); // Request video ads to be pre-loaded
google.ima.settings.setDisableCustomPlaybackForIOS10Plus(this.player.config.playsinline); // We assume the adContainer is the video container of the plyr element that will house the ads
this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container, this.player.media); // Request video ads to be pre-loaded
this.requestAds();
}
@ -9552,11 +9563,9 @@ function () {
// Hide the advertisement container
this.elements.container.style.zIndex = ''; // Ad is stopped
this.playing = false; // Play our video
this.playing = false; // Play video
if (this.player.currentTime < this.player.duration) {
this.player.play();
}
this.player.media.play();
}
/**
* Pause our video
@ -9566,11 +9575,11 @@ function () {
key: "pauseContent",
value: function pauseContent() {
// Show the advertisement container
this.elements.container.style.zIndex = 3; // Ad is playing.
this.elements.container.style.zIndex = 3; // Ad is playing
this.playing = true; // Pause our video.
this.player.pause();
this.player.media.pause();
}
/**
* Destroy the adsManager so we can grab new ads after this. If we don't then we're not
@ -9973,8 +9982,8 @@ function () {
}
}
}, {
key: "finishScrubbing",
value: function finishScrubbing() {
key: "endScrubbing",
value: function endScrubbing() {
var _this4 = this;
this.mouseDown = false; // Hide scrubbing preview. But wait until the video has successfully seeked before hiding the scrubbing preview
@ -10816,8 +10825,19 @@ function () {
* Play the media, or play the advertisement (if they are not blocked)
*/
value: function play() {
var _this2 = this;
if (!is$1.function(this.media.play)) {
return null;
} // Intecept play with ads
if (this.ads && this.ads.enabled) {
this.ads.managerPromise.then(function () {
return _this2.ads.play();
}).catch(function () {
return _this2.media.play();
});
} // Return the promise (for HTML5)
@ -11035,7 +11055,7 @@ function () {
}, {
key: "destroy",
value: function destroy(callback) {
var _this2 = this;
var _this3 = this;
var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@ -11047,20 +11067,20 @@ function () {
// Reset overflow (incase destroyed while in fullscreen)
document.body.style.overflow = ''; // GC for embed
_this2.embed = null; // If it's a soft destroy, make minimal changes
_this3.embed = null; // If it's a soft destroy, make minimal changes
if (soft) {
if (Object.keys(_this2.elements).length) {
if (Object.keys(_this3.elements).length) {
// Remove elements
removeElement(_this2.elements.buttons.play);
removeElement(_this2.elements.captions);
removeElement(_this2.elements.controls);
removeElement(_this2.elements.wrapper); // Clear for GC
removeElement(_this3.elements.buttons.play);
removeElement(_this3.elements.captions);
removeElement(_this3.elements.controls);
removeElement(_this3.elements.wrapper); // Clear for GC
_this2.elements.buttons.play = null;
_this2.elements.captions = null;
_this2.elements.controls = null;
_this2.elements.wrapper = null;
_this3.elements.buttons.play = null;
_this3.elements.captions = null;
_this3.elements.controls = null;
_this3.elements.wrapper = null;
} // Callback
@ -11069,22 +11089,22 @@ function () {
}
} else {
// Unbind listeners
unbindListeners.call(_this2); // Replace the container with the original element provided
unbindListeners.call(_this3); // Replace the container with the original element provided
replaceElement(_this2.elements.original, _this2.elements.container); // Event
replaceElement(_this3.elements.original, _this3.elements.container); // Event
triggerEvent.call(_this2, _this2.elements.original, 'destroyed', true); // Callback
triggerEvent.call(_this3, _this3.elements.original, 'destroyed', true); // Callback
if (is$1.function(callback)) {
callback.call(_this2.elements.original);
callback.call(_this3.elements.original);
} // Reset state
_this2.ready = false; // Clear for garbage collection
_this3.ready = false; // Clear for garbage collection
setTimeout(function () {
_this2.elements = null;
_this2.media = null;
_this3.elements = null;
_this3.media = null;
}, 200);
}
}; // Stop playback

View File

@ -238,6 +238,7 @@ try {
}
// If deployment is setup
// TODO: Use gulp-awspublish and use AWS CLI credentials
if (Object.keys(credentials).includes('aws') && Object.keys(credentials).includes('fastly')) {
const { version } = pkg;
const { aws, fastly } = credentials;
@ -258,7 +259,7 @@ if (Object.keys(credentials).includes('aws') && Object.keys(credentials).include
},
},
demo: {
uploadPath: branch.current === branch.beta ? 'beta/' : null,
uploadPath: branch.current === branch.beta ? 'beta' : null,
headers: {
'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0',
Vary: 'Accept-Encoding',
@ -300,8 +301,9 @@ if (Object.keys(credentials).includes('aws') && Object.keys(credentials).include
return true;
};
gulp.task('version', () => {
gulp.task('version', done => {
if (!canDeploy()) {
done();
return null;
}
@ -318,8 +320,9 @@ if (Object.keys(credentials).includes('aws') && Object.keys(credentials).include
});
// Publish version to CDN bucket
gulp.task('cdn', () => {
gulp.task('cdn', done => {
if (!canDeploy()) {
done();
return null;
}
@ -379,8 +382,9 @@ if (Object.keys(credentials).includes('aws') && Object.keys(credentials).include
});
// Publish to demo bucket
gulp.task('demo', () => {
gulp.task('demo', done => {
if (!canDeploy()) {
done();
return null;
}
@ -407,6 +411,7 @@ if (Object.keys(credentials).includes('aws') && Object.keys(credentials).include
// Only update CDN for master (prod)
if (branch.current !== branch.master) {
done();
return null;
}
@ -441,14 +446,12 @@ if (Object.keys(credentials).includes('aws') && Object.keys(credentials).include
}); */
// Open the demo site to check it's ok
gulp.task('open', callback => {
gulp.src(__filename).pipe(
gulp.task('open', () => {
return gulp.src(__filename).pipe(
open({
uri: `https://${aws.demo.domain}`,
uri: `https://${aws.demo.domain}/${branch.current === branch.beta ? 'beta' : ''}`,
}),
);
callback();
});
// Do everything

View File

@ -1,6 +1,6 @@
{
"name": "plyr",
"version": "3.5.0-beta.1",
"version": "3.5.0-beta.3",
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
"homepage": "https://plyr.io",
"author": "Sam Potts <sam@potts.es>",
@ -44,7 +44,7 @@
"eslint": "^5.12.1",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-config-prettier": "^4.0.0",
"eslint-plugin-import": "^2.15.0",
"eslint-plugin-import": "^2.16.0",
"fastly-purge": "^1.0.1",
"git-branch": "^2.0.1",
"gulp": "^4.0.0",

View File

@ -146,13 +146,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.
```html
<script src="https://cdn.plyr.io/3.4.8/plyr.js"></script>
<script src="https://cdn.plyr.io/3.5.0-beta.3/plyr.js"></script>
```
...or...
```html
<script src="https://cdn.plyr.io/3.4.8/plyr.polyfilled.js"></script>
<script src="https://cdn.plyr.io/3.5.0-beta.3/plyr.polyfilled.js"></script>
```
### CSS
@ -166,13 +166,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:
```html
<link rel="stylesheet" href="https://cdn.plyr.io/3.4.8/plyr.css" />
<link rel="stylesheet" href="https://cdn.plyr.io/3.5.0-beta.3/plyr.css" />
```
### 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
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.4.8/plyr.svg`.
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.5.0-beta.3/plyr.svg`.
## Ads

View File

@ -60,7 +60,7 @@ const defaults = {
// Sprite (for icons)
loadSprite: true,
iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/3.4.8/plyr.svg',
iconUrl: 'https://cdn.plyr.io/3.5.0-beta.3/plyr.svg',
// Blank video (used to prevent errors on source change)
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',

View File

@ -414,20 +414,6 @@ class Listeners {
// Loading state
on.call(player, player.media, 'waiting canplay seeked playing', event => ui.checkLoading.call(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
on.call(player, player.media, 'playing', () => {
if (!player.ads) {
return;
}
// If ads are enabled, wait for them first
if (player.ads.enabled && !player.ads.initialized) {
// Wait for manager response
player.ads.managerPromise.then(() => player.ads.play()).catch(() => player.play());
}
});
// Click video
if (player.supported.ui && player.config.clickToPlay && !player.isAudio) {
// Re-fetch the wrapper

View File

@ -136,6 +136,7 @@ class Ads {
this.elements.container = createElement('div', {
class: this.player.config.classNames.ads,
});
this.player.elements.container.appendChild(this.elements.container);
// So we can run VPAID2
@ -144,9 +145,11 @@ class Ads {
// Set language
google.ima.settings.setLocale(this.player.config.ads.language);
// We assume the adContainer is the video container of the plyr element
// that will house the ads
this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container);
// Set playback for iOS10+
google.ima.settings.setDisableCustomPlaybackForIOS10Plus(this.player.config.playsinline);
// We assume the adContainer is the video container of the plyr element that will house the ads
this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container, this.player.media);
// Request video ads to be pre-loaded
this.requestAds();
@ -488,10 +491,8 @@ class Ads {
// Ad is stopped
this.playing = false;
// Play our video
if (this.player.currentTime < this.player.duration) {
this.player.play();
}
// Play video
this.player.media.play();
}
/**
@ -501,11 +502,11 @@ class Ads {
// Show the advertisement container
this.elements.container.style.zIndex = 3;
// Ad is playing.
// Ad is playing
this.playing = true;
// Pause our video.
this.player.pause();
this.player.media.pause();
}
/**

View File

@ -231,7 +231,7 @@ class PreviewThumbnails {
}
}
finishScrubbing() {
endScrubbing() {
this.mouseDown = false;
// Hide scrubbing preview. But wait until the video has successfully seeked before hiding the scrubbing preview

View File

@ -1,6 +1,6 @@
// ==========================================================================
// Plyr
// plyr.js v3.4.8
// plyr.js v3.5.0-beta.3
// https://github.com/sampotts/plyr
// License: The MIT License (MIT)
// ==========================================================================
@ -353,6 +353,11 @@ class Plyr {
return null;
}
// Intecept play with ads
if (this.ads && this.ads.enabled) {
this.ads.managerPromise.then(() => this.ads.play()).catch(() => this.media.play());
}
// Return the promise (for HTML5)
return this.media.play();
}

View File

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

View File

@ -19,6 +19,7 @@ const isEvent = input => instanceOf(input, Event);
const isKeyboardEvent = input => instanceOf(input, KeyboardEvent);
const isCue = input => instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue);
const isTrack = input => instanceOf(input, TextTrack) || (!isNullOrUndefined(input) && isString(input.kind));
const isPromise = input => instanceOf(input, Promise);
const isEmpty = input =>
isNullOrUndefined(input) ||
@ -65,6 +66,7 @@ export default {
keyboardEvent: isKeyboardEvent,
cue: isCue,
track: isTrack,
promise: isPromise,
url: isUrl,
empty: isEmpty,
};

View File

@ -2311,10 +2311,10 @@ eslint-config-airbnb-base@^13.1.0:
object.assign "^4.1.0"
object.entries "^1.0.4"
eslint-config-prettier@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-3.6.0.tgz#8ca3ffac4bd6eeef623a0651f9d754900e3ec217"
integrity sha512-ixJ4U3uTLXwJts4rmSVW/lMXjlGwCijhBJHk8iVqKKSifeI0qgFEfWl8L63isfc8Od7EiBALF6BX3jKLluf/jQ==
eslint-config-prettier@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-4.0.0.tgz#16cedeea0a56e74de60dcbbe3be0ab2c645405b9"
integrity sha512-kWuiJxzV5NwOwZcpyozTzDT5KJhBw292bbYro9Is7BWnbNMg15Gmpluc1CTetiCatF8DRkNvgPAOaSyg+bYr3g==
dependencies:
get-stdin "^6.0.0"