Compare commits
20 Commits
v3.0.0-bet
...
v3.0.2
Author | SHA1 | Date | |
---|---|---|---|
bb7eea27e5 | |||
595c5e95bc | |||
43e6dcd41d | |||
b06c8ae43f | |||
c7ea13c0c7 | |||
0f8c6e147b | |||
e566365288 | |||
a06e0f5890 | |||
3bccc0da01 | |||
a0173d991e | |||
600f0eb8a3 | |||
5db73b1327 | |||
5cb1628cd8 | |||
c74b75e8e1 | |||
0538476d6f | |||
5ebe18d081 | |||
e0562752ea | |||
e6db374a72 | |||
ab7f277a1b | |||
d5a1a7ca1c |
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"plugins": ["stylelint-selector-bem-pattern", "stylelint-scss"],
|
"plugins": ["stylelint-selector-bem-pattern", "stylelint-scss"],
|
||||||
"extends": ["stylelint-config-sass-guidelines", "stylelint-config-recommended", "stylelint-config-prettier"],
|
"extends": ["stylelint-config-recommended", "stylelint-config-sass-guidelines", "stylelint-config-prettier"],
|
||||||
"rules": {
|
"rules": {
|
||||||
"selector-class-pattern": null,
|
"selector-class-pattern": null,
|
||||||
"selector-no-qualifying-type": [
|
"selector-no-qualifying-type": [
|
||||||
|
10
changelog.md
10
changelog.md
@ -1,3 +1,11 @@
|
|||||||
|
# v3.0.2
|
||||||
|
|
||||||
|
* Fix for Safari not firing error events when trying to load blocked scripts
|
||||||
|
|
||||||
|
# v3.0.1
|
||||||
|
|
||||||
|
* Fix for trying to accessing local storage when it's blocked
|
||||||
|
|
||||||
# v3.0.0
|
# v3.0.0
|
||||||
|
|
||||||
This is a massive release. A _mostly_ complete rewrite in ES6. What started out as a few changes quickly snowballed. There's many breaking changes so be careful upgrading.
|
This is a massive release. A _mostly_ complete rewrite in ES6. What started out as a few changes quickly snowballed. There's many breaking changes so be careful upgrading.
|
||||||
@ -67,7 +75,7 @@ You gotta break eggs to make an omelette. Sadly, there's quite a few breaking ch
|
|||||||
|
|
||||||
### Polyfilling
|
### Polyfilling
|
||||||
|
|
||||||
Because we're using the fancy new ES6 syntax, you will need to polyfill for vintage browsers if you want to use Plyr and still support them. Luckily there's a decent service for this that makes it painless, [polyfill.io](https://polyfill.io).
|
Because we're using the fancy new ES6 syntax, you will need to polyfill for vintage browsers if you want to use Plyr and still support them. Luckily there's a decent service for this that makes it painless, [polyfill.io](https://polyfill.io). Alternatively, you can use the prebuilt polyfilled build but bear in mind this is 20kb larger. I'd suggest working our your own polyfill strategy.
|
||||||
|
|
||||||
## v2.0.18
|
## v2.0.18
|
||||||
|
|
||||||
|
2
demo/dist/demo.css
vendored
2
demo/dist/demo.css
vendored
File diff suppressed because one or more lines are too long
3793
demo/dist/demo.js
vendored
3793
demo/dist/demo.js
vendored
File diff suppressed because it is too large
Load Diff
2
demo/dist/demo.js.map
vendored
2
demo/dist/demo.js.map
vendored
File diff suppressed because one or more lines are too long
2
demo/dist/demo.min.js
vendored
2
demo/dist/demo.min.js
vendored
File diff suppressed because one or more lines are too long
2
demo/dist/demo.min.js.map
vendored
2
demo/dist/demo.min.js.map
vendored
File diff suppressed because one or more lines are too long
@ -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.&url=http%3A%2F%2Fplyr.io&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>
|
@ -4,7 +4,19 @@
|
|||||||
// 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';
|
||||||
|
|
||||||
|
(() => {
|
||||||
|
const isLive = window.location.host === 'plyr.io';
|
||||||
|
|
||||||
|
// Raven / Sentry
|
||||||
|
// For demo site (https://plyr.io) only
|
||||||
|
if (isLive) {
|
||||||
|
Raven.config('https://d4ad9866ad834437a4754e23937071e4@sentry.io/305555').install();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
Raven.context(() => {
|
||||||
if (window.shr) {
|
if (window.shr) {
|
||||||
window.shr.setup({
|
window.shr.setup({
|
||||||
count: {
|
count: {
|
||||||
@ -53,6 +65,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
},
|
},
|
||||||
ads: {
|
ads: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
publisherId: '918848828995742',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -219,12 +232,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
newSource(currentType, true);
|
newSource(currentType, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Google analytics
|
// Google analytics
|
||||||
// For demo site (https://plyr.io) only
|
// For demo site (https://plyr.io) only
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
if (window.location.host === 'plyr.io') {
|
if (isLive) {
|
||||||
(function(i, s, o, g, r, a, m) {
|
(function(i, s, o, g, r, a, m) {
|
||||||
i.GoogleAnalyticsObject = r;
|
i.GoogleAnalyticsObject = r;
|
||||||
i[r] =
|
i[r] =
|
||||||
@ -241,5 +255,6 @@ if (window.location.host === 'plyr.io') {
|
|||||||
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
|
})(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');
|
||||||
window.ga('create', 'UA-40881672-11', 'auto');
|
window.ga('create', 'UA-40881672-11', 'auto');
|
||||||
window.ga('send', 'pageview');
|
window.ga('send', 'pageview');
|
||||||
}
|
}
|
||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
|
})();
|
||||||
|
2
dist/plyr.css
vendored
2
dist/plyr.css
vendored
File diff suppressed because one or more lines are too long
513
dist/plyr.js
vendored
513
dist/plyr.js
vendored
@ -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.17/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',
|
||||||
@ -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);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -1260,6 +1521,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 +1773,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:
|
||||||
@ -2179,7 +2437,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 +2656,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 +2679,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;
|
||||||
|
|
||||||
@ -3883,7 +4124,9 @@ var Listeners = function () {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: 'global',
|
key: 'global',
|
||||||
value: function global(toggle) {
|
value: function global() {
|
||||||
|
var toggle = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
||||||
|
|
||||||
// Keyboard shortcuts
|
// Keyboard shortcuts
|
||||||
if (this.player.config.keyboard.global) {
|
if (this.player.config.keyboard.global) {
|
||||||
utils.toggleListener(window, 'keydown keyup', this.handleKey, toggle, false);
|
utils.toggleListener(window, 'keydown keyup', this.handleKey, toggle, false);
|
||||||
@ -4294,6 +4537,14 @@ var Listeners = function () {
|
|||||||
});
|
});
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset on destroy
|
||||||
|
|
||||||
|
}, {
|
||||||
|
key: 'clear',
|
||||||
|
value: function clear() {
|
||||||
|
this.global(false);
|
||||||
|
}
|
||||||
}]);
|
}]);
|
||||||
return Listeners;
|
return Listeners;
|
||||||
}();
|
}();
|
||||||
@ -4316,9 +4567,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4356,6 +4611,7 @@ var Storage = function () {
|
|||||||
}], [{
|
}], [{
|
||||||
key: 'supported',
|
key: 'supported',
|
||||||
get: function get$$1() {
|
get: function get$$1() {
|
||||||
|
try {
|
||||||
if (!('localStorage' in window)) {
|
if (!('localStorage' in window)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -4364,9 +4620,9 @@ var Storage = function () {
|
|||||||
|
|
||||||
// Try to use it (it might be disabled, e.g. user is in private mode)
|
// Try to use it (it might be disabled, e.g. user is in private mode)
|
||||||
// see: https://github.com/sampotts/plyr/issues/131
|
// see: https://github.com/sampotts/plyr/issues/131
|
||||||
try {
|
|
||||||
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;
|
||||||
@ -4565,7 +4821,7 @@ var Ads = function () {
|
|||||||
var start = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
var start = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
||||||
|
|
||||||
if (!start) {
|
if (!start) {
|
||||||
window.clearInterval(this.countdownTimer);
|
clearInterval(this.countdownTimer);
|
||||||
this.elements.container.removeAttribute('data-badge-text');
|
this.elements.container.removeAttribute('data-badge-text');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -4576,7 +4832,7 @@ var Ads = function () {
|
|||||||
_this5.elements.container.setAttribute('data-badge-text', label);
|
_this5.elements.container.setAttribute('data-badge-text', label);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.countdownTimer = window.setInterval(update, 100);
|
this.countdownTimer = setInterval(update, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -5351,10 +5607,10 @@ var youtube = {
|
|||||||
utils.dispatchEvent.call(player, player.media, 'durationchange');
|
utils.dispatchEvent.call(player, player.media, 'durationchange');
|
||||||
|
|
||||||
// Reset timer
|
// Reset timer
|
||||||
window.clearInterval(player.timers.buffering);
|
clearInterval(player.timers.buffering);
|
||||||
|
|
||||||
// Setup buffering
|
// Setup buffering
|
||||||
player.timers.buffering = window.setInterval(function () {
|
player.timers.buffering = setInterval(function () {
|
||||||
// Get loaded % from YouTube
|
// Get loaded % from YouTube
|
||||||
player.media.buffered = instance.getVideoLoadedFraction();
|
player.media.buffered = instance.getVideoLoadedFraction();
|
||||||
|
|
||||||
@ -5368,7 +5624,7 @@ var youtube = {
|
|||||||
|
|
||||||
// Bail if we're at 100%
|
// Bail if we're at 100%
|
||||||
if (player.media.buffered === 1) {
|
if (player.media.buffered === 1) {
|
||||||
window.clearInterval(player.timers.buffering);
|
clearInterval(player.timers.buffering);
|
||||||
|
|
||||||
// Trigger event
|
// Trigger event
|
||||||
utils.dispatchEvent.call(player, player.media, 'canplaythrough');
|
utils.dispatchEvent.call(player, player.media, 'canplaythrough');
|
||||||
@ -5385,7 +5641,7 @@ var youtube = {
|
|||||||
var instance = event.target;
|
var instance = event.target;
|
||||||
|
|
||||||
// Reset timer
|
// Reset timer
|
||||||
window.clearInterval(player.timers.playing);
|
clearInterval(player.timers.playing);
|
||||||
|
|
||||||
// Handle events
|
// Handle events
|
||||||
// -1 Unstarted
|
// -1 Unstarted
|
||||||
@ -5425,7 +5681,7 @@ var youtube = {
|
|||||||
utils.dispatchEvent.call(player, player.media, 'playing');
|
utils.dispatchEvent.call(player, player.media, 'playing');
|
||||||
|
|
||||||
// Poll to get playback progress
|
// Poll to get playback progress
|
||||||
player.timers.playing = window.setInterval(function () {
|
player.timers.playing = setInterval(function () {
|
||||||
utils.dispatchEvent.call(player, player.media, 'timeupdate');
|
utils.dispatchEvent.call(player, player.media, 'timeupdate');
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|
||||||
@ -6031,7 +6287,7 @@ var source = {
|
|||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Plyr
|
// Plyr
|
||||||
// plyr.js v3.0.0-beta.17
|
// 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)
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
@ -6287,7 +6543,7 @@ var Plyr = function () {
|
|||||||
this.listeners.container();
|
this.listeners.container();
|
||||||
|
|
||||||
// Global listeners
|
// Global listeners
|
||||||
this.listeners.global(true);
|
this.listeners.global();
|
||||||
|
|
||||||
// Setup fullscreen
|
// Setup fullscreen
|
||||||
this.fullscreen = new Fullscreen(this);
|
this.fullscreen = new Fullscreen(this);
|
||||||
@ -6315,6 +6571,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 () {
|
||||||
@ -6335,7 +6595,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6547,7 +6807,7 @@ var Plyr = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clear timer on every call
|
// Clear timer on every call
|
||||||
window.clearTimeout(this.timers.controls);
|
clearTimeout(this.timers.controls);
|
||||||
|
|
||||||
// If the mouse is not over the controls, set a timeout to hide them
|
// If the mouse is not over the controls, set a timeout to hide them
|
||||||
if (show || this.paused || this.loading) {
|
if (show || this.paused || this.loading) {
|
||||||
@ -6638,6 +6898,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 = '';
|
||||||
@ -6666,12 +6930,12 @@ var Plyr = function () {
|
|||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Unbind listeners
|
||||||
|
_this4.listeners.clear();
|
||||||
|
|
||||||
// Replace the container with the original element provided
|
// Replace the container with the original element provided
|
||||||
utils.replaceElement(_this4.elements.original, _this4.elements.container);
|
utils.replaceElement(_this4.elements.original, _this4.elements.container);
|
||||||
|
|
||||||
// Unbind global listeners
|
|
||||||
_this4.listeners.global(false);
|
|
||||||
|
|
||||||
// Event
|
// Event
|
||||||
utils.dispatchEvent.call(_this4, _this4.elements.original, 'destroyed', true);
|
utils.dispatchEvent.call(_this4, _this4.elements.original, 'destroyed', true);
|
||||||
|
|
||||||
@ -6680,15 +6944,27 @@ var Plyr = function () {
|
|||||||
callback.call(_this4.elements.original);
|
callback.call(_this4.elements.original);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear for GC
|
// Reset state
|
||||||
|
_this4.ready = false;
|
||||||
|
|
||||||
|
// Clear for garbage collection
|
||||||
|
setTimeout(function () {
|
||||||
_this4.elements = null;
|
_this4.elements = null;
|
||||||
|
_this4.media = null;
|
||||||
|
}, 200);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Stop playback
|
||||||
|
this.stop();
|
||||||
|
|
||||||
// Type specific stuff
|
// Type specific stuff
|
||||||
switch (this.provider + ':' + this.type) {
|
switch (this.provider + ':' + this.type) {
|
||||||
case 'html5:video':
|
case 'html5:video':
|
||||||
case 'html5:audio':
|
case 'html5:audio':
|
||||||
|
// Clear timeout
|
||||||
|
clearTimeout(this.timers.loading);
|
||||||
|
|
||||||
// Restore native video controls
|
// Restore native video controls
|
||||||
ui.toggleNativeControls.call(this, true);
|
ui.toggleNativeControls.call(this, true);
|
||||||
|
|
||||||
@ -6699,11 +6975,11 @@ var Plyr = function () {
|
|||||||
|
|
||||||
case 'youtube:video':
|
case 'youtube:video':
|
||||||
// Clear timers
|
// Clear timers
|
||||||
window.clearInterval(this.timers.buffering);
|
clearInterval(this.timers.buffering);
|
||||||
window.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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6750,37 +7026,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -6790,7 +7066,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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -6800,7 +7076,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',
|
||||||
@ -6833,6 +7109,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
|
||||||
*/
|
*/
|
||||||
@ -6840,7 +7141,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -6854,7 +7155,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;
|
||||||
@ -6912,7 +7213,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',
|
||||||
@ -6941,7 +7242,7 @@ var Plyr = function () {
|
|||||||
*/
|
*/
|
||||||
,
|
,
|
||||||
get: function get$$1() {
|
get: function get$$1() {
|
||||||
return this.media.muted;
|
return Boolean(this.media.muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -6961,12 +7262,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)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
@ -7011,7 +7312,7 @@ var Plyr = function () {
|
|||||||
*/
|
*/
|
||||||
,
|
,
|
||||||
get: function get$$1() {
|
get: function get$$1() {
|
||||||
return this.media.playbackRate;
|
return Number(this.media.playbackRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -7114,7 +7415,7 @@ var Plyr = function () {
|
|||||||
*/
|
*/
|
||||||
,
|
,
|
||||||
get: function get$$1() {
|
get: function get$$1() {
|
||||||
return this.media.loop;
|
return Boolean(this.media.loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -7183,7 +7484,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',
|
||||||
|
2
dist/plyr.js.map
vendored
2
dist/plyr.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.min.js
vendored
2
dist/plyr.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.min.js.map
vendored
2
dist/plyr.min.js.map
vendored
File diff suppressed because one or more lines are too long
505
dist/plyr.polyfilled.js
vendored
505
dist/plyr.polyfilled.js
vendored
@ -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.18/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',
|
||||||
@ -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);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -6451,6 +6702,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 +6954,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:
|
||||||
@ -7370,7 +7618,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 +7837,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 +7860,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;
|
||||||
|
|
||||||
@ -9074,7 +9305,9 @@ var Listeners = function () {
|
|||||||
|
|
||||||
}, {
|
}, {
|
||||||
key: 'global',
|
key: 'global',
|
||||||
value: function global(toggle) {
|
value: function global() {
|
||||||
|
var toggle = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
||||||
|
|
||||||
// Keyboard shortcuts
|
// Keyboard shortcuts
|
||||||
if (this.player.config.keyboard.global) {
|
if (this.player.config.keyboard.global) {
|
||||||
utils.toggleListener(window, 'keydown keyup', this.handleKey, toggle, false);
|
utils.toggleListener(window, 'keydown keyup', this.handleKey, toggle, false);
|
||||||
@ -9485,6 +9718,14 @@ var Listeners = function () {
|
|||||||
});
|
});
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset on destroy
|
||||||
|
|
||||||
|
}, {
|
||||||
|
key: 'clear',
|
||||||
|
value: function clear() {
|
||||||
|
this.global(false);
|
||||||
|
}
|
||||||
}]);
|
}]);
|
||||||
return Listeners;
|
return Listeners;
|
||||||
}();
|
}();
|
||||||
@ -9507,9 +9748,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9547,6 +9792,7 @@ var Storage = function () {
|
|||||||
}], [{
|
}], [{
|
||||||
key: 'supported',
|
key: 'supported',
|
||||||
get: function get() {
|
get: function get() {
|
||||||
|
try {
|
||||||
if (!('localStorage' in window)) {
|
if (!('localStorage' in window)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -9555,9 +9801,9 @@ var Storage = function () {
|
|||||||
|
|
||||||
// Try to use it (it might be disabled, e.g. user is in private mode)
|
// Try to use it (it might be disabled, e.g. user is in private mode)
|
||||||
// see: https://github.com/sampotts/plyr/issues/131
|
// see: https://github.com/sampotts/plyr/issues/131
|
||||||
try {
|
|
||||||
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;
|
||||||
@ -9756,7 +10002,7 @@ var Ads = function () {
|
|||||||
var start = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
var start = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
||||||
|
|
||||||
if (!start) {
|
if (!start) {
|
||||||
window.clearInterval(this.countdownTimer);
|
clearInterval(this.countdownTimer);
|
||||||
this.elements.container.removeAttribute('data-badge-text');
|
this.elements.container.removeAttribute('data-badge-text');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -9767,7 +10013,7 @@ var Ads = function () {
|
|||||||
_this5.elements.container.setAttribute('data-badge-text', label);
|
_this5.elements.container.setAttribute('data-badge-text', label);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.countdownTimer = window.setInterval(update, 100);
|
this.countdownTimer = setInterval(update, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -10542,10 +10788,10 @@ var youtube = {
|
|||||||
utils.dispatchEvent.call(player, player.media, 'durationchange');
|
utils.dispatchEvent.call(player, player.media, 'durationchange');
|
||||||
|
|
||||||
// Reset timer
|
// Reset timer
|
||||||
window.clearInterval(player.timers.buffering);
|
clearInterval(player.timers.buffering);
|
||||||
|
|
||||||
// Setup buffering
|
// Setup buffering
|
||||||
player.timers.buffering = window.setInterval(function () {
|
player.timers.buffering = setInterval(function () {
|
||||||
// Get loaded % from YouTube
|
// Get loaded % from YouTube
|
||||||
player.media.buffered = instance.getVideoLoadedFraction();
|
player.media.buffered = instance.getVideoLoadedFraction();
|
||||||
|
|
||||||
@ -10559,7 +10805,7 @@ var youtube = {
|
|||||||
|
|
||||||
// Bail if we're at 100%
|
// Bail if we're at 100%
|
||||||
if (player.media.buffered === 1) {
|
if (player.media.buffered === 1) {
|
||||||
window.clearInterval(player.timers.buffering);
|
clearInterval(player.timers.buffering);
|
||||||
|
|
||||||
// Trigger event
|
// Trigger event
|
||||||
utils.dispatchEvent.call(player, player.media, 'canplaythrough');
|
utils.dispatchEvent.call(player, player.media, 'canplaythrough');
|
||||||
@ -10576,7 +10822,7 @@ var youtube = {
|
|||||||
var instance = event.target;
|
var instance = event.target;
|
||||||
|
|
||||||
// Reset timer
|
// Reset timer
|
||||||
window.clearInterval(player.timers.playing);
|
clearInterval(player.timers.playing);
|
||||||
|
|
||||||
// Handle events
|
// Handle events
|
||||||
// -1 Unstarted
|
// -1 Unstarted
|
||||||
@ -10616,7 +10862,7 @@ var youtube = {
|
|||||||
utils.dispatchEvent.call(player, player.media, 'playing');
|
utils.dispatchEvent.call(player, player.media, 'playing');
|
||||||
|
|
||||||
// Poll to get playback progress
|
// Poll to get playback progress
|
||||||
player.timers.playing = window.setInterval(function () {
|
player.timers.playing = setInterval(function () {
|
||||||
utils.dispatchEvent.call(player, player.media, 'timeupdate');
|
utils.dispatchEvent.call(player, player.media, 'timeupdate');
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|
||||||
@ -11222,7 +11468,7 @@ var source = {
|
|||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Plyr
|
// Plyr
|
||||||
// plyr.js v3.0.0-beta.18
|
// 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)
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
@ -11478,7 +11724,7 @@ var Plyr$1 = function () {
|
|||||||
this.listeners.container();
|
this.listeners.container();
|
||||||
|
|
||||||
// Global listeners
|
// Global listeners
|
||||||
this.listeners.global(true);
|
this.listeners.global();
|
||||||
|
|
||||||
// Setup fullscreen
|
// Setup fullscreen
|
||||||
this.fullscreen = new Fullscreen(this);
|
this.fullscreen = new Fullscreen(this);
|
||||||
@ -11506,6 +11752,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 () {
|
||||||
@ -11526,7 +11776,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11738,7 +11988,7 @@ var Plyr$1 = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clear timer on every call
|
// Clear timer on every call
|
||||||
window.clearTimeout(this.timers.controls);
|
clearTimeout(this.timers.controls);
|
||||||
|
|
||||||
// If the mouse is not over the controls, set a timeout to hide them
|
// If the mouse is not over the controls, set a timeout to hide them
|
||||||
if (show || this.paused || this.loading) {
|
if (show || this.paused || this.loading) {
|
||||||
@ -11829,6 +12079,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 = '';
|
||||||
@ -11857,12 +12111,12 @@ var Plyr$1 = function () {
|
|||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Unbind listeners
|
||||||
|
_this4.listeners.clear();
|
||||||
|
|
||||||
// Replace the container with the original element provided
|
// Replace the container with the original element provided
|
||||||
utils.replaceElement(_this4.elements.original, _this4.elements.container);
|
utils.replaceElement(_this4.elements.original, _this4.elements.container);
|
||||||
|
|
||||||
// Unbind global listeners
|
|
||||||
_this4.listeners.global(false);
|
|
||||||
|
|
||||||
// Event
|
// Event
|
||||||
utils.dispatchEvent.call(_this4, _this4.elements.original, 'destroyed', true);
|
utils.dispatchEvent.call(_this4, _this4.elements.original, 'destroyed', true);
|
||||||
|
|
||||||
@ -11871,15 +12125,27 @@ var Plyr$1 = function () {
|
|||||||
callback.call(_this4.elements.original);
|
callback.call(_this4.elements.original);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear for GC
|
// Reset state
|
||||||
|
_this4.ready = false;
|
||||||
|
|
||||||
|
// Clear for garbage collection
|
||||||
|
setTimeout(function () {
|
||||||
_this4.elements = null;
|
_this4.elements = null;
|
||||||
|
_this4.media = null;
|
||||||
|
}, 200);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Stop playback
|
||||||
|
this.stop();
|
||||||
|
|
||||||
// Type specific stuff
|
// Type specific stuff
|
||||||
switch (this.provider + ':' + this.type) {
|
switch (this.provider + ':' + this.type) {
|
||||||
case 'html5:video':
|
case 'html5:video':
|
||||||
case 'html5:audio':
|
case 'html5:audio':
|
||||||
|
// Clear timeout
|
||||||
|
clearTimeout(this.timers.loading);
|
||||||
|
|
||||||
// Restore native video controls
|
// Restore native video controls
|
||||||
ui.toggleNativeControls.call(this, true);
|
ui.toggleNativeControls.call(this, true);
|
||||||
|
|
||||||
@ -11890,11 +12156,11 @@ var Plyr$1 = function () {
|
|||||||
|
|
||||||
case 'youtube:video':
|
case 'youtube:video':
|
||||||
// Clear timers
|
// Clear timers
|
||||||
window.clearInterval(this.timers.buffering);
|
clearInterval(this.timers.buffering);
|
||||||
window.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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11941,37 +12207,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11981,7 +12247,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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11991,7 +12257,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',
|
||||||
@ -12024,6 +12290,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
|
||||||
*/
|
*/
|
||||||
@ -12031,7 +12322,7 @@ var Plyr$1 = function () {
|
|||||||
}, {
|
}, {
|
||||||
key: 'seeking',
|
key: 'seeking',
|
||||||
get: function get() {
|
get: function get() {
|
||||||
return this.media.seeking;
|
return Boolean(this.media.seeking);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12045,7 +12336,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;
|
||||||
@ -12103,7 +12394,7 @@ var Plyr$1 = function () {
|
|||||||
*/
|
*/
|
||||||
,
|
,
|
||||||
get: function get() {
|
get: function get() {
|
||||||
return this.media.volume;
|
return Number(this.media.volume);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'muted',
|
key: 'muted',
|
||||||
@ -12132,7 +12423,7 @@ var Plyr$1 = function () {
|
|||||||
*/
|
*/
|
||||||
,
|
,
|
||||||
get: function get() {
|
get: function get() {
|
||||||
return this.media.muted;
|
return Boolean(this.media.muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12152,12 +12443,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)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
@ -12202,7 +12493,7 @@ var Plyr$1 = function () {
|
|||||||
*/
|
*/
|
||||||
,
|
,
|
||||||
get: function get() {
|
get: function get() {
|
||||||
return this.media.playbackRate;
|
return Number(this.media.playbackRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12305,7 +12596,7 @@ var Plyr$1 = function () {
|
|||||||
*/
|
*/
|
||||||
,
|
,
|
||||||
get: function get() {
|
get: function get() {
|
||||||
return this.media.loop;
|
return Boolean(this.media.loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12374,7 +12665,7 @@ var Plyr$1 = function () {
|
|||||||
*/
|
*/
|
||||||
,
|
,
|
||||||
get: function get() {
|
get: function get() {
|
||||||
return this.config.autoplay;
|
return Boolean(this.config.autoplay);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'language',
|
key: 'language',
|
||||||
@ -12481,7 +12772,7 @@ var Plyr$1 = function () {
|
|||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Plyr Polyfilled Build
|
// Plyr Polyfilled Build
|
||||||
// plyr.js v3.0.0-beta.17
|
// 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)
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
2
dist/plyr.polyfilled.js.map
vendored
2
dist/plyr.polyfilled.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.polyfilled.min.js
vendored
2
dist/plyr.polyfilled.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.polyfilled.min.js.map
vendored
2
dist/plyr.polyfilled.min.js.map
vendored
File diff suppressed because one or more lines are too long
13
gulpfile.js
13
gulpfile.js
@ -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,7 +304,8 @@ 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 (
|
||||||
|
gulp
|
||||||
.src(paths.upload)
|
.src(paths.upload)
|
||||||
.pipe(
|
.pipe(
|
||||||
rename(p => {
|
rename(p => {
|
||||||
@ -311,6 +313,8 @@ if (Object.keys(aws).includes('cdn') && Object.keys(aws).includes('demo')) {
|
|||||||
p.dirname = p.dirname.replace('.', version); // eslint-disable-line
|
p.dirname = p.dirname.replace('.', version); // eslint-disable-line
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
// Remove min suffix from source map URL
|
||||||
|
.pipe(replace(/sourceMappingURL=([\w-?.]+)/, (match, p1) => `sourceMappingURL=${p1.replace(minSuffix, '')}`))
|
||||||
.pipe(
|
.pipe(
|
||||||
size({
|
size({
|
||||||
showFiles: true,
|
showFiles: true,
|
||||||
@ -318,7 +322,8 @@ if (Object.keys(aws).includes('cdn') && Object.keys(aws).includes('demo')) {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.pipe(replace(localPath, versionPath))
|
.pipe(replace(localPath, versionPath))
|
||||||
.pipe(s3(aws.cdn, options.cdn));
|
.pipe(s3(aws.cdn, options.cdn))
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Publish to demo bucket
|
// Publish to demo bucket
|
||||||
|
22
package.json
22
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "plyr",
|
"name": "plyr",
|
||||||
"version": "3.0.0-beta.18",
|
"version": "3.0.2",
|
||||||
"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,15 +13,15 @@
|
|||||||
"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",
|
||||||
"git-branch": "^1.0.0",
|
"git-branch": "^2.0.1",
|
||||||
"gulp": "^3.9.1",
|
"gulp": "^3.9.1",
|
||||||
"gulp-autoprefixer": "^5.0.0",
|
"gulp-autoprefixer": "^5.0.0",
|
||||||
"gulp-better-rollup": "^3.0.0",
|
"gulp-better-rollup": "^3.0.0",
|
||||||
"gulp-clean-css": "^3.9.2",
|
"gulp-clean-css": "^3.9.3",
|
||||||
"gulp-concat": "^2.6.1",
|
"gulp-concat": "^2.6.1",
|
||||||
"gulp-filter": "^5.1.0",
|
"gulp-filter": "^5.1.0",
|
||||||
"gulp-open": "^3.0.0",
|
"gulp-open": "^3.0.0",
|
||||||
@ -35,14 +35,16 @@
|
|||||||
"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": "^9.0.0",
|
"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": "^2.1.0",
|
"stylelint-config-prettier": "^3.0.4",
|
||||||
"stylelint-config-sass-guidelines": "^5.0.0",
|
|
||||||
"stylelint-config-recommended": "^2.1.0",
|
"stylelint-config-recommended": "^2.1.0",
|
||||||
|
"stylelint-config-sass-guidelines": "^5.0.0",
|
||||||
"stylelint-order": "^0.8.1",
|
"stylelint-order": "^0.8.1",
|
||||||
"stylelint-scss": "^2.5.0",
|
"stylelint-scss": "^2.5.0",
|
||||||
"stylelint-selector-bem-pattern": "^2.0.0"
|
"stylelint-selector-bem-pattern": "^2.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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
28
readme.md
28
readme.md
@ -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)
|
||||||
|
|
||||||
[](https://plyr.io)
|
[](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.18/plyr.js"></script>
|
<script src="https://cdn.plyr.io/3.0.2/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.18/plyr.css">
|
<link rel="stylesheet" href="https://cdn.plyr.io/3.0.2/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.18/plyr.svg`.
|
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.0.2/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
|
||||||
|
|
||||||
@ -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
|
||||||
|
|
||||||
[](https://www.fastly.com/)
|
[](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.
|
||||||
|
|
||||||
|
@ -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.18/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',
|
||||||
@ -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: '',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ class Listeners {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Global window & document listeners
|
// Global window & document listeners
|
||||||
global(toggle) {
|
global(toggle = true) {
|
||||||
// Keyboard shortcuts
|
// Keyboard shortcuts
|
||||||
if (this.player.config.keyboard.global) {
|
if (this.player.config.keyboard.global) {
|
||||||
utils.toggleListener(window, 'keydown keyup', this.handleKey, toggle, false);
|
utils.toggleListener(window, 'keydown keyup', this.handleKey, toggle, false);
|
||||||
@ -585,6 +585,11 @@ class Listeners {
|
|||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset on destroy
|
||||||
|
clear() {
|
||||||
|
this.global(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Listeners;
|
export default Listeners;
|
||||||
|
@ -171,7 +171,7 @@ class Ads {
|
|||||||
*/
|
*/
|
||||||
pollCountdown(start = false) {
|
pollCountdown(start = false) {
|
||||||
if (!start) {
|
if (!start) {
|
||||||
window.clearInterval(this.countdownTimer);
|
clearInterval(this.countdownTimer);
|
||||||
this.elements.container.removeAttribute('data-badge-text');
|
this.elements.container.removeAttribute('data-badge-text');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@ class Ads {
|
|||||||
this.elements.container.setAttribute('data-badge-text', label);
|
this.elements.container.setAttribute('data-badge-text', label);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.countdownTimer = window.setInterval(update, 100);
|
this.countdownTimer = setInterval(update, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -305,10 +305,10 @@ const youtube = {
|
|||||||
utils.dispatchEvent.call(player, player.media, 'durationchange');
|
utils.dispatchEvent.call(player, player.media, 'durationchange');
|
||||||
|
|
||||||
// Reset timer
|
// Reset timer
|
||||||
window.clearInterval(player.timers.buffering);
|
clearInterval(player.timers.buffering);
|
||||||
|
|
||||||
// Setup buffering
|
// Setup buffering
|
||||||
player.timers.buffering = window.setInterval(() => {
|
player.timers.buffering = setInterval(() => {
|
||||||
// Get loaded % from YouTube
|
// Get loaded % from YouTube
|
||||||
player.media.buffered = instance.getVideoLoadedFraction();
|
player.media.buffered = instance.getVideoLoadedFraction();
|
||||||
|
|
||||||
@ -322,7 +322,7 @@ const youtube = {
|
|||||||
|
|
||||||
// Bail if we're at 100%
|
// Bail if we're at 100%
|
||||||
if (player.media.buffered === 1) {
|
if (player.media.buffered === 1) {
|
||||||
window.clearInterval(player.timers.buffering);
|
clearInterval(player.timers.buffering);
|
||||||
|
|
||||||
// Trigger event
|
// Trigger event
|
||||||
utils.dispatchEvent.call(player, player.media, 'canplaythrough');
|
utils.dispatchEvent.call(player, player.media, 'canplaythrough');
|
||||||
@ -337,7 +337,7 @@ const youtube = {
|
|||||||
const instance = event.target;
|
const instance = event.target;
|
||||||
|
|
||||||
// Reset timer
|
// Reset timer
|
||||||
window.clearInterval(player.timers.playing);
|
clearInterval(player.timers.playing);
|
||||||
|
|
||||||
// Handle events
|
// Handle events
|
||||||
// -1 Unstarted
|
// -1 Unstarted
|
||||||
@ -377,7 +377,7 @@ const youtube = {
|
|||||||
utils.dispatchEvent.call(player, player.media, 'playing');
|
utils.dispatchEvent.call(player, player.media, 'playing');
|
||||||
|
|
||||||
// Poll to get playback progress
|
// Poll to get playback progress
|
||||||
player.timers.playing = window.setInterval(() => {
|
player.timers.playing = setInterval(() => {
|
||||||
utils.dispatchEvent.call(player, player.media, 'timeupdate');
|
utils.dispatchEvent.call(player, player.media, 'timeupdate');
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|
||||||
|
103
src/js/plyr.js
103
src/js/plyr.js
@ -1,6 +1,6 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Plyr
|
// Plyr
|
||||||
// plyr.js v3.0.0-beta.18
|
// 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)
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
@ -276,7 +276,7 @@ class Plyr {
|
|||||||
this.listeners.container();
|
this.listeners.container();
|
||||||
|
|
||||||
// Global listeners
|
// Global listeners
|
||||||
this.listeners.global(true);
|
this.listeners.global();
|
||||||
|
|
||||||
// Setup fullscreen
|
// Setup fullscreen
|
||||||
this.fullscreen = new Fullscreen(this);
|
this.fullscreen = new Fullscreen(this);
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -434,11 +438,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 +474,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 +528,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 +577,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 +594,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 +644,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 +744,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 +801,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -951,7 +980,7 @@ class Plyr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clear timer on every call
|
// Clear timer on every call
|
||||||
window.clearTimeout(this.timers.controls);
|
clearTimeout(this.timers.controls);
|
||||||
|
|
||||||
// If the mouse is not over the controls, set a timeout to hide them
|
// If the mouse is not over the controls, set a timeout to hide them
|
||||||
if (show || this.paused || this.loading) {
|
if (show || this.paused || this.loading) {
|
||||||
@ -1029,6 +1058,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 = '';
|
||||||
@ -1057,12 +1090,12 @@ class Plyr {
|
|||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Unbind listeners
|
||||||
|
this.listeners.clear();
|
||||||
|
|
||||||
// Replace the container with the original element provided
|
// Replace the container with the original element provided
|
||||||
utils.replaceElement(this.elements.original, this.elements.container);
|
utils.replaceElement(this.elements.original, this.elements.container);
|
||||||
|
|
||||||
// Unbind global listeners
|
|
||||||
this.listeners.global(false);
|
|
||||||
|
|
||||||
// Event
|
// Event
|
||||||
utils.dispatchEvent.call(this, this.elements.original, 'destroyed', true);
|
utils.dispatchEvent.call(this, this.elements.original, 'destroyed', true);
|
||||||
|
|
||||||
@ -1071,15 +1104,27 @@ class Plyr {
|
|||||||
callback.call(this.elements.original);
|
callback.call(this.elements.original);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear for GC
|
// Reset state
|
||||||
|
this.ready = false;
|
||||||
|
|
||||||
|
// Clear for garbage collection
|
||||||
|
setTimeout(() => {
|
||||||
this.elements = null;
|
this.elements = null;
|
||||||
|
this.media = null;
|
||||||
|
}, 200);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Stop playback
|
||||||
|
this.stop();
|
||||||
|
|
||||||
// Type specific stuff
|
// Type specific stuff
|
||||||
switch (`${this.provider}:${this.type}`) {
|
switch (`${this.provider}:${this.type}`) {
|
||||||
case 'html5:video':
|
case 'html5:video':
|
||||||
case 'html5:audio':
|
case 'html5:audio':
|
||||||
|
// Clear timeout
|
||||||
|
clearTimeout(this.timers.loading);
|
||||||
|
|
||||||
// Restore native video controls
|
// Restore native video controls
|
||||||
ui.toggleNativeControls.call(this, true);
|
ui.toggleNativeControls.call(this, true);
|
||||||
|
|
||||||
@ -1090,11 +1135,11 @@ class Plyr {
|
|||||||
|
|
||||||
case 'youtube:video':
|
case 'youtube:video':
|
||||||
// Clear timers
|
// Clear timers
|
||||||
window.clearInterval(this.timers.buffering);
|
clearInterval(this.timers.buffering);
|
||||||
window.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,6 +1,6 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// Plyr Polyfilled Build
|
// Plyr Polyfilled Build
|
||||||
// plyr.js v3.0.0-beta.18
|
// 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)
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -12,6 +12,7 @@ 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() {
|
||||||
|
try {
|
||||||
if (!('localStorage' in window)) {
|
if (!('localStorage' in window)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -20,9 +21,9 @@ class Storage {
|
|||||||
|
|
||||||
// Try to use it (it might be disabled, e.g. user is in private mode)
|
// Try to use it (it might be disabled, e.g. user is in private mode)
|
||||||
// see: https://github.com/sampotts/plyr/issues/131
|
// see: https://github.com/sampotts/plyr/issues/131
|
||||||
try {
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
19
src/js/ui.js
19
src/js/ui.js
@ -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;
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -671,6 +630,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);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
direction: ltr;
|
direction: ltr;
|
||||||
font-family: $plyr-font-family;
|
font-family: $plyr-font-family;
|
||||||
|
font-variant-numeric: tabular-nums; // Force monosace-esque number widths
|
||||||
font-weight: $plyr-font-weight-regular;
|
font-weight: $plyr-font-weight-regular;
|
||||||
line-height: $plyr-line-height;
|
line-height: $plyr-line-height;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
@ -3,22 +3,25 @@
|
|||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
.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;
|
||||||
z-index: -1; // Hide it.
|
z-index: -1; // Hide it by default
|
||||||
|
|
||||||
// Make sure the inner container is big enough for the ad creative.
|
// Make sure the inner container is big enough for the ad creative.
|
||||||
> div,
|
> div,
|
||||||
> div iframe {
|
> div iframe {
|
||||||
|
height: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The countdown label
|
||||||
&::after {
|
&::after {
|
||||||
background: rgba($plyr-color-gunmetal, 0.8);
|
background: rgba($plyr-color-gunmetal, 0.8);
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
Reference in New Issue
Block a user