Compare commits

...

30 Commits

Author SHA1 Message Date
Sam Potts 9b23e13ce8 v3.0.3 2018-03-22 01:13:37 +11:00
Sam Potts 5eafe9baff Vimeo offset tweak (fixes #826) 2018-03-22 01:08:08 +11:00
Sam Potts c251c94131 Fix for .stop() method (fixes #819) 2018-03-22 01:02:38 +11:00
Sam Potts 17041efc71 Check for array for speed options (fixes #252) 2018-03-22 00:33:14 +11:00
Sam Potts 05b8e8a6e0 Restore as float (fixes #828) 2018-03-22 00:28:42 +11:00
Sam Potts f998b996fa Fix for Firefox fullscreen oddness (Fixes #821) 2018-03-22 00:26:01 +11:00
Sam Potts 958b47c435 Merge branch 'master' of github.com:sampotts/plyr 2018-03-22 00:06:26 +11:00
Sam Potts a27248d3b6 Merge pull request #820 from saadshahd/patch-1
Fix fast-forward control
2018-03-22 00:05:24 +11:00
Sam Potts 1b1f7be7ff Merge branch 'master' of github.com:sampotts/plyr 2018-03-22 00:04:34 +11:00
Sam Potts 59d4a27240 Improve Sprite checking (fixes #827) 2018-03-22 00:04:28 +11:00
Saad Shahd 75e9f3c2e3 Fix fast-forward control
fast-forward control doesn't work.
2018-03-21 12:15:57 +02:00
Sam Potts 7132eccf50 Merge pull request #822 from DanielRuf/patch/fix-options-link
fix the options link in the readme
2018-03-21 09:12:06 +11:00
Daniel Ruf e953c6398c fix the options link in the readme 2018-03-20 15:05:51 +01:00
Sam Potts bb7eea27e5 v3.0.2 2018-03-18 22:46:36 +11:00
Sam Potts 595c5e95bc Fix for Safari with adblockers 2018-03-18 22:37:06 +11:00
Sam Potts 43e6dcd41d Fix for local storage issue 2018-03-18 01:37:24 +11:00
Sam Potts b06c8ae43f Changelog updated 2018-03-18 01:14:18 +11:00
Sam Potts c7ea13c0c7 Sentry in live only 2018-03-18 01:08:05 +11:00
Sam Potts 0f8c6e147b Added Sentry 2018-03-18 00:21:23 +11:00
Sam Potts e566365288 Typo 2018-03-17 23:44:40 +11:00
Sam Potts a06e0f5890 Updated screenshot 2018-03-17 23:40:28 +11:00
Sam Potts 3bccc0da01 v3.0.0 2018-03-17 23:33:25 +11:00
Sam Potts a0173d991e Removed beta message 2018-03-17 23:31:34 +11:00
Sam Potts 600f0eb8a3 Merge branch 'beta'
# Conflicts:
#	readme.md
2018-03-17 23:30:16 +11:00
Sam Potts 5db73b1327 Added buffered getter 2018-03-17 23:27:40 +11:00
Sam Potts 5cb1628cd8 Vimeo fix 2018-03-15 10:29:05 +11:00
Sam Potts e0562752ea Merge pull request #795 from frogg/patch-1
Added link that explains Webkit's autoplay blocker
2018-03-10 23:29:22 +11:00
Frederik Riedel e6db374a72 Added link that explains Webkit's autoplay blocker 2018-02-24 16:19:55 +01:00
Sam Potts ab7f277a1b Merge pull request #769 from redxtech/add-vue-plyr-to-readme
Add vue-plyr to readme
2018-02-06 10:51:42 +11:00
Gabriel Dunn d5a1a7ca1c Add vue-plyr to readme 2018-01-28 23:03:05 -07:00
35 changed files with 6475 additions and 1562 deletions
+334 -315
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+3972 -197
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+6 -6
View File
@@ -163,25 +163,25 @@
c-1.1,0.9-2.5,1.4-4.1,1.4c-0.3,0-0.5,0-0.8,0c1.5,0.9,3.2,1.5,5,1.5c6,0,9.3-5,9.3-9.3c0-0.1,0-0.3,0-0.4C15,4.3,15.6,3.7,16,3z"></path> c-1.1,0.9-2.5,1.4-4.1,1.4c-0.3,0-0.5,0-0.8,0c1.5,0.9,3.2,1.5,5,1.5c6,0,9.3-5,9.3-9.3c0-0.1,0-0.3,0-0.4C15,4.3,15.6,3.7,16,3z"></path>
</svg> </svg>
<p>If you think Plyr's good, <p>If you think Plyr's good,
<a href="https://twitter.com/intent/tweet?text=A+simple+HTML5+media+player+with+custom+controls+and+WebVTT+captions.&url=http%3A%2F%2Fplyr.io&via=Sam_Potts" <a href="https://twitter.com/intent/tweet?text=A+simple+HTML5+media+player+with+custom+controls+and+WebVTT+captions.&amp;url=http%3A%2F%2Fplyr.io&amp;via=Sam_Potts"
target="_blank" data-shr-network="twitter">tweet it</a> target="_blank" data-shr-network="twitter">tweet it</a>
</p> </p>
</aside> </aside>
<!-- Polyfills --> <!-- Polyfills -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=es6,Array.prototype.includes,CustomEvent"></script> <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=es6,Array.prototype.includes,CustomEvent" crossorigin="anonymous"></script>
<!-- Plyr core script --> <!-- Plyr core script -->
<script src="../dist/plyr.js"></script> <script src="../dist/plyr.js" crossorigin="anonymous"></script>
<!-- Sharing libary (https://shr.one) --> <!-- Sharing libary (https://shr.one) -->
<script src="https://cdn.shr.one/1.0.1/shr.js"></script> <script src="https://cdn.shr.one/1.0.1/shr.js" crossorigin="anonymous"></script>
<!-- Rangetouch to fix <input type="range"> on touch devices (see https://rangetouch.com) --> <!-- Rangetouch to fix <input type="range"> on touch devices (see https://rangetouch.com) -->
<script src="https://cdn.rangetouch.com/1.0.1/rangetouch.js" async></script> <script src="https://cdn.rangetouch.com/1.0.1/rangetouch.js" async crossorigin="anonymous"></script>
<!-- Docs script --> <!-- Docs script -->
<script src="dist/demo.js"></script> <script src="dist/demo.js" crossorigin="anonymous"></script>
</body> </body>
</html> </html>
+222 -207
View File
@@ -4,242 +4,257 @@
// Please see readme.md in the root or github.com/sampotts/plyr // Please see readme.md in the root or github.com/sampotts/plyr
// ========================================================================== // ==========================================================================
document.addEventListener('DOMContentLoaded', () => { import Raven from 'raven-js';
if (window.shr) {
window.shr.setup({ (() => {
count: { const isLive = window.location.host === 'plyr.io';
classname: 'button__count',
}, // Raven / Sentry
}); // For demo site (https://plyr.io) only
if (isLive) {
Raven.config('https://d4ad9866ad834437a4754e23937071e4@sentry.io/305555').install();
} }
// Setup tab focus document.addEventListener('DOMContentLoaded', () => {
const tabClassName = 'tab-focus'; Raven.context(() => {
if (window.shr) {
window.shr.setup({
count: {
classname: 'button__count',
},
});
}
// Remove class on blur // Setup tab focus
document.addEventListener('focusout', event => { const tabClassName = 'tab-focus';
event.target.classList.remove(tabClassName);
});
// Add classname to tabbed elements // Remove class on blur
document.addEventListener('keydown', event => { document.addEventListener('focusout', event => {
if (event.keyCode !== 9) { event.target.classList.remove(tabClassName);
return; });
}
// Delay the adding of classname until the focus has changed // Add classname to tabbed elements
// This event fires before the focusin event document.addEventListener('keydown', event => {
setTimeout(() => { if (event.keyCode !== 9) {
document.activeElement.classList.add(tabClassName); return;
}, 0); }
});
// Setup the player // Delay the adding of classname until the focus has changed
const player = new Plyr('#player', { // This event fires before the focusin event
debug: true, setTimeout(() => {
title: 'View From A Blue Moon', document.activeElement.classList.add(tabClassName);
iconUrl: '../dist/plyr.svg', }, 0);
keyboard: { });
global: true,
},
tooltips: {
controls: true,
},
captions: {
active: true,
},
keys: {
google: 'AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c',
},
ads: {
enabled: true,
},
});
// Expose for tinkering in the console // Setup the player
window.player = player; const player = new Plyr('#player', {
debug: true,
title: 'View From A Blue Moon',
iconUrl: '../dist/plyr.svg',
keyboard: {
global: true,
},
tooltips: {
controls: true,
},
captions: {
active: true,
},
keys: {
google: 'AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c',
},
ads: {
enabled: true,
publisherId: '918848828995742',
},
});
// Setup type toggle // Expose for tinkering in the console
const buttons = document.querySelectorAll('[data-source]'); window.player = player;
const types = {
video: 'video',
audio: 'audio',
youtube: 'youtube',
vimeo: 'vimeo',
};
let currentType = window.location.hash.replace('#', '');
const historySupport = window.history && window.history.pushState;
// Toggle class on an element // Setup type toggle
function toggleClass(element, className, state) { const buttons = document.querySelectorAll('[data-source]');
if (element) { const types = {
element.classList[state ? 'add' : 'remove'](className); video: 'video',
} audio: 'audio',
} youtube: 'youtube',
vimeo: 'vimeo',
};
let currentType = window.location.hash.replace('#', '');
const historySupport = window.history && window.history.pushState;
// Set a new source // Toggle class on an element
function newSource(type, init) { function toggleClass(element, className, state) {
// Bail if new type isn't known, it's the current type, or current type is empty (video is default) and new type is video if (element) {
if (!(type in types) || (!init && type === currentType) || (!currentType.length && type === types.video)) { element.classList[state ? 'add' : 'remove'](className);
return; }
} }
switch (type) { // Set a new source
case types.video: function newSource(type, init) {
player.source = { // Bail if new type isn't known, it's the current type, or current type is empty (video is default) and new type is video
type: 'video', if (!(type in types) || (!init && type === currentType) || (!currentType.length && type === types.video)) {
title: 'View From A Blue Moon', return;
sources: [{ }
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4',
type: 'video/mp4',
}],
poster: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg',
tracks: [
{
kind: 'captions',
label: 'English',
srclang: 'en',
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt',
default: true,
},
{
kind: 'captions',
label: 'French',
srclang: 'fr',
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt',
},
],
};
break; switch (type) {
case types.video:
player.source = {
type: 'video',
title: 'View From A Blue Moon',
sources: [{
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4',
type: 'video/mp4',
}],
poster: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg',
tracks: [
{
kind: 'captions',
label: 'English',
srclang: 'en',
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt',
default: true,
},
{
kind: 'captions',
label: 'French',
srclang: 'fr',
src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt',
},
],
};
case types.audio: break;
player.source = {
type: 'audio',
title: 'Kishi Bashi &ndash; &ldquo;It All Began With A Burst&rdquo;',
sources: [
{
src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3',
type: 'audio/mp3',
},
{
src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg',
type: 'audio/ogg',
},
],
};
break; case types.audio:
player.source = {
type: 'audio',
title: 'Kishi Bashi &ndash; &ldquo;It All Began With A Burst&rdquo;',
sources: [
{
src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3',
type: 'audio/mp3',
},
{
src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg',
type: 'audio/ogg',
},
],
};
case types.youtube: break;
player.source = {
type: 'video',
title: 'View From A Blue Moon',
sources: [{
src: 'https://youtube.com/watch?v=bTqVqk7FSmY',
provider: 'youtube',
}],
};
break; case types.youtube:
player.source = {
type: 'video',
title: 'View From A Blue Moon',
sources: [{
src: 'https://youtube.com/watch?v=bTqVqk7FSmY',
provider: 'youtube',
}],
};
case types.vimeo: break;
player.source = {
type: 'video',
sources: [{
src: 'https://vimeo.com/76979871',
provider: 'vimeo',
}],
};
break; case types.vimeo:
player.source = {
type: 'video',
sources: [{
src: 'https://vimeo.com/76979871',
provider: 'vimeo',
}],
};
default: break;
break;
}
// Set the current type for next time default:
currentType = type; break;
}
// Remove active classes // Set the current type for next time
Array.from(buttons).forEach(button => toggleClass(button.parentElement, 'active', false)); currentType = type;
// Set active on parent // Remove active classes
toggleClass(document.querySelector(`[data-source="${type}"]`), 'active', true); Array.from(buttons).forEach(button => toggleClass(button.parentElement, 'active', false));
// Show cite // Set active on parent
Array.from(document.querySelectorAll('.plyr__cite')).forEach(cite => { toggleClass(document.querySelector(`[data-source="${type}"]`), 'active', true);
cite.setAttribute('hidden', '');
});
document.querySelector(`.plyr__cite--${type}`).removeAttribute('hidden');
}
// Bind to each button // Show cite
Array.from(buttons).forEach(button => { Array.from(document.querySelectorAll('.plyr__cite')).forEach(cite => {
button.addEventListener('click', () => { cite.setAttribute('hidden', '');
const type = button.getAttribute('data-source'); });
document.querySelector(`.plyr__cite--${type}`).removeAttribute('hidden');
}
newSource(type); // Bind to each button
Array.from(buttons).forEach(button => {
button.addEventListener('click', () => {
const type = button.getAttribute('data-source');
newSource(type);
if (historySupport) {
window.history.pushState({ type }, '', `#${type}`);
}
});
});
// List for backwards/forwards
window.addEventListener('popstate', event => {
if (event.state && 'type' in event.state) {
newSource(event.state.type);
}
});
// On load
if (historySupport) { if (historySupport) {
window.history.pushState({ type }, '', `#${type}`); const video = !currentType.length;
// If there's no current type set, assume video
if (video) {
currentType = types.video;
}
// Replace current history state
if (currentType in types) {
window.history.replaceState(
{
type: currentType,
},
'',
video ? '' : `#${currentType}`,
);
}
// If it's not video, load the source
if (currentType !== types.video) {
newSource(currentType, true);
}
} }
}); });
}); });
// List for backwards/forwards // Google analytics
window.addEventListener('popstate', event => { // For demo site (https://plyr.io) only
if (event.state && 'type' in event.state) { /* eslint-disable */
newSource(event.state.type); if (isLive) {
} (function(i, s, o, g, r, a, m) {
}); i.GoogleAnalyticsObject = r;
i[r] =
// On load i[r] ||
if (historySupport) { function() {
const video = !currentType.length; (i[r].q = i[r].q || []).push(arguments);
};
// If there's no current type set, assume video i[r].l = 1 * new Date();
if (video) { a = s.createElement(o);
currentType = types.video; m = s.getElementsByTagName(o)[0];
} a.async = 1;
a.src = g;
// Replace current history state m.parentNode.insertBefore(a, m);
if (currentType in types) { })(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
window.history.replaceState( window.ga('create', 'UA-40881672-11', 'auto');
{ window.ga('send', 'pageview');
type: currentType,
},
'',
video ? '' : `#${currentType}`,
);
}
// If it's not video, load the source
if (currentType !== types.video) {
newSource(currentType, true);
}
} }
}); /* eslint-enable */
})();
// Google analytics
// For demo site (https://plyr.io) only
/* eslint-disable */
if (window.location.host === 'plyr.io') {
(function(i, s, o, g, r, a, m) {
i.GoogleAnalyticsObject = r;
i[r] =
i[r] ||
function() {
(i[r].q = i[r].q || []).push(arguments);
};
i[r].l = 1 * new Date();
a = s.createElement(o);
m = s.getElementsByTagName(o)[0];
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
window.ga('create', 'UA-40881672-11', 'auto');
window.ga('send', 'pageview');
}
/* eslint-enable */
+1 -1
View File
File diff suppressed because one or more lines are too long
+433 -124
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.0-beta.19/plyr.svg', iconUrl: 'https://cdn.plyr.io/3.0.2/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',
@@ -233,7 +233,7 @@ var defaults = {
pause: '[data-plyr="pause"]', pause: '[data-plyr="pause"]',
restart: '[data-plyr="restart"]', restart: '[data-plyr="restart"]',
rewind: '[data-plyr="rewind"]', rewind: '[data-plyr="rewind"]',
forward: '[data-plyr="fast-forward"]', fastForward: '[data-plyr="fast-forward"]',
mute: '[data-plyr="mute"]', mute: '[data-plyr="mute"]',
captions: '[data-plyr="captions"]', captions: '[data-plyr="captions"]',
fullscreen: '[data-plyr="fullscreen"]', fullscreen: '[data-plyr="fullscreen"]',
@@ -326,10 +326,309 @@ var defaults = {
// Register for an account here: http://vi.ai/publisher-video-monetization/?aid=plyrio // Register for an account here: http://vi.ai/publisher-video-monetization/?aid=plyrio
ads: { ads: {
enabled: false, enabled: false,
publisherId: '918848828995742' publisherId: ''
} }
}; };
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var loadjs_umd = createCommonjsModule(function (module, exports) {
(function(root, factory) {
if (typeof undefined === 'function' && undefined.amd) {
undefined([], factory);
} else {
module.exports = factory();
}
}(commonjsGlobal, function() {
/**
* Global dependencies.
* @global {Object} document - DOM
*/
var devnull = function() {},
bundleIdCache = {},
bundleResultCache = {},
bundleCallbackQueue = {};
/**
* Subscribe to bundle load event.
* @param {string[]} bundleIds - Bundle ids
* @param {Function} callbackFn - The callback function
*/
function subscribe(bundleIds, callbackFn) {
// listify
bundleIds = bundleIds.push ? bundleIds : [bundleIds];
var depsNotFound = [],
i = bundleIds.length,
numWaiting = i,
fn,
bundleId,
r,
q;
// define callback function
fn = function (bundleId, pathsNotFound) {
if (pathsNotFound.length) depsNotFound.push(bundleId);
numWaiting--;
if (!numWaiting) callbackFn(depsNotFound);
};
// register callback
while (i--) {
bundleId = bundleIds[i];
// execute callback if in result cache
r = bundleResultCache[bundleId];
if (r) {
fn(bundleId, r);
continue;
}
// add to callback queue
q = bundleCallbackQueue[bundleId] = bundleCallbackQueue[bundleId] || [];
q.push(fn);
}
}
/**
* Publish bundle load event.
* @param {string} bundleId - Bundle id
* @param {string[]} pathsNotFound - List of files not found
*/
function publish(bundleId, pathsNotFound) {
// exit if id isn't defined
if (!bundleId) return;
var q = bundleCallbackQueue[bundleId];
// cache result
bundleResultCache[bundleId] = pathsNotFound;
// exit if queue is empty
if (!q) return;
// empty callback queue
while (q.length) {
q[0](bundleId, pathsNotFound);
q.splice(0, 1);
}
}
/**
* Execute callbacks.
* @param {Object or Function} args - The callback args
* @param {string[]} depsNotFound - List of dependencies not found
*/
function executeCallbacks(args, depsNotFound) {
// accept function as argument
if (args.call) args = {success: args};
// success and error callbacks
if (depsNotFound.length) (args.error || devnull)(depsNotFound);
else (args.success || devnull)(args);
}
/**
* Load individual file.
* @param {string} path - The file path
* @param {Function} callbackFn - The callback function
*/
function loadFile(path, callbackFn, args, numTries) {
var doc = document,
async = args.async,
maxTries = (args.numRetries || 0) + 1,
beforeCallbackFn = args.before || devnull,
isCss,
e;
numTries = numTries || 0;
if (/(^css!|\.css$)/.test(path)) {
isCss = true;
// css
e = doc.createElement('link');
e.rel = 'stylesheet';
e.href = path.replace(/^css!/, ''); // remove "css!" prefix
} else {
// javascript
e = doc.createElement('script');
e.src = path;
e.async = async === undefined ? true : async;
}
e.onload = e.onerror = e.onbeforeload = function (ev) {
var result = ev.type[0];
// Note: The following code isolates IE using `hideFocus` and treats empty
// stylesheets as failures to get around lack of onerror support
if (isCss && 'hideFocus' in e) {
try {
if (!e.sheet.cssText.length) result = 'e';
} catch (x) {
// sheets objects created from load errors don't allow access to
// `cssText`
result = 'e';
}
}
// handle retries in case of load failure
if (result == 'e') {
// increment counter
numTries += 1;
// exit function and try again
if (numTries < maxTries) {
return loadFile(path, callbackFn, args, numTries);
}
}
// execute callback
callbackFn(path, result, ev.defaultPrevented);
};
// add to document (unless callback returns `false`)
if (beforeCallbackFn(path, e) !== false) doc.head.appendChild(e);
}
/**
* Load multiple files.
* @param {string[]} paths - The file paths
* @param {Function} callbackFn - The callback function
*/
function loadFiles(paths, callbackFn, args) {
// listify paths
paths = paths.push ? paths : [paths];
var numWaiting = paths.length,
x = numWaiting,
pathsNotFound = [],
fn,
i;
// define callback function
fn = function(path, result, defaultPrevented) {
// handle error
if (result == 'e') pathsNotFound.push(path);
// handle beforeload event. If defaultPrevented then that means the load
// will be blocked (ex. Ghostery/ABP on Safari)
if (result == 'b') {
if (defaultPrevented) pathsNotFound.push(path);
else return;
}
numWaiting--;
if (!numWaiting) callbackFn(pathsNotFound);
};
// load scripts
for (i=0; i < x; i++) loadFile(paths[i], fn, args);
}
/**
* Initiate script load and register bundle.
* @param {(string|string[])} paths - The file paths
* @param {(string|Function)} [arg1] - The bundleId or success callback
* @param {Function} [arg2] - The success or error callback
* @param {Function} [arg3] - The error callback
*/
function loadjs(paths, arg1, arg2) {
var bundleId,
args;
// bundleId (if string)
if (arg1 && arg1.trim) bundleId = arg1;
// args (default is {})
args = (bundleId ? arg2 : arg1) || {};
// throw error if bundle is already defined
if (bundleId) {
if (bundleId in bundleIdCache) {
throw "LoadJS";
} else {
bundleIdCache[bundleId] = true;
}
}
// load scripts
loadFiles(paths, function (pathsNotFound) {
// execute callbacks
executeCallbacks(args, pathsNotFound);
// publish bundle load event
publish(bundleId, pathsNotFound);
}, args);
}
/**
* Execute callbacks when dependencies have been satisfied.
* @param {(string|string[])} deps - List of bundle ids
* @param {Object} args - success/error arguments
*/
loadjs.ready = function ready(deps, args) {
// subscribe to bundle load event
subscribe(deps, function (depsNotFound) {
// execute callbacks
executeCallbacks(args, depsNotFound);
});
return loadjs;
};
/**
* Manually satisfy bundle dependencies.
* @param {string} bundleId - The bundle id
*/
loadjs.done = function done(bundleId) {
publish(bundleId, []);
};
/**
* Reset loadjs dependencies statuses
*/
loadjs.reset = function reset() {
bundleIdCache = {};
bundleResultCache = {};
bundleCallbackQueue = {};
};
/**
* Determine if bundle has already been defined
* @param String} bundleId - The bundle id
*/
loadjs.isDefined = function isDefined(bundleId) {
return bundleId in bundleIdCache;
};
// export
return loadjs;
}));
});
var asyncGenerator = function () { var asyncGenerator = function () {
function AwaitValue(value) { function AwaitValue(value) {
this.value = value; this.value = value;
@@ -693,48 +992,10 @@ var utils = {
// Load an external script // Load an external script
loadScript: function loadScript(url) { loadScript: function loadScript(url) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
var current = document.querySelector('script[src="' + url + '"]'); loadjs_umd(url, {
success: resolve,
// Check script is not already referenced, if so wait for load error: reject
if (current !== null) { });
current.callbacks = current.callbacks || [];
current.callbacks.push(resolve);
return;
}
// Build the element
var element = document.createElement('script');
// Callback queue
element.callbacks = element.callbacks || [];
element.callbacks.push(resolve);
// Error queue
element.errors = element.errors || [];
element.errors.push(reject);
// Bind callback
element.addEventListener('load', function (event) {
element.callbacks.forEach(function (cb) {
return cb.call(null, event);
});
element.callbacks = null;
}, false);
// Bind error handling
element.addEventListener('error', function (event) {
element.errors.forEach(function (err) {
return err.call(null, event);
});
element.errors = null;
}, false);
// Set the URL after binding callback
element.src = url;
// Inject
var first = document.getElementsByTagName('script')[0];
first.parentNode.insertBefore(element, first);
}); });
}, },
@@ -749,7 +1010,16 @@ var utils = {
var hasId = utils.is.string(id); var hasId = utils.is.string(id);
var isCached = false; var isCached = false;
function updateSprite(data) { var exists = function exists() {
return document.querySelectorAll('#' + id).length;
};
function injectSprite(data) {
// Check again incase of race condition
if (hasId && exists()) {
return;
}
// Inject content // Inject content
this.innerHTML = data; this.innerHTML = data;
@@ -757,8 +1027,8 @@ var utils = {
document.body.insertBefore(this, document.body.childNodes[0]); document.body.insertBefore(this, document.body.childNodes[0]);
} }
// Only load once // Only load once if ID set
if (!hasId || !document.querySelectorAll('#' + id).length) { if (!hasId || !exists()) {
// Create container // Create container
var container = document.createElement('div'); var container = document.createElement('div');
utils.toggleHidden(container, true); utils.toggleHidden(container, true);
@@ -774,7 +1044,7 @@ var utils = {
if (isCached) { if (isCached) {
var data = JSON.parse(cached); var data = JSON.parse(cached);
updateSprite.call(container, data.content); injectSprite.call(container, data.content);
return; return;
} }
} }
@@ -791,7 +1061,7 @@ var utils = {
})); }));
} }
updateSprite.call(container, result); injectSprite.call(container, result);
}).catch(function () {}); }).catch(function () {});
} }
}, },
@@ -1057,7 +1327,7 @@ var utils = {
pause: utils.getElement.call(this, this.config.selectors.buttons.pause), pause: utils.getElement.call(this, this.config.selectors.buttons.pause),
restart: utils.getElement.call(this, this.config.selectors.buttons.restart), restart: utils.getElement.call(this, this.config.selectors.buttons.restart),
rewind: utils.getElement.call(this, this.config.selectors.buttons.rewind), rewind: utils.getElement.call(this, this.config.selectors.buttons.rewind),
forward: utils.getElement.call(this, this.config.selectors.buttons.forward), fastForward: utils.getElement.call(this, this.config.selectors.buttons.fastForward),
mute: utils.getElement.call(this, this.config.selectors.buttons.mute), mute: utils.getElement.call(this, this.config.selectors.buttons.mute),
pip: utils.getElement.call(this, this.config.selectors.buttons.pip), pip: utils.getElement.call(this, this.config.selectors.buttons.pip),
airplay: utils.getElement.call(this, this.config.selectors.buttons.airplay), airplay: utils.getElement.call(this, this.config.selectors.buttons.airplay),
@@ -1260,6 +1530,7 @@ var utils = {
if (current === 0 || max === 0 || Number.isNaN(current) || Number.isNaN(max)) { if (current === 0 || max === 0 || Number.isNaN(current) || Number.isNaN(max)) {
return 0; return 0;
} }
return (current / max * 100).toFixed(2); return (current / max * 100).toFixed(2);
}, },
@@ -1511,13 +1782,9 @@ var support = {
break; break;
case 'youtube:video': case 'youtube:video':
api = true;
ui = support.rangeInput && (!browser.isIPhone || playsInline);
break;
case 'vimeo:video': case 'vimeo:video':
api = true; api = true;
ui = support.rangeInput && !browser.isIPhone; ui = support.rangeInput && (!browser.isIPhone || playsInline);
break; break;
default: default:
@@ -1684,6 +1951,7 @@ var Console = function () {
// ========================================================================== // ==========================================================================
// Fullscreen wrapper // Fullscreen wrapper
// https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API#prefixing
// ========================================================================== // ==========================================================================
var browser = utils.getBrowser(); var browser = utils.getBrowser();
@@ -1742,6 +2010,7 @@ var Fullscreen = function () {
// Get prefix // Get prefix
this.prefix = Fullscreen.prefix; this.prefix = Fullscreen.prefix;
this.name = Fullscreen.name;
// Scroll position // Scroll position
this.scrollPosition = { x: 0, y: 0 }; this.scrollPosition = { x: 0, y: 0 };
@@ -1805,7 +2074,7 @@ var Fullscreen = function () {
} else if (!this.prefix) { } else if (!this.prefix) {
this.target.requestFullScreen(); this.target.requestFullScreen();
} else if (!utils.is.empty(this.prefix)) { } else if (!utils.is.empty(this.prefix)) {
this.target['' + this.prefix + (this.prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')](); this.target[this.prefix + 'Request' + this.name]();
} }
} }
@@ -1827,7 +2096,8 @@ var Fullscreen = function () {
} else if (!this.prefix) { } else if (!this.prefix) {
document.cancelFullScreen(); document.cancelFullScreen();
} else if (!utils.is.empty(this.prefix)) { } else if (!utils.is.empty(this.prefix)) {
document['' + this.prefix + (this.prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen')](); var action = this.prefix === 'moz' ? 'Cancel' : 'Exit';
document['' + this.prefix + action + this.name]();
} }
} }
@@ -1867,7 +2137,7 @@ var Fullscreen = function () {
return utils.hasClass(this.target, this.player.config.classNames.fullscreen.fallback); return utils.hasClass(this.target, this.player.config.classNames.fullscreen.fallback);
} }
var element = !this.prefix ? document.fullscreenElement : document[this.prefix + 'FullscreenElement']; var element = !this.prefix ? document.fullscreenElement : document['' + this.prefix + this.name + 'Element'];
return element === this.target; return element === this.target;
} }
@@ -1891,7 +2161,7 @@ var Fullscreen = function () {
key: 'prefix', key: 'prefix',
get: function get$$1() { get: function get$$1() {
// No prefix // No prefix
if (utils.is.function(document.cancelFullScreen)) { if (utils.is.function(document.exitFullscreen)) {
return false; return false;
} }
@@ -1900,12 +2170,9 @@ var Fullscreen = function () {
var prefixes = ['webkit', 'moz', 'ms']; var prefixes = ['webkit', 'moz', 'ms'];
prefixes.some(function (pre) { prefixes.some(function (pre) {
if (utils.is.function(document[pre + 'CancelFullScreen'])) { if (utils.is.function(document[pre + 'ExitFullscreen']) || utils.is.function(document[pre + 'CancelFullScreen'])) {
value = pre; value = pre;
return true; return true;
} else if (utils.is.function(document.msExitFullscreen)) {
value = 'ms';
return true;
} }
return false; return false;
@@ -1913,6 +2180,11 @@ var Fullscreen = function () {
return value; return value;
} }
}, {
key: 'name',
get: function get$$1() {
return this.prefix === 'moz' ? 'FullScreen' : 'Fullscreen';
}
}]); }]);
return Fullscreen; return Fullscreen;
}(); }();
@@ -2179,7 +2451,7 @@ var ui = {
var _this = this; var _this = this;
// Re-attach media element listeners // Re-attach media element listeners
// TODO: Use event bubbling // TODO: Use event bubbling?
this.listeners.media(); this.listeners.media();
// Don't setup interface if no support // Don't setup interface if no support
@@ -2398,8 +2670,6 @@ var ui = {
// Update <progress> elements // Update <progress> elements
updateProgress: function updateProgress(event) { updateProgress: function updateProgress(event) {
var _this4 = this;
if (!this.supported.ui || !utils.is.event(event)) { if (!this.supported.ui || !utils.is.event(event)) {
return; return;
} }
@@ -2423,22 +2693,7 @@ var ui = {
// Check buffer status // Check buffer status
case 'playing': case 'playing':
case 'progress': case 'progress':
value = function () { ui.setProgress.call(this, this.elements.display.buffer, this.buffered * 100);
var buffered = _this4.media.buffered;
if (buffered && buffered.length) {
// HTML5
return utils.getPercentage(buffered.end(0), _this4.duration);
} else if (utils.is.number(buffered)) {
// YouTube returns between 0 and 1
return buffered * 100;
}
return 0;
}();
ui.setProgress.call(this, this.elements.display.buffer, value);
break; break;
@@ -3185,7 +3440,7 @@ var controls = {
var type = 'speed'; var type = 'speed';
// Set the default speeds // Set the default speeds
if (!utils.is.object(this.options.speed) || !Object.keys(this.options.speed).length) { if (!utils.is.array(this.options.speed) || !this.options.speed.length) {
this.options.speed = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2]; this.options.speed = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
} }
@@ -3405,7 +3660,7 @@ var controls = {
// Fast forward button // Fast forward button
if (this.config.controls.includes('fast-forward')) { if (this.config.controls.includes('fast-forward')) {
container.appendChild(controls.createButton.call(this, 'fast-forward')); container.appendChild(controls.createButton.call(this, 'fastForward'));
} }
// Progress // Progress
@@ -3982,7 +4237,7 @@ var Listeners = function () {
}); });
// Handle native play/pause // Handle native play/pause
utils.on(this.player.media, 'playing play pause ended', 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);
}); });
@@ -4326,9 +4581,13 @@ var Storage = function () {
createClass(Storage, [{ createClass(Storage, [{
key: 'get', key: 'get',
value: function get$$1(key) { value: function get$$1(key) {
if (!Storage.supported) {
return null;
}
var store = window.localStorage.getItem(this.key); var store = window.localStorage.getItem(this.key);
if (!Storage.supported || utils.is.empty(store)) { if (utils.is.empty(store)) {
return null; return null;
} }
@@ -4366,17 +4625,18 @@ var Storage = function () {
}], [{ }], [{
key: 'supported', key: 'supported',
get: function get$$1() { get: function get$$1() {
if (!('localStorage' in window)) {
return false;
}
var test = '___test';
// Try to use it (it might be disabled, e.g. user is in private mode)
// see: https://github.com/sampotts/plyr/issues/131
try { try {
if (!('localStorage' in window)) {
return false;
}
var test = '___test';
// Try to use it (it might be disabled, e.g. user is in private mode)
// see: https://github.com/sampotts/plyr/issues/131
window.localStorage.setItem(test, test); window.localStorage.setItem(test, test);
window.localStorage.removeItem(test); window.localStorage.removeItem(test);
return true; return true;
} catch (e) { } catch (e) {
return false; return false;
@@ -5397,6 +5657,8 @@ var youtube = {
// Reset timer // Reset timer
clearInterval(player.timers.playing); clearInterval(player.timers.playing);
console.warn(event.data);
// Handle events // Handle events
// -1 Unstarted // -1 Unstarted
// 0 Ended // 0 Ended
@@ -5405,6 +5667,16 @@ var youtube = {
// 3 Buffering // 3 Buffering
// 5 Video cued // 5 Video cued
switch (event.data) { switch (event.data) {
case -1:
// Update scrubber
utils.dispatchEvent.call(player, player.media, 'timeupdate');
// Get loaded % from YouTube
player.media.buffered = instance.getVideoLoadedFraction();
utils.dispatchEvent.call(player, player.media, 'progress');
break;
case 0: case 0:
player.media.paused = true; player.media.paused = true;
@@ -5504,7 +5776,7 @@ var vimeo = {
setAspectRatio: function setAspectRatio(input) { setAspectRatio: function setAspectRatio(input) {
var ratio = utils.is.string(input) ? input.split(':') : this.config.ratio.split(':'); var ratio = utils.is.string(input) ? input.split(':') : this.config.ratio.split(':');
var padding = 100 / ratio[0] * ratio[1]; var padding = 100 / ratio[0] * ratio[1];
var height = 200; var height = 240;
var offset = (height - padding) / (height / 50); var offset = (height - padding) / (height / 50);
this.elements.wrapper.style.paddingBottom = padding + '%'; this.elements.wrapper.style.paddingBottom = padding + '%';
this.media.style.transform = 'translateY(-' + offset + '%)'; this.media.style.transform = 'translateY(-' + offset + '%)';
@@ -5574,10 +5846,8 @@ var vimeo = {
}; };
player.media.stop = function () { player.media.stop = function () {
player.embed.stop().then(function () { player.pause();
player.media.paused = true; player.currentTime = 0;
player.currentTime = 0;
});
}; };
// Seeking // Seeking
@@ -6041,7 +6311,7 @@ var source = {
// ========================================================================== // ==========================================================================
// Plyr // Plyr
// plyr.js v3.0.0-beta.19 // plyr.js v3.0.2
// https://github.com/sampotts/plyr // https://github.com/sampotts/plyr
// License: The MIT License (MIT) // License: The MIT License (MIT)
// ========================================================================== // ==========================================================================
@@ -6325,6 +6595,10 @@ var Plyr = function () {
value: function play() { value: function play() {
var _this2 = this; var _this2 = this;
if (!utils.is.function(this.media.play)) {
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(function () {
@@ -6345,7 +6619,7 @@ var Plyr = function () {
}, { }, {
key: 'pause', key: 'pause',
value: function pause() { value: function pause() {
if (!this.playing) { if (!this.playing || !utils.is.function(this.media.pause)) {
return; return;
} }
@@ -6382,8 +6656,11 @@ var Plyr = function () {
}, { }, {
key: 'stop', key: 'stop',
value: function stop() { value: function stop() {
this.restart(); if (this.isHTML5) {
this.pause(); this.media.load();
} else {
this.media.stop();
}
} }
/** /**
@@ -6648,6 +6925,10 @@ var Plyr = function () {
var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
if (!this.ready) {
return;
}
var done = function done() { var done = function done() {
// Reset overflow (incase destroyed while in fullscreen) // Reset overflow (incase destroyed while in fullscreen)
document.body.style.overflow = ''; document.body.style.overflow = '';
@@ -6690,6 +6971,9 @@ var Plyr = function () {
callback.call(_this4.elements.original); callback.call(_this4.elements.original);
} }
// Reset state
_this4.ready = false;
// Clear for garbage collection // Clear for garbage collection
setTimeout(function () { setTimeout(function () {
_this4.elements = null; _this4.elements = null;
@@ -6722,7 +7006,7 @@ var Plyr = function () {
clearInterval(this.timers.playing); clearInterval(this.timers.playing);
// Destroy YouTube API // Destroy YouTube API
if (this.embed !== null) { if (this.embed !== null && utils.is.function(this.embed.destroy)) {
this.embed.destroy(); this.embed.destroy();
} }
@@ -6769,37 +7053,37 @@ var Plyr = function () {
}, { }, {
key: 'isHTML5', key: 'isHTML5',
get: function get$$1() { get: function get$$1() {
return this.provider === providers.html5; return Boolean(this.provider === providers.html5);
} }
}, { }, {
key: 'isEmbed', key: 'isEmbed',
get: function get$$1() { get: function get$$1() {
return this.isYouTube || this.isVimeo; return Boolean(this.isYouTube || this.isVimeo);
} }
}, { }, {
key: 'isYouTube', key: 'isYouTube',
get: function get$$1() { get: function get$$1() {
return this.provider === providers.youtube; return Boolean(this.provider === providers.youtube);
} }
}, { }, {
key: 'isVimeo', key: 'isVimeo',
get: function get$$1() { get: function get$$1() {
return this.provider === providers.vimeo; return Boolean(this.provider === providers.vimeo);
} }
}, { }, {
key: 'isVideo', key: 'isVideo',
get: function get$$1() { get: function get$$1() {
return this.type === types.video; return Boolean(this.type === types.video);
} }
}, { }, {
key: 'isAudio', key: 'isAudio',
get: function get$$1() { get: function get$$1() {
return this.type === types.audio; return Boolean(this.type === types.audio);
} }
}, { }, {
key: 'paused', key: 'paused',
get: function get$$1() { get: function get$$1() {
return this.media.paused; return Boolean(this.media.paused);
} }
/** /**
@@ -6809,7 +7093,7 @@ var Plyr = function () {
}, { }, {
key: 'playing', key: 'playing',
get: function get$$1() { get: function get$$1() {
return !this.paused && !this.ended && (this.isHTML5 ? this.media.readyState > 2 : true); return Boolean(!this.paused && !this.ended && (this.isHTML5 ? this.media.readyState > 2 : true));
} }
/** /**
@@ -6819,7 +7103,7 @@ var Plyr = function () {
}, { }, {
key: 'ended', key: 'ended',
get: function get$$1() { get: function get$$1() {
return this.media.ended; return Boolean(this.media.ended);
} }
}, { }, {
key: 'currentTime', key: 'currentTime',
@@ -6838,7 +7122,7 @@ var Plyr = function () {
} }
// Set // Set
this.media.currentTime = targetTime.toFixed(4); this.media.currentTime = parseFloat(targetTime.toFixed(4));
// Logging // Logging
this.debug.log('Seeking to ' + this.currentTime + ' seconds'); this.debug.log('Seeking to ' + this.currentTime + ' seconds');
@@ -6852,6 +7136,31 @@ var Plyr = function () {
return Number(this.media.currentTime); return Number(this.media.currentTime);
} }
/**
* Get buffered
*/
}, {
key: 'buffered',
get: function get$$1() {
var buffered = this.media.buffered;
// YouTube / Vimeo return a float between 0-1
if (utils.is.number(buffered)) {
return buffered;
}
// HTML5
// TODO: Handle buffered chunks of the media
// (i.e. seek to another section buffers only that section)
if (buffered && buffered.length && this.duration > 0) {
return buffered.end(0) / this.duration;
}
return 0;
}
/** /**
* Get seeking status * Get seeking status
*/ */
@@ -6859,7 +7168,7 @@ var Plyr = function () {
}, { }, {
key: 'seeking', key: 'seeking',
get: function get$$1() { get: function get$$1() {
return this.media.seeking; return Boolean(this.media.seeking);
} }
/** /**
@@ -6873,7 +7182,7 @@ var Plyr = function () {
var fauxDuration = parseInt(this.config.duration, 10); var fauxDuration = parseInt(this.config.duration, 10);
// True duration // True duration
var realDuration = Number(this.media.duration); var realDuration = this.media ? Number(this.media.duration) : 0;
// If custom duration is funky, use regular duration // If custom duration is funky, use regular duration
return !Number.isNaN(fauxDuration) ? fauxDuration : realDuration; return !Number.isNaN(fauxDuration) ? fauxDuration : realDuration;
@@ -6931,7 +7240,7 @@ var Plyr = function () {
*/ */
, ,
get: function get$$1() { get: function get$$1() {
return this.media.volume; return Number(this.media.volume);
} }
}, { }, {
key: 'muted', key: 'muted',
@@ -6960,7 +7269,7 @@ var Plyr = function () {
*/ */
, ,
get: function get$$1() { get: function get$$1() {
return this.media.muted; return Boolean(this.media.muted);
} }
/** /**
@@ -6980,12 +7289,12 @@ var Plyr = function () {
} }
// Get audio tracks // Get audio tracks
return this.media.mozHasAudio || Boolean(this.media.webkitAudioDecodedByteCount) || Boolean(this.media.audioTracks && this.media.audioTracks.length); return Boolean(this.media.mozHasAudio) || Boolean(this.media.webkitAudioDecodedByteCount) || Boolean(this.media.audioTracks && this.media.audioTracks.length);
} }
/** /**
* Set playback speed * Set playback speed
* @param {decimal} speed - the speed of playback (0.5-2.0) * @param {number} speed - the speed of playback (0.5-2.0)
*/ */
}, { }, {
@@ -7030,7 +7339,7 @@ var Plyr = function () {
*/ */
, ,
get: function get$$1() { get: function get$$1() {
return this.media.playbackRate; return Number(this.media.playbackRate);
} }
/** /**
@@ -7133,7 +7442,7 @@ var Plyr = function () {
*/ */
, ,
get: function get$$1() { get: function get$$1() {
return this.media.loop; return Boolean(this.media.loop);
} }
/** /**
@@ -7202,7 +7511,7 @@ var Plyr = function () {
*/ */
, ,
get: function get$$1() { get: function get$$1() {
return this.config.autoplay; return Boolean(this.config.autoplay);
} }
}, { }, {
key: 'language', key: 'language',
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+424 -125
View File
@@ -5268,7 +5268,7 @@ var defaults = {
// Sprite (for icons) // Sprite (for icons)
loadSprite: true, loadSprite: true,
iconPrefix: 'plyr', iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/3.0.0-beta.20/plyr.svg', iconUrl: 'https://cdn.plyr.io/3.0.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',
@@ -5424,7 +5424,7 @@ var defaults = {
pause: '[data-plyr="pause"]', pause: '[data-plyr="pause"]',
restart: '[data-plyr="restart"]', restart: '[data-plyr="restart"]',
rewind: '[data-plyr="rewind"]', rewind: '[data-plyr="rewind"]',
forward: '[data-plyr="fast-forward"]', fastForward: '[data-plyr="fast-forward"]',
mute: '[data-plyr="mute"]', mute: '[data-plyr="mute"]',
captions: '[data-plyr="captions"]', captions: '[data-plyr="captions"]',
fullscreen: '[data-plyr="fullscreen"]', fullscreen: '[data-plyr="fullscreen"]',
@@ -5517,10 +5517,299 @@ var defaults = {
// Register for an account here: http://vi.ai/publisher-video-monetization/?aid=plyrio // Register for an account here: http://vi.ai/publisher-video-monetization/?aid=plyrio
ads: { ads: {
enabled: false, enabled: false,
publisherId: '918848828995742' publisherId: ''
} }
}; };
var loadjs_umd = createCommonjsModule(function (module, exports) {
(function(root, factory) {
if (typeof undefined === 'function' && undefined.amd) {
undefined([], factory);
} else {
module.exports = factory();
}
}(commonjsGlobal, function() {
/**
* Global dependencies.
* @global {Object} document - DOM
*/
var devnull = function() {},
bundleIdCache = {},
bundleResultCache = {},
bundleCallbackQueue = {};
/**
* Subscribe to bundle load event.
* @param {string[]} bundleIds - Bundle ids
* @param {Function} callbackFn - The callback function
*/
function subscribe(bundleIds, callbackFn) {
// listify
bundleIds = bundleIds.push ? bundleIds : [bundleIds];
var depsNotFound = [],
i = bundleIds.length,
numWaiting = i,
fn,
bundleId,
r,
q;
// define callback function
fn = function (bundleId, pathsNotFound) {
if (pathsNotFound.length) depsNotFound.push(bundleId);
numWaiting--;
if (!numWaiting) callbackFn(depsNotFound);
};
// register callback
while (i--) {
bundleId = bundleIds[i];
// execute callback if in result cache
r = bundleResultCache[bundleId];
if (r) {
fn(bundleId, r);
continue;
}
// add to callback queue
q = bundleCallbackQueue[bundleId] = bundleCallbackQueue[bundleId] || [];
q.push(fn);
}
}
/**
* Publish bundle load event.
* @param {string} bundleId - Bundle id
* @param {string[]} pathsNotFound - List of files not found
*/
function publish(bundleId, pathsNotFound) {
// exit if id isn't defined
if (!bundleId) return;
var q = bundleCallbackQueue[bundleId];
// cache result
bundleResultCache[bundleId] = pathsNotFound;
// exit if queue is empty
if (!q) return;
// empty callback queue
while (q.length) {
q[0](bundleId, pathsNotFound);
q.splice(0, 1);
}
}
/**
* Execute callbacks.
* @param {Object or Function} args - The callback args
* @param {string[]} depsNotFound - List of dependencies not found
*/
function executeCallbacks(args, depsNotFound) {
// accept function as argument
if (args.call) args = {success: args};
// success and error callbacks
if (depsNotFound.length) (args.error || devnull)(depsNotFound);
else (args.success || devnull)(args);
}
/**
* Load individual file.
* @param {string} path - The file path
* @param {Function} callbackFn - The callback function
*/
function loadFile(path, callbackFn, args, numTries) {
var doc = document,
async = args.async,
maxTries = (args.numRetries || 0) + 1,
beforeCallbackFn = args.before || devnull,
isCss,
e;
numTries = numTries || 0;
if (/(^css!|\.css$)/.test(path)) {
isCss = true;
// css
e = doc.createElement('link');
e.rel = 'stylesheet';
e.href = path.replace(/^css!/, ''); // remove "css!" prefix
} else {
// javascript
e = doc.createElement('script');
e.src = path;
e.async = async === undefined ? true : async;
}
e.onload = e.onerror = e.onbeforeload = function (ev) {
var result = ev.type[0];
// Note: The following code isolates IE using `hideFocus` and treats empty
// stylesheets as failures to get around lack of onerror support
if (isCss && 'hideFocus' in e) {
try {
if (!e.sheet.cssText.length) result = 'e';
} catch (x) {
// sheets objects created from load errors don't allow access to
// `cssText`
result = 'e';
}
}
// handle retries in case of load failure
if (result == 'e') {
// increment counter
numTries += 1;
// exit function and try again
if (numTries < maxTries) {
return loadFile(path, callbackFn, args, numTries);
}
}
// execute callback
callbackFn(path, result, ev.defaultPrevented);
};
// add to document (unless callback returns `false`)
if (beforeCallbackFn(path, e) !== false) doc.head.appendChild(e);
}
/**
* Load multiple files.
* @param {string[]} paths - The file paths
* @param {Function} callbackFn - The callback function
*/
function loadFiles(paths, callbackFn, args) {
// listify paths
paths = paths.push ? paths : [paths];
var numWaiting = paths.length,
x = numWaiting,
pathsNotFound = [],
fn,
i;
// define callback function
fn = function(path, result, defaultPrevented) {
// handle error
if (result == 'e') pathsNotFound.push(path);
// handle beforeload event. If defaultPrevented then that means the load
// will be blocked (ex. Ghostery/ABP on Safari)
if (result == 'b') {
if (defaultPrevented) pathsNotFound.push(path);
else return;
}
numWaiting--;
if (!numWaiting) callbackFn(pathsNotFound);
};
// load scripts
for (i=0; i < x; i++) loadFile(paths[i], fn, args);
}
/**
* Initiate script load and register bundle.
* @param {(string|string[])} paths - The file paths
* @param {(string|Function)} [arg1] - The bundleId or success callback
* @param {Function} [arg2] - The success or error callback
* @param {Function} [arg3] - The error callback
*/
function loadjs(paths, arg1, arg2) {
var bundleId,
args;
// bundleId (if string)
if (arg1 && arg1.trim) bundleId = arg1;
// args (default is {})
args = (bundleId ? arg2 : arg1) || {};
// throw error if bundle is already defined
if (bundleId) {
if (bundleId in bundleIdCache) {
throw "LoadJS";
} else {
bundleIdCache[bundleId] = true;
}
}
// load scripts
loadFiles(paths, function (pathsNotFound) {
// execute callbacks
executeCallbacks(args, pathsNotFound);
// publish bundle load event
publish(bundleId, pathsNotFound);
}, args);
}
/**
* Execute callbacks when dependencies have been satisfied.
* @param {(string|string[])} deps - List of bundle ids
* @param {Object} args - success/error arguments
*/
loadjs.ready = function ready(deps, args) {
// subscribe to bundle load event
subscribe(deps, function (depsNotFound) {
// execute callbacks
executeCallbacks(args, depsNotFound);
});
return loadjs;
};
/**
* Manually satisfy bundle dependencies.
* @param {string} bundleId - The bundle id
*/
loadjs.done = function done(bundleId) {
publish(bundleId, []);
};
/**
* Reset loadjs dependencies statuses
*/
loadjs.reset = function reset() {
bundleIdCache = {};
bundleResultCache = {};
bundleCallbackQueue = {};
};
/**
* Determine if bundle has already been defined
* @param String} bundleId - The bundle id
*/
loadjs.isDefined = function isDefined(bundleId) {
return bundleId in bundleIdCache;
};
// export
return loadjs;
}));
});
var asyncGenerator = function () { var asyncGenerator = function () {
function AwaitValue(value) { function AwaitValue(value) {
this.value = value; this.value = value;
@@ -5884,48 +6173,10 @@ var utils = {
// Load an external script // Load an external script
loadScript: function loadScript(url) { loadScript: function loadScript(url) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
var current = document.querySelector('script[src="' + url + '"]'); loadjs_umd(url, {
success: resolve,
// Check script is not already referenced, if so wait for load error: reject
if (current !== null) { });
current.callbacks = current.callbacks || [];
current.callbacks.push(resolve);
return;
}
// Build the element
var element = document.createElement('script');
// Callback queue
element.callbacks = element.callbacks || [];
element.callbacks.push(resolve);
// Error queue
element.errors = element.errors || [];
element.errors.push(reject);
// Bind callback
element.addEventListener('load', function (event) {
element.callbacks.forEach(function (cb) {
return cb.call(null, event);
});
element.callbacks = null;
}, false);
// Bind error handling
element.addEventListener('error', function (event) {
element.errors.forEach(function (err) {
return err.call(null, event);
});
element.errors = null;
}, false);
// Set the URL after binding callback
element.src = url;
// Inject
var first = document.getElementsByTagName('script')[0];
first.parentNode.insertBefore(element, first);
}); });
}, },
@@ -5940,7 +6191,16 @@ var utils = {
var hasId = utils.is.string(id); var hasId = utils.is.string(id);
var isCached = false; var isCached = false;
function updateSprite(data) { var exists = function exists() {
return document.querySelectorAll('#' + id).length;
};
function injectSprite(data) {
// Check again incase of race condition
if (hasId && exists()) {
return;
}
// Inject content // Inject content
this.innerHTML = data; this.innerHTML = data;
@@ -5948,8 +6208,8 @@ var utils = {
document.body.insertBefore(this, document.body.childNodes[0]); document.body.insertBefore(this, document.body.childNodes[0]);
} }
// Only load once // Only load once if ID set
if (!hasId || !document.querySelectorAll('#' + id).length) { if (!hasId || !exists()) {
// Create container // Create container
var container = document.createElement('div'); var container = document.createElement('div');
utils.toggleHidden(container, true); utils.toggleHidden(container, true);
@@ -5965,7 +6225,7 @@ var utils = {
if (isCached) { if (isCached) {
var data = JSON.parse(cached); var data = JSON.parse(cached);
updateSprite.call(container, data.content); injectSprite.call(container, data.content);
return; return;
} }
} }
@@ -5982,7 +6242,7 @@ var utils = {
})); }));
} }
updateSprite.call(container, result); injectSprite.call(container, result);
}).catch(function () {}); }).catch(function () {});
} }
}, },
@@ -6248,7 +6508,7 @@ var utils = {
pause: utils.getElement.call(this, this.config.selectors.buttons.pause), pause: utils.getElement.call(this, this.config.selectors.buttons.pause),
restart: utils.getElement.call(this, this.config.selectors.buttons.restart), restart: utils.getElement.call(this, this.config.selectors.buttons.restart),
rewind: utils.getElement.call(this, this.config.selectors.buttons.rewind), rewind: utils.getElement.call(this, this.config.selectors.buttons.rewind),
forward: utils.getElement.call(this, this.config.selectors.buttons.forward), fastForward: utils.getElement.call(this, this.config.selectors.buttons.fastForward),
mute: utils.getElement.call(this, this.config.selectors.buttons.mute), mute: utils.getElement.call(this, this.config.selectors.buttons.mute),
pip: utils.getElement.call(this, this.config.selectors.buttons.pip), pip: utils.getElement.call(this, this.config.selectors.buttons.pip),
airplay: utils.getElement.call(this, this.config.selectors.buttons.airplay), airplay: utils.getElement.call(this, this.config.selectors.buttons.airplay),
@@ -6451,6 +6711,7 @@ var utils = {
if (current === 0 || max === 0 || Number.isNaN(current) || Number.isNaN(max)) { if (current === 0 || max === 0 || Number.isNaN(current) || Number.isNaN(max)) {
return 0; return 0;
} }
return (current / max * 100).toFixed(2); return (current / max * 100).toFixed(2);
}, },
@@ -6702,13 +6963,9 @@ var support = {
break; break;
case 'youtube:video': case 'youtube:video':
api = true;
ui = support.rangeInput && (!browser.isIPhone || playsInline);
break;
case 'vimeo:video': case 'vimeo:video':
api = true; api = true;
ui = support.rangeInput && !browser.isIPhone; ui = support.rangeInput && (!browser.isIPhone || playsInline);
break; break;
default: default:
@@ -6875,6 +7132,7 @@ var Console = function () {
// ========================================================================== // ==========================================================================
// Fullscreen wrapper // Fullscreen wrapper
// https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API#prefixing
// ========================================================================== // ==========================================================================
var browser = utils.getBrowser(); var browser = utils.getBrowser();
@@ -6933,6 +7191,7 @@ var Fullscreen = function () {
// Get prefix // Get prefix
this.prefix = Fullscreen.prefix; this.prefix = Fullscreen.prefix;
this.name = Fullscreen.name;
// Scroll position // Scroll position
this.scrollPosition = { x: 0, y: 0 }; this.scrollPosition = { x: 0, y: 0 };
@@ -6996,7 +7255,7 @@ var Fullscreen = function () {
} else if (!this.prefix) { } else if (!this.prefix) {
this.target.requestFullScreen(); this.target.requestFullScreen();
} else if (!utils.is.empty(this.prefix)) { } else if (!utils.is.empty(this.prefix)) {
this.target['' + this.prefix + (this.prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')](); this.target[this.prefix + 'Request' + this.name]();
} }
} }
@@ -7018,7 +7277,8 @@ var Fullscreen = function () {
} else if (!this.prefix) { } else if (!this.prefix) {
document.cancelFullScreen(); document.cancelFullScreen();
} else if (!utils.is.empty(this.prefix)) { } else if (!utils.is.empty(this.prefix)) {
document['' + this.prefix + (this.prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen')](); var action = this.prefix === 'moz' ? 'Cancel' : 'Exit';
document['' + this.prefix + action + this.name]();
} }
} }
@@ -7058,7 +7318,7 @@ var Fullscreen = function () {
return utils.hasClass(this.target, this.player.config.classNames.fullscreen.fallback); return utils.hasClass(this.target, this.player.config.classNames.fullscreen.fallback);
} }
var element = !this.prefix ? document.fullscreenElement : document[this.prefix + 'FullscreenElement']; var element = !this.prefix ? document.fullscreenElement : document['' + this.prefix + this.name + 'Element'];
return element === this.target; return element === this.target;
} }
@@ -7082,7 +7342,7 @@ var Fullscreen = function () {
key: 'prefix', key: 'prefix',
get: function get() { get: function get() {
// No prefix // No prefix
if (utils.is.function(document.cancelFullScreen)) { if (utils.is.function(document.exitFullscreen)) {
return false; return false;
} }
@@ -7091,12 +7351,9 @@ var Fullscreen = function () {
var prefixes = ['webkit', 'moz', 'ms']; var prefixes = ['webkit', 'moz', 'ms'];
prefixes.some(function (pre) { prefixes.some(function (pre) {
if (utils.is.function(document[pre + 'CancelFullScreen'])) { if (utils.is.function(document[pre + 'ExitFullscreen']) || utils.is.function(document[pre + 'CancelFullScreen'])) {
value = pre; value = pre;
return true; return true;
} else if (utils.is.function(document.msExitFullscreen)) {
value = 'ms';
return true;
} }
return false; return false;
@@ -7104,6 +7361,11 @@ var Fullscreen = function () {
return value; return value;
} }
}, {
key: 'name',
get: function get() {
return this.prefix === 'moz' ? 'FullScreen' : 'Fullscreen';
}
}]); }]);
return Fullscreen; return Fullscreen;
}(); }();
@@ -7370,7 +7632,7 @@ var ui = {
var _this = this; var _this = this;
// Re-attach media element listeners // Re-attach media element listeners
// TODO: Use event bubbling // TODO: Use event bubbling?
this.listeners.media(); this.listeners.media();
// Don't setup interface if no support // Don't setup interface if no support
@@ -7589,8 +7851,6 @@ var ui = {
// Update <progress> elements // Update <progress> elements
updateProgress: function updateProgress(event) { updateProgress: function updateProgress(event) {
var _this4 = this;
if (!this.supported.ui || !utils.is.event(event)) { if (!this.supported.ui || !utils.is.event(event)) {
return; return;
} }
@@ -7614,22 +7874,7 @@ var ui = {
// Check buffer status // Check buffer status
case 'playing': case 'playing':
case 'progress': case 'progress':
value = function () { ui.setProgress.call(this, this.elements.display.buffer, this.buffered * 100);
var buffered = _this4.media.buffered;
if (buffered && buffered.length) {
// HTML5
return utils.getPercentage(buffered.end(0), _this4.duration);
} else if (utils.is.number(buffered)) {
// YouTube returns between 0 and 1
return buffered * 100;
}
return 0;
}();
ui.setProgress.call(this, this.elements.display.buffer, value);
break; break;
@@ -8376,7 +8621,7 @@ var controls = {
var type = 'speed'; var type = 'speed';
// Set the default speeds // Set the default speeds
if (!utils.is.object(this.options.speed) || !Object.keys(this.options.speed).length) { if (!utils.is.array(this.options.speed) || !this.options.speed.length) {
this.options.speed = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2]; this.options.speed = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
} }
@@ -8596,7 +8841,7 @@ var controls = {
// Fast forward button // Fast forward button
if (this.config.controls.includes('fast-forward')) { if (this.config.controls.includes('fast-forward')) {
container.appendChild(controls.createButton.call(this, 'fast-forward')); container.appendChild(controls.createButton.call(this, 'fastForward'));
} }
// Progress // Progress
@@ -9173,7 +9418,7 @@ var Listeners = function () {
}); });
// Handle native play/pause // Handle native play/pause
utils.on(this.player.media, 'playing play pause ended', 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);
}); });
@@ -9517,9 +9762,13 @@ var Storage = function () {
createClass(Storage, [{ createClass(Storage, [{
key: 'get', key: 'get',
value: function get(key) { value: function get(key) {
if (!Storage.supported) {
return null;
}
var store = window.localStorage.getItem(this.key); var store = window.localStorage.getItem(this.key);
if (!Storage.supported || utils.is.empty(store)) { if (utils.is.empty(store)) {
return null; return null;
} }
@@ -9557,17 +9806,18 @@ var Storage = function () {
}], [{ }], [{
key: 'supported', key: 'supported',
get: function get() { get: function get() {
if (!('localStorage' in window)) {
return false;
}
var test = '___test';
// Try to use it (it might be disabled, e.g. user is in private mode)
// see: https://github.com/sampotts/plyr/issues/131
try { try {
if (!('localStorage' in window)) {
return false;
}
var test = '___test';
// Try to use it (it might be disabled, e.g. user is in private mode)
// see: https://github.com/sampotts/plyr/issues/131
window.localStorage.setItem(test, test); window.localStorage.setItem(test, test);
window.localStorage.removeItem(test); window.localStorage.removeItem(test);
return true; return true;
} catch (e) { } catch (e) {
return false; return false;
@@ -10588,6 +10838,8 @@ var youtube = {
// Reset timer // Reset timer
clearInterval(player.timers.playing); clearInterval(player.timers.playing);
console.warn(event.data);
// Handle events // Handle events
// -1 Unstarted // -1 Unstarted
// 0 Ended // 0 Ended
@@ -10596,6 +10848,16 @@ var youtube = {
// 3 Buffering // 3 Buffering
// 5 Video cued // 5 Video cued
switch (event.data) { switch (event.data) {
case -1:
// Update scrubber
utils.dispatchEvent.call(player, player.media, 'timeupdate');
// Get loaded % from YouTube
player.media.buffered = instance.getVideoLoadedFraction();
utils.dispatchEvent.call(player, player.media, 'progress');
break;
case 0: case 0:
player.media.paused = true; player.media.paused = true;
@@ -10695,7 +10957,7 @@ var vimeo = {
setAspectRatio: function setAspectRatio(input) { setAspectRatio: function setAspectRatio(input) {
var ratio = utils.is.string(input) ? input.split(':') : this.config.ratio.split(':'); var ratio = utils.is.string(input) ? input.split(':') : this.config.ratio.split(':');
var padding = 100 / ratio[0] * ratio[1]; var padding = 100 / ratio[0] * ratio[1];
var height = 200; var height = 240;
var offset = (height - padding) / (height / 50); var offset = (height - padding) / (height / 50);
this.elements.wrapper.style.paddingBottom = padding + '%'; this.elements.wrapper.style.paddingBottom = padding + '%';
this.media.style.transform = 'translateY(-' + offset + '%)'; this.media.style.transform = 'translateY(-' + offset + '%)';
@@ -10765,10 +11027,8 @@ var vimeo = {
}; };
player.media.stop = function () { player.media.stop = function () {
player.embed.stop().then(function () { player.pause();
player.media.paused = true; player.currentTime = 0;
player.currentTime = 0;
});
}; };
// Seeking // Seeking
@@ -11232,7 +11492,7 @@ var source = {
// ========================================================================== // ==========================================================================
// Plyr // Plyr
// plyr.js v3.0.0-beta.20 // plyr.js v3.0.3
// https://github.com/sampotts/plyr // https://github.com/sampotts/plyr
// License: The MIT License (MIT) // License: The MIT License (MIT)
// ========================================================================== // ==========================================================================
@@ -11516,6 +11776,10 @@ var Plyr$1 = function () {
value: function play() { value: function play() {
var _this2 = this; var _this2 = this;
if (!utils.is.function(this.media.play)) {
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(function () {
@@ -11536,7 +11800,7 @@ var Plyr$1 = function () {
}, { }, {
key: 'pause', key: 'pause',
value: function pause() { value: function pause() {
if (!this.playing) { if (!this.playing || !utils.is.function(this.media.pause)) {
return; return;
} }
@@ -11573,8 +11837,11 @@ var Plyr$1 = function () {
}, { }, {
key: 'stop', key: 'stop',
value: function stop() { value: function stop() {
this.restart(); if (this.isHTML5) {
this.pause(); this.media.load();
} else {
this.media.stop();
}
} }
/** /**
@@ -11839,6 +12106,10 @@ var Plyr$1 = function () {
var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
if (!this.ready) {
return;
}
var done = function done() { var done = function done() {
// Reset overflow (incase destroyed while in fullscreen) // Reset overflow (incase destroyed while in fullscreen)
document.body.style.overflow = ''; document.body.style.overflow = '';
@@ -11881,6 +12152,9 @@ var Plyr$1 = function () {
callback.call(_this4.elements.original); callback.call(_this4.elements.original);
} }
// Reset state
_this4.ready = false;
// Clear for garbage collection // Clear for garbage collection
setTimeout(function () { setTimeout(function () {
_this4.elements = null; _this4.elements = null;
@@ -11913,7 +12187,7 @@ var Plyr$1 = function () {
clearInterval(this.timers.playing); clearInterval(this.timers.playing);
// Destroy YouTube API // Destroy YouTube API
if (this.embed !== null) { if (this.embed !== null && utils.is.function(this.embed.destroy)) {
this.embed.destroy(); this.embed.destroy();
} }
@@ -11960,37 +12234,37 @@ var Plyr$1 = function () {
}, { }, {
key: 'isHTML5', key: 'isHTML5',
get: function get() { get: function get() {
return this.provider === providers.html5; return Boolean(this.provider === providers.html5);
} }
}, { }, {
key: 'isEmbed', key: 'isEmbed',
get: function get() { get: function get() {
return this.isYouTube || this.isVimeo; return Boolean(this.isYouTube || this.isVimeo);
} }
}, { }, {
key: 'isYouTube', key: 'isYouTube',
get: function get() { get: function get() {
return this.provider === providers.youtube; return Boolean(this.provider === providers.youtube);
} }
}, { }, {
key: 'isVimeo', key: 'isVimeo',
get: function get() { get: function get() {
return this.provider === providers.vimeo; return Boolean(this.provider === providers.vimeo);
} }
}, { }, {
key: 'isVideo', key: 'isVideo',
get: function get() { get: function get() {
return this.type === types.video; return Boolean(this.type === types.video);
} }
}, { }, {
key: 'isAudio', key: 'isAudio',
get: function get() { get: function get() {
return this.type === types.audio; return Boolean(this.type === types.audio);
} }
}, { }, {
key: 'paused', key: 'paused',
get: function get() { get: function get() {
return this.media.paused; return Boolean(this.media.paused);
} }
/** /**
@@ -12000,7 +12274,7 @@ var Plyr$1 = function () {
}, { }, {
key: 'playing', key: 'playing',
get: function get() { get: function get() {
return !this.paused && !this.ended && (this.isHTML5 ? this.media.readyState > 2 : true); return Boolean(!this.paused && !this.ended && (this.isHTML5 ? this.media.readyState > 2 : true));
} }
/** /**
@@ -12010,7 +12284,7 @@ var Plyr$1 = function () {
}, { }, {
key: 'ended', key: 'ended',
get: function get() { get: function get() {
return this.media.ended; return Boolean(this.media.ended);
} }
}, { }, {
key: 'currentTime', key: 'currentTime',
@@ -12029,7 +12303,7 @@ var Plyr$1 = function () {
} }
// Set // Set
this.media.currentTime = targetTime.toFixed(4); this.media.currentTime = parseFloat(targetTime.toFixed(4));
// Logging // Logging
this.debug.log('Seeking to ' + this.currentTime + ' seconds'); this.debug.log('Seeking to ' + this.currentTime + ' seconds');
@@ -12043,6 +12317,31 @@ var Plyr$1 = function () {
return Number(this.media.currentTime); return Number(this.media.currentTime);
} }
/**
* Get buffered
*/
}, {
key: 'buffered',
get: function get() {
var buffered = this.media.buffered;
// YouTube / Vimeo return a float between 0-1
if (utils.is.number(buffered)) {
return buffered;
}
// HTML5
// TODO: Handle buffered chunks of the media
// (i.e. seek to another section buffers only that section)
if (buffered && buffered.length && this.duration > 0) {
return buffered.end(0) / this.duration;
}
return 0;
}
/** /**
* Get seeking status * Get seeking status
*/ */
@@ -12050,7 +12349,7 @@ var Plyr$1 = function () {
}, { }, {
key: 'seeking', key: 'seeking',
get: function get() { get: function get() {
return this.media.seeking; return Boolean(this.media.seeking);
} }
/** /**
@@ -12064,7 +12363,7 @@ var Plyr$1 = function () {
var fauxDuration = parseInt(this.config.duration, 10); var fauxDuration = parseInt(this.config.duration, 10);
// True duration // True duration
var realDuration = Number(this.media.duration); var realDuration = this.media ? Number(this.media.duration) : 0;
// If custom duration is funky, use regular duration // If custom duration is funky, use regular duration
return !Number.isNaN(fauxDuration) ? fauxDuration : realDuration; return !Number.isNaN(fauxDuration) ? fauxDuration : realDuration;
@@ -12122,7 +12421,7 @@ var Plyr$1 = function () {
*/ */
, ,
get: function get() { get: function get() {
return this.media.volume; return Number(this.media.volume);
} }
}, { }, {
key: 'muted', key: 'muted',
@@ -12151,7 +12450,7 @@ var Plyr$1 = function () {
*/ */
, ,
get: function get() { get: function get() {
return this.media.muted; return Boolean(this.media.muted);
} }
/** /**
@@ -12171,12 +12470,12 @@ var Plyr$1 = function () {
} }
// Get audio tracks // Get audio tracks
return this.media.mozHasAudio || Boolean(this.media.webkitAudioDecodedByteCount) || Boolean(this.media.audioTracks && this.media.audioTracks.length); return Boolean(this.media.mozHasAudio) || Boolean(this.media.webkitAudioDecodedByteCount) || Boolean(this.media.audioTracks && this.media.audioTracks.length);
} }
/** /**
* Set playback speed * Set playback speed
* @param {decimal} speed - the speed of playback (0.5-2.0) * @param {number} speed - the speed of playback (0.5-2.0)
*/ */
}, { }, {
@@ -12221,7 +12520,7 @@ var Plyr$1 = function () {
*/ */
, ,
get: function get() { get: function get() {
return this.media.playbackRate; return Number(this.media.playbackRate);
} }
/** /**
@@ -12324,7 +12623,7 @@ var Plyr$1 = function () {
*/ */
, ,
get: function get() { get: function get() {
return this.media.loop; return Boolean(this.media.loop);
} }
/** /**
@@ -12393,7 +12692,7 @@ var Plyr$1 = function () {
*/ */
, ,
get: function get() { get: function get() {
return this.config.autoplay; return Boolean(this.config.autoplay);
} }
}, { }, {
key: 'language', key: 'language',
@@ -12500,7 +12799,7 @@ var Plyr$1 = function () {
// ========================================================================== // ==========================================================================
// Plyr Polyfilled Build // Plyr Polyfilled Build
// plyr.js v3.0.0-beta.19 // plyr.js v3.0.2
// https://github.com/sampotts/plyr // https://github.com/sampotts/plyr
// License: The MIT License (MIT) // License: The MIT License (MIT)
// ========================================================================== // ==========================================================================
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+23 -18
View File
@@ -70,10 +70,11 @@ const paths = {
root: path.join(root, 'demo/'), root: path.join(root, 'demo/'),
}, },
upload: [ upload: [
path.join(root, `dist/*${minSuffix}.js`), path.join(root, `dist/*${minSuffix}.*`),
path.join(root, 'dist/*.css'), path.join(root, 'dist/*.css'),
path.join(root, 'dist/*.svg'), path.join(root, 'dist/*.svg'),
path.join(root, 'demo/dist/**'), path.join(root, `demo/dist/*${minSuffix}.*`),
path.join(root, 'demo/dist/*.css'),
], ],
}; };
@@ -303,22 +304,26 @@ if (Object.keys(aws).includes('cdn') && Object.keys(aws).includes('demo')) {
console.log(`Uploading '${version}' to ${aws.cdn.domain}...`); console.log(`Uploading '${version}' to ${aws.cdn.domain}...`);
// Upload to CDN // Upload to CDN
return gulp return (
.src(paths.upload) gulp
.pipe( .src(paths.upload)
rename(p => { .pipe(
p.basename = p.basename.replace(minSuffix, ''); // eslint-disable-line rename(p => {
p.dirname = p.dirname.replace('.', version); // eslint-disable-line p.basename = p.basename.replace(minSuffix, ''); // eslint-disable-line
}), p.dirname = p.dirname.replace('.', version); // eslint-disable-line
) }),
.pipe( )
size({ // Remove min suffix from source map URL
showFiles: true, .pipe(replace(/sourceMappingURL=([\w-?.]+)/, (match, p1) => `sourceMappingURL=${p1.replace(minSuffix, '')}`))
gzip: true, .pipe(
}), size({
) showFiles: true,
.pipe(replace(localPath, versionPath)) gzip: true,
.pipe(s3(aws.cdn, options.cdn)); }),
)
.pipe(replace(localPath, versionPath))
.pipe(s3(aws.cdn, options.cdn))
);
}); });
// Publish to demo bucket // Publish to demo bucket
+8 -4
View File
@@ -1,6 +1,6 @@
{ {
"name": "plyr", "name": "plyr",
"version": "3.0.0-beta.20", "version": "3.0.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",
"main": "./dist/plyr.js", "main": "./dist/plyr.js",
@@ -13,7 +13,7 @@
"babel-plugin-external-helpers": "^6.22.0", "babel-plugin-external-helpers": "^6.22.0",
"babel-preset-env": "^1.6.1", "babel-preset-env": "^1.6.1",
"del": "^3.0.0", "del": "^3.0.0",
"eslint": "^4.18.2", "eslint": "^4.19.0",
"eslint-config-airbnb-base": "^12.1.0", "eslint-config-airbnb-base": "^12.1.0",
"eslint-config-prettier": "^2.9.0", "eslint-config-prettier": "^2.9.0",
"eslint-plugin-import": "^2.9.0", "eslint-plugin-import": "^2.9.0",
@@ -35,11 +35,13 @@
"gulp-svgstore": "^6.1.1", "gulp-svgstore": "^6.1.1",
"gulp-uglify-es": "^1.0.1", "gulp-uglify-es": "^1.0.1",
"gulp-util": "^3.0.8", "gulp-util": "^3.0.8",
"prettier-eslint": "^8.8.1",
"prettier-stylelint": "^0.4.2",
"rollup-plugin-babel": "^3.0.3", "rollup-plugin-babel": "^3.0.3",
"rollup-plugin-commonjs": "^8.4.1", "rollup-plugin-commonjs": "^8.4.1",
"rollup-plugin-node-resolve": "^3.2.0", "rollup-plugin-node-resolve": "^3.2.0",
"run-sequence": "^2.2.1", "run-sequence": "^2.2.1",
"stylelint": "^9.1.1", "stylelint": "^9.1.3",
"stylelint-config-prettier": "^3.0.4", "stylelint-config-prettier": "^3.0.4",
"stylelint-config-recommended": "^2.1.0", "stylelint-config-recommended": "^2.1.0",
"stylelint-config-sass-guidelines": "^5.0.0", "stylelint-config-sass-guidelines": "^5.0.0",
@@ -65,6 +67,8 @@
"author": "Sam Potts <sam@potts.es>", "author": "Sam Potts <sam@potts.es>",
"dependencies": { "dependencies": {
"babel-polyfill": "^6.26.0", "babel-polyfill": "^6.26.0",
"custom-event-polyfill": "^0.3.0" "custom-event-polyfill": "^0.3.0",
"loadjs": "^3.5.2",
"raven-js": "^3.23.3"
} }
} }
+19 -11
View File
@@ -1,25 +1,21 @@
---
Beware: This version is currently in beta and not production-ready
---
# Plyr # Plyr
A simple, lightweight, accessible and customizable HTML5, YouTube and Vimeo media player that supports [_modern_](#browser-support) browsers. A simple, lightweight, accessible and customizable HTML5, YouTube and Vimeo media player that supports [_modern_](#browser-support) browsers.
[Checkout the demo](https://plyr.io) - [Donate to support Plyr](#donate) - [Chat on Slack](https://bit.ly/plyr-slack) [Checkout the demo](https://plyr.io) - [Donate to support Plyr](#donate) - [Chat on Slack](https://bit.ly/plyr-slack)
[![Image of Plyr](https://cdn.plyr.io/static/demo/screenshot.png)](https://plyr.io) [![Image of Plyr](https://cdn.plyr.io/static/demo/screenshot.png?v=3)](https://plyr.io)
## Features ## Features
* **Accessible** - full support for VTT captions and screen readers * **Accessible** - full support for VTT captions and screen readers
* **Lightweight** - just 18KB minified and gzipped
* **[Customisable](#html)** - make the player look how you want with the markup you want * **[Customisable](#html)** - make the player look how you want with the markup you want
* **Semantic** - uses the _right_ elements. `<input type="range">` for volume and `<progress>` for progress and well, `<button>`s for buttons. There's no * **Semantic** - uses the _right_ elements. `<input type="range">` for volume and `<progress>` for progress and well, `<button>`s for buttons. There's no
`<span>` or `<a href="#">` button hacks `<span>` or `<a href="#">` button hacks
* **Responsive** - works with any screen size * **Responsive** - works with any screen size
* **HTML Video & Audio** - support for both formats * **HTML Video & Audio** - support for both formats
* **[Embedded Video](#embeds)** - support for YouTube and Vimeo video playback * **[Embedded Video](#embeds)** - support for YouTube and Vimeo video playback
* **[Monetization](#ads)** - make money from your videos
* **[Streaming](#streaming)** - support for hls.js, Shaka and dash.js streaming playback * **[Streaming](#streaming)** - support for hls.js, Shaka and dash.js streaming playback
* **[API](#api)** - toggle playback, volume, seeking, and more through a standardized API * **[API](#api)** - toggle playback, volume, seeking, and more through a standardized API
* **[Events](#events)** - no messing around with Vimeo and YouTube APIs, all events are standardized across formats * **[Events](#events)** - no messing around with Vimeo and YouTube APIs, all events are standardized across formats
@@ -128,7 +124,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.0-beta.20/plyr.js"></script> <script src="https://cdn.plyr.io/3.0.3/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 +140,23 @@ 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.0-beta.20/plyr.css"> <link rel="stylesheet" href="https://cdn.plyr.io/3.0.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.0.0-beta.20/plyr.svg`. reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.0.3/plyr.svg`.
## Ads
Plyr has partnered up with [vi.ai](http://vi.ai/publisher-video-monetization/?aid=plyrio) to offer monetization options for your videos. Getting setup is easy:
* [Sign up for a vi.ai account](http://vi.ai/publisher-video-monetization/?aid=plyrio)
* Grab your publisher ID from the code snippet
* Enable ads in the [config options](#options) and enter your publisher ID
Any questions regarding the ads can be sent straight to vi.ai and any issues with rendering raised through GitHub issues.
## Advanced ## Advanced
@@ -230,7 +236,7 @@ The NodeList, HTMLElement or string selector can be the target `<video>`, `<audi
const players = Array.from(document.querySelectorAll('.js-player')).map(player => new Plyr(player)); const players = Array.from(document.querySelectorAll('.js-player')).map(player => new Plyr(player));
``` ```
The second argument for the constructor is the [#options](options) object: The second argument for the constructor is the [options](#options) object:
```javascript ```javascript
const player = new Plyr('#player', { const player = new Plyr('#player', {
@@ -284,6 +290,7 @@ Note the single quotes encapsulating the JSON and double quotes on the object ke
| `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: '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. |
| `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 vi.ai ads. `publisherId`: Your unique vi.ai publisher ID. |
1. Vimeo only 1. Vimeo only
@@ -366,6 +373,7 @@ player.fullscreen.active; // false;
| `paused` | ✓ | - | Returns a boolean indicating if the current player is paused. | | `paused` | ✓ | - | Returns a boolean indicating if the current player is paused. |
| `playing` | ✓ | - | Returns a boolean indicating if the current player is playing. | | `playing` | ✓ | - | Returns a boolean indicating if the current player is playing. |
| `ended` | ✓ | - | Returns a boolean indicating if the current player has finished playback. | | `ended` | ✓ | - | Returns a boolean indicating if the current player has finished playback. |
| `buffered` | ✓ | - | Returns a float between 0 and 1 indicating how much of the media is buffered |
| `currentTime` | ✓ | ✓ | Gets or sets the currentTime for the player. The setter accepts a float in seconds. | | `currentTime` | ✓ | ✓ | Gets or sets the currentTime for the player. The setter accepts a float in seconds. |
| `seeking` | ✓ | - | Returns a boolean indicating if the current player is seeking. | | `seeking` | ✓ | - | Returns a boolean indicating if the current player is seeking. |
| `duration` | ✓ | - | Returns the duration for the current media. | | `duration` | ✓ | - | Returns the duration for the current media. |
@@ -695,7 +703,7 @@ Credit to the PayPal HTML5 Video player from which Plyr's caption functionality
## Thanks ## Thanks
[![Fastly](https://www.fastly.com/sites/all/themes/custom/fastly2016/logo.png)](https://www.fastly.com/) [![Fastly](https://cdn.plyr.io/static/demo/fastly-logo.png)](https://www.fastly.com/)
Massive thanks to [Fastly](https://www.fastly.com/) for providing the CDN services. Massive thanks to [Fastly](https://www.fastly.com/) for providing the CDN services.
+2 -2
View File
@@ -708,7 +708,7 @@ const controls = {
const type = 'speed'; const type = 'speed';
// Set the default speeds // Set the default speeds
if (!utils.is.object(this.options.speed) || !Object.keys(this.options.speed).length) { if (!utils.is.array(this.options.speed) || !this.options.speed.length) {
this.options.speed = [ this.options.speed = [
0.5, 0.5,
0.75, 0.75,
@@ -927,7 +927,7 @@ const controls = {
// Fast forward button // Fast forward button
if (this.config.controls.includes('fast-forward')) { if (this.config.controls.includes('fast-forward')) {
container.appendChild(controls.createButton.call(this, 'fast-forward')); container.appendChild(controls.createButton.call(this, 'fastForward'));
} }
// Progress // Progress
+3 -3
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.0-beta.20/plyr.svg', iconUrl: 'https://cdn.plyr.io/3.0.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',
@@ -283,7 +283,7 @@ const defaults = {
pause: '[data-plyr="pause"]', pause: '[data-plyr="pause"]',
restart: '[data-plyr="restart"]', restart: '[data-plyr="restart"]',
rewind: '[data-plyr="rewind"]', rewind: '[data-plyr="rewind"]',
forward: '[data-plyr="fast-forward"]', fastForward: '[data-plyr="fast-forward"]',
mute: '[data-plyr="mute"]', mute: '[data-plyr="mute"]',
captions: '[data-plyr="captions"]', captions: '[data-plyr="captions"]',
fullscreen: '[data-plyr="fullscreen"]', fullscreen: '[data-plyr="fullscreen"]',
@@ -376,7 +376,7 @@ const defaults = {
// Register for an account here: http://vi.ai/publisher-video-monetization/?aid=plyrio // Register for an account here: http://vi.ai/publisher-video-monetization/?aid=plyrio
ads: { ads: {
enabled: false, enabled: false,
publisherId: '918848828995742', publisherId: '',
}, },
}; };
+12 -8
View File
@@ -1,5 +1,6 @@
// ========================================================================== // ==========================================================================
// Fullscreen wrapper // Fullscreen wrapper
// https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API#prefixing
// ========================================================================== // ==========================================================================
import utils from './utils'; import utils from './utils';
@@ -54,6 +55,7 @@ class Fullscreen {
// Get prefix // Get prefix
this.prefix = Fullscreen.prefix; this.prefix = Fullscreen.prefix;
this.name = Fullscreen.name;
// Scroll position // Scroll position
this.scrollPosition = { x: 0, y: 0 }; this.scrollPosition = { x: 0, y: 0 };
@@ -85,7 +87,7 @@ class Fullscreen {
// Get the prefix for handlers // Get the prefix for handlers
static get prefix() { static get prefix() {
// No prefix // No prefix
if (utils.is.function(document.cancelFullScreen)) { if (utils.is.function(document.exitFullscreen)) {
return false; return false;
} }
@@ -98,12 +100,9 @@ class Fullscreen {
]; ];
prefixes.some(pre => { prefixes.some(pre => {
if (utils.is.function(document[`${pre}CancelFullScreen`])) { if (utils.is.function(document[`${pre}ExitFullscreen`]) || utils.is.function(document[`${pre}CancelFullScreen`])) {
value = pre; value = pre;
return true; return true;
} else if (utils.is.function(document.msExitFullscreen)) {
value = 'ms';
return true;
} }
return false; return false;
@@ -112,6 +111,10 @@ class Fullscreen {
return value; return value;
} }
static get name() {
return this.prefix === 'moz' ? 'FullScreen' : 'Fullscreen';
}
// Determine if fullscreen is enabled // Determine if fullscreen is enabled
get enabled() { get enabled() {
const fallback = this.player.config.fullscreen.fallback && !utils.inFrame(); const fallback = this.player.config.fullscreen.fallback && !utils.inFrame();
@@ -130,7 +133,7 @@ class Fullscreen {
return utils.hasClass(this.target, this.player.config.classNames.fullscreen.fallback); return utils.hasClass(this.target, this.player.config.classNames.fullscreen.fallback);
} }
const element = !this.prefix ? document.fullscreenElement : document[`${this.prefix}FullscreenElement`]; const element = !this.prefix ? document.fullscreenElement : document[`${this.prefix}${this.name}Element`];
return element === this.target; return element === this.target;
} }
@@ -168,7 +171,7 @@ class Fullscreen {
} else if (!this.prefix) { } else if (!this.prefix) {
this.target.requestFullScreen(); this.target.requestFullScreen();
} else if (!utils.is.empty(this.prefix)) { } else if (!utils.is.empty(this.prefix)) {
this.target[`${this.prefix}${this.prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen'}`](); this.target[`${this.prefix}Request${this.name}`]();
} }
} }
@@ -187,7 +190,8 @@ class Fullscreen {
} else if (!this.prefix) { } else if (!this.prefix) {
document.cancelFullScreen(); document.cancelFullScreen();
} else if (!utils.is.empty(this.prefix)) { } else if (!utils.is.empty(this.prefix)) {
document[`${this.prefix}${this.prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen'}`](); const action = this.prefix === 'moz' ? 'Cancel' : 'Exit';
document[`${this.prefix}${action}${this.name}`]();
} }
} }
+1 -1
View File
@@ -267,7 +267,7 @@ class Listeners {
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 native play/pause
utils.on(this.player.media, 'playing play pause ended', 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
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));
+3 -5
View File
@@ -34,7 +34,7 @@ const vimeo = {
setAspectRatio(input) { setAspectRatio(input) {
const ratio = utils.is.string(input) ? input.split(':') : this.config.ratio.split(':'); const ratio = utils.is.string(input) ? input.split(':') : this.config.ratio.split(':');
const padding = 100 / ratio[0] * ratio[1]; const padding = 100 / ratio[0] * ratio[1];
const height = 200; const height = 240;
const offset = (height - padding) / (height / 50); const offset = (height - padding) / (height / 50);
this.elements.wrapper.style.paddingBottom = `${padding}%`; this.elements.wrapper.style.paddingBottom = `${padding}%`;
this.media.style.transform = `translateY(-${offset}%)`; this.media.style.transform = `translateY(-${offset}%)`;
@@ -101,10 +101,8 @@ const vimeo = {
}; };
player.media.stop = () => { player.media.stop = () => {
player.embed.stop().then(() => { player.pause();
player.media.paused = true; player.currentTime = 0;
player.currentTime = 0;
});
}; };
// Seeking // Seeking
+12
View File
@@ -339,6 +339,8 @@ const youtube = {
// Reset timer // Reset timer
clearInterval(player.timers.playing); clearInterval(player.timers.playing);
console.warn(event.data);
// Handle events // Handle events
// -1 Unstarted // -1 Unstarted
// 0 Ended // 0 Ended
@@ -347,6 +349,16 @@ const youtube = {
// 3 Buffering // 3 Buffering
// 5 Video cued // 5 Video cued
switch (event.data) { switch (event.data) {
case -1:
// Update scrubber
utils.dispatchEvent.call(player, player.media, 'timeupdate');
// Get loaded % from YouTube
player.media.buffered = instance.getVideoLoadedFraction();
utils.dispatchEvent.call(player, player.media, 'progress');
break;
case 0: case 0:
player.media.paused = true; player.media.paused = true;
+63 -24
View File
@@ -1,6 +1,6 @@
// ========================================================================== // ==========================================================================
// Plyr // Plyr
// plyr.js v3.0.0-beta.20 // plyr.js v3.0.3
// https://github.com/sampotts/plyr // https://github.com/sampotts/plyr
// License: The MIT License (MIT) // License: The MIT License (MIT)
// ========================================================================== // ==========================================================================
@@ -293,28 +293,32 @@ class Plyr {
* Types and provider helpers * Types and provider helpers
*/ */
get isHTML5() { get isHTML5() {
return this.provider === providers.html5; return Boolean(this.provider === providers.html5);
} }
get isEmbed() { get isEmbed() {
return this.isYouTube || this.isVimeo; return Boolean(this.isYouTube || this.isVimeo);
} }
get isYouTube() { get isYouTube() {
return this.provider === providers.youtube; return Boolean(this.provider === providers.youtube);
} }
get isVimeo() { get isVimeo() {
return this.provider === providers.vimeo; return Boolean(this.provider === providers.vimeo);
} }
get isVideo() { get isVideo() {
return this.type === types.video; return Boolean(this.type === types.video);
} }
get isAudio() { get isAudio() {
return this.type === types.audio; return Boolean(this.type === types.audio);
} }
/** /**
* Play the media, or play the advertisement (if they are not blocked) * Play the media, or play the advertisement (if they are not blocked)
*/ */
play() { play() {
if (!utils.is.function(this.media.play)) {
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(() => this.ads.play()).catch(() => this.media.play()); return this.ads.managerPromise.then(() => this.ads.play()).catch(() => this.media.play());
@@ -328,7 +332,7 @@ class Plyr {
* Pause the media * Pause the media
*/ */
pause() { pause() {
if (!this.playing) { if (!this.playing || !utils.is.function(this.media.pause)) {
return; return;
} }
@@ -339,21 +343,21 @@ class Plyr {
* Get paused state * Get paused state
*/ */
get paused() { get paused() {
return this.media.paused; return Boolean(this.media.paused);
} }
/** /**
* Get playing state * Get playing state
*/ */
get playing() { get playing() {
return !this.paused && !this.ended && (this.isHTML5 ? this.media.readyState > 2 : true); return Boolean(!this.paused && !this.ended && (this.isHTML5 ? this.media.readyState > 2 : true));
} }
/** /**
* Get ended state * Get ended state
*/ */
get ended() { get ended() {
return this.media.ended; return Boolean(this.media.ended);
} }
/** /**
@@ -375,8 +379,11 @@ class Plyr {
* Stop playback * Stop playback
*/ */
stop() { stop() {
this.restart(); if (this.isHTML5) {
this.pause(); this.media.load();
} else {
this.media.stop();
}
} }
/** /**
@@ -421,7 +428,7 @@ class Plyr {
} }
// Set // Set
this.media.currentTime = targetTime.toFixed(4); this.media.currentTime = parseFloat(targetTime.toFixed(4));
// Logging // Logging
this.debug.log(`Seeking to ${this.currentTime} seconds`); this.debug.log(`Seeking to ${this.currentTime} seconds`);
@@ -434,11 +441,32 @@ class Plyr {
return Number(this.media.currentTime); return Number(this.media.currentTime);
} }
/**
* Get buffered
*/
get buffered() {
const { buffered } = this.media;
// YouTube / Vimeo return a float between 0-1
if (utils.is.number(buffered)) {
return buffered;
}
// HTML5
// TODO: Handle buffered chunks of the media
// (i.e. seek to another section buffers only that section)
if (buffered && buffered.length && this.duration > 0) {
return buffered.end(0) / this.duration;
}
return 0;
}
/** /**
* Get seeking status * Get seeking status
*/ */
get seeking() { get seeking() {
return this.media.seeking; return Boolean(this.media.seeking);
} }
/** /**
@@ -449,7 +477,7 @@ class Plyr {
const fauxDuration = parseInt(this.config.duration, 10); const fauxDuration = parseInt(this.config.duration, 10);
// True duration // True duration
const realDuration = Number(this.media.duration); const realDuration = this.media ? Number(this.media.duration) : 0;
// If custom duration is funky, use regular duration // If custom duration is funky, use regular duration
return !Number.isNaN(fauxDuration) ? fauxDuration : realDuration; return !Number.isNaN(fauxDuration) ? fauxDuration : realDuration;
@@ -503,7 +531,7 @@ class Plyr {
* Get the current player volume * Get the current player volume
*/ */
get volume() { get volume() {
return this.media.volume; return Number(this.media.volume);
} }
/** /**
@@ -552,7 +580,7 @@ class Plyr {
* Get current muted state * Get current muted state
*/ */
get muted() { get muted() {
return this.media.muted; return Boolean(this.media.muted);
} }
/** /**
@@ -569,12 +597,16 @@ class Plyr {
} }
// Get audio tracks // Get audio tracks
return this.media.mozHasAudio || Boolean(this.media.webkitAudioDecodedByteCount) || Boolean(this.media.audioTracks && this.media.audioTracks.length); return (
Boolean(this.media.mozHasAudio) ||
Boolean(this.media.webkitAudioDecodedByteCount) ||
Boolean(this.media.audioTracks && this.media.audioTracks.length)
);
} }
/** /**
* Set playback speed * Set playback speed
* @param {decimal} speed - the speed of playback (0.5-2.0) * @param {number} speed - the speed of playback (0.5-2.0)
*/ */
set speed(input) { set speed(input) {
let speed = null; let speed = null;
@@ -615,7 +647,7 @@ class Plyr {
* Get current playback speed * Get current playback speed
*/ */
get speed() { get speed() {
return this.media.playbackRate; return Number(this.media.playbackRate);
} }
/** /**
@@ -715,7 +747,7 @@ class Plyr {
* Get current loop state * Get current loop state
*/ */
get loop() { get loop() {
return this.media.loop; return Boolean(this.media.loop);
} }
/** /**
@@ -772,7 +804,7 @@ class Plyr {
* Get the current autoplay state * Get the current autoplay state
*/ */
get autoplay() { get autoplay() {
return this.config.autoplay; return Boolean(this.config.autoplay);
} }
/** /**
@@ -1029,6 +1061,10 @@ class Plyr {
* @param {boolean} soft - Whether it's a soft destroy (for source changes etc) * @param {boolean} soft - Whether it's a soft destroy (for source changes etc)
*/ */
destroy(callback, soft = false) { destroy(callback, soft = false) {
if (!this.ready) {
return;
}
const done = () => { const done = () => {
// Reset overflow (incase destroyed while in fullscreen) // Reset overflow (incase destroyed while in fullscreen)
document.body.style.overflow = ''; document.body.style.overflow = '';
@@ -1071,6 +1107,9 @@ class Plyr {
callback.call(this.elements.original); callback.call(this.elements.original);
} }
// Reset state
this.ready = false;
// Clear for garbage collection // Clear for garbage collection
setTimeout(() => { setTimeout(() => {
this.elements = null; this.elements = null;
@@ -1103,7 +1142,7 @@ class Plyr {
clearInterval(this.timers.playing); clearInterval(this.timers.playing);
// Destroy YouTube API // Destroy YouTube API
if (this.embed !== null) { if (this.embed !== null && utils.is.function(this.embed.destroy)) {
this.embed.destroy(); this.embed.destroy();
} }
+1 -1
View File
@@ -1,6 +1,6 @@
// ========================================================================== // ==========================================================================
// Plyr Polyfilled Build // Plyr Polyfilled Build
// plyr.js v3.0.0-beta.20 // plyr.js v3.0.3
// https://github.com/sampotts/plyr // https://github.com/sampotts/plyr
// License: The MIT License (MIT) // License: The MIT License (MIT)
// ========================================================================== // ==========================================================================
+14 -9
View File
@@ -12,17 +12,18 @@ class Storage {
// Check for actual support (see if we can use it) // Check for actual support (see if we can use it)
static get supported() { static get supported() {
if (!('localStorage' in window)) {
return false;
}
const test = '___test';
// Try to use it (it might be disabled, e.g. user is in private mode)
// see: https://github.com/sampotts/plyr/issues/131
try { try {
if (!('localStorage' in window)) {
return false;
}
const test = '___test';
// Try to use it (it might be disabled, e.g. user is in private mode)
// see: https://github.com/sampotts/plyr/issues/131
window.localStorage.setItem(test, test); window.localStorage.setItem(test, test);
window.localStorage.removeItem(test); window.localStorage.removeItem(test);
return true; return true;
} catch (e) { } catch (e) {
return false; return false;
@@ -30,9 +31,13 @@ class Storage {
} }
get(key) { get(key) {
if (!Storage.supported) {
return null;
}
const store = window.localStorage.getItem(this.key); const store = window.localStorage.getItem(this.key);
if (!Storage.supported || utils.is.empty(store)) { if (utils.is.empty(store)) {
return null; return null;
} }
+1 -5
View File
@@ -30,13 +30,9 @@ const support = {
break; break;
case 'youtube:video': case 'youtube:video':
api = true;
ui = support.rangeInput && (!browser.isIPhone || playsInline);
break;
case 'vimeo:video': case 'vimeo:video':
api = true; api = true;
ui = support.rangeInput && !browser.isIPhone; ui = support.rangeInput && (!browser.isIPhone || playsInline);
break; break;
default: default:
+2 -17
View File
@@ -5,7 +5,6 @@
import utils from './utils'; import utils from './utils';
import captions from './captions'; import captions from './captions';
import controls from './controls'; import controls from './controls';
import listeners from './listeners';
const ui = { const ui = {
addStyleHook() { addStyleHook() {
@@ -25,7 +24,7 @@ const ui = {
// Setup the UI // Setup the UI
build() { build() {
// Re-attach media element listeners // Re-attach media element listeners
// TODO: Use event bubbling // TODO: Use event bubbling?
this.listeners.media(); this.listeners.media();
// Don't setup interface if no support // Don't setup interface if no support
@@ -256,21 +255,7 @@ const ui = {
// Check buffer status // Check buffer status
case 'playing': case 'playing':
case 'progress': case 'progress':
value = (() => { ui.setProgress.call(this, this.elements.display.buffer, this.buffered * 100);
const { buffered } = this.media;
if (buffered && buffered.length) {
// HTML5
return utils.getPercentage(buffered.end(0), this.duration);
} else if (utils.is.number(buffered)) {
// YouTube returns between 0 and 1
return buffered * 100;
}
return 0;
})();
ui.setProgress.call(this, this.elements.display.buffer, value);
break; break;
+23 -56
View File
@@ -2,6 +2,8 @@
// Plyr utils // Plyr utils
// ========================================================================== // ==========================================================================
import loadjs from 'loadjs';
import support from './support'; import support from './support';
import { providers } from './types'; import { providers } from './types';
@@ -97,11 +99,10 @@ const utils = {
if (responseType === 'text') { if (responseType === 'text') {
try { try {
resolve(JSON.parse(request.responseText)); resolve(JSON.parse(request.responseText));
} catch(e) { } catch (e) {
resolve(request.responseText); resolve(request.responseText);
} }
} } else {
else {
resolve(request.response); resolve(request.response);
} }
}); });
@@ -125,52 +126,10 @@ const utils = {
// Load an external script // Load an external script
loadScript(url) { loadScript(url) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const current = document.querySelector(`script[src="${url}"]`); loadjs(url, {
success: resolve,
// Check script is not already referenced, if so wait for load error: reject,
if (current !== null) { });
current.callbacks = current.callbacks || [];
current.callbacks.push(resolve);
return;
}
// Build the element
const element = document.createElement('script');
// Callback queue
element.callbacks = element.callbacks || [];
element.callbacks.push(resolve);
// Error queue
element.errors = element.errors || [];
element.errors.push(reject);
// Bind callback
element.addEventListener(
'load',
event => {
element.callbacks.forEach(cb => cb.call(null, event));
element.callbacks = null;
},
false,
);
// Bind error handling
element.addEventListener(
'error',
event => {
element.errors.forEach(err => err.call(null, event));
element.errors = null;
},
false,
);
// Set the URL after binding callback
element.src = url;
// Inject
const first = document.getElementsByTagName('script')[0];
first.parentNode.insertBefore(element, first);
}); });
}, },
@@ -184,7 +143,14 @@ const utils = {
const hasId = utils.is.string(id); const hasId = utils.is.string(id);
let isCached = false; let isCached = false;
function updateSprite(data) { const exists = () => document.querySelectorAll(`#${id}`).length;
function injectSprite(data) {
// Check again incase of race condition
if (hasId && exists()) {
return;
}
// Inject content // Inject content
this.innerHTML = data; this.innerHTML = data;
@@ -192,8 +158,8 @@ const utils = {
document.body.insertBefore(this, document.body.childNodes[0]); document.body.insertBefore(this, document.body.childNodes[0]);
} }
// Only load once // Only load once if ID set
if (!hasId || !document.querySelectorAll(`#${id}`).length) { if (!hasId || !exists()) {
// Create container // Create container
const container = document.createElement('div'); const container = document.createElement('div');
utils.toggleHidden(container, true); utils.toggleHidden(container, true);
@@ -209,7 +175,7 @@ const utils = {
if (isCached) { if (isCached) {
const data = JSON.parse(cached); const data = JSON.parse(cached);
updateSprite.call(container, data.content); injectSprite.call(container, data.content);
return; return;
} }
} }
@@ -231,7 +197,7 @@ const utils = {
); );
} }
updateSprite.call(container, result); injectSprite.call(container, result);
}) })
.catch(() => {}); .catch(() => {});
} }
@@ -481,7 +447,7 @@ const utils = {
pause: utils.getElement.call(this, this.config.selectors.buttons.pause), pause: utils.getElement.call(this, this.config.selectors.buttons.pause),
restart: utils.getElement.call(this, this.config.selectors.buttons.restart), restart: utils.getElement.call(this, this.config.selectors.buttons.restart),
rewind: utils.getElement.call(this, this.config.selectors.buttons.rewind), rewind: utils.getElement.call(this, this.config.selectors.buttons.rewind),
forward: utils.getElement.call(this, this.config.selectors.buttons.forward), fastForward: utils.getElement.call(this, this.config.selectors.buttons.fastForward),
mute: utils.getElement.call(this, this.config.selectors.buttons.mute), mute: utils.getElement.call(this, this.config.selectors.buttons.mute),
pip: utils.getElement.call(this, this.config.selectors.buttons.pip), pip: utils.getElement.call(this, this.config.selectors.buttons.pip),
airplay: utils.getElement.call(this, this.config.selectors.buttons.airplay), airplay: utils.getElement.call(this, this.config.selectors.buttons.airplay),
@@ -576,7 +542,7 @@ const utils = {
// Toggle event listener // Toggle event listener
toggleListener(elements, event, callback, toggle, passive, capture) { toggleListener(elements, event, callback, toggle, passive, capture) {
// Bail if no elemetns, event, or callback // Bail if no elemetns, event, or callback
if (utils.is.empty(elements) || utils.is.empty(event) || !utils.is.function(callback)) { if (utils.is.empty(elements) || utils.is.empty(event) || !utils.is.function(callback)) {
return; return;
} }
@@ -671,6 +637,7 @@ const utils = {
if (current === 0 || max === 0 || Number.isNaN(current) || Number.isNaN(max)) { if (current === 0 || max === 0 || Number.isNaN(current) || Number.isNaN(max)) {
return 0; return 0;
} }
return (current / max * 100).toFixed(2); return (current / max * 100).toFixed(2);
}, },
+1 -1
View File
@@ -6,7 +6,7 @@
.plyr__video-embed { .plyr__video-embed {
// Default to 16:9 ratio but this is set by JavaScript based on config // Default to 16:9 ratio but this is set by JavaScript based on config
$padding: ((100 / 16) * 9); $padding: ((100 / 16) * 9);
$height: 200; $height: 240;
$offset: to-percentage(($height - $padding) / ($height / 50)); $offset: to-percentage(($height - $padding) / ($height / 50));
height: 0; height: 0;
+2
View File
@@ -3,9 +3,11 @@
// ========================================================================== // ==========================================================================
.plyr__ads { .plyr__ads {
border-radius: inherit;
bottom: 0; bottom: 0;
cursor: pointer; cursor: pointer;
left: 0; left: 0;
overflow: hidden;
position: absolute; position: absolute;
right: 0; right: 0;
top: 0; top: 0;
+883 -412
View File
File diff suppressed because it is too large Load Diff