Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
3b69f47590 | |||
8172e2339d | |||
44bb6c077c | |||
e11a58a841 | |||
c4e3b5a242 | |||
f1b44e6da0 | |||
aa093b6c42 | |||
97870a7cdc | |||
9a6433488f | |||
993617f75f | |||
48399f6364 | |||
47e0800f02 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -7,3 +7,5 @@ docs/index.dev.html
|
||||
*.mp4
|
||||
index-dev.html
|
||||
notes.txt
|
||||
*.vtt
|
||||
docs/index.dev.php
|
||||
|
10
changelog.md
10
changelog.md
@ -1,5 +1,15 @@
|
||||
# Changelog
|
||||
|
||||
## v1.6.2
|
||||
- Fix for tooltip displaying when duration is not set (fixes #177)
|
||||
- `showPosterOnEnd` option to show poster when HTML5 video ended (fixes #59)
|
||||
- Error handler for YouTube (fixes #189)
|
||||
- Initial SoundCloud support (fixes #194)
|
||||
- Other minor bug fixes
|
||||
|
||||
## v1.6.1
|
||||
- Tooltip changes for accessibility
|
||||
|
||||
## v1.6.0
|
||||
- New, cleaner, UI:
|
||||
- Controls are now overlaid, maintaining the video's ratio and making sizing easier
|
||||
|
2
dist/plyr.css
vendored
2
dist/plyr.css
vendored
File diff suppressed because one or more lines are too long
4
dist/plyr.js
vendored
4
dist/plyr.js
vendored
File diff suppressed because one or more lines are too long
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "plyr",
|
||||
"version": "1.6.0",
|
||||
"version": "1.6.2",
|
||||
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
||||
"homepage": "http://plyr.io",
|
||||
"main": "src/js/plyr.js",
|
||||
|
14
readme.md
14
readme.md
@ -40,10 +40,9 @@ If you have any cool ideas or features, please let me know by [creating an issue
|
||||
## Implementation
|
||||
Check `docs/index.html` and `docs/dist/docs.js` for an example setup.
|
||||
|
||||
**Heads up:** the example `index.html` file needs to be served from a webserver (such as Apache, Nginx, IIS or similar) unless you change the file sources to include http or https. e.g. change `//cdn.plyr.io/1.6.0/plyr.js` to `https://cdn.plyr.io/1.6.0/plyr.js`
|
||||
**Heads up:** the example `index.html` file needs to be served from a webserver (such as Apache, Nginx, IIS or similar) unless you change the file sources to include http or https. e.g. change `//cdn.plyr.io/1.6.2/plyr.js` to `https://cdn.plyr.io/1.6.2/plyr.js`
|
||||
|
||||
### Node Package Manager (NPM)
|
||||
[](https://badge.fury.io/js/plyr)
|
||||
|
||||
Using NPM, you can grab Plyr:
|
||||
```
|
||||
@ -52,7 +51,6 @@ npm install plyr
|
||||
[https://www.npmjs.com/package/plyr](https://www.npmjs.com/package/plyr)
|
||||
|
||||
### Bower
|
||||
[](https://badge.fury.io/bo/plyr)
|
||||
|
||||
If bower is your thang, you can grab Plyr using:
|
||||
```
|
||||
@ -73,11 +71,11 @@ More info is on [npm](https://www.npmjs.com/package/ember-cli-plyr) and [GitHub]
|
||||
If you want to use our CDN, you can use the following:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/1.6.0/plyr.css">
|
||||
<script src="https://cdn.plyr.io/1.6.0/plyr.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/1.6.2/plyr.css">
|
||||
<script src="https://cdn.plyr.io/1.6.2/plyr.js"></script>
|
||||
```
|
||||
|
||||
You can also access the `sprite.svg` file at `https://cdn.plyr.io/1.6.0/sprite.svg`.
|
||||
You can also access the `sprite.svg` file at `https://cdn.plyr.io/1.6.2/sprite.svg`.
|
||||
|
||||
### CSS & Styling
|
||||
If you want to use the default css, add the `plyr.css` file from `/dist` into your head, or even better use `plyr.less` or `plyr.scss` file included in `/src` in your build to save a request.
|
||||
@ -115,7 +113,7 @@ Using AJAX means you can load the sprite from a different origin. Avoiding the i
|
||||
c.innerHTML = a.responseText;
|
||||
b.insertBefore(c, b.childNodes[0]);
|
||||
};
|
||||
})(document, 'https://cdn.plyr.io/1.6.0/sprite.svg');
|
||||
})(document, 'https://cdn.plyr.io/1.6.2/sprite.svg');
|
||||
</script>
|
||||
```
|
||||
|
||||
@ -190,7 +188,7 @@ Be sure to [validate your caption files](https://quuz.org/webvtt/)
|
||||
Here's an example of a default setup:
|
||||
|
||||
```html
|
||||
<script src="https://cdn.plyr.io/1.6.0/plyr.js"></script>
|
||||
<script src="https://cdn.plyr.io/1.6.2/plyr.js"></script>
|
||||
<script>plyr.setup();</script>
|
||||
```
|
||||
|
||||
|
408
src/js/plyr.js
408
src/js/plyr.js
@ -1,6 +1,6 @@
|
||||
// ==========================================================================
|
||||
// Plyr
|
||||
// plyr.js v1.6.0
|
||||
// plyr.js v1.6.2
|
||||
// https://github.com/selz/plyr
|
||||
// License: The MIT License (MIT)
|
||||
// ==========================================================================
|
||||
@ -42,6 +42,7 @@
|
||||
iconUrl: '',
|
||||
clickToPlay: true,
|
||||
hideControls: true,
|
||||
showPosterOnEnd: false,
|
||||
tooltips: {
|
||||
controls: false,
|
||||
seek: true
|
||||
@ -131,7 +132,7 @@
|
||||
frameTitle: 'Player for {title}'
|
||||
},
|
||||
types: {
|
||||
embed: ['youtube', 'vimeo'],
|
||||
embed: ['youtube', 'vimeo', 'soundcloud'],
|
||||
html5: ['video', 'audio']
|
||||
},
|
||||
// URLs
|
||||
@ -141,6 +142,9 @@
|
||||
},
|
||||
youtube: {
|
||||
api: 'https://www.youtube.com/iframe_api'
|
||||
},
|
||||
soundcloud: {
|
||||
api: 'https://w.soundcloud.com/player/api.js'
|
||||
}
|
||||
},
|
||||
// Custom control listeners
|
||||
@ -333,7 +337,7 @@
|
||||
|
||||
// Remove an element
|
||||
function _remove(element) {
|
||||
if(!element) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
element.parentNode.removeChild(element);
|
||||
@ -411,7 +415,7 @@
|
||||
// Bind along with custom handler
|
||||
function _proxyListener(element, eventName, userListener, defaultListener, useCapture) {
|
||||
_on(element, eventName, function(event) {
|
||||
if(userListener) {
|
||||
if (userListener) {
|
||||
userListener.apply(element, [event]);
|
||||
}
|
||||
defaultListener.apply(element, [event]);
|
||||
@ -424,7 +428,7 @@
|
||||
|
||||
// Whether the listener is a capturing listener or not
|
||||
// Default to false
|
||||
if(typeof useCapture !== 'boolean') {
|
||||
if (typeof useCapture !== 'boolean') {
|
||||
useCapture = false;
|
||||
}
|
||||
|
||||
@ -445,14 +449,22 @@
|
||||
}
|
||||
|
||||
// Trigger event
|
||||
function _triggerEvent(element, eventName, properties) {
|
||||
function _triggerEvent(element, eventName, bubbles, properties) {
|
||||
// Bail if no element
|
||||
if(!element || !eventName) {
|
||||
if (!element || !eventName) {
|
||||
return;
|
||||
}
|
||||
|
||||
// create and dispatch the event
|
||||
var event = new CustomEvent(eventName, properties);
|
||||
// Default bubbles to false
|
||||
if (typeof bubbles !== 'boolean') {
|
||||
bubbles = false;
|
||||
}
|
||||
|
||||
// Create and dispatch the event
|
||||
var event = new CustomEvent(eventName, {
|
||||
bubbles: bubbles,
|
||||
detail: properties
|
||||
});
|
||||
|
||||
// Dispatch the event
|
||||
element.dispatchEvent(event);
|
||||
@ -462,7 +474,7 @@
|
||||
// http://www.ssbbartgroup.com/blog/how-not-to-misuse-aria-states-properties-and-roles
|
||||
function _toggleState(target, state) {
|
||||
// Bail if no target
|
||||
if(!target) {
|
||||
if (!target) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -491,12 +503,12 @@
|
||||
var objects = arguments;
|
||||
|
||||
// Bail if nothing to merge
|
||||
if(!objects.length) {
|
||||
if (!objects.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Return first if specified but nothing to merge
|
||||
if(objects.lenth == 1) {
|
||||
if (objects.lenth == 1) {
|
||||
return objects[0];
|
||||
}
|
||||
|
||||
@ -597,7 +609,7 @@
|
||||
function _storage() {
|
||||
var storage = {
|
||||
supported: (function() {
|
||||
if(!('localStorage' in window)) {
|
||||
if (!('localStorage' in window)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -943,7 +955,7 @@
|
||||
index = 0;
|
||||
|
||||
// Incase caption numbers are added
|
||||
if(parts[index].indexOf(":") === -1) {
|
||||
if (parts[index].indexOf(":") === -1) {
|
||||
index = 1;
|
||||
}
|
||||
|
||||
@ -971,6 +983,7 @@
|
||||
|
||||
// Set the current caption
|
||||
function _setCaption(caption) {
|
||||
/* jshint unused:false */
|
||||
var container = _getElement(config.selectors.captions),
|
||||
content = document.createElement('span');
|
||||
|
||||
@ -978,12 +991,12 @@
|
||||
container.innerHTML = '';
|
||||
|
||||
// Default to empty
|
||||
if(typeof caption === 'undefined') {
|
||||
if (typeof caption === 'undefined') {
|
||||
caption = '';
|
||||
}
|
||||
|
||||
// Set the span content
|
||||
if(typeof caption === 'string') {
|
||||
if (typeof caption === 'string') {
|
||||
content.innerHTML = caption.trim();
|
||||
}
|
||||
else {
|
||||
@ -993,7 +1006,7 @@
|
||||
// Set new caption text
|
||||
container.appendChild(content);
|
||||
|
||||
// Force redraw
|
||||
// Force redraw (for Safari)
|
||||
var redraw = container.offsetHeight;
|
||||
}
|
||||
|
||||
@ -1170,7 +1183,7 @@
|
||||
if (config.selectors.controls.container !== null) {
|
||||
container = config.selectors.controls.container;
|
||||
|
||||
if(typeof selector === 'string') {
|
||||
if (typeof selector === 'string') {
|
||||
container = document.querySelector(container);
|
||||
}
|
||||
}
|
||||
@ -1259,7 +1272,7 @@
|
||||
|
||||
// Toggle native controls
|
||||
function _toggleNativeControls(toggle) {
|
||||
if(toggle) {
|
||||
if (toggle) {
|
||||
plyr.media.setAttribute('controls', '');
|
||||
}
|
||||
else {
|
||||
@ -1344,7 +1357,7 @@
|
||||
// Setup YouTube/Vimeo
|
||||
function _setupEmbed() {
|
||||
var container = document.createElement('div'),
|
||||
videoId = plyr.embedId,
|
||||
mediaId = plyr.embedId,
|
||||
id = plyr.type + '-' + Math.floor(Math.random() * (10000));
|
||||
|
||||
// Remove old containers
|
||||
@ -1367,7 +1380,7 @@
|
||||
|
||||
// Setup API
|
||||
if (typeof YT === 'object') {
|
||||
_youTubeReady(videoId, container);
|
||||
_youTubeReady(mediaId, container);
|
||||
}
|
||||
else {
|
||||
// Load the API
|
||||
@ -1377,7 +1390,7 @@
|
||||
window.onYouTubeReadyCallbacks = window.onYouTubeReadyCallbacks || [];
|
||||
|
||||
// Add to queue
|
||||
window.onYouTubeReadyCallbacks.push(function() { _youTubeReady(videoId, container) });
|
||||
window.onYouTubeReadyCallbacks.push(function() { _youTubeReady(mediaId, container) });
|
||||
|
||||
// Set callback to process queue
|
||||
window.onYouTubeIframeAPIReady = function () {
|
||||
@ -1388,14 +1401,14 @@
|
||||
// Vimeo
|
||||
else if (plyr.type === 'vimeo') {
|
||||
// Inject the iframe
|
||||
var iframe = document.createElement('iframe');
|
||||
var vimeo = document.createElement('iframe');
|
||||
|
||||
// Watch for iframe load
|
||||
iframe.loaded = false;
|
||||
_on(iframe, 'load', function() { iframe.loaded = true; });
|
||||
vimeo.loaded = false;
|
||||
_on(vimeo, 'load', function() { vimeo.loaded = true; });
|
||||
|
||||
_setAttributes(iframe, {
|
||||
'src': 'https://player.vimeo.com/video/' + videoId + '?player_id=' + id + '&api=1&badge=0&byline=0&portrait=0&title=0',
|
||||
_setAttributes(vimeo, {
|
||||
'src': 'https://player.vimeo.com/video/' + mediaId + '?player_id=' + id + '&api=1&badge=0&byline=0&portrait=0&title=0',
|
||||
'id': id,
|
||||
'webkitallowfullscreen': '',
|
||||
'mozallowfullscreen': '',
|
||||
@ -1404,24 +1417,54 @@
|
||||
});
|
||||
|
||||
// If full support, we can use custom controls (hiding Vimeos), if not, use Vimeo
|
||||
if(plyr.supported.full) {
|
||||
container.appendChild(iframe);
|
||||
if (plyr.supported.full) {
|
||||
container.appendChild(vimeo);
|
||||
plyr.media.appendChild(container);
|
||||
}
|
||||
else {
|
||||
plyr.media.appendChild(iframe);
|
||||
plyr.media.appendChild(vimeo);
|
||||
}
|
||||
|
||||
// Load the API
|
||||
// Load the API if not already
|
||||
if (!('$f' in window)) {
|
||||
_injectScript(config.urls.vimeo.api);
|
||||
}
|
||||
|
||||
// Wait for fragaloop load
|
||||
var timer = window.setInterval(function() {
|
||||
if ('$f' in window && iframe.loaded) {
|
||||
window.clearInterval(timer);
|
||||
_vimeoReady.call(iframe);
|
||||
var vimeoTimer = window.setInterval(function() {
|
||||
if ('$f' in window && vimeo.loaded) {
|
||||
window.clearInterval(vimeoTimer);
|
||||
_vimeoReady.call(vimeo);
|
||||
}
|
||||
}, 50);
|
||||
}
|
||||
// Soundcloud
|
||||
else if (plyr.type === 'soundcloud') {
|
||||
// Inject the iframe
|
||||
var soundCloud = document.createElement('iframe');
|
||||
|
||||
// Watch for iframe load
|
||||
soundCloud.loaded = false;
|
||||
_on(soundCloud, 'load', function() { soundCloud.loaded = true; });
|
||||
|
||||
_setAttributes(soundCloud, {
|
||||
'src': 'https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/' + mediaId,
|
||||
'id': id
|
||||
});
|
||||
|
||||
container.appendChild(soundCloud);
|
||||
plyr.media.appendChild(container);
|
||||
|
||||
// Load the API if not already
|
||||
if (!window.SC) {
|
||||
_injectScript(config.urls.soundcloud.api);
|
||||
}
|
||||
|
||||
// Wait for SC load
|
||||
var soundCloudTimer = window.setInterval(function() {
|
||||
if (window.SC && soundCloud.loaded) {
|
||||
window.clearInterval(soundCloudTimer);
|
||||
_soundcloudReady.call(soundCloud);
|
||||
}
|
||||
}, 50);
|
||||
}
|
||||
@ -1452,19 +1495,25 @@
|
||||
plyr.embed = new YT.Player(container.id, {
|
||||
videoId: videoId,
|
||||
playerVars: {
|
||||
autoplay: (config.autoplay ? 1 : 0),
|
||||
controls: (plyr.supported.full ? 0 : 1),
|
||||
rel: 0,
|
||||
showinfo: 0,
|
||||
autoplay: (config.autoplay ? 1 : 0),
|
||||
controls: (plyr.supported.full ? 0 : 1),
|
||||
rel: 0,
|
||||
showinfo: 0,
|
||||
iv_load_policy: 3,
|
||||
cc_load_policy: (config.captions.defaultActive ? 1 : 0),
|
||||
cc_lang_pref: 'en',
|
||||
wmode: 'transparent',
|
||||
cc_lang_pref: 'en',
|
||||
wmode: 'transparent',
|
||||
modestbranding: 1,
|
||||
disablekb: 1,
|
||||
origin: '*' // https://code.google.com/p/gdata-issues/issues/detail?id=5788#c45
|
||||
disablekb: 1,
|
||||
origin: '*' // https://code.google.com/p/gdata-issues/issues/detail?id=5788#c45
|
||||
},
|
||||
events: {
|
||||
'onError': function(event) {
|
||||
_triggerEvent(plyr.container, 'error', true, {
|
||||
code: event.data,
|
||||
embed: event.target
|
||||
});
|
||||
},
|
||||
'onReady': function(event) {
|
||||
// Get the instance
|
||||
var instance = event.target;
|
||||
@ -1628,7 +1677,7 @@
|
||||
plyr.media.buffered = data.percent;
|
||||
_triggerEvent(plyr.media, 'progress');
|
||||
|
||||
if(parseInt(data.percent) === 1) {
|
||||
if (parseInt(data.percent) === 1) {
|
||||
// Trigger event
|
||||
_triggerEvent(plyr.media, 'canplaythrough');
|
||||
}
|
||||
@ -1649,16 +1698,95 @@
|
||||
});
|
||||
}
|
||||
|
||||
// Soundcloud ready
|
||||
function _soundcloudReady() {
|
||||
/* jshint validthis: true */
|
||||
plyr.embed = window.SC.Widget(this);
|
||||
|
||||
// Setup on ready
|
||||
plyr.embed.bind(window.SC.Widget.Events.READY, function() {
|
||||
// Create a faux HTML5 API using the Soundcloud API
|
||||
plyr.media.play = function() {
|
||||
plyr.embed.play();
|
||||
plyr.media.paused = false;
|
||||
};
|
||||
plyr.media.pause = function() {
|
||||
plyr.embed.pause();
|
||||
plyr.media.paused = true;
|
||||
};
|
||||
plyr.media.stop = function() {
|
||||
plyr.embed.seekTo(0);
|
||||
plyr.embed.pause();
|
||||
plyr.media.paused = true;
|
||||
};
|
||||
plyr.media.paused = true;
|
||||
plyr.media.currentTime = 0;
|
||||
|
||||
// Update UI
|
||||
_embedReady();
|
||||
|
||||
plyr.embed.getPosition(function(value) {
|
||||
plyr.media.currentTime = value;
|
||||
|
||||
// Trigger timeupdate
|
||||
_triggerEvent(plyr.media, 'timeupdate');
|
||||
});
|
||||
|
||||
plyr.embed.getDuration(function(value) {
|
||||
plyr.media.duration = value/1000;
|
||||
// Display duration if available
|
||||
_displayDuration();
|
||||
});
|
||||
|
||||
plyr.embed.bind(window.SC.Widget.Events.PLAY, function() {
|
||||
plyr.media.paused = false;
|
||||
_triggerEvent(plyr.media, 'play');
|
||||
_triggerEvent(plyr.media, 'playing');
|
||||
});
|
||||
|
||||
plyr.embed.bind(window.SC.Widget.Events.PAUSE, function() {
|
||||
plyr.media.paused = true;
|
||||
_triggerEvent(plyr.media, 'pause');
|
||||
});
|
||||
|
||||
plyr.embed.bind(window.SC.Widget.Events.PLAY_PROGRESS, function(data) {
|
||||
plyr.media.seeking = false;
|
||||
plyr.media.currentTime = data.currentPosition/1000;
|
||||
_triggerEvent(plyr.media, 'timeupdate');
|
||||
});
|
||||
|
||||
plyr.embed.bind(window.SC.Widget.Events.LOAD_PROGRESS, function(data) {
|
||||
plyr.media.buffered = data.loadProgress;
|
||||
_triggerEvent(plyr.media, 'progress');
|
||||
|
||||
if (parseInt(data.loadProgress) === 1) {
|
||||
// Trigger event
|
||||
_triggerEvent(plyr.media, 'canplaythrough');
|
||||
}
|
||||
});
|
||||
|
||||
plyr.embed.bind(window.SC.Widget.Events.FINISH, function() {
|
||||
plyr.media.paused = true;
|
||||
_triggerEvent(plyr.media, 'ended');
|
||||
});
|
||||
|
||||
// Autoplay
|
||||
if (config.autoplay) {
|
||||
plyr.embed.play();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Play media
|
||||
function _play() {
|
||||
if('play' in plyr.media) {
|
||||
if ('play' in plyr.media) {
|
||||
plyr.media.play();
|
||||
}
|
||||
}
|
||||
|
||||
// Pause media
|
||||
function _pause() {
|
||||
if('pause' in plyr.media) {
|
||||
if ('pause' in plyr.media) {
|
||||
plyr.media.pause();
|
||||
}
|
||||
}
|
||||
@ -1700,9 +1828,9 @@
|
||||
// Seek to time
|
||||
// The input parameter can be an event or a number
|
||||
function _seek(input) {
|
||||
var targetTime = 0,
|
||||
paused = plyr.media.paused,
|
||||
duration = _getDuration();
|
||||
var targetTime = 0,
|
||||
paused = plyr.media.paused,
|
||||
duration = _getDuration();
|
||||
|
||||
// Explicit position
|
||||
if (typeof input === 'number') {
|
||||
@ -1723,10 +1851,8 @@
|
||||
targetTime = duration;
|
||||
}
|
||||
|
||||
// Update progress
|
||||
if(plyr.progress && plyr.progress.played) {
|
||||
plyr.progress.played.value = ((100 / duration) * targetTime);
|
||||
}
|
||||
// Update seek range and progress
|
||||
_updateSeekDisplay(targetTime);
|
||||
|
||||
// Set the current time
|
||||
// Try/catch incase the media isn't set and we're calling seek() from source() and IE moans
|
||||
@ -1736,7 +1862,7 @@
|
||||
catch(e) {}
|
||||
|
||||
// Embeds
|
||||
if(_inArray(config.types.embed, plyr.type)) {
|
||||
if (_inArray(config.types.embed, plyr.type)) {
|
||||
// YouTube
|
||||
switch(plyr.type) {
|
||||
case 'youtube':
|
||||
@ -1747,6 +1873,10 @@
|
||||
// Round to nearest second for vimeo
|
||||
plyr.embed.api('seekTo', targetTime.toFixed(0));
|
||||
break;
|
||||
|
||||
case 'soundcloud':
|
||||
plyr.embed.seekTo(targetTime * 1000);
|
||||
break;
|
||||
}
|
||||
|
||||
if (paused) {
|
||||
@ -1770,10 +1900,18 @@
|
||||
// Get the duration (or custom if set)
|
||||
function _getDuration() {
|
||||
// It should be a number, but parse it just incase
|
||||
var duration = parseInt(config.duration);
|
||||
var duration = parseInt(config.duration),
|
||||
|
||||
// True duration
|
||||
mediaDuration = 0;
|
||||
|
||||
// Only if duration available
|
||||
if(plyr.media.duration !== null && !isNaN(plyr.media.duration)) {
|
||||
mediaDuration = plyr.media.duration;
|
||||
}
|
||||
|
||||
// If custom duration is funky, use regular duration
|
||||
return (isNaN(duration) ? plyr.media.duration : duration);
|
||||
return (isNaN(duration) ? mediaDuration : duration);
|
||||
}
|
||||
|
||||
// Check playing state
|
||||
@ -1826,7 +1964,7 @@
|
||||
_toggleClass(plyr.container, config.classes.fullscreen.active, plyr.isFullscreen);
|
||||
|
||||
// Trap focus
|
||||
if(plyr.isFullscreen) {
|
||||
if (plyr.isFullscreen) {
|
||||
plyr.container.setAttribute('tabindex', '-1');
|
||||
}
|
||||
else {
|
||||
@ -1865,12 +2003,12 @@
|
||||
plyr.media.muted = muted;
|
||||
|
||||
// If volume is 0 after unmuting, set to default
|
||||
if(plyr.media.volume === 0) {
|
||||
if (plyr.media.volume === 0) {
|
||||
_setVolume(config.volume);
|
||||
}
|
||||
|
||||
// Embeds
|
||||
if(_inArray(config.types.embed, plyr.type)) {
|
||||
if (_inArray(config.types.embed, plyr.type)) {
|
||||
// YouTube
|
||||
switch(plyr.type) {
|
||||
case 'youtube':
|
||||
@ -1880,6 +2018,10 @@
|
||||
case 'vimeo':
|
||||
plyr.embed.api('setVolume', plyr.media.muted ? 0 : parseFloat(config.volume / 10));
|
||||
break;
|
||||
|
||||
case 'soundcloud':
|
||||
plyr.embed.setVolume(plyr.media.muted ? 0 : parseFloat(config.volume / 10));
|
||||
break;
|
||||
}
|
||||
|
||||
// Trigger volumechange for embeds
|
||||
@ -1903,7 +2045,7 @@
|
||||
}
|
||||
|
||||
// Use config if all else fails
|
||||
if(volume === null || isNaN(volume)) {
|
||||
if (volume === null || isNaN(volume)) {
|
||||
volume = config.volume;
|
||||
}
|
||||
|
||||
@ -1925,7 +2067,7 @@
|
||||
}
|
||||
|
||||
// Embeds
|
||||
if(_inArray(config.types.embed, plyr.type)) {
|
||||
if (_inArray(config.types.embed, plyr.type)) {
|
||||
// YouTube
|
||||
switch(plyr.type) {
|
||||
case 'youtube':
|
||||
@ -1935,6 +2077,10 @@
|
||||
case 'vimeo':
|
||||
plyr.embed.api('setVolume', plyr.media.volume);
|
||||
break;
|
||||
|
||||
case 'soundcloud':
|
||||
plyr.embed.setVolume(plyr.media.volume);
|
||||
break;
|
||||
}
|
||||
|
||||
// Trigger volumechange for embeds
|
||||
@ -2017,7 +2163,6 @@
|
||||
// Update <progress> elements
|
||||
function _updateProgress(event) {
|
||||
var progress = plyr.progress.played,
|
||||
text = false,
|
||||
value = 0,
|
||||
duration = _getDuration();
|
||||
|
||||
@ -2038,8 +2183,7 @@
|
||||
// Check buffer status
|
||||
case 'playing':
|
||||
case 'progress':
|
||||
progress = plyr.progress.buffer.bar;
|
||||
text = plyr.progress.buffer.text;
|
||||
progress = plyr.progress.buffer;
|
||||
value = (function() {
|
||||
var buffered = plyr.media.buffered;
|
||||
|
||||
@ -2060,11 +2204,27 @@
|
||||
}
|
||||
|
||||
// Set values
|
||||
if (progress) {
|
||||
_setProgress(progress, value);
|
||||
}
|
||||
|
||||
// Set <progress> value
|
||||
function _setProgress(progress, value) {
|
||||
if (typeof value === 'undefined') {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
// One progress element passed
|
||||
if (progress instanceof HTMLElement) {
|
||||
progress.value = value;
|
||||
}
|
||||
if (text) {
|
||||
text.innerHTML = value;
|
||||
// Object of progress + text element
|
||||
else {
|
||||
if (progress.bar) {
|
||||
progress.bar.value = value;
|
||||
}
|
||||
if (progress.text) {
|
||||
progress.text.innerHTML = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2124,7 +2284,7 @@
|
||||
_updateTimeDisplay(plyr.media.currentTime, plyr.currentTime);
|
||||
|
||||
// Ignore updates while seeking
|
||||
if(event && event.type == 'timeupdate' && plyr.media.seeking) {
|
||||
if (event && event.type == 'timeupdate' && plyr.media.seeking) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2132,10 +2292,33 @@
|
||||
_updateProgress(event);
|
||||
}
|
||||
|
||||
// Update seek range and progress
|
||||
function _updateSeekDisplay(time) {
|
||||
// Default to 0
|
||||
if (typeof time !== 'number') {
|
||||
time = 0;
|
||||
}
|
||||
|
||||
var duration = _getDuration(),
|
||||
value = _getPercentage(time, duration);
|
||||
|
||||
// Update progress
|
||||
if (plyr.progress && plyr.progress.played) {
|
||||
plyr.progress.played.value = value;
|
||||
}
|
||||
|
||||
// Update seek range input
|
||||
if (plyr.buttons && plyr.buttons.seek) {
|
||||
plyr.buttons.seek.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Update hover tooltip for seeking
|
||||
function _updateSeekTooltip(event) {
|
||||
var duration = _getDuration();
|
||||
|
||||
// Bail if setting not true
|
||||
if (!config.tooltips.seek || plyr.browser.touch || !plyr.progress.container) {
|
||||
if (!config.tooltips.seek || !plyr.progress.container || duration === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2146,7 +2329,7 @@
|
||||
|
||||
// Determine percentage, if already visible
|
||||
if (!event) {
|
||||
if(_hasClass(plyr.progress.tooltip, visible)) {
|
||||
if (_hasClass(plyr.progress.tooltip, visible)) {
|
||||
percent = plyr.progress.tooltip.style.left.replace('%', '');
|
||||
}
|
||||
else {
|
||||
@ -2166,14 +2349,14 @@
|
||||
}
|
||||
|
||||
// Display the time a click would seek to
|
||||
_updateTimeDisplay(((_getDuration() / 100) * percent), plyr.progress.tooltip);
|
||||
_updateTimeDisplay(((duration / 100) * percent), plyr.progress.tooltip);
|
||||
|
||||
// Set position
|
||||
plyr.progress.tooltip.style.left = percent + "%";
|
||||
|
||||
// Show/hide the tooltip
|
||||
// If the event is a moues in/out and percentage is inside bounds
|
||||
if(event && _inArray(['mouseenter', 'mouseleave'], event.type)) {
|
||||
if (event && _inArray(['mouseenter', 'mouseleave'], event.type)) {
|
||||
_toggleClass(plyr.progress.tooltip, visible, (event.type === 'mouseenter'));
|
||||
}
|
||||
}
|
||||
@ -2188,8 +2371,8 @@
|
||||
show = toggle;
|
||||
|
||||
// Default to false if no boolean
|
||||
if(typeof toggle !== "boolean") {
|
||||
if(toggle && toggle.type) {
|
||||
if (typeof toggle !== "boolean") {
|
||||
if (toggle && toggle.type) {
|
||||
// Is the enter fullscreen event
|
||||
isEnterFullscreen = (toggle.type === 'enterfullscreen');
|
||||
|
||||
@ -2215,21 +2398,21 @@
|
||||
window.clearTimeout(plyr.timers.hover);
|
||||
|
||||
// If the mouse is not over the controls, set a timeout to hide them
|
||||
if(show || plyr.media.paused) {
|
||||
if (show || plyr.media.paused) {
|
||||
_toggleClass(plyr.container, config.classes.hideControls, false);
|
||||
|
||||
// Always show controls when paused
|
||||
if(plyr.media.paused) {
|
||||
if (plyr.media.paused) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If toggle is false or if we're playing (regardless of toggle), then
|
||||
// set the timer to hide the controls
|
||||
if(!show || !plyr.media.paused) {
|
||||
if (!show || !plyr.media.paused) {
|
||||
plyr.timers.hover = window.setTimeout(function() {
|
||||
// If the mouse is over the controls (and not entering fullscreen), bail
|
||||
if(plyr.controls.active && !isEnterFullscreen) {
|
||||
if (plyr.controls.active && !isEnterFullscreen) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2241,7 +2424,7 @@
|
||||
// Add common function to retrieve media source
|
||||
function _source(source) {
|
||||
// If not null or undefined, parse it
|
||||
if(typeof source !== 'undefined') {
|
||||
if (typeof source !== 'undefined') {
|
||||
_updateSource(source);
|
||||
return;
|
||||
}
|
||||
@ -2259,6 +2442,12 @@
|
||||
});
|
||||
break;
|
||||
|
||||
case 'soundcloud':
|
||||
plyr.embed.getCurrentSound(function(object) {
|
||||
url = object.permalink_url;
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
url = plyr.media.currentSrc;
|
||||
break;
|
||||
@ -2278,13 +2467,14 @@
|
||||
// Pause playback
|
||||
_pause();
|
||||
|
||||
// Set seek input to 0
|
||||
if (plyr.buttons && plyr.buttons.seek) {
|
||||
plyr.buttons.seek.value = 0;
|
||||
}
|
||||
if (plyr.progress && plyr.progress.played) {
|
||||
plyr.progress.played.value = 0;
|
||||
}
|
||||
// Update seek range and progress
|
||||
_updateSeekDisplay();
|
||||
|
||||
// Reset buffer progress
|
||||
_setProgress(plyr.progress.buffer);
|
||||
|
||||
// Cancel current network requests
|
||||
_cancelRequests();
|
||||
|
||||
// Clean up YouTube stuff
|
||||
if (plyr.type === 'youtube') {
|
||||
@ -2295,6 +2485,7 @@
|
||||
window.clearInterval(plyr.timer.buffering);
|
||||
window.clearInterval(plyr.timer.playing);
|
||||
}
|
||||
// HTML5 Video
|
||||
else if (plyr.type === 'video' && plyr.videoContainer) {
|
||||
// Remove video wrapper
|
||||
_remove(plyr.videoContainer);
|
||||
@ -2303,9 +2494,6 @@
|
||||
// Remove embed object
|
||||
plyr.embed = null;
|
||||
|
||||
// Cancel current network requests
|
||||
_cancelRequests();
|
||||
|
||||
// Remove the old media
|
||||
_remove(plyr.media);
|
||||
|
||||
@ -2314,10 +2502,10 @@
|
||||
plyr.type = source.type;
|
||||
|
||||
// Get child type for video (it might be an embed)
|
||||
if(plyr.type === 'video') {
|
||||
if (plyr.type === 'video') {
|
||||
var firstSource = source.sources[0];
|
||||
|
||||
if('type' in firstSource && _inArray(config.types.embed, firstSource.type)) {
|
||||
if ('type' in firstSource && _inArray(config.types.embed, firstSource.type)) {
|
||||
plyr.type = firstSource.type;
|
||||
}
|
||||
}
|
||||
@ -2338,6 +2526,7 @@
|
||||
|
||||
case 'youtube':
|
||||
case 'vimeo':
|
||||
case 'soundcloud':
|
||||
plyr.media = document.createElement('div');
|
||||
plyr.embedId = source.sources[0].src;
|
||||
break;
|
||||
@ -2437,7 +2626,7 @@
|
||||
target = plyr.buttons[play ? 'pause' : 'play'];
|
||||
|
||||
// Get the last play button to account for the large play button
|
||||
if(target && target.length > 1) {
|
||||
if (target && target.length > 1) {
|
||||
target = target[target.length - 1];
|
||||
}
|
||||
else {
|
||||
@ -2445,13 +2634,13 @@
|
||||
}
|
||||
|
||||
// Setup focus and tab focus
|
||||
if(target) {
|
||||
if (target) {
|
||||
var hadTabFocus = _hasClass(trigger, config.classes.tabFocus);
|
||||
|
||||
setTimeout(function() {
|
||||
target.focus();
|
||||
|
||||
if(hadTabFocus) {
|
||||
if (hadTabFocus) {
|
||||
_toggleClass(trigger, config.classes.tabFocus, false);
|
||||
_toggleClass(target, config.classes.tabFocus, true);
|
||||
}
|
||||
@ -2575,6 +2764,15 @@
|
||||
|
||||
// Reset UI
|
||||
_checkPlaying();
|
||||
|
||||
// Show poster on end
|
||||
if(config.showPosterOnEnd) {
|
||||
// Seek to 0
|
||||
_seek(0);
|
||||
|
||||
// Re-load media
|
||||
plyr.media.load();
|
||||
}
|
||||
});
|
||||
|
||||
// Check for buffer progress
|
||||
@ -2595,7 +2793,7 @@
|
||||
var wrapper = _getElement('.' + config.classes.videoWrapper);
|
||||
|
||||
// Bail if there's no wrapper (this should never happen)
|
||||
if(!wrapper) {
|
||||
if (!wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2619,26 +2817,29 @@
|
||||
|
||||
// Proxy events to container
|
||||
_on(plyr.media, config.events.join(' '), function(event) {
|
||||
_triggerEvent(plyr.container, event.type);
|
||||
_triggerEvent(plyr.container, event.type, true);
|
||||
});
|
||||
}
|
||||
|
||||
// Cancel current network requests
|
||||
// See https://github.com/Selz/plyr/issues/174
|
||||
function _cancelRequests() {
|
||||
if(!_inArray(config.types.html5, plyr.type)) {
|
||||
if (!_inArray(config.types.html5, plyr.type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set empty src attribute
|
||||
plyr.media.setAttribute('src', '');
|
||||
|
||||
// Remove child sources
|
||||
var sources = plyr.media.querySelectorAll('source');
|
||||
for (var i = 0; i < sources.length; i++) {
|
||||
_remove(sources[i]);
|
||||
}
|
||||
|
||||
// Set blank video src attribute
|
||||
// This is to prevent a MEDIA_ERR_SRC_NOT_SUPPORTED error
|
||||
// Small mp4: https://github.com/mathiasbynens/small/blob/master/mp4.mp4
|
||||
// Info: http://stackoverflow.com/questions/32231579/how-to-properly-dispose-of-an-html5-video-and-close-socket-or-connection
|
||||
plyr.media.setAttribute('src', 'data:video/mp4;base64,AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAAGm1kYXQAAAGzABAHAAABthBgUYI9t+8AAAMNbW9vdgAAAGxtdmhkAAAAAMXMvvrFzL76AAAD6AAAACoAAQAAAQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAABhpb2RzAAAAABCAgIAHAE/////+/wAAAiF0cmFrAAAAXHRraGQAAAAPxcy++sXMvvoAAAABAAAAAAAAACoAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAABAAAAAAAgAAAAIAAAAAAG9bWRpYQAAACBtZGhkAAAAAMXMvvrFzL76AAAAGAAAAAEVxwAAAAAALWhkbHIAAAAAAAAAAHZpZGUAAAAAAAAAAAAAAABWaWRlb0hhbmRsZXIAAAABaG1pbmYAAAAUdm1oZAAAAAEAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAShzdGJsAAAAxHN0c2QAAAAAAAAAAQAAALRtcDR2AAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAgACABIAAAASAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGP//AAAAXmVzZHMAAAAAA4CAgE0AAQAEgICAPyARAAAAAAMNQAAAAAAFgICALQAAAbABAAABtYkTAAABAAAAASAAxI2IAMUARAEUQwAAAbJMYXZjNTMuMzUuMAaAgIABAgAAABhzdHRzAAAAAAAAAAEAAAABAAAAAQAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAAUc3RzegAAAAAAAAASAAAAAQAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYHVkdGEAAABYbWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAraWxzdAAAACOpdG9vAAAAG2RhdGEAAAABAAAAAExhdmY1My4yMS4x');
|
||||
|
||||
// Load the new empty source
|
||||
// This will cancel existing requests
|
||||
// See https://github.com/Selz/plyr/issues/174
|
||||
@ -2707,12 +2908,12 @@
|
||||
plyr.media = plyr.container.querySelectorAll('audio, video')[0];
|
||||
|
||||
// Get the div placeholder for YouTube and Vimeo
|
||||
if(!plyr.media) {
|
||||
if (!plyr.media) {
|
||||
plyr.media = plyr.container.querySelectorAll('div')[0];
|
||||
}
|
||||
|
||||
// Bail if nothing to setup
|
||||
if(!plyr.media) {
|
||||
if (!plyr.media) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2897,6 +3098,7 @@
|
||||
|
||||
case 'vimeo':
|
||||
case 'youtube':
|
||||
case 'soundcloud':
|
||||
basic = true;
|
||||
full = (!oldIE && !iPhone);
|
||||
break;
|
||||
@ -2954,7 +3156,7 @@
|
||||
var config = _extend(defaults, options, JSON.parse(element.getAttribute("data-plyr")));
|
||||
|
||||
// Bail if not enabled
|
||||
if(!config.enabled) {
|
||||
if (!config.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -201,12 +201,13 @@
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
padding: (@plyr-control-spacing * 2) (@plyr-control-spacing * 2) (@plyr-control-spacing * 8);
|
||||
padding: (@plyr-control-spacing * 2);
|
||||
transform: translateY(-(@plyr-control-spacing * 6));
|
||||
transition: transform .3s ease;
|
||||
color: #fff;
|
||||
font-size: @plyr-font-size-captions-base;
|
||||
text-align: center;
|
||||
font-weight: 400;
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
|
||||
span {
|
||||
border-radius: 2px;
|
||||
@ -227,6 +228,9 @@
|
||||
.plyr--fullscreen-active .plyr__captions {
|
||||
font-size: @plyr-font-size-captions-large;
|
||||
}
|
||||
.plyr--hide-controls .plyr__captions {
|
||||
transform: translateY(-(@plyr-control-spacing * 2));
|
||||
}
|
||||
|
||||
// Controls
|
||||
// --------------------------------------------------------------
|
||||
@ -421,7 +425,6 @@
|
||||
// Tooltips
|
||||
// --------------------------------------------------------------
|
||||
.plyr__tooltip {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
bottom: 100%;
|
||||
@ -437,11 +440,10 @@
|
||||
color: @plyr-tooltip-color;
|
||||
font-size: @plyr-font-size-small;
|
||||
line-height: 1.3;
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
|
||||
transform: translate(-50%, 10px) scale(.8);
|
||||
transform-origin: 50% 100%;
|
||||
transition: transform .2s .1s ease, opacity .2s .1s ease, visibility .3s ease;
|
||||
transition: transform .2s .1s ease, opacity .2s .1s ease;
|
||||
|
||||
// Arrows
|
||||
&::before {
|
||||
@ -464,7 +466,6 @@
|
||||
.plyr button:hover .plyr__tooltip,
|
||||
.plyr button.tab-focus:focus .plyr__tooltip,
|
||||
.plyr__tooltip--visible {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transform: translate(-50%, 0) scale(1);
|
||||
}
|
||||
@ -500,9 +501,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
.plyr__progress--buffer[value],
|
||||
.plyr__progress--played[value],
|
||||
.plyr__volume--display[value] {
|
||||
.plyr__progress--buffer,
|
||||
.plyr__progress--played,
|
||||
.plyr__volume--display {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
@ -532,8 +533,8 @@
|
||||
border-radius: 100px;
|
||||
}
|
||||
}
|
||||
.plyr__progress--played[value],
|
||||
.plyr__volume--display[value] {
|
||||
.plyr__progress--played,
|
||||
.plyr__volume--display {
|
||||
z-index: 1;
|
||||
color: @plyr-range-selected-bg;
|
||||
background: transparent;
|
||||
@ -555,7 +556,7 @@
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.plyr__progress--buffer[value] {
|
||||
.plyr__progress--buffer {
|
||||
&::-webkit-progress-value {
|
||||
transition: width .2s ease;
|
||||
}
|
||||
@ -566,18 +567,18 @@
|
||||
transition: width .2s ease;
|
||||
}
|
||||
}
|
||||
.plyr--video .plyr__progress--buffer[value],
|
||||
.plyr--video .plyr__volume--display[value] {
|
||||
.plyr--video .plyr__progress--buffer,
|
||||
.plyr--video .plyr__volume--display {
|
||||
background: @plyr-video-range-track-bg;
|
||||
}
|
||||
.plyr--video .plyr__progress--buffer[value] {
|
||||
.plyr--video .plyr__progress--buffer {
|
||||
color: @plyr-video-progress-buffered-bg;
|
||||
}
|
||||
.plyr--audio .plyr__progress--buffer[value],
|
||||
.plyr--audio .plyr__volume--display[value] {
|
||||
.plyr--audio .plyr__progress--buffer,
|
||||
.plyr--audio .plyr__volume--display {
|
||||
background: @plyr-audio-range-track-bg;
|
||||
}
|
||||
.plyr--audio .plyr__progress--buffer[value] {
|
||||
.plyr--audio .plyr__progress--buffer {
|
||||
color: @plyr-audio-progress-buffered-bg;
|
||||
}
|
||||
|
||||
@ -611,7 +612,6 @@
|
||||
vertical-align: middle;
|
||||
font-size: @plyr-font-size-small;
|
||||
line-height: .95;
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
}
|
||||
// Media duration hidden on small screens
|
||||
.plyr__time + .plyr__time {
|
||||
|
@ -201,12 +201,13 @@
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
padding: ($plyr-control-spacing * 2) ($plyr-control-spacing * 2) ($plyr-control-spacing * 8);
|
||||
padding: ($plyr-control-spacing * 2);
|
||||
transform: translateY(-($plyr-control-spacing * 6));
|
||||
transition: transform .3s ease;
|
||||
color: #fff;
|
||||
font-size: $plyr-font-size-captions-base;
|
||||
text-align: center;
|
||||
font-weight: 400;
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
|
||||
span {
|
||||
border-radius: 2px;
|
||||
@ -227,6 +228,9 @@
|
||||
.plyr--fullscreen-active .plyr__captions {
|
||||
font-size: $plyr-font-size-captions-large;
|
||||
}
|
||||
.plyr--hide-controls .plyr__captions {
|
||||
transform: translateY(-($plyr-control-spacing * 2));
|
||||
}
|
||||
|
||||
// Controls
|
||||
// --------------------------------------------------------------
|
||||
@ -421,7 +425,6 @@
|
||||
// Tooltips
|
||||
// --------------------------------------------------------------
|
||||
.plyr__tooltip {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
bottom: 100%;
|
||||
@ -437,11 +440,10 @@
|
||||
color: $plyr-tooltip-color;
|
||||
font-size: $plyr-font-size-small;
|
||||
line-height: 1.3;
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
|
||||
transform: translate(-50%, 10px) scale(.8);
|
||||
transform-origin: 50% 100%;
|
||||
transition: transform .2s .1s ease, opacity .2s .1s ease, visibility .3s ease;
|
||||
transition: transform .2s .1s ease, opacity .2s .1s ease;
|
||||
|
||||
// Arrows
|
||||
&::before {
|
||||
@ -464,7 +466,6 @@
|
||||
.plyr button:hover .plyr__tooltip,
|
||||
.plyr button.tab-focus:focus .plyr__tooltip,
|
||||
.plyr__tooltip--visible {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transform: translate(-50%, 0) scale(1);
|
||||
}
|
||||
@ -500,9 +501,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
.plyr__progress--buffer[value],
|
||||
.plyr__progress--played[value],
|
||||
.plyr__volume--display[value] {
|
||||
.plyr__progress--buffer,
|
||||
.plyr__progress--played,
|
||||
.plyr__volume--display {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
@ -532,8 +533,8 @@
|
||||
border-radius: 100px;
|
||||
}
|
||||
}
|
||||
.plyr__progress--played[value],
|
||||
.plyr__volume--display[value] {
|
||||
.plyr__progress--played,
|
||||
.plyr__volume--display {
|
||||
z-index: 1;
|
||||
color: $plyr-range-selected-bg;
|
||||
background: transparent;
|
||||
@ -555,7 +556,7 @@
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.plyr__progress--buffer[value] {
|
||||
.plyr__progress--buffer {
|
||||
&::-webkit-progress-value {
|
||||
transition: width .2s ease;
|
||||
}
|
||||
@ -566,18 +567,18 @@
|
||||
transition: width .2s ease;
|
||||
}
|
||||
}
|
||||
.plyr--video .plyr__progress--buffer[value],
|
||||
.plyr--video .plyr__volume--display[value] {
|
||||
.plyr--video .plyr__progress--buffer,
|
||||
.plyr--video .plyr__volume--display {
|
||||
background: $plyr-video-range-track-bg;
|
||||
}
|
||||
.plyr--video .plyr__progress--buffer[value] {
|
||||
.plyr--video .plyr__progress--buffer {
|
||||
color: $plyr-video-progress-buffered-bg;
|
||||
}
|
||||
.plyr--audio .plyr__progress--buffer[value],
|
||||
.plyr--audio .plyr__volume--display[value] {
|
||||
.plyr--audio .plyr__progress--buffer,
|
||||
.plyr--audio .plyr__volume--display {
|
||||
background: $plyr-audio-range-track-bg;
|
||||
}
|
||||
.plyr--audio .plyr__progress--buffer[value] {
|
||||
.plyr--audio .plyr__progress--buffer {
|
||||
color: $plyr-audio-progress-buffered-bg;
|
||||
}
|
||||
|
||||
@ -611,7 +612,6 @@
|
||||
vertical-align: middle;
|
||||
font-size: $plyr-font-size-small;
|
||||
line-height: .95;
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
}
|
||||
// Media duration hidden on small screens
|
||||
.plyr__time + .plyr__time {
|
||||
|
Reference in New Issue
Block a user