Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
cce143a7da | |||
d593005b32 | |||
7be9d5d4d3 | |||
d7141d5ed7 | |||
0d0ece94d3 |
15
.vscode/launch.json
vendored
Normal file
15
.vscode/launch.json
vendored
Normal 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}"
|
||||
}
|
||||
]
|
||||
}
|
15
changelog.md
15
changelog.md
@ -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
|
||||
|
||||
* Vimeo hotfix for private videos
|
||||
|
208
controls.md
208
controls.md
@ -1,27 +1,72 @@
|
||||
# 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.
|
||||
|
||||
### Example
|
||||
#### Example
|
||||
|
||||
```javascript
|
||||
i18n: {
|
||||
restart: "Restart",
|
||||
rewind: "Rewind {seektime} secs",
|
||||
play: "Play",
|
||||
pause: "Pause",
|
||||
forward: "Forward {seektime} secs",
|
||||
buffered: "buffered",
|
||||
currentTime: "Current time",
|
||||
duration: "Duration",
|
||||
volume: "Volume",
|
||||
toggleMute: "Toggle Mute",
|
||||
toggleCaptions: "Toggle Captions",
|
||||
toggleFullscreen: "Toggle Fullscreen"
|
||||
restart: 'Restart',
|
||||
rewind: 'Rewind {seektime} secs',
|
||||
play: 'Play',
|
||||
pause: 'Pause',
|
||||
fastForward: 'Forward {seektime} secs',
|
||||
seek: 'Seek',
|
||||
played: 'Played',
|
||||
buffered: 'Buffered',
|
||||
currentTime: 'Current time',
|
||||
duration: 'Duration',
|
||||
volume: 'Volume',
|
||||
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
|
||||
|
||||
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)
|
||||
- `{seektime}` - the seek time specified in options for fast forward and rewind
|
||||
- `{title}` - the title of your media, if specified
|
||||
* `{id}` - the dynamically generated ID for the player (for form controls)
|
||||
* `{seektime}` - the seek time specified in options for fast forward and rewind
|
||||
* `{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
|
||||
|
||||
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
|
||||
var controls = ["<div class='plyr__controls'>",
|
||||
"<button type='button' data-plyr='restart'>",
|
||||
"<svg><use xlink:href='#plyr-restart'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Restart</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-plyr='rewind'>",
|
||||
"<svg><use xlink:href='#plyr-rewind'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Rewind {seektime} secs</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-plyr='play'>",
|
||||
"<svg><use xlink:href='#plyr-play'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Play</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-plyr='pause'>",
|
||||
"<svg><use xlink:href='#plyr-pause'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Pause</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-plyr='fast-forward'>",
|
||||
"<svg><use xlink:href='#plyr-fast-forward'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Forward {seektime} secs</span>",
|
||||
"</button>",
|
||||
"<span class='plyr__progress'>",
|
||||
"<label for='seek{id}' class='plyr__sr-only'>Seek</label>",
|
||||
"<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--played' max='100' value='0' role='presentation'></progress>",
|
||||
"<progress class='plyr__progress--buffer' max='100' value='0'>",
|
||||
"<span>0</span>% buffered",
|
||||
"</progress>",
|
||||
"<span class='plyr__tooltip'>00:00</span>",
|
||||
"</span>",
|
||||
"<span class='plyr__time'>",
|
||||
"<span class='plyr__sr-only'>Current time</span>",
|
||||
"<span class='plyr__time--current'>00:00</span>",
|
||||
"</span>",
|
||||
"<span class='plyr__time'>",
|
||||
"<span class='plyr__sr-only'>Duration</span>",
|
||||
"<span class='plyr__time--duration'>00:00</span>",
|
||||
"</span>",
|
||||
"<button type='button' data-plyr='mute'>",
|
||||
"<svg class='icon--muted'><use xlink:href='#plyr-muted'></use></svg>",
|
||||
"<svg><use xlink:href='#plyr-volume'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Toggle Mute</span>",
|
||||
"</button>",
|
||||
"<span class='plyr__volume'>",
|
||||
"<label for='volume{id}' class='plyr__sr-only'>Volume</label>",
|
||||
"<input id='volume{id}' class='plyr__volume--input' type='range' min='0' max='10' value='5' data-plyr='volume'>",
|
||||
"<progress class='plyr__volume--display' max='10' value='0' role='presentation'></progress>",
|
||||
"</span>",
|
||||
"<button type='button' data-plyr='captions'>",
|
||||
"<svg class='icon--captions-on'><use xlink:href='#plyr-captions-on'></use></svg>",
|
||||
"<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("");
|
||||
const controls = `
|
||||
<div class="plyr__controls">
|
||||
<button type="button" class="plyr__control" data-plyr="restart">
|
||||
<svg role="presentation"><use xlink:href="#plyr-restart"></use></svg>
|
||||
<span class="plyr__tooltip" role="tooltip">Restart</span>
|
||||
</button>
|
||||
<button type="button" class="plyr__control" data-plyr="rewind">
|
||||
<svg role="presentation"><use xlink:href="#plyr-rewind"></use></svg>
|
||||
<span class="plyr__tooltip" role="tooltip">Rewind {seektime} secs</span>
|
||||
</button>
|
||||
<button type="button" class="plyr__control" aria-pressed="false" aria-label="Play, {title}" data-plyr="play">
|
||||
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-pause"></use></svg>
|
||||
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-play"></use></svg>
|
||||
<span class="label--pressed plyr__tooltip" role="tooltip">Pause</span>
|
||||
<span class="label--not-pressed plyr__tooltip" role="tooltip">Play</span>
|
||||
</button>
|
||||
<button type="button" class="plyr__control" data-plyr="fast-forward">
|
||||
<svg role="presentation"><use xlink:href="#plyr-fast-forward"></use></svg>
|
||||
<span class="plyr__tooltip" role="tooltip">Forward {seektime} secs</span>
|
||||
</button>
|
||||
<div class="plyr__progress">
|
||||
<label for="plyr-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}">
|
||||
<progress class="plyr__progress--buffer" min="0" max="100" value="0">% buffered</progress>
|
||||
<span role="tooltip" class="plyr__tooltip">00:00</span>
|
||||
</div>
|
||||
<div class="plyr__time">00:00</div>
|
||||
<button type="button" class="plyr__control" aria-pressed="false" aria-label="Mute" data-plyr="mute">
|
||||
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-muted"></use></svg>
|
||||
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-volume"></use></svg>
|
||||
<span class="label--pressed plyr__tooltip" role="tooltip">Unmute</span>
|
||||
<span class="label--not-pressed plyr__tooltip" role="tooltip">Mute</span>
|
||||
</button>
|
||||
<div class="plyr__volume">
|
||||
<label for="plyr-volume-{id}" class="plyr__sr-only">Volume</label>
|
||||
<input data-plyr="volume" type="range" min="0" max="1" step="0.05" value="1" autocomplete="off" id="plyr-volume-{id}">
|
||||
</div>
|
||||
<button type="button" class="plyr__control" aria-pressed="true" aria-label="Enable captions" data-plyr="captions">
|
||||
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-captions-on"></use></svg>
|
||||
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-captions-off"></use></svg>
|
||||
<span class="label--pressed plyr__tooltip" role="tooltip">Disable captions</span>
|
||||
<span class="label--not-pressed plyr__tooltip" role="tooltip">Enable captions</span>
|
||||
</button>
|
||||
<button type="button" class="plyr__control" aria-pressed="false" aria-label="Enter fullscreen" data-plyr="fullscreen">
|
||||
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-exit-fullscreen"></use></svg>
|
||||
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-enter-fullscreen"></use></svg>
|
||||
<span class="label--pressed plyr__tooltip" role="tooltip">Exit fullscreen</span>
|
||||
<span class="label--not-pressed plyr__tooltip" role="tooltip">Enter fullscreen</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Setup the player
|
||||
plyr.setup('.js-player', {
|
||||
html: controls
|
||||
});
|
||||
const player = new Plyr('#player', { controls });
|
||||
```
|
||||
|
557
demo/dist/demo.js
vendored
557
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
@ -169,7 +169,8 @@
|
||||
</aside>
|
||||
|
||||
<!-- 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 -->
|
||||
<script src="../dist/plyr.js" crossorigin="anonymous"></script>
|
||||
|
@ -65,6 +65,7 @@ import Raven from 'raven-js';
|
||||
'fast-forward',
|
||||
'progress',
|
||||
'current-time',
|
||||
'duration',
|
||||
'mute',
|
||||
'volume',
|
||||
'captions',
|
||||
@ -83,9 +84,6 @@ import Raven from 'raven-js';
|
||||
enabled: true,
|
||||
publisherId: '918848828995742',
|
||||
},
|
||||
/* listeners: {
|
||||
seek: () => false,
|
||||
}, */
|
||||
});
|
||||
|
||||
// Expose for tinkering in the console
|
||||
@ -179,7 +177,7 @@ import Raven from 'raven-js';
|
||||
player.source = {
|
||||
type: 'video',
|
||||
sources: [{
|
||||
src: 'https://vimeo.com/25345658',
|
||||
src: 'https://vimeo.com/76979871',
|
||||
provider: 'vimeo',
|
||||
}],
|
||||
};
|
||||
|
370
dist/plyr.js
vendored
370
dist/plyr.js
vendored
@ -77,7 +77,7 @@ var defaults = {
|
||||
// Sprite (for icons)
|
||||
loadSprite: true,
|
||||
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)
|
||||
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 : {};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function createCommonjsModule(fn, module) {
|
||||
return module = { exports: {} }, fn(module, module.exports), module.exports;
|
||||
}
|
||||
@ -456,6 +452,7 @@ function loadFile(path, callbackFn, args, numTries) {
|
||||
async = args.async,
|
||||
maxTries = (args.numRetries || 0) + 1,
|
||||
beforeCallbackFn = args.before || devnull,
|
||||
pathStripped = path.replace(/^(css|img)!/, ''),
|
||||
isCss,
|
||||
e;
|
||||
|
||||
@ -467,7 +464,11 @@ function loadFile(path, callbackFn, args, numTries) {
|
||||
// css
|
||||
e = doc.createElement('link');
|
||||
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 {
|
||||
// javascript
|
||||
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) {
|
||||
if (!(instance instanceof Constructor)) {
|
||||
throw new TypeError("Cannot call a class as a function");
|
||||
@ -774,10 +658,6 @@ var createClass = function () {
|
||||
};
|
||||
}();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var defineProperty = function (obj, key, value) {
|
||||
if (key in obj) {
|
||||
Object.defineProperty(obj, key, {
|
||||
@ -792,26 +672,6 @@ var defineProperty = function (obj, key, value) {
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var slicedToArray = function () {
|
||||
function sliceIterator(arr, i) {
|
||||
@ -851,18 +711,6 @@ var slicedToArray = function () {
|
||||
};
|
||||
}();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var toConsumableArray = function (arr) {
|
||||
if (Array.isArray(arr)) {
|
||||
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 = {
|
||||
@ -1818,8 +1664,6 @@ var utils = {
|
||||
}
|
||||
};
|
||||
|
||||
// ==========================================================================
|
||||
// Plyr support checks
|
||||
// ==========================================================================
|
||||
|
||||
// Check for feature support
|
||||
@ -2015,9 +1859,6 @@ var Console = function () {
|
||||
return Console;
|
||||
}();
|
||||
|
||||
// ==========================================================================
|
||||
// Fullscreen wrapper
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API#prefixing
|
||||
// ==========================================================================
|
||||
|
||||
var browser = utils.getBrowser();
|
||||
@ -2253,9 +2094,6 @@ var Fullscreen = function () {
|
||||
return Fullscreen;
|
||||
}();
|
||||
|
||||
// ==========================================================================
|
||||
// Plyr Captions
|
||||
// TODO: Create as class
|
||||
// ==========================================================================
|
||||
|
||||
var captions = {
|
||||
@ -2487,8 +2325,6 @@ var captions = {
|
||||
}
|
||||
};
|
||||
|
||||
// ==========================================================================
|
||||
// Plyr internationalization
|
||||
// ==========================================================================
|
||||
|
||||
var i18n = {
|
||||
@ -2519,8 +2355,6 @@ var i18n = {
|
||||
}
|
||||
};
|
||||
|
||||
// ==========================================================================
|
||||
// Plyr UI
|
||||
// ==========================================================================
|
||||
|
||||
var ui = {
|
||||
@ -2596,6 +2430,9 @@ var ui = {
|
||||
// Reset quality options
|
||||
this.options.quality = [];
|
||||
|
||||
// Reset volume display
|
||||
ui.updateVolume.call(this);
|
||||
|
||||
// Reset time display
|
||||
ui.timeUpdate.call(this);
|
||||
|
||||
@ -2861,18 +2698,16 @@ var ui = {
|
||||
}
|
||||
};
|
||||
|
||||
// ==========================================================================
|
||||
// Plyr controls
|
||||
// ==========================================================================
|
||||
|
||||
// Sniff out the browser
|
||||
var browser$2 = utils.getBrowser();
|
||||
var browser$1 = utils.getBrowser();
|
||||
|
||||
var controls = {
|
||||
// Webkit polyfill for lower fill range
|
||||
updateRangeFill: function updateRangeFill(target) {
|
||||
// WebKit only
|
||||
if (!browser$2.isWebkit) {
|
||||
if (!browser$1.isWebkit) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2893,7 +2728,7 @@ var controls = {
|
||||
getIconUrl: function getIconUrl() {
|
||||
return {
|
||||
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;
|
||||
|
||||
if (this.isHTML5) {
|
||||
controls.setSpeedMenu.call(this);
|
||||
}
|
||||
controls.setSpeedMenu.call(this);
|
||||
|
||||
return container;
|
||||
},
|
||||
@ -4086,12 +3919,10 @@ var controls = {
|
||||
}
|
||||
};
|
||||
|
||||
// ==========================================================================
|
||||
// Plyr Event Listeners
|
||||
// ==========================================================================
|
||||
|
||||
// Sniff out the browser
|
||||
var browser$1 = utils.getBrowser();
|
||||
var browser$2 = utils.getBrowser();
|
||||
|
||||
var Listeners = function () {
|
||||
function Listeners(player) {
|
||||
@ -4372,17 +4203,17 @@ var Listeners = function () {
|
||||
return ui.updateProgress.call(_this3.player, event);
|
||||
});
|
||||
|
||||
// Handle native mute
|
||||
// Handle volume changes
|
||||
utils.on(this.player.media, 'volumechange', function (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) {
|
||||
return ui.checkPlaying.call(_this3.player, event);
|
||||
});
|
||||
|
||||
// Loading
|
||||
// Loading state
|
||||
utils.on(this.player.media, 'waiting canplay seeked playing', function (event) {
|
||||
return ui.checkLoading.call(_this3.player, event);
|
||||
});
|
||||
@ -4390,6 +4221,20 @@ var Listeners = function () {
|
||||
// Check if media failed to load
|
||||
// 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
|
||||
if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) {
|
||||
// Re-fetch the wrapper
|
||||
@ -4489,7 +4334,7 @@ var Listeners = function () {
|
||||
var _this4 = this;
|
||||
|
||||
// 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
|
||||
var proxy = function proxy(event, defaultHandler, customHandlerKey) {
|
||||
@ -4605,7 +4450,7 @@ var Listeners = function () {
|
||||
}, 'volume');
|
||||
|
||||
// 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) {
|
||||
controls.updateRangeFill.call(_this4.player, event.target);
|
||||
});
|
||||
@ -4682,8 +4527,6 @@ var Listeners = function () {
|
||||
return Listeners;
|
||||
}();
|
||||
|
||||
// ==========================================================================
|
||||
// Plyr storage
|
||||
// ==========================================================================
|
||||
|
||||
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 () {
|
||||
/**
|
||||
@ -4993,21 +4830,23 @@ var Ads = function () {
|
||||
this.cuePoints = this.manager.getCuePoints();
|
||||
|
||||
// Add advertisement cue's within the time line if available
|
||||
this.cuePoints.forEach(function (cuePoint) {
|
||||
if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < _this6.player.duration) {
|
||||
var seekElement = _this6.player.elements.progress;
|
||||
if (!utils.is.empty(this.cuePoints)) {
|
||||
this.cuePoints.forEach(function (cuePoint) {
|
||||
if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < _this6.player.duration) {
|
||||
var seekElement = _this6.player.elements.progress;
|
||||
|
||||
if (seekElement) {
|
||||
var cuePercentage = 100 / _this6.player.duration * cuePoint;
|
||||
var cue = utils.createElement('span', {
|
||||
class: _this6.player.config.classNames.cues
|
||||
});
|
||||
if (utils.is.element(seekElement)) {
|
||||
var cuePercentage = 100 / _this6.player.duration * cuePoint;
|
||||
var cue = utils.createElement('span', {
|
||||
class: _this6.player.config.classNames.cues
|
||||
});
|
||||
|
||||
cue.style.left = cuePercentage.toString() + '%';
|
||||
seekElement.appendChild(cue);
|
||||
cue.style.left = cuePercentage.toString() + '%';
|
||||
seekElement.appendChild(cue);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Get skippable state
|
||||
// TODO: Skip button
|
||||
@ -5191,6 +5030,10 @@ var Ads = function () {
|
||||
this.player.on('seeked', function () {
|
||||
var seekedTime = _this8.player.currentTime;
|
||||
|
||||
if (utils.is.empty(_this8.cuePoints)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_this8.cuePoints.forEach(function (cuePoint, index) {
|
||||
if (time < cuePoint && cuePoint < seekedTime) {
|
||||
_this8.manager.discardAdBreak();
|
||||
@ -5202,7 +5045,9 @@ var Ads = function () {
|
||||
// Listen to the resizing of the window. And resize ad accordingly
|
||||
// TODO: eventually implement ResizeObserver
|
||||
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;
|
||||
}();
|
||||
|
||||
// ==========================================================================
|
||||
// YouTube plugin
|
||||
// ==========================================================================
|
||||
|
||||
var youtube = {
|
||||
@ -5862,8 +5705,6 @@ var youtube = {
|
||||
}
|
||||
};
|
||||
|
||||
// ==========================================================================
|
||||
// Vimeo plugin
|
||||
// ==========================================================================
|
||||
|
||||
var vimeo = {
|
||||
@ -6193,8 +6034,6 @@ var vimeo = {
|
||||
}
|
||||
};
|
||||
|
||||
// ==========================================================================
|
||||
// Plyr Media
|
||||
// ==========================================================================
|
||||
|
||||
// Sniff out the browser
|
||||
@ -6293,8 +6132,6 @@ var media = {
|
||||
}
|
||||
};
|
||||
|
||||
// ==========================================================================
|
||||
// Plyr source update
|
||||
// ==========================================================================
|
||||
|
||||
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
|
||||
@ -6553,7 +6385,17 @@ var Plyr = function () {
|
||||
}
|
||||
|
||||
// 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
|
||||
// Supported: video, audio, vimeo, youtube
|
||||
@ -6703,6 +6545,11 @@ var Plyr = function () {
|
||||
|
||||
// Setup ads if provided
|
||||
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)
|
||||
*/
|
||||
value: function play() {
|
||||
var _this2 = this;
|
||||
|
||||
if (!utils.is.function(this.media.play)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// If ads are enabled, wait for them first
|
||||
if (this.ads.enabled && !this.ads.initialized) {
|
||||
return this.ads.managerPromise.then(function () {
|
||||
return _this2.ads.play();
|
||||
}).catch(function () {
|
||||
return _this2.media.play();
|
||||
});
|
||||
}
|
||||
/* if (this.ads.enabled && !this.ads.initialized) {
|
||||
return this.ads.managerPromise.then(() => this.ads.play()).catch(() => this.media.play());
|
||||
} */
|
||||
|
||||
// Return the promise (for HTML5)
|
||||
return this.media.play();
|
||||
@ -6787,7 +6628,7 @@ var Plyr = function () {
|
||||
value: function stop() {
|
||||
if (this.isHTML5) {
|
||||
this.media.load();
|
||||
} else {
|
||||
} else if (utils.is.function(this.media.stop)) {
|
||||
this.media.stop();
|
||||
}
|
||||
}
|
||||
@ -6922,7 +6763,7 @@ var Plyr = function () {
|
||||
}, {
|
||||
key: 'toggleControls',
|
||||
value: function toggleControls(toggle) {
|
||||
var _this3 = this;
|
||||
var _this2 = this;
|
||||
|
||||
// We need controls of course...
|
||||
if (!utils.is.element(this.elements.controls)) {
|
||||
@ -6996,25 +6837,30 @@ var Plyr = function () {
|
||||
// then set the timer to hide the controls
|
||||
if (!show || this.playing) {
|
||||
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 ((_this3.elements.controls.pressed || _this3.elements.controls.hover) && !isEnterFullscreen) {
|
||||
if ((_this2.elements.controls.pressed || _this2.elements.controls.hover) && !isEnterFullscreen) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Restore transition behaviour
|
||||
if (!utils.hasClass(_this3.elements.container, _this3.config.classNames.hideControls)) {
|
||||
utils.toggleClass(_this3.elements.controls, _this3.config.classNames.noTransition, false);
|
||||
if (!utils.hasClass(_this2.elements.container, _this2.config.classNames.hideControls)) {
|
||||
utils.toggleClass(_this2.elements.controls, _this2.config.classNames.noTransition, false);
|
||||
}
|
||||
|
||||
// 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
|
||||
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)) {
|
||||
controls.toggleMenu.call(_this3, false);
|
||||
if (_this2.config.controls.includes('settings') && !utils.is.empty(_this2.config.settings)) {
|
||||
controls.toggleMenu.call(_this2, false);
|
||||
}
|
||||
}
|
||||
}, delay);
|
||||
@ -7056,7 +6902,7 @@ var Plyr = function () {
|
||||
}, {
|
||||
key: 'destroy',
|
||||
value: function destroy(callback) {
|
||||
var _this4 = this;
|
||||
var _this3 = this;
|
||||
|
||||
var soft = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
||||
|
||||
@ -7069,22 +6915,22 @@ var Plyr = function () {
|
||||
document.body.style.overflow = '';
|
||||
|
||||
// GC for embed
|
||||
_this4.embed = null;
|
||||
_this3.embed = null;
|
||||
|
||||
// If it's a soft destroy, make minimal changes
|
||||
if (soft) {
|
||||
if (Object.keys(_this4.elements).length) {
|
||||
if (Object.keys(_this3.elements).length) {
|
||||
// Remove elements
|
||||
utils.removeElement(_this4.elements.buttons.play);
|
||||
utils.removeElement(_this4.elements.captions);
|
||||
utils.removeElement(_this4.elements.controls);
|
||||
utils.removeElement(_this4.elements.wrapper);
|
||||
utils.removeElement(_this3.elements.buttons.play);
|
||||
utils.removeElement(_this3.elements.captions);
|
||||
utils.removeElement(_this3.elements.controls);
|
||||
utils.removeElement(_this3.elements.wrapper);
|
||||
|
||||
// Clear for GC
|
||||
_this4.elements.buttons.play = null;
|
||||
_this4.elements.captions = null;
|
||||
_this4.elements.controls = null;
|
||||
_this4.elements.wrapper = null;
|
||||
_this3.elements.buttons.play = null;
|
||||
_this3.elements.captions = null;
|
||||
_this3.elements.controls = null;
|
||||
_this3.elements.wrapper = null;
|
||||
}
|
||||
|
||||
// Callback
|
||||
@ -7093,26 +6939,26 @@ var Plyr = function () {
|
||||
}
|
||||
} else {
|
||||
// Unbind listeners
|
||||
_this4.listeners.clear();
|
||||
_this3.listeners.clear();
|
||||
|
||||
// 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
|
||||
utils.dispatchEvent.call(_this4, _this4.elements.original, 'destroyed', true);
|
||||
utils.dispatchEvent.call(_this3, _this3.elements.original, 'destroyed', true);
|
||||
|
||||
// Callback
|
||||
if (utils.is.function(callback)) {
|
||||
callback.call(_this4.elements.original);
|
||||
callback.call(_this3.elements.original);
|
||||
}
|
||||
|
||||
// Reset state
|
||||
_this4.ready = false;
|
||||
_this3.ready = false;
|
||||
|
||||
// Clear for garbage collection
|
||||
setTimeout(function () {
|
||||
_this4.elements = null;
|
||||
_this4.media = null;
|
||||
_this3.elements = null;
|
||||
_this3.media = null;
|
||||
}, 200);
|
||||
}
|
||||
};
|
||||
@ -7364,8 +7210,8 @@ var Plyr = function () {
|
||||
// Set the player volume
|
||||
this.media.volume = volume;
|
||||
|
||||
// If muted, and we're increasing volume, reset muted state
|
||||
if (this.muted && volume > 0) {
|
||||
// If muted, and we're increasing volume manually, reset muted state
|
||||
if (!utils.is.empty(value) && this.muted && volume > 0) {
|
||||
this.muted = false;
|
||||
}
|
||||
}
|
||||
|
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
656
dist/plyr.polyfilled.js
vendored
656
dist/plyr.polyfilled.js
vendored
File diff suppressed because it is too large
Load Diff
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
18
package.json
18
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "plyr",
|
||||
"version": "3.0.8",
|
||||
"version": "3.0.11",
|
||||
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
||||
"homepage": "https://plyr.io",
|
||||
"main": "./dist/plyr.js",
|
||||
@ -13,22 +13,22 @@
|
||||
"babel-plugin-external-helpers": "^6.22.0",
|
||||
"babel-preset-env": "^1.6.1",
|
||||
"del": "^3.0.0",
|
||||
"eslint": "^4.19.0",
|
||||
"eslint": "^4.19.1",
|
||||
"eslint-config-airbnb-base": "^12.1.0",
|
||||
"eslint-config-prettier": "^2.9.0",
|
||||
"eslint-plugin-import": "^2.9.0",
|
||||
"git-branch": "^2.0.1",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-autoprefixer": "^5.0.0",
|
||||
"gulp-better-rollup": "^3.0.0",
|
||||
"gulp-better-rollup": "^3.1.0",
|
||||
"gulp-clean-css": "^3.9.3",
|
||||
"gulp-concat": "^2.6.1",
|
||||
"gulp-filter": "^5.1.0",
|
||||
"gulp-open": "^3.0.0",
|
||||
"gulp-open": "^3.0.1",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-replace": "^0.6.1",
|
||||
"gulp-s3": "^0.11.0",
|
||||
"gulp-sass": "^3.1.0",
|
||||
"gulp-sass": "^3.2.1",
|
||||
"gulp-size": "^3.0.0",
|
||||
"gulp-sourcemaps": "^2.6.4",
|
||||
"gulp-svgmin": "^1.2.4",
|
||||
@ -38,8 +38,8 @@
|
||||
"prettier-eslint": "^8.8.1",
|
||||
"prettier-stylelint": "^0.4.2",
|
||||
"rollup-plugin-babel": "^3.0.3",
|
||||
"rollup-plugin-commonjs": "^8.4.1",
|
||||
"rollup-plugin-node-resolve": "^3.2.0",
|
||||
"rollup-plugin-commonjs": "^9.1.0",
|
||||
"rollup-plugin-node-resolve": "^3.3.0",
|
||||
"run-sequence": "^2.2.1",
|
||||
"stylelint": "^9.1.3",
|
||||
"stylelint-config-prettier": "^3.0.4",
|
||||
@ -68,7 +68,7 @@
|
||||
"dependencies": {
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"custom-event-polyfill": "^0.3.0",
|
||||
"loadjs": "^3.5.2",
|
||||
"raven-js": "^3.23.3"
|
||||
"loadjs": "^3.5.4",
|
||||
"raven-js": "^3.24.0"
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
||||
```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
|
||||
@ -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:
|
||||
|
||||
```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
|
||||
|
||||
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
|
||||
|
||||
|
4
src/js/controls.js
vendored
4
src/js/controls.js
vendored
@ -1177,9 +1177,7 @@ const controls = {
|
||||
|
||||
this.elements.controls = container;
|
||||
|
||||
if (this.isHTML5) {
|
||||
controls.setSpeedMenu.call(this);
|
||||
}
|
||||
controls.setSpeedMenu.call(this);
|
||||
|
||||
return container;
|
||||
},
|
||||
|
@ -56,7 +56,7 @@ const defaults = {
|
||||
// Sprite (for icons)
|
||||
loadSprite: true,
|
||||
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)
|
||||
blankVideo: 'https://cdn.plyr.io/static/blank.mp4',
|
||||
|
@ -278,18 +278,28 @@ class Listeners {
|
||||
// Check for buffer progress
|
||||
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));
|
||||
|
||||
// Handle native play/pause
|
||||
// Handle play/pause
|
||||
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));
|
||||
|
||||
// Check if media failed to load
|
||||
// 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
|
||||
if (this.player.supported.ui && this.player.config.clickToPlay && !this.player.isAudio) {
|
||||
// Re-fetch the wrapper
|
||||
|
@ -206,21 +206,23 @@ class Ads {
|
||||
this.cuePoints = this.manager.getCuePoints();
|
||||
|
||||
// Add advertisement cue's within the time line if available
|
||||
this.cuePoints.forEach(cuePoint => {
|
||||
if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < this.player.duration) {
|
||||
const seekElement = this.player.elements.progress;
|
||||
if (!utils.is.empty(this.cuePoints)) {
|
||||
this.cuePoints.forEach(cuePoint => {
|
||||
if (cuePoint !== 0 && cuePoint !== -1 && cuePoint < this.player.duration) {
|
||||
const seekElement = this.player.elements.progress;
|
||||
|
||||
if (seekElement) {
|
||||
const cuePercentage = 100 / this.player.duration * cuePoint;
|
||||
const cue = utils.createElement('span', {
|
||||
class: this.player.config.classNames.cues,
|
||||
});
|
||||
if (utils.is.element(seekElement)) {
|
||||
const cuePercentage = 100 / this.player.duration * cuePoint;
|
||||
const cue = utils.createElement('span', {
|
||||
class: this.player.config.classNames.cues,
|
||||
});
|
||||
|
||||
cue.style.left = `${cuePercentage.toString()}%`;
|
||||
seekElement.appendChild(cue);
|
||||
cue.style.left = `${cuePercentage.toString()}%`;
|
||||
seekElement.appendChild(cue);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Get skippable state
|
||||
// TODO: Skip button
|
||||
@ -385,6 +387,10 @@ class Ads {
|
||||
this.player.on('seeked', () => {
|
||||
const seekedTime = this.player.currentTime;
|
||||
|
||||
if (utils.is.empty(this.cuePoints)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.cuePoints.forEach((cuePoint, index) => {
|
||||
if (time < cuePoint && cuePoint < seekedTime) {
|
||||
this.manager.discardAdBreak();
|
||||
@ -396,7 +402,9 @@ class Ads {
|
||||
// Listen to the resizing of the window. And resize ad accordingly
|
||||
// TODO: eventually implement ResizeObserver
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// ==========================================================================
|
||||
// Plyr
|
||||
// plyr.js v3.0.8
|
||||
// plyr.js v3.0.11
|
||||
// https://github.com/sampotts/plyr
|
||||
// License: The MIT License (MIT)
|
||||
// ==========================================================================
|
||||
@ -133,7 +133,17 @@ class Plyr {
|
||||
}
|
||||
|
||||
// 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
|
||||
// Supported: video, audio, vimeo, youtube
|
||||
@ -286,6 +296,11 @@ class Plyr {
|
||||
|
||||
// Setup ads if provided
|
||||
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 (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 the promise (for HTML5)
|
||||
return this.media.play();
|
||||
@ -384,7 +399,7 @@ class Plyr {
|
||||
stop() {
|
||||
if (this.isHTML5) {
|
||||
this.media.load();
|
||||
} else {
|
||||
} else if (utils.is.function(this.media.stop)) {
|
||||
this.media.stop();
|
||||
}
|
||||
}
|
||||
@ -524,8 +539,8 @@ class Plyr {
|
||||
// Set the player volume
|
||||
this.media.volume = volume;
|
||||
|
||||
// If muted, and we're increasing volume, reset muted state
|
||||
if (this.muted && volume > 0) {
|
||||
// If muted, and we're increasing volume manually, reset muted state
|
||||
if (!utils.is.empty(value) && this.muted && volume > 0) {
|
||||
this.muted = false;
|
||||
}
|
||||
}
|
||||
@ -1019,6 +1034,11 @@ class Plyr {
|
||||
// then set the timer to hide the controls
|
||||
if (!show || this.playing) {
|
||||
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 ((this.elements.controls.pressed || this.elements.controls.hover) && !isEnterFullscreen) {
|
||||
return;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// ==========================================================================
|
||||
// Plyr Polyfilled Build
|
||||
// plyr.js v3.0.8
|
||||
// plyr.js v3.0.11
|
||||
// https://github.com/sampotts/plyr
|
||||
// License: The MIT License (MIT)
|
||||
// ==========================================================================
|
||||
|
@ -74,6 +74,9 @@ const ui = {
|
||||
// Reset quality options
|
||||
this.options.quality = [];
|
||||
|
||||
// Reset volume display
|
||||
ui.updateVolume.call(this);
|
||||
|
||||
// Reset time display
|
||||
ui.timeUpdate.call(this);
|
||||
|
||||
|
122
yarn.lock
122
yarn.lock
@ -105,7 +105,7 @@ acorn-jsx@^3.0.0:
|
||||
dependencies:
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.0.tgz#9e900efb5506812ac374557034ef6f5c3642fc4c"
|
||||
dependencies:
|
||||
@ -1818,6 +1818,49 @@ eslint@^4.0.0, eslint@^4.19.0:
|
||||
table "4.0.2"
|
||||
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:
|
||||
version "3.5.4"
|
||||
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"
|
||||
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"
|
||||
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"
|
||||
vinyl-sourcemaps-apply "^0.2.0"
|
||||
|
||||
gulp-better-rollup@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/gulp-better-rollup/-/gulp-better-rollup-3.0.0.tgz#2bf5c2d0e7908fae72bba1f2496d24eb3c482e33"
|
||||
gulp-better-rollup@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/gulp-better-rollup/-/gulp-better-rollup-3.1.0.tgz#b226ba0c672882075472158b82d22ba9976d4ecb"
|
||||
dependencies:
|
||||
lodash.camelcase "^4.3.0"
|
||||
plugin-error "^0.1.2"
|
||||
rollup "^0.50.0"
|
||||
rollup ">=0.48 <0.57"
|
||||
vinyl "^2.1.0"
|
||||
vinyl-sourcemaps-apply "^0.2.1"
|
||||
|
||||
@ -2479,9 +2522,9 @@ gulp-filter@^5.1.0:
|
||||
plugin-error "^0.1.2"
|
||||
streamfilter "^1.0.5"
|
||||
|
||||
gulp-open@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/gulp-open/-/gulp-open-3.0.0.tgz#5a572a99044fdc461685d0eb8f7529b34bf9a62c"
|
||||
gulp-open@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/gulp-open/-/gulp-open-3.0.1.tgz#a2f747b4aa31abec9399b527158b0368c57e2102"
|
||||
dependencies:
|
||||
colors "^1.1.2"
|
||||
opn "5.2.0"
|
||||
@ -2510,13 +2553,13 @@ gulp-s3@^0.11.0:
|
||||
knox ""
|
||||
mime "~1.2.11"
|
||||
|
||||
gulp-sass@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/gulp-sass/-/gulp-sass-3.1.0.tgz#53dc4b68a1f5ddfe4424ab4c247655269a8b74b7"
|
||||
gulp-sass@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/gulp-sass/-/gulp-sass-3.2.1.tgz#2e3688a96fd8be1c0c01340750c191b2e79fab94"
|
||||
dependencies:
|
||||
gulp-util "^3.0"
|
||||
lodash.clonedeep "^4.3.2"
|
||||
node-sass "^4.2.0"
|
||||
node-sass "^4.8.3"
|
||||
through2 "^2.0.0"
|
||||
vinyl-sourcemaps-apply "^0.2.0"
|
||||
|
||||
@ -3402,9 +3445,9 @@ load-json-file@^4.0.0:
|
||||
pify "^3.0.0"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
loadjs@^3.5.2:
|
||||
version "3.5.2"
|
||||
resolved "https://registry.yarnpkg.com/loadjs/-/loadjs-3.5.2.tgz#add0e0e0322859840b362598f762c02f5539ce0b"
|
||||
loadjs@^3.5.4:
|
||||
version "3.5.4"
|
||||
resolved "https://registry.yarnpkg.com/loadjs/-/loadjs-3.5.4.tgz#ef0f4eb5a6ac2b86c7597a3d4de97b83816e36b8"
|
||||
|
||||
locate-path@^2.0.0:
|
||||
version "2.0.0"
|
||||
@ -3957,9 +4000,9 @@ mute-stream@0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
|
||||
|
||||
nan@^2.3.2:
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.9.2.tgz#f564d75f5f8f36a6d9456cca7a6c4fe488ab7866"
|
||||
nan@^2.10.0:
|
||||
version "2.10.0"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"
|
||||
|
||||
nanomatch@^1.2.9:
|
||||
version "1.2.9"
|
||||
@ -4008,9 +4051,9 @@ node-gyp@^3.3.1:
|
||||
tar "^2.0.0"
|
||||
which "1"
|
||||
|
||||
node-sass@^4.2.0:
|
||||
version "4.7.2"
|
||||
resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.7.2.tgz#9366778ba1469eb01438a9e8592f4262bcb6794e"
|
||||
node-sass@^4.8.3:
|
||||
version "4.8.3"
|
||||
resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.8.3.tgz#d077cc20a08ac06f661ca44fb6f19cd2ed41debb"
|
||||
dependencies:
|
||||
async-foreach "^0.1.3"
|
||||
chalk "^1.1.1"
|
||||
@ -4024,7 +4067,7 @@ node-sass@^4.2.0:
|
||||
lodash.mergewith "^4.6.0"
|
||||
meow "^3.7.0"
|
||||
mkdirp "^0.5.1"
|
||||
nan "^2.3.2"
|
||||
nan "^2.10.0"
|
||||
node-gyp "^3.3.1"
|
||||
npmlog "^4.0.0"
|
||||
request "~2.79.0"
|
||||
@ -4662,9 +4705,9 @@ randomatic@^1.1.3:
|
||||
is-number "^3.0.0"
|
||||
kind-of "^4.0.0"
|
||||
|
||||
raven-js@^3.23.3:
|
||||
version "3.23.3"
|
||||
resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.23.3.tgz#6174f506c7362eb8bb72b291af5f22edb44ef165"
|
||||
raven-js@^3.24.0:
|
||||
version "3.24.0"
|
||||
resolved "https://registry.yarnpkg.com/raven-js/-/raven-js-3.24.0.tgz#59464d8bc4b3812ae87a282e9bb98ecad5b4b047"
|
||||
|
||||
rc@^1.0.1, rc@^1.1.6:
|
||||
version "1.2.6"
|
||||
@ -5070,7 +5113,7 @@ resolve-url@^0.2.1, resolve-url@~0.2.1:
|
||||
version "0.2.1"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
|
||||
dependencies:
|
||||
@ -5099,19 +5142,18 @@ rollup-plugin-babel@^3.0.3:
|
||||
dependencies:
|
||||
rollup-pluginutils "^1.5.0"
|
||||
|
||||
rollup-plugin-commonjs@^8.4.1:
|
||||
version "8.4.1"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-8.4.1.tgz#5c9cea2b2c3de322f5fbccd147e07ed5e502d7a0"
|
||||
rollup-plugin-commonjs@^9.1.0:
|
||||
version "9.1.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-9.1.0.tgz#468341aab32499123ee9a04b22f51d9bf26fdd94"
|
||||
dependencies:
|
||||
acorn "^5.2.1"
|
||||
estree-walker "^0.5.0"
|
||||
estree-walker "^0.5.1"
|
||||
magic-string "^0.22.4"
|
||||
resolve "^1.4.0"
|
||||
resolve "^1.5.0"
|
||||
rollup-pluginutils "^2.0.1"
|
||||
|
||||
rollup-plugin-node-resolve@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.2.0.tgz#31534952f3ab21f9473c1d092be7ed43937ea4d4"
|
||||
rollup-plugin-node-resolve@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.3.0.tgz#c26d110a36812cbefa7ce117cadcd3439aa1c713"
|
||||
dependencies:
|
||||
builtin-modules "^2.0.0"
|
||||
is-module "^1.0.0"
|
||||
@ -5131,9 +5173,9 @@ rollup-pluginutils@^2.0.1:
|
||||
estree-walker "^0.3.0"
|
||||
micromatch "^2.3.11"
|
||||
|
||||
rollup@^0.50.0:
|
||||
version "0.50.1"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.50.1.tgz#e4dafcbf8d2bb0d9f5589d0cc6f64d76b8815730"
|
||||
"rollup@>=0.48 <0.57":
|
||||
version "0.56.5"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.56.5.tgz#40fe3cf0cd1659d469baad11f4d5b6336c14ce84"
|
||||
|
||||
run-async@^2.2.0:
|
||||
version "2.3.0"
|
||||
|
Reference in New Issue
Block a user