Compare commits

...

5 Commits

Author SHA1 Message Date
cce143a7da v3.0.11 2018-03-30 23:14:07 +11:00
d593005b32 Muted and autoplay fixes, small bug fixes 2018-03-30 23:09:17 +11:00
7be9d5d4d3 v3.0.10 2018-03-30 00:16:42 +11:00
d7141d5ed7 Controls docs, package upgrades 2018-03-30 00:11:48 +11:00
0d0ece94d3 Fix regression 2018-03-29 20:20:37 +11:00
27 changed files with 926 additions and 1163 deletions

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

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

View File

@ -1,3 +1,18 @@
## v3.0.11
* Muted and autoplay fixes
* Small bug fixes from Sentry logs
## v3.0.10
* Docs fix
* Package upgrades
## v3.0.9
* Demo fix
* Fix Vimeo regression
## v3.0.8 ## v3.0.8
* Vimeo hotfix for private videos * Vimeo hotfix for private videos

View File

@ -1,27 +1,72 @@
# Controls # Controls
This is the markup that is rendered for the Plyr controls. You can use the default controls or provide a customized version of markup based on your needs. This is the markup that is rendered for the Plyr controls. You can use the default controls or provide a customized version of markup based on your needs. You can pass the following to the `controls` option:
## Internationalization using default controls * `Array` of options (this builds the default controls based on your choices)
* `String` containing the desired HTML
* `Function` that will be executed and should return one of the above
## Using default controls
If you want to use the standard controls as they are, you don't need to pass any options. If you want to turn on off controls, here's the full list:
```javascript
controls: [
'play-large', // The large play button in the center
'restart', // Restart playback
'rewind', // Rewind by the seek time (default 10 seconds)
'play', // Play/pause playback
'fast-forward', // Fast forward by the seek time (default 10 seconds)
'progress', // The progress bar and scrubber for playback and buffering
'current-time', // The current time of playback
'duration', // The full duration of the media
'mute', // Toggle mute
'volume', // Volume control
'captions', // Toggle captions
'settings', // Settings menu
'pip', // Picture-in-picture (currently Safari only)
'airplay', // Airplay (currently Safari only)
'fullscreen', // Toggle fullscreen
];
```
### Internationalization using default controls
You can provide an `i18n` object as one of your options when initialising the plugin which we be used when rendering the controls. You can provide an `i18n` object as one of your options when initialising the plugin which we be used when rendering the controls.
### Example #### Example
```javascript ```javascript
i18n: { i18n: {
restart: "Restart", restart: 'Restart',
rewind: "Rewind {seektime} secs", rewind: 'Rewind {seektime} secs',
play: "Play", play: 'Play',
pause: "Pause", pause: 'Pause',
forward: "Forward {seektime} secs", fastForward: 'Forward {seektime} secs',
buffered: "buffered", seek: 'Seek',
currentTime: "Current time", played: 'Played',
duration: "Duration", buffered: 'Buffered',
volume: "Volume", currentTime: 'Current time',
toggleMute: "Toggle Mute", duration: 'Duration',
toggleCaptions: "Toggle Captions", volume: 'Volume',
toggleFullscreen: "Toggle Fullscreen" mute: 'Mute',
unmute: 'Unmute',
enableCaptions: 'Enable captions',
disableCaptions: 'Disable captions',
enterFullscreen: 'Enter fullscreen',
exitFullscreen: 'Exit fullscreen',
frameTitle: 'Player for {title}',
captions: 'Captions',
settings: 'Settings',
speed: 'Speed',
quality: 'Quality',
loop: 'Loop',
start: 'Start',
end: 'End',
all: 'All',
reset: 'Reset',
disabled: 'Disabled',
advertisement: 'Ad',
} }
``` ```
@ -29,85 +74,78 @@ Note: `{seektime}` will be replaced with your configured seek time or the defaul
## Using custom HTML ## Using custom HTML
You can specify the HTML for the controls using the `html` option. You can specify the HTML as a `String` or your `Function` return for the controls using the `controls` option.
The classes and data attributes used in your template should match the `selectors` option. The classes and data attributes used in your template should match the `selectors` option if you change any.
You need to add several placeholders to your html template that are replaced when rendering: You need to add several placeholders to your HTML template that are replaced when rendering:
- `{id}` - the dynamically generated ID for the player (for form controls) * `{id}` - the dynamically generated ID for the player (for form controls)
- `{seektime}` - the seek time specified in options for fast forward and rewind * `{seektime}` - the seek time specified in options for fast forward and rewind
- `{title}` - the title of your media, if specified * `{title}` - the title of your media, if specified
You can include only the controls you need when specifying custom html. ### Limitations
* Currently the settings menus are not supported with custom controls HTML
* AirPlay and PiP buttons can be added but you will have to manage feature detection
### Example ### Example
This is an example `html` option with all controls. Here's an example of custom controls markup (this is just all default controls shown).
```javascript ```javascript
var controls = ["<div class='plyr__controls'>", const controls = `
"<button type='button' data-plyr='restart'>", <div class="plyr__controls">
"<svg><use xlink:href='#plyr-restart'></use></svg>", <button type="button" class="plyr__control" data-plyr="restart">
"<span class='plyr__sr-only'>Restart</span>", <svg role="presentation"><use xlink:href="#plyr-restart"></use></svg>
"</button>", <span class="plyr__tooltip" role="tooltip">Restart</span>
"<button type='button' data-plyr='rewind'>", </button>
"<svg><use xlink:href='#plyr-rewind'></use></svg>", <button type="button" class="plyr__control" data-plyr="rewind">
"<span class='plyr__sr-only'>Rewind {seektime} secs</span>", <svg role="presentation"><use xlink:href="#plyr-rewind"></use></svg>
"</button>", <span class="plyr__tooltip" role="tooltip">Rewind {seektime} secs</span>
"<button type='button' data-plyr='play'>", </button>
"<svg><use xlink:href='#plyr-play'></use></svg>", <button type="button" class="plyr__control" aria-pressed="false" aria-label="Play, {title}" data-plyr="play">
"<span class='plyr__sr-only'>Play</span>", <svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-pause"></use></svg>
"</button>", <svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-play"></use></svg>
"<button type='button' data-plyr='pause'>", <span class="label--pressed plyr__tooltip" role="tooltip">Pause</span>
"<svg><use xlink:href='#plyr-pause'></use></svg>", <span class="label--not-pressed plyr__tooltip" role="tooltip">Play</span>
"<span class='plyr__sr-only'>Pause</span>", </button>
"</button>", <button type="button" class="plyr__control" data-plyr="fast-forward">
"<button type='button' data-plyr='fast-forward'>", <svg role="presentation"><use xlink:href="#plyr-fast-forward"></use></svg>
"<svg><use xlink:href='#plyr-fast-forward'></use></svg>", <span class="plyr__tooltip" role="tooltip">Forward {seektime} secs</span>
"<span class='plyr__sr-only'>Forward {seektime} secs</span>", </button>
"</button>", <div class="plyr__progress">
"<span class='plyr__progress'>", <label for="plyr-seek-{id}" class="plyr__sr-only">Seek</label>
"<label for='seek{id}' class='plyr__sr-only'>Seek</label>", <input data-plyr="seek" type="range" min="0" max="100" step="0.01" value="0" id="plyr-seek-{id}">
"<input id='seek{id}' class='plyr__progress--seek' type='range' min='0' max='100' step='0.1' value='0' data-plyr='seek'>", <progress class="plyr__progress--buffer" min="0" max="100" value="0">% buffered</progress>
"<progress class='plyr__progress--played' max='100' value='0' role='presentation'></progress>", <span role="tooltip" class="plyr__tooltip">00:00</span>
"<progress class='plyr__progress--buffer' max='100' value='0'>", </div>
"<span>0</span>% buffered", <div class="plyr__time">00:00</div>
"</progress>", <button type="button" class="plyr__control" aria-pressed="false" aria-label="Mute" data-plyr="mute">
"<span class='plyr__tooltip'>00:00</span>", <svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-muted"></use></svg>
"</span>", <svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-volume"></use></svg>
"<span class='plyr__time'>", <span class="label--pressed plyr__tooltip" role="tooltip">Unmute</span>
"<span class='plyr__sr-only'>Current time</span>", <span class="label--not-pressed plyr__tooltip" role="tooltip">Mute</span>
"<span class='plyr__time--current'>00:00</span>", </button>
"</span>", <div class="plyr__volume">
"<span class='plyr__time'>", <label for="plyr-volume-{id}" class="plyr__sr-only">Volume</label>
"<span class='plyr__sr-only'>Duration</span>", <input data-plyr="volume" type="range" min="0" max="1" step="0.05" value="1" autocomplete="off" id="plyr-volume-{id}">
"<span class='plyr__time--duration'>00:00</span>", </div>
"</span>", <button type="button" class="plyr__control" aria-pressed="true" aria-label="Enable captions" data-plyr="captions">
"<button type='button' data-plyr='mute'>", <svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-captions-on"></use></svg>
"<svg class='icon--muted'><use xlink:href='#plyr-muted'></use></svg>", <svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-captions-off"></use></svg>
"<svg><use xlink:href='#plyr-volume'></use></svg>", <span class="label--pressed plyr__tooltip" role="tooltip">Disable captions</span>
"<span class='plyr__sr-only'>Toggle Mute</span>", <span class="label--not-pressed plyr__tooltip" role="tooltip">Enable captions</span>
"</button>", </button>
"<span class='plyr__volume'>", <button type="button" class="plyr__control" aria-pressed="false" aria-label="Enter fullscreen" data-plyr="fullscreen">
"<label for='volume{id}' class='plyr__sr-only'>Volume</label>", <svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-exit-fullscreen"></use></svg>
"<input id='volume{id}' class='plyr__volume--input' type='range' min='0' max='10' value='5' data-plyr='volume'>", <svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-enter-fullscreen"></use></svg>
"<progress class='plyr__volume--display' max='10' value='0' role='presentation'></progress>", <span class="label--pressed plyr__tooltip" role="tooltip">Exit fullscreen</span>
"</span>", <span class="label--not-pressed plyr__tooltip" role="tooltip">Enter fullscreen</span>
"<button type='button' data-plyr='captions'>", </button>
"<svg class='icon--captions-on'><use xlink:href='#plyr-captions-on'></use></svg>", </div>
"<svg><use xlink:href='#plyr-captions-off'></use></svg>", `;
"<span class='plyr__sr-only'>Toggle Captions</span>",
"</button>",
"<button type='button' data-plyr='fullscreen'>",
"<svg class='icon--exit-fullscreen'><use xlink:href='#plyr-exit-fullscreen'></use></svg>",
"<svg><use xlink:href='#plyr-enter-fullscreen'></use></svg>",
"<span class='plyr__sr-only'>Toggle Fullscreen</span>",
"</button>",
"</div>"].join("");
// Setup the player // Setup the player
plyr.setup('.js-player', { const player = new Plyr('#player', { controls });
html: controls
});
``` ```

557
demo/dist/demo.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

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

View File

@ -65,6 +65,7 @@ import Raven from 'raven-js';
'fast-forward', 'fast-forward',
'progress', 'progress',
'current-time', 'current-time',
'duration',
'mute', 'mute',
'volume', 'volume',
'captions', 'captions',
@ -83,9 +84,6 @@ import Raven from 'raven-js';
enabled: true, enabled: true,
publisherId: '918848828995742', publisherId: '918848828995742',
}, },
/* listeners: {
seek: () => false,
}, */
}); });
// Expose for tinkering in the console // Expose for tinkering in the console
@ -179,7 +177,7 @@ import Raven from 'raven-js';
player.source = { player.source = {
type: 'video', type: 'video',
sources: [{ sources: [{
src: 'https://vimeo.com/25345658', src: 'https://vimeo.com/76979871',
provider: 'vimeo', provider: 'vimeo',
}], }],
}; };

370
dist/plyr.js vendored
View File

@ -77,7 +77,7 @@ var defaults = {
// Sprite (for icons) // Sprite (for icons)
loadSprite: true, loadSprite: true,
iconPrefix: 'plyr', iconPrefix: 'plyr',
iconUrl: 'https://cdn.plyr.io/3.0.8/plyr.svg', iconUrl: 'https://cdn.plyr.io/3.0.10/plyr.svg',
// Blank video (used to prevent errors on source change) // Blank video (used to prevent errors on source change)
blankVideo: 'https://cdn.plyr.io/static/blank.mp4', blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
@ -336,10 +336,6 @@ var defaults = {
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function createCommonjsModule(fn, module) { function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports; return module = { exports: {} }, fn(module, module.exports), module.exports;
} }
@ -456,6 +452,7 @@ function loadFile(path, callbackFn, args, numTries) {
async = args.async, async = args.async,
maxTries = (args.numRetries || 0) + 1, maxTries = (args.numRetries || 0) + 1,
beforeCallbackFn = args.before || devnull, beforeCallbackFn = args.before || devnull,
pathStripped = path.replace(/^(css|img)!/, ''),
isCss, isCss,
e; e;
@ -467,7 +464,11 @@ function loadFile(path, callbackFn, args, numTries) {
// css // css
e = doc.createElement('link'); e = doc.createElement('link');
e.rel = 'stylesheet'; e.rel = 'stylesheet';
e.href = path.replace(/^css!/, ''); // remove "css!" prefix e.href = pathStripped; //.replace(/^css!/, ''); // remove "css!" prefix
} else if (/(^img!|\.(png|gif|jpg|svg)$)/.test(path)) {
// image
e = doc.createElement('img');
e.src = pathStripped;
} else { } else {
// javascript // javascript
e = doc.createElement('script'); e = doc.createElement('script');
@ -633,123 +634,6 @@ return loadjs;
})); }));
}); });
var asyncGenerator = function () {
function AwaitValue(value) {
this.value = value;
}
function AsyncGenerator(gen) {
var front, back;
function send(key, arg) {
return new Promise(function (resolve, reject) {
var request = {
key: key,
arg: arg,
resolve: resolve,
reject: reject,
next: null
};
if (back) {
back = back.next = request;
} else {
front = back = request;
resume(key, arg);
}
});
}
function resume(key, arg) {
try {
var result = gen[key](arg);
var value = result.value;
if (value instanceof AwaitValue) {
Promise.resolve(value.value).then(function (arg) {
resume("next", arg);
}, function (arg) {
resume("throw", arg);
});
} else {
settle(result.done ? "return" : "normal", result.value);
}
} catch (err) {
settle("throw", err);
}
}
function settle(type, value) {
switch (type) {
case "return":
front.resolve({
value: value,
done: true
});
break;
case "throw":
front.reject(value);
break;
default:
front.resolve({
value: value,
done: false
});
break;
}
front = front.next;
if (front) {
resume(front.key, front.arg);
} else {
back = null;
}
}
this._invoke = send;
if (typeof gen.return !== "function") {
this.return = undefined;
}
}
if (typeof Symbol === "function" && Symbol.asyncIterator) {
AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
return this;
};
}
AsyncGenerator.prototype.next = function (arg) {
return this._invoke("next", arg);
};
AsyncGenerator.prototype.throw = function (arg) {
return this._invoke("throw", arg);
};
AsyncGenerator.prototype.return = function (arg) {
return this._invoke("return", arg);
};
return {
wrap: function (fn) {
return function () {
return new AsyncGenerator(fn.apply(this, arguments));
};
},
await: function (value) {
return new AwaitValue(value);
}
};
}();
var classCallCheck = function (instance, Constructor) { var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) { if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function"); throw new TypeError("Cannot call a class as a function");
@ -774,10 +658,6 @@ var createClass = function () {
}; };
}(); }();
var defineProperty = function (obj, key, value) { var defineProperty = function (obj, key, value) {
if (key in obj) { if (key in obj) {
Object.defineProperty(obj, key, { Object.defineProperty(obj, key, {
@ -792,26 +672,6 @@ var defineProperty = function (obj, key, value) {
return obj; return obj;
}; };
var slicedToArray = function () { var slicedToArray = function () {
function sliceIterator(arr, i) { function sliceIterator(arr, i) {
@ -851,18 +711,6 @@ var slicedToArray = function () {
}; };
}(); }();
var toConsumableArray = function (arr) { var toConsumableArray = function (arr) {
if (Array.isArray(arr)) { if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
@ -873,8 +721,6 @@ var toConsumableArray = function (arr) {
} }
}; };
// ==========================================================================
// Plyr utils
// ========================================================================== // ==========================================================================
var utils = { var utils = {
@ -1818,8 +1664,6 @@ var utils = {
} }
}; };
// ==========================================================================
// Plyr support checks
// ========================================================================== // ==========================================================================
// Check for feature support // Check for feature support
@ -2015,9 +1859,6 @@ var Console = function () {
return Console; return Console;
}(); }();
// ==========================================================================
// Fullscreen wrapper
// https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API#prefixing
// ========================================================================== // ==========================================================================
var browser = utils.getBrowser(); var browser = utils.getBrowser();
@ -2253,9 +2094,6 @@ var Fullscreen = function () {
return Fullscreen; return Fullscreen;
}(); }();
// ==========================================================================
// Plyr Captions
// TODO: Create as class
// ========================================================================== // ==========================================================================
var captions = { var captions = {
@ -2487,8 +2325,6 @@ var captions = {
} }
}; };
// ==========================================================================
// Plyr internationalization
// ========================================================================== // ==========================================================================
var i18n = { var i18n = {
@ -2519,8 +2355,6 @@ var i18n = {
} }
}; };
// ==========================================================================
// Plyr UI
// ========================================================================== // ==========================================================================
var ui = { var ui = {
@ -2596,6 +2430,9 @@ var ui = {
// Reset quality options // Reset quality options
this.options.quality = []; this.options.quality = [];
// Reset volume display
ui.updateVolume.call(this);
// Reset time display // Reset time display
ui.timeUpdate.call(this); ui.timeUpdate.call(this);
@ -2861,18 +2698,16 @@ var ui = {
} }
}; };
// ==========================================================================
// Plyr controls
// ========================================================================== // ==========================================================================
// Sniff out the browser // Sniff out the browser
var browser$2 = utils.getBrowser(); var browser$1 = utils.getBrowser();
var controls = { var controls = {
// Webkit polyfill for lower fill range // Webkit polyfill for lower fill range
updateRangeFill: function updateRangeFill(target) { updateRangeFill: function updateRangeFill(target) {
// WebKit only // WebKit only
if (!browser$2.isWebkit) { if (!browser$1.isWebkit) {
return; return;
} }
@ -2893,7 +2728,7 @@ var controls = {
getIconUrl: function getIconUrl() { getIconUrl: function getIconUrl() {
return { return {
url: this.config.iconUrl, url: this.config.iconUrl,
absolute: this.config.iconUrl.indexOf('http') === 0 || browser$2.isIE && !window.svg4everybody absolute: this.config.iconUrl.indexOf('http') === 0 || browser$1.isIE && !window.svg4everybody
}; };
}, },
@ -3990,9 +3825,7 @@ var controls = {
this.elements.controls = container; this.elements.controls = container;
if (this.isHTML5) { controls.setSpeedMenu.call(this);
controls.setSpeedMenu.call(this);
}
return container; return container;
}, },
@ -4086,12 +3919,10 @@ var controls = {
} }
}; };
// ==========================================================================
// Plyr Event Listeners
// ========================================================================== // ==========================================================================
// Sniff out the browser // Sniff out the browser
var browser$1 = utils.getBrowser(); var browser$2 = utils.getBrowser();
var Listeners = function () { var Listeners = function () {
function Listeners(player) { function Listeners(player) {
@ -4372,17 +4203,17 @@ var Listeners = function () {
return ui.updateProgress.call(_this3.player, event); return ui.updateProgress.call(_this3.player, event);
}); });
// Handle native mute // Handle volume changes
utils.on(this.player.media, 'volumechange', function (event) { utils.on(this.player.media, 'volumechange', function (event) {
return ui.updateVolume.call(_this3.player, event); return ui.updateVolume.call(_this3.player, event);
}); });
// Handle native play/pause // Handle play/pause
utils.on(this.player.media, 'playing play pause ended emptied', function (event) { utils.on(this.player.media, 'playing play pause ended emptied', function (event) {
return ui.checkPlaying.call(_this3.player, event); return ui.checkPlaying.call(_this3.player, event);
}); });
// Loading // Loading state
utils.on(this.player.media, 'waiting canplay seeked playing', function (event) { utils.on(this.player.media, 'waiting canplay seeked playing', function (event) {
return ui.checkLoading.call(_this3.player, event); return ui.checkLoading.call(_this3.player, event);
}); });
@ -4390,6 +4221,20 @@ var Listeners = function () {
// Check if media failed to load // Check if media failed to load
// utils.on(this.player.media, 'play', event => ui.checkFailed.call(this.player, event)); // utils.on(this.player.media, 'play', event => ui.checkFailed.call(this.player, event));
// If autoplay, then load advertisement if required
// TODO: Show some sort of loading state while the ad manager loads else there's a delay before ad shows
utils.on(this.player.media, 'playing', function () {
// If ads are enabled, wait for them first
if (_this3.player.ads.enabled && !_this3.player.ads.initialized) {
// Wait for manager response
_this3.player.ads.managerPromise.then(function () {
return _this3.player.ads.play();
}).catch(function () {
return _this3.player.play();
});
}
});
// Click video // Click video
if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) { if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) {
// Re-fetch the wrapper // Re-fetch the wrapper
@ -4489,7 +4334,7 @@ var Listeners = function () {
var _this4 = this; var _this4 = this;
// IE doesn't support input event, so we fallback to change // IE doesn't support input event, so we fallback to change
var inputEvent = browser$1.isIE ? 'change' : 'input'; var inputEvent = browser$2.isIE ? 'change' : 'input';
// Run default and custom handlers // Run default and custom handlers
var proxy = function proxy(event, defaultHandler, customHandlerKey) { var proxy = function proxy(event, defaultHandler, customHandlerKey) {
@ -4605,7 +4450,7 @@ var Listeners = function () {
}, 'volume'); }, 'volume');
// Polyfill for lower fill in <input type="range"> for webkit // Polyfill for lower fill in <input type="range"> for webkit
if (browser$1.isWebkit) { if (browser$2.isWebkit) {
on(utils.getElements.call(this.player, 'input[type="range"]'), 'input', function (event) { on(utils.getElements.call(this.player, 'input[type="range"]'), 'input', function (event) {
controls.updateRangeFill.call(_this4.player, event.target); controls.updateRangeFill.call(_this4.player, event.target);
}); });
@ -4682,8 +4527,6 @@ var Listeners = function () {
return Listeners; return Listeners;
}(); }();
// ==========================================================================
// Plyr storage
// ========================================================================== // ==========================================================================
var Storage = function () { var Storage = function () {
@ -4766,12 +4609,6 @@ var Storage = function () {
}(); }();
// ========================================================================== // ==========================================================================
// Advertisement plugin using Google IMA HTML5 SDK
// Create an account with our ad partner, vi here:
// https://www.vi.ai/publisher-video-monetization/
// ==========================================================================
/* global google */
var Ads = function () { var Ads = function () {
/** /**
@ -4993,21 +4830,23 @@ var Ads = function () {
this.cuePoints = this.manager.getCuePoints(); this.cuePoints = this.manager.getCuePoints();
// Add advertisement cue's within the time line if available // Add advertisement cue's within the time line if available
this.cuePoints.forEach(function (cuePoint) { if (!utils.is.empty(this.cuePoints)) {
if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < _this6.player.duration) { this.cuePoints.forEach(function (cuePoint) {
var seekElement = _this6.player.elements.progress; if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < _this6.player.duration) {
var seekElement = _this6.player.elements.progress;
if (seekElement) { if (utils.is.element(seekElement)) {
var cuePercentage = 100 / _this6.player.duration * cuePoint; var cuePercentage = 100 / _this6.player.duration * cuePoint;
var cue = utils.createElement('span', { var cue = utils.createElement('span', {
class: _this6.player.config.classNames.cues class: _this6.player.config.classNames.cues
}); });
cue.style.left = cuePercentage.toString() + '%'; cue.style.left = cuePercentage.toString() + '%';
seekElement.appendChild(cue); seekElement.appendChild(cue);
}
} }
} });
}); }
// Get skippable state // Get skippable state
// TODO: Skip button // TODO: Skip button
@ -5191,6 +5030,10 @@ var Ads = function () {
this.player.on('seeked', function () { this.player.on('seeked', function () {
var seekedTime = _this8.player.currentTime; var seekedTime = _this8.player.currentTime;
if (utils.is.empty(_this8.cuePoints)) {
return;
}
_this8.cuePoints.forEach(function (cuePoint, index) { _this8.cuePoints.forEach(function (cuePoint, index) {
if (time < cuePoint && cuePoint < seekedTime) { if (time < cuePoint && cuePoint < seekedTime) {
_this8.manager.discardAdBreak(); _this8.manager.discardAdBreak();
@ -5202,7 +5045,9 @@ var Ads = function () {
// Listen to the resizing of the window. And resize ad accordingly // Listen to the resizing of the window. And resize ad accordingly
// TODO: eventually implement ResizeObserver // TODO: eventually implement ResizeObserver
window.addEventListener('resize', function () { window.addEventListener('resize', function () {
_this8.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL); if (_this8.manager) {
_this8.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);
}
}); });
} }
@ -5433,8 +5278,6 @@ var Ads = function () {
return Ads; return Ads;
}(); }();
// ==========================================================================
// YouTube plugin
// ========================================================================== // ==========================================================================
var youtube = { var youtube = {
@ -5862,8 +5705,6 @@ var youtube = {
} }
}; };
// ==========================================================================
// Vimeo plugin
// ========================================================================== // ==========================================================================
var vimeo = { var vimeo = {
@ -6193,8 +6034,6 @@ var vimeo = {
} }
}; };
// ==========================================================================
// Plyr Media
// ========================================================================== // ==========================================================================
// Sniff out the browser // Sniff out the browser
@ -6293,8 +6132,6 @@ var media = {
} }
}; };
// ==========================================================================
// Plyr source update
// ========================================================================== // ==========================================================================
var source = { var source = {
@ -6435,11 +6272,6 @@ var source = {
} }
}; };
// ==========================================================================
// Plyr
// plyr.js v3.0.8
// https://github.com/sampotts/plyr
// License: The MIT License (MIT)
// ========================================================================== // ==========================================================================
// Private properties // Private properties
@ -6553,7 +6385,17 @@ var Plyr = function () {
} }
// Cache original element state for .destroy() // Cache original element state for .destroy()
this.elements.original = this.media.cloneNode(true); // TODO: Investigate a better solution as I suspect this causes reported double load issues?
setTimeout(function () {
var clone = _this.media.cloneNode(true);
// Prevent the clone autoplaying
if (clone.getAttribute('autoplay')) {
clone.pause();
}
_this.elements.original = clone;
}, 0);
// Set media type based on tag or data attribute // Set media type based on tag or data attribute
// Supported: video, audio, vimeo, youtube // Supported: video, audio, vimeo, youtube
@ -6703,6 +6545,11 @@ var Plyr = function () {
// Setup ads if provided // Setup ads if provided
this.ads = new Ads(this); this.ads = new Ads(this);
// Autoplay if required
if (this.config.autoplay) {
this.play();
}
} }
// --------------------------------------- // ---------------------------------------
@ -6722,20 +6569,14 @@ var Plyr = function () {
* Play the media, or play the advertisement (if they are not blocked) * Play the media, or play the advertisement (if they are not blocked)
*/ */
value: function play() { value: function play() {
var _this2 = this;
if (!utils.is.function(this.media.play)) { if (!utils.is.function(this.media.play)) {
return null; return null;
} }
// If ads are enabled, wait for them first // If ads are enabled, wait for them first
if (this.ads.enabled && !this.ads.initialized) { /* if (this.ads.enabled && !this.ads.initialized) {
return this.ads.managerPromise.then(function () { return this.ads.managerPromise.then(() => this.ads.play()).catch(() => this.media.play());
return _this2.ads.play(); } */
}).catch(function () {
return _this2.media.play();
});
}
// Return the promise (for HTML5) // Return the promise (for HTML5)
return this.media.play(); return this.media.play();
@ -6787,7 +6628,7 @@ var Plyr = function () {
value: function stop() { value: function stop() {
if (this.isHTML5) { if (this.isHTML5) {
this.media.load(); this.media.load();
} else { } else if (utils.is.function(this.media.stop)) {
this.media.stop(); this.media.stop();
} }
} }
@ -6922,7 +6763,7 @@ var Plyr = function () {
}, { }, {
key: 'toggleControls', key: 'toggleControls',
value: function toggleControls(toggle) { value: function toggleControls(toggle) {
var _this3 = this; var _this2 = this;
// We need controls of course... // We need controls of course...
if (!utils.is.element(this.elements.controls)) { if (!utils.is.element(this.elements.controls)) {
@ -6996,25 +6837,30 @@ var Plyr = function () {
// then set the timer to hide the controls // then set the timer to hide the controls
if (!show || this.playing) { if (!show || this.playing) {
this.timers.controls = setTimeout(function () { this.timers.controls = setTimeout(function () {
// We need controls of course...
if (!utils.is.element(_this2.elements.controls)) {
return;
}
// If the mouse is over the controls (and not entering fullscreen), bail // If the mouse is over the controls (and not entering fullscreen), bail
if ((_this3.elements.controls.pressed || _this3.elements.controls.hover) && !isEnterFullscreen) { if ((_this2.elements.controls.pressed || _this2.elements.controls.hover) && !isEnterFullscreen) {
return; return;
} }
// Restore transition behaviour // Restore transition behaviour
if (!utils.hasClass(_this3.elements.container, _this3.config.classNames.hideControls)) { if (!utils.hasClass(_this2.elements.container, _this2.config.classNames.hideControls)) {
utils.toggleClass(_this3.elements.controls, _this3.config.classNames.noTransition, false); utils.toggleClass(_this2.elements.controls, _this2.config.classNames.noTransition, false);
} }
// Check if controls toggled // Check if controls toggled
var toggled = utils.toggleClass(_this3.elements.container, _this3.config.classNames.hideControls, true); var toggled = utils.toggleClass(_this2.elements.container, _this2.config.classNames.hideControls, true);
// Trigger event and close menu // Trigger event and close menu
if (toggled) { if (toggled) {
utils.dispatchEvent.call(_this3, _this3.media, 'controlshidden'); utils.dispatchEvent.call(_this2, _this2.media, 'controlshidden');
if (_this3.config.controls.includes('settings') && !utils.is.empty(_this3.config.settings)) { if (_this2.config.controls.includes('settings') && !utils.is.empty(_this2.config.settings)) {
controls.toggleMenu.call(_this3, false); controls.toggleMenu.call(_this2, false);
} }
} }
}, delay); }, delay);
@ -7056,7 +6902,7 @@ var Plyr = function () {
}, { }, {
key: 'destroy', key: 'destroy',
value: function destroy(callback) { value: function destroy(callback) {
var _this4 = this; var _this3 = this;
var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@ -7069,22 +6915,22 @@ var Plyr = function () {
document.body.style.overflow = ''; document.body.style.overflow = '';
// GC for embed // GC for embed
_this4.embed = null; _this3.embed = null;
// If it's a soft destroy, make minimal changes // If it's a soft destroy, make minimal changes
if (soft) { if (soft) {
if (Object.keys(_this4.elements).length) { if (Object.keys(_this3.elements).length) {
// Remove elements // Remove elements
utils.removeElement(_this4.elements.buttons.play); utils.removeElement(_this3.elements.buttons.play);
utils.removeElement(_this4.elements.captions); utils.removeElement(_this3.elements.captions);
utils.removeElement(_this4.elements.controls); utils.removeElement(_this3.elements.controls);
utils.removeElement(_this4.elements.wrapper); utils.removeElement(_this3.elements.wrapper);
// Clear for GC // Clear for GC
_this4.elements.buttons.play = null; _this3.elements.buttons.play = null;
_this4.elements.captions = null; _this3.elements.captions = null;
_this4.elements.controls = null; _this3.elements.controls = null;
_this4.elements.wrapper = null; _this3.elements.wrapper = null;
} }
// Callback // Callback
@ -7093,26 +6939,26 @@ var Plyr = function () {
} }
} else { } else {
// Unbind listeners // Unbind listeners
_this4.listeners.clear(); _this3.listeners.clear();
// Replace the container with the original element provided // Replace the container with the original element provided
utils.replaceElement(_this4.elements.original, _this4.elements.container); utils.replaceElement(_this3.elements.original, _this3.elements.container);
// Event // Event
utils.dispatchEvent.call(_this4, _this4.elements.original, 'destroyed', true); utils.dispatchEvent.call(_this3, _this3.elements.original, 'destroyed', true);
// Callback // Callback
if (utils.is.function(callback)) { if (utils.is.function(callback)) {
callback.call(_this4.elements.original); callback.call(_this3.elements.original);
} }
// Reset state // Reset state
_this4.ready = false; _this3.ready = false;
// Clear for garbage collection // Clear for garbage collection
setTimeout(function () { setTimeout(function () {
_this4.elements = null; _this3.elements = null;
_this4.media = null; _this3.media = null;
}, 200); }, 200);
} }
}; };
@ -7364,8 +7210,8 @@ var Plyr = function () {
// Set the player volume // Set the player volume
this.media.volume = volume; this.media.volume = volume;
// If muted, and we're increasing volume, reset muted state // If muted, and we're increasing volume manually, reset muted state
if (this.muted && volume > 0) { if (!utils.is.empty(value) && this.muted && volume > 0) {
this.muted = false; this.muted = false;
} }
} }

2
dist/plyr.js.map vendored

File diff suppressed because one or more lines are too long

2
dist/plyr.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{ {
"name": "plyr", "name": "plyr",
"version": "3.0.8", "version": "3.0.11",
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player", "description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
"homepage": "https://plyr.io", "homepage": "https://plyr.io",
"main": "./dist/plyr.js", "main": "./dist/plyr.js",
@ -13,22 +13,22 @@
"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.19.0", "eslint": "^4.19.1",
"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": "^2.0.1", "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.1.0",
"gulp-clean-css": "^3.9.3", "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.1",
"gulp-rename": "^1.2.2", "gulp-rename": "^1.2.2",
"gulp-replace": "^0.6.1", "gulp-replace": "^0.6.1",
"gulp-s3": "^0.11.0", "gulp-s3": "^0.11.0",
"gulp-sass": "^3.1.0", "gulp-sass": "^3.2.1",
"gulp-size": "^3.0.0", "gulp-size": "^3.0.0",
"gulp-sourcemaps": "^2.6.4", "gulp-sourcemaps": "^2.6.4",
"gulp-svgmin": "^1.2.4", "gulp-svgmin": "^1.2.4",
@ -38,8 +38,8 @@
"prettier-eslint": "^8.8.1", "prettier-eslint": "^8.8.1",
"prettier-stylelint": "^0.4.2", "prettier-stylelint": "^0.4.2",
"rollup-plugin-babel": "^3.0.3", "rollup-plugin-babel": "^3.0.3",
"rollup-plugin-commonjs": "^8.4.1", "rollup-plugin-commonjs": "^9.1.0",
"rollup-plugin-node-resolve": "^3.2.0", "rollup-plugin-node-resolve": "^3.3.0",
"run-sequence": "^2.2.1", "run-sequence": "^2.2.1",
"stylelint": "^9.1.3", "stylelint": "^9.1.3",
"stylelint-config-prettier": "^3.0.4", "stylelint-config-prettier": "^3.0.4",
@ -68,7 +68,7 @@
"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", "loadjs": "^3.5.4",
"raven-js": "^3.23.3" "raven-js": "^3.24.0"
} }
} }

View File

@ -128,7 +128,7 @@ See [initialising](#initialising) for more information on advanced setups.
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript, you can use the following: If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript, you can use the following:
```html ```html
<script src="https://cdn.plyr.io/3.0.8/plyr.js"></script> <script src="https://cdn.plyr.io/3.0.11/plyr.js"></script>
``` ```
_Note_: Be sure to read the [polyfills](#polyfills) section below about browser compatibility _Note_: Be sure to read the [polyfills](#polyfills) section below about browser compatibility
@ -144,13 +144,13 @@ Include the `plyr.css` stylsheet into your `<head>`
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following: If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following:
```html ```html
<link rel="stylesheet" href="https://cdn.plyr.io/3.0.8/plyr.css"> <link rel="stylesheet" href="https://cdn.plyr.io/3.0.11/plyr.css">
``` ```
### SVG Sprite ### SVG Sprite
The SVG sprite is loaded automatically from our CDN (provided by [Fastly](https://www.fastly.com/)). To change this, see the [options](#options) below. For The SVG sprite is loaded automatically from our CDN (provided by [Fastly](https://www.fastly.com/)). To change this, see the [options](#options) below. For
reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.0.8/plyr.svg`. reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/3.0.11/plyr.svg`.
## Ads ## Ads

4
src/js/controls.js vendored
View File

@ -1177,9 +1177,7 @@ const controls = {
this.elements.controls = container; this.elements.controls = container;
if (this.isHTML5) { controls.setSpeedMenu.call(this);
controls.setSpeedMenu.call(this);
}
return container; return container;
}, },

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

122
yarn.lock
View File

@ -105,7 +105,7 @@ acorn-jsx@^3.0.0:
dependencies: dependencies:
acorn "^3.0.4" acorn "^3.0.4"
acorn@5.X, acorn@^5.0.3, acorn@^5.2.1, acorn@^5.5.0: acorn@5.X, acorn@^5.0.3, acorn@^5.5.0:
version "5.5.3" version "5.5.3"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9"
@ -1775,7 +1775,7 @@ eslint-visitor-keys@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
eslint@^4.0.0, eslint@^4.19.0: eslint@^4.0.0:
version "4.19.0" version "4.19.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.0.tgz#9e900efb5506812ac374557034ef6f5c3642fc4c" resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.0.tgz#9e900efb5506812ac374557034ef6f5c3642fc4c"
dependencies: dependencies:
@ -1818,6 +1818,49 @@ eslint@^4.0.0, eslint@^4.19.0:
table "4.0.2" table "4.0.2"
text-table "~0.2.0" text-table "~0.2.0"
eslint@^4.19.1:
version "4.19.1"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300"
dependencies:
ajv "^5.3.0"
babel-code-frame "^6.22.0"
chalk "^2.1.0"
concat-stream "^1.6.0"
cross-spawn "^5.1.0"
debug "^3.1.0"
doctrine "^2.1.0"
eslint-scope "^3.7.1"
eslint-visitor-keys "^1.0.0"
espree "^3.5.4"
esquery "^1.0.0"
esutils "^2.0.2"
file-entry-cache "^2.0.0"
functional-red-black-tree "^1.0.1"
glob "^7.1.2"
globals "^11.0.1"
ignore "^3.3.3"
imurmurhash "^0.1.4"
inquirer "^3.0.6"
is-resolvable "^1.0.0"
js-yaml "^3.9.1"
json-stable-stringify-without-jsonify "^1.0.1"
levn "^0.3.0"
lodash "^4.17.4"
minimatch "^3.0.2"
mkdirp "^0.5.1"
natural-compare "^1.4.0"
optionator "^0.8.2"
path-is-inside "^1.0.2"
pluralize "^7.0.0"
progress "^2.0.0"
regexpp "^1.0.1"
require-uncached "^1.0.3"
semver "^5.3.0"
strip-ansi "^4.0.0"
strip-json-comments "~2.0.1"
table "4.0.2"
text-table "~0.2.0"
espree@^3.5.4: espree@^3.5.4:
version "3.5.4" version "3.5.4"
resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7"
@ -1857,7 +1900,7 @@ estree-walker@^0.3.0:
version "0.3.1" version "0.3.1"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.3.1.tgz#e6b1a51cf7292524e7237c312e5fe6660c1ce1aa" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.3.1.tgz#e6b1a51cf7292524e7237c312e5fe6660c1ce1aa"
estree-walker@^0.5.0: estree-walker@^0.5.1:
version "0.5.1" version "0.5.1"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.5.1.tgz#64fc375053abc6f57d73e9bd2f004644ad3c5854" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.5.1.tgz#64fc375053abc6f57d73e9bd2f004644ad3c5854"
@ -2444,13 +2487,13 @@ gulp-autoprefixer@^5.0.0:
through2 "^2.0.0" through2 "^2.0.0"
vinyl-sourcemaps-apply "^0.2.0" vinyl-sourcemaps-apply "^0.2.0"
gulp-better-rollup@^3.0.0: gulp-better-rollup@^3.1.0:
version "3.0.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/gulp-better-rollup/-/gulp-better-rollup-3.0.0.tgz#2bf5c2d0e7908fae72bba1f2496d24eb3c482e33" resolved "https://registry.yarnpkg.com/gulp-better-rollup/-/gulp-better-rollup-3.1.0.tgz#b226ba0c672882075472158b82d22ba9976d4ecb"
dependencies: dependencies:
lodash.camelcase "^4.3.0" lodash.camelcase "^4.3.0"
plugin-error "^0.1.2" plugin-error "^0.1.2"
rollup "^0.50.0" rollup ">=0.48 <0.57"
vinyl "^2.1.0" vinyl "^2.1.0"
vinyl-sourcemaps-apply "^0.2.1" vinyl-sourcemaps-apply "^0.2.1"
@ -2479,9 +2522,9 @@ gulp-filter@^5.1.0:
plugin-error "^0.1.2" plugin-error "^0.1.2"
streamfilter "^1.0.5" streamfilter "^1.0.5"
gulp-open@^3.0.0: gulp-open@^3.0.1:
version "3.0.0" version "3.0.1"
resolved "https://registry.yarnpkg.com/gulp-open/-/gulp-open-3.0.0.tgz#5a572a99044fdc461685d0eb8f7529b34bf9a62c" resolved "https://registry.yarnpkg.com/gulp-open/-/gulp-open-3.0.1.tgz#a2f747b4aa31abec9399b527158b0368c57e2102"
dependencies: dependencies:
colors "^1.1.2" colors "^1.1.2"
opn "5.2.0" opn "5.2.0"
@ -2510,13 +2553,13 @@ gulp-s3@^0.11.0:
knox "" knox ""
mime "~1.2.11" mime "~1.2.11"
gulp-sass@^3.1.0: gulp-sass@^3.2.1:
version "3.1.0" version "3.2.1"
resolved "https://registry.yarnpkg.com/gulp-sass/-/gulp-sass-3.1.0.tgz#53dc4b68a1f5ddfe4424ab4c247655269a8b74b7" resolved "https://registry.yarnpkg.com/gulp-sass/-/gulp-sass-3.2.1.tgz#2e3688a96fd8be1c0c01340750c191b2e79fab94"
dependencies: dependencies:
gulp-util "^3.0" gulp-util "^3.0"
lodash.clonedeep "^4.3.2" lodash.clonedeep "^4.3.2"
node-sass "^4.2.0" node-sass "^4.8.3"
through2 "^2.0.0" through2 "^2.0.0"
vinyl-sourcemaps-apply "^0.2.0" vinyl-sourcemaps-apply "^0.2.0"
@ -3402,9 +3445,9 @@ load-json-file@^4.0.0:
pify "^3.0.0" pify "^3.0.0"
strip-bom "^3.0.0" strip-bom "^3.0.0"
loadjs@^3.5.2: loadjs@^3.5.4:
version "3.5.2" version "3.5.4"
resolved "https://registry.yarnpkg.com/loadjs/-/loadjs-3.5.2.tgz#add0e0e0322859840b362598f762c02f5539ce0b" resolved "https://registry.yarnpkg.com/loadjs/-/loadjs-3.5.4.tgz#ef0f4eb5a6ac2b86c7597a3d4de97b83816e36b8"
locate-path@^2.0.0: locate-path@^2.0.0:
version "2.0.0" version "2.0.0"
@ -3957,9 +4000,9 @@ mute-stream@0.0.7:
version "0.0.7" version "0.0.7"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
nan@^2.3.2: nan@^2.10.0:
version "2.9.2" version "2.10.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.9.2.tgz#f564d75f5f8f36a6d9456cca7a6c4fe488ab7866" resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"
nanomatch@^1.2.9: nanomatch@^1.2.9:
version "1.2.9" version "1.2.9"
@ -4008,9 +4051,9 @@ node-gyp@^3.3.1:
tar "^2.0.0" tar "^2.0.0"
which "1" which "1"
node-sass@^4.2.0: node-sass@^4.8.3:
version "4.7.2" version "4.8.3"
resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.7.2.tgz#9366778ba1469eb01438a9e8592f4262bcb6794e" resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.8.3.tgz#d077cc20a08ac06f661ca44fb6f19cd2ed41debb"
dependencies: dependencies:
async-foreach "^0.1.3" async-foreach "^0.1.3"
chalk "^1.1.1" chalk "^1.1.1"
@ -4024,7 +4067,7 @@ node-sass@^4.2.0:
lodash.mergewith "^4.6.0" lodash.mergewith "^4.6.0"
meow "^3.7.0" meow "^3.7.0"
mkdirp "^0.5.1" mkdirp "^0.5.1"
nan "^2.3.2" nan "^2.10.0"
node-gyp "^3.3.1" node-gyp "^3.3.1"
npmlog "^4.0.0" npmlog "^4.0.0"
request "~2.79.0" request "~2.79.0"
@ -4662,9 +4705,9 @@ randomatic@^1.1.3:
is-number "^3.0.0" is-number "^3.0.0"
kind-of "^4.0.0" kind-of "^4.0.0"
raven-js@^3.23.3: raven-js@^3.24.0:
version "3.23.3" version "3.24.0"
resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.23.3.tgz#6174f506c7362eb8bb72b291af5f22edb44ef165" resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.24.0.tgz#59464d8bc4b3812ae87a282e9bb98ecad5b4b047"
rc@^1.0.1, rc@^1.1.6: rc@^1.0.1, rc@^1.1.6:
version "1.2.6" version "1.2.6"
@ -5070,7 +5113,7 @@ resolve-url@^0.2.1, resolve-url@~0.2.1:
version "0.2.1" version "0.2.1"
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
resolve@^1.1.6, resolve@^1.1.7, resolve@^1.4.0, resolve@^1.5.0: resolve@^1.1.6, resolve@^1.1.7, resolve@^1.5.0:
version "1.5.0" version "1.5.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
dependencies: dependencies:
@ -5099,19 +5142,18 @@ rollup-plugin-babel@^3.0.3:
dependencies: dependencies:
rollup-pluginutils "^1.5.0" rollup-pluginutils "^1.5.0"
rollup-plugin-commonjs@^8.4.1: rollup-plugin-commonjs@^9.1.0:
version "8.4.1" version "9.1.0"
resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-8.4.1.tgz#5c9cea2b2c3de322f5fbccd147e07ed5e502d7a0" resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-9.1.0.tgz#468341aab32499123ee9a04b22f51d9bf26fdd94"
dependencies: dependencies:
acorn "^5.2.1" estree-walker "^0.5.1"
estree-walker "^0.5.0"
magic-string "^0.22.4" magic-string "^0.22.4"
resolve "^1.4.0" resolve "^1.5.0"
rollup-pluginutils "^2.0.1" rollup-pluginutils "^2.0.1"
rollup-plugin-node-resolve@^3.2.0: rollup-plugin-node-resolve@^3.3.0:
version "3.2.0" version "3.3.0"
resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.2.0.tgz#31534952f3ab21f9473c1d092be7ed43937ea4d4" resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.3.0.tgz#c26d110a36812cbefa7ce117cadcd3439aa1c713"
dependencies: dependencies:
builtin-modules "^2.0.0" builtin-modules "^2.0.0"
is-module "^1.0.0" is-module "^1.0.0"
@ -5131,9 +5173,9 @@ rollup-pluginutils@^2.0.1:
estree-walker "^0.3.0" estree-walker "^0.3.0"
micromatch "^2.3.11" micromatch "^2.3.11"
rollup@^0.50.0: "rollup@>=0.48 <0.57":
version "0.50.1" version "0.56.5"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.50.1.tgz#e4dafcbf8d2bb0d9f5589d0cc6f64d76b8815730" resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.56.5.tgz#40fe3cf0cd1659d469baad11f4d5b6336c14ce84"
run-async@^2.2.0: run-async@^2.2.0:
version "2.3.0" version "2.3.0"