Merge branch 'develop' into feature/subtitles
This commit is contained in:
12
.github/issue_template.md
vendored
12
.github/issue_template.md
vendored
@ -1,3 +1,7 @@
|
||||
<!---
|
||||
Please use this issue template as it makes replicating and fixing the issue easier!
|
||||
--->
|
||||
|
||||
- [ ] Issue does not already exist
|
||||
- [ ] Issue observed on https://plyr.io
|
||||
|
||||
@ -12,7 +16,13 @@
|
||||
- Operating System:
|
||||
- Version:
|
||||
|
||||
Players affected:
|
||||
- [ ] HTML5 Video
|
||||
- [ ] HTML5 Audio
|
||||
- [ ] YouTube
|
||||
- [ ] Vimeo
|
||||
|
||||
### Steps to reproduce
|
||||
-
|
||||
|
||||
### Relevant links
|
||||
### Relevant links
|
||||
|
30
changelog.md
30
changelog.md
@ -1,5 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
## v2.0.12
|
||||
- Ability to set custom `blankUrl` for source changes (https://github.com/Selz/plyr/pull/504)
|
||||
- Ability to set caption button listener (https://github.com/Selz/plyr/pull/468)
|
||||
|
||||
## v2.0.11
|
||||
- Fix for `cleanUp` being called twice (thanks to @sebastiancarlsson)
|
||||
- Fix for YouTube controls on iPad (fixes #391)
|
||||
|
||||
## v2.0.10
|
||||
- Added seek event fixes for Vimeo and YouTube (fixes #409)
|
||||
- Added support for embed URLs rather than ID only (fixes #345)
|
||||
@ -21,10 +29,10 @@
|
||||
|
||||
## v2.0.6
|
||||
- Fixed merge issue with `Updated define to work with AMD imports #326` PR
|
||||
- Code formatting
|
||||
- Code formatting
|
||||
|
||||
## v2.0.5
|
||||
- Fix for Vimeo in IE9 & IE10
|
||||
- Fix for Vimeo in IE9 & IE10
|
||||
- Fix for HTML5 elements not firing `ready` event
|
||||
|
||||
## v2.0.4
|
||||
@ -44,8 +52,8 @@ This version contains several potential ***breaking changes***:
|
||||
|
||||
- `setup()` has been reverted to pre v1.8.0 behaviour; meaning it will return the *instance* rather than the *element*. This is because the reference to the instance is no longer added to the original element (see below).
|
||||
- The reference to the `plyr` instance is now added to the media element rather than original container. This is because if a container with multiple children was passed to `setup()` the references to all instances would have been added to the container, creating issues. I would recommend using the return value from `setup()` or the new `get()` method to access the instance.
|
||||
- Players will always be wrapped in their own div now - this makes `setup()` and `destroy()` cleaner. This *may* break any custom styling based on DOM position.
|
||||
- Players no longer seek to 0 on 'ended' - this is to fix a bug with Microsoft Edge as it triggers 'ended' on media change for whatever reason. They'll never change ;-)
|
||||
- Players will always be wrapped in their own div now - this makes `setup()` and `destroy()` cleaner. This *may* break any custom styling based on DOM position.
|
||||
- Players no longer seek to 0 on 'ended' - this is to fix a bug with Microsoft Edge as it triggers 'ended' on media change for whatever reason. They'll never change ;-)
|
||||
|
||||
And some other changes and bug fixes:
|
||||
|
||||
@ -75,7 +83,7 @@ And some other changes and bug fixes:
|
||||
|
||||
## v1.8.11
|
||||
- Fix for keyboard navigation on Vimeo (Fixes #317)
|
||||
- Fix for bug introduced in v1.8.9 related to additional controls
|
||||
- Fix for bug introduced in v1.8.9 related to additional controls
|
||||
- Vimeo API upgrade
|
||||
- Fix for YouTube bug introduced in v1.8.9
|
||||
- Added support for passing array to .setup() (Fixes #319)
|
||||
@ -115,20 +123,20 @@ And some other changes and bug fixes:
|
||||
- Improvements for controls hiding and showing on touch devices
|
||||
|
||||
## v1.8.2
|
||||
- Fixed event bubbling
|
||||
- Fixed event bubbling
|
||||
|
||||
## v1.8.1
|
||||
- Fixed inaccurate log message
|
||||
|
||||
# v1.8.0
|
||||
- ***(Important)*** `setup()` now returns the element Plyr was setup on rather than the `plyr` object. This means `var player = plyr.setup()[0];` would now be `var player = plyr.setup()[0].plyr;`. This improves support for React and other virtual dom frameworks as mentioned in #254
|
||||
- Fixed using a relative URL for `iconUrl` in IE (fixes #269)
|
||||
- Fixed using a relative URL for `iconUrl` in IE (fixes #269)
|
||||
|
||||
# v1.7.0
|
||||
- SASS cleanup (fixes #265)
|
||||
- Docs tidy up to help quick start (fixes #253)
|
||||
- Fix for issues with data attribute options passing (fixes #257)
|
||||
- ***(Important)*** Removed the requirement for a wrapper div to setup Plyr and removed the dependency on the `plyr` classname as a JS hook. By default it will now look for `<video>`, `<audio>` and `[data-type]` elements. If you are just calling `setup()` with a `<div class="plyr">` you may want to give it a good test after upgrading. You can probably remove the wrapper div. The reason behind this is to make setup easier for newcomers and prevent the styling being used on unsupported players (because the plyr classname was used as a CSS and JS hook - which isn't ideal)
|
||||
- ***(Important)*** Removed the requirement for a wrapper div to setup Plyr and removed the dependency on the `plyr` classname as a JS hook. By default it will now look for `<video>`, `<audio>` and `[data-type]` elements. If you are just calling `setup()` with a `<div class="plyr">` you may want to give it a good test after upgrading. You can probably remove the wrapper div. The reason behind this is to make setup easier for newcomers and prevent the styling being used on unsupported players (because the plyr classname was used as a CSS and JS hook - which isn't ideal)
|
||||
- Renamed the 'docs' folder to `demo` to avoid confusion - the readme is the docs after all
|
||||
|
||||
## v1.6.20
|
||||
@ -158,7 +166,7 @@ And some other changes and bug fixes:
|
||||
- Decreased sensitivity and inverted scroll on volume slider (scroll up to increase, down to decrease)
|
||||
|
||||
## v1.6.12
|
||||
- Fix for undefined buffer error
|
||||
- Fix for undefined buffer error
|
||||
- Add scroll listener on volume slider (PR #227 bty @igoradamenko)
|
||||
|
||||
## v1.6.11
|
||||
@ -200,13 +208,13 @@ And some other changes and bug fixes:
|
||||
- Other minor bug fixes
|
||||
|
||||
## v1.6.1
|
||||
- Tooltip changes for accessibility
|
||||
- Tooltip changes for accessibility
|
||||
|
||||
## v1.6.0
|
||||
- New, cleaner, UI:
|
||||
- Controls are now overlaid, maintaining the video's ratio and making sizing easier
|
||||
- A large play button can now be overlaid over videos
|
||||
- Default number of control buttons reduced
|
||||
- Default number of control buttons reduced
|
||||
- New play, pause, rewind and fast forward icons
|
||||
- Flexbox all the things!
|
||||
- Tidied up the LESS (and SCSS) as part of the above, variables and mixins in seprate files amking customization and upgrades easier
|
||||
|
2
demo/dist/demo.js
vendored
2
demo/dist/demo.js
vendored
@ -1 +1 @@
|
||||
"document"in self&&("classList"in document.createElement("_")?!function(){"use strict";var e=document.createElement("_");if(e.classList.add("c1","c2"),!e.classList.contains("c2")){var t=function(e){var t=DOMTokenList.prototype[e];DOMTokenList.prototype[e]=function(e){var i,s=arguments.length;for(i=0;i<s;i++)e=arguments[i],t.call(this,e)}};t("add"),t("remove")}if(e.classList.toggle("c3",!1),e.classList.contains("c3")){var i=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(e,t){return 1 in arguments&&!this.contains(e)==!t?t:i.call(this,e)}}e=null}():!function(e){"use strict";if("Element"in e){var t="classList",i="prototype",s=e.Element[i],o=Object,n=String[i].trim||function(){return this.replace(/^\s+|\s+$/g,"")},r=Array[i].indexOf||function(e){for(var t=0,i=this.length;t<i;t++)if(t in this&&this[t]===e)return t;return-1},a=function(e,t){this.name=e,this.code=DOMException[e],this.message=t},c=function(e,t){if(""===t)throw new a("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(t))throw new a("INVALID_CHARACTER_ERR","String contains an invalid character");return r.call(e,t)},l=function(e){for(var t=n.call(e.getAttribute("class")||""),i=t?t.split(/\s+/):[],s=0,o=i.length;s<o;s++)this.push(i[s]);this._updateClassName=function(){e.setAttribute("class",this.toString())}},u=l[i]=[],d=function(){return new l(this)};if(a[i]=Error[i],u.item=function(e){return this[e]||null},u.contains=function(e){return e+="",c(this,e)!==-1},u.add=function(){var e,t=arguments,i=0,s=t.length,o=!1;do e=t[i]+"",c(this,e)===-1&&(this.push(e),o=!0);while(++i<s);o&&this._updateClassName()},u.remove=function(){var e,t,i=arguments,s=0,o=i.length,n=!1;do for(e=i[s]+"",t=c(this,e);t!==-1;)this.splice(t,1),n=!0,t=c(this,e);while(++s<o);n&&this._updateClassName()},u.toggle=function(e,t){e+="";var i=this.contains(e),s=i?t!==!0&&"remove":t!==!1&&"add";return s&&this[s](e),t===!0||t===!1?t:!i},u.toString=function(){return this.join(" ")},o.defineProperty){var p={get:d,enumerable:!0,configurable:!0};try{o.defineProperty(s,t,p)}catch(e){e.number===-2146823252&&(p.enumerable=!1,o.defineProperty(s,t,p))}}else o[i].__defineGetter__&&s.__defineGetter__(t,d)}}(self)),function(){function e(e,t,i){if(e)if(e.classList)e.classList[i?"add":"remove"](t);else{var s=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=s+(i?" "+t:"")}}function t(t,i){if(t in n&&(i||t!==r)&&(r.length||t!==n.video)){switch(t){case n.video:s.source({type:"video",title:"View From A Blue Moon",sources:[{src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.mp4",type:"video/mp4"},{src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.webm",type:"video/webm"}],poster:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.jpg",tracks:[{kind:"captions",label:"English",srclang:"en",src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.en.vtt",default:!0}]});break;case n.audio:s.source({type:"audio",title:"Kishi Bashi – “It All Began With A Burst”",sources:[{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3",type:"audio/mp3"},{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg",type:"audio/ogg"}]});break;case n.youtube:s.source({type:"video",title:"View From A Blue Moon",sources:[{src:"bTqVqk7FSmY",type:"youtube"}]});break;case n.vimeo:s.source({type:"video",title:"View From A Blue Moon",sources:[{src:"143418951",type:"vimeo"}]})}r=t;for(var a=o.length-1;a>=0;a--)e(o[a].parentElement,"active",!1);e(document.querySelector('[data-source="'+t+'"]').parentElement,"active",!0)}}var i=plyr.setup({debug:!0,title:"Video demo",iconUrl:"../dist/plyr.svg",tooltips:{controls:!0},captions:{defaultActive:!0},controls:["play-large","play","speed-up","progress","current-time","mute","volume","captions","settings","fullscreen"]});plyr.loadSprite("dist/demo.svg");for(var s=i[0],o=document.querySelectorAll("[data-source]"),n={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},r=window.location.hash.replace("#",""),a=window.history&&window.history.pushState,c=o.length-1;c>=0;c--)o[c].addEventListener("click",function(){var e=this.getAttribute("data-source");t(e),a&&history.pushState({type:e},"","#"+e)});if(window.addEventListener("popstate",function(e){e.state&&"type"in e.state&&t(e.state.type)}),a){var l=!r.length;l&&(r=n.video),r in n&&history.replaceState({type:r},"",l?"":"#"+r),r!==n.video&&t(r,!0)}}(),document.domain.indexOf("plyr.io")>-1&&(!function(e,t,i,s,o,n,r){e.GoogleAnalyticsObject=o,e[o]=e[o]||function(){(e[o].q=e[o].q||[]).push(arguments)},e[o].l=1*new Date,n=t.createElement(i),r=t.getElementsByTagName(i)[0],n.async=1,n.src=s,r.parentNode.insertBefore(n,r)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),ga("create","UA-40881672-11","auto"),ga("send","pageview"));
|
||||
"document"in self&&("classList"in document.createElement("_")?!function(){"use strict";var e=document.createElement("_");if(e.classList.add("c1","c2"),!e.classList.contains("c2")){var t=function(e){var t=DOMTokenList.prototype[e];DOMTokenList.prototype[e]=function(e){var i,s=arguments.length;for(i=0;i<s;i++)e=arguments[i],t.call(this,e)}};t("add"),t("remove")}if(e.classList.toggle("c3",!1),e.classList.contains("c3")){var i=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(e,t){return 1 in arguments&&!this.contains(e)==!t?t:i.call(this,e)}}e=null}():!function(e){"use strict";if("Element"in e){var t="classList",i="prototype",s=e.Element[i],o=Object,n=String[i].trim||function(){return this.replace(/^\s+|\s+$/g,"")},r=Array[i].indexOf||function(e){for(var t=0,i=this.length;t<i;t++)if(t in this&&this[t]===e)return t;return-1},a=function(e,t){this.name=e,this.code=DOMException[e],this.message=t},c=function(e,t){if(""===t)throw new a("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(t))throw new a("INVALID_CHARACTER_ERR","String contains an invalid character");return r.call(e,t)},l=function(e){for(var t=n.call(e.getAttribute("class")||""),i=t?t.split(/\s+/):[],s=0,o=i.length;s<o;s++)this.push(i[s]);this._updateClassName=function(){e.setAttribute("class",this.toString())}},u=l[i]=[],d=function(){return new l(this)};if(a[i]=Error[i],u.item=function(e){return this[e]||null},u.contains=function(e){return e+="",c(this,e)!==-1},u.add=function(){var e,t=arguments,i=0,s=t.length,o=!1;do e=t[i]+"",c(this,e)===-1&&(this.push(e),o=!0);while(++i<s);o&&this._updateClassName()},u.remove=function(){var e,t,i=arguments,s=0,o=i.length,n=!1;do for(e=i[s]+"",t=c(this,e);t!==-1;)this.splice(t,1),n=!0,t=c(this,e);while(++s<o);n&&this._updateClassName()},u.toggle=function(e,t){e+="";var i=this.contains(e),s=i?t!==!0&&"remove":t!==!1&&"add";return s&&this[s](e),t===!0||t===!1?t:!i},u.toString=function(){return this.join(" ")},o.defineProperty){var p={get:d,enumerable:!0,configurable:!0};try{o.defineProperty(s,t,p)}catch(e){e.number===-2146823252&&(p.enumerable=!1,o.defineProperty(s,t,p))}}else o[i].__defineGetter__&&s.__defineGetter__(t,d)}}(self)),function(){function e(e,t,i){if(e)if(e.classList)e.classList[i?"add":"remove"](t);else{var s=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=s+(i?" "+t:"")}}function t(t,i){if(t in n&&(i||t!==r)&&(r.length||t!==n.video)){switch(t){case n.video:s.source({type:"video",title:"View From A Blue Moon",sources:[{src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.mp4",type:"video/mp4"},{src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.webm",type:"video/webm"}],poster:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.jpg",tracks:[{kind:"captions",label:"English",srclang:"en",src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.en.vtt",default:!0}]});break;case n.audio:s.source({type:"audio",title:"Kishi Bashi – “It All Began With A Burst”",sources:[{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3",type:"audio/mp3"},{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg",type:"audio/ogg"}]});break;case n.youtube:s.source({type:"video",title:"View From A Blue Moon",sources:[{src:"bTqVqk7FSmY",type:"youtube"}]});break;case n.vimeo:s.source({type:"video",title:"View From A Blue Moon",sources:[{src:"143418951",type:"vimeo"}]})}r=t;for(var a=o.length-1;a>=0;a--)e(o[a].parentElement,"active",!1);e(document.querySelector('[data-source="'+t+'"]').parentElement,"active",!0)}}var i=plyr.setup({debug:!0,title:"Video demo",iconUrl:"../dist/plyr.svg",tooltips:{controls:!0},captions:{defaultActive:!0},controls:["play-large","play","progress","current-time","mute","volume","captions","settings","fullscreen"]});plyr.loadSprite("dist/demo.svg");for(var s=i[0],o=document.querySelectorAll("[data-source]"),n={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},r=window.location.hash.replace("#",""),a=window.history&&window.history.pushState,c=o.length-1;c>=0;c--)o[c].addEventListener("click",function(){var e=this.getAttribute("data-source");t(e),a&&history.pushState({type:e},"","#"+e)});if(window.addEventListener("popstate",function(e){e.state&&"type"in e.state&&t(e.state.type)}),a){var l=!r.length;l&&(r=n.video),r in n&&history.replaceState({type:r},"",l?"":"#"+r),r!==n.video&&t(r,!0)}}(),document.domain.indexOf("plyr.io")>-1&&(!function(e,t,i,s,o,n,r){e.GoogleAnalyticsObject=o,e[o]=e[o]||function(){(e[o].q=e[o].q||[]).push(arguments)},e[o].l=1*new Date,n=t.createElement(i),r=t.getElementsByTagName(i)[0],n.async=1,n.src=s,r.parentNode.insertBefore(n,r)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),ga("create","UA-40881672-11","auto"),ga("send","pageview"));
|
@ -67,8 +67,8 @@
|
||||
<ul>
|
||||
<li class="plyr__cite plyr__cite--video"><small><a href="http://viewfromabluemoon.com/" target="_blank">View From A Blue Moon</a> © Brainfarm</small></li>
|
||||
<li class="plyr__cite plyr__cite--audio"><small><a href="http://www.kishibashi.com/" target="_blank">Kishi Bashi – “It All Began With A Burst”</a> © Kishi Bashi</small></li>
|
||||
<li class="plyr__cite plyr__cite--youtube"><small><a href="https://www.youtube.com/watch?v=bTqVqk7FSmY" target="_blank">View From A Blue Moon</a> on <span class="color--youtube"><svg class="icon"><use xlink:href="#icon-youtube"/></svg>YouTube</span></small>
|
||||
<li class="plyr__cite plyr__cite--vimeo"><small><a href="https://vimeo.com/ondemand/viewfromabluemoon4k" target="_blank">View From A Blue Moon</a> on <span class="color--vimeo"><svg class="icon"><use xlink:href="#icon-vimeo"/></svg>Vimeo</span></small>
|
||||
<li class="plyr__cite plyr__cite--youtube"><small><a href="https://www.youtube.com/watch?v=bTqVqk7FSmY" target="_blank">View From A Blue Moon</a> on <span class="color--youtube"><svg class="icon"><use xlink:href="#icon-youtube"/></svg>YouTube</span></small></li>
|
||||
<li class="plyr__cite plyr__cite--vimeo"><small><a href="https://vimeo.com/ondemand/viewfromabluemoon4k" target="_blank">View From A Blue Moon</a> on <span class="color--vimeo"><svg class="icon"><use xlink:href="#icon-vimeo"/></svg>Vimeo</span></small></li>
|
||||
</ul>
|
||||
</section>
|
||||
</main>
|
||||
|
@ -21,7 +21,7 @@
|
||||
captions: {
|
||||
defaultActive: true
|
||||
},
|
||||
controls: ['play-large', 'play', 'speed-up', 'progress', 'current-time', 'mute', 'volume', 'captions', 'settings', 'fullscreen']
|
||||
controls: ['play-large', 'play', 'progress', 'current-time', 'mute', 'volume', 'captions', 'settings', 'fullscreen']
|
||||
});
|
||||
plyr.loadSprite('dist/demo.svg');
|
||||
|
||||
|
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
6
notes.md
6
notes.md
@ -1,14 +1,16 @@
|
||||
### Todo
|
||||
|
||||
#### Features
|
||||
- Get list of subtitles/captions available (HTML5)
|
||||
- Add preferred quality option
|
||||
- Update quality options on YouTube play
|
||||
- Update speed options on YouTube load
|
||||
- No Vimeo quality support
|
||||
- No Vimeo or YouTube caption support
|
||||
- Get quality options for HTML5 somehow (multi source?)
|
||||
- Get list of subtitles/captions available (HTML5)
|
||||
- Build templating for controls somehow
|
||||
- Finish PiP
|
||||
- Finish AirPlay
|
||||
|
||||
#### Bugs
|
||||
- Fix audio setup bug
|
||||
- Fix audio setup bug when calling .setup() again
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "plyr",
|
||||
"version": "2.0.10",
|
||||
"version": "2.0.12",
|
||||
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
||||
"homepage": "http://plyr.io",
|
||||
"main": "src/js/plyr.js",
|
||||
|
51
readme.md
51
readme.md
@ -1,6 +1,8 @@
|
||||
# Plyr
|
||||
A simple, accessible and customizable HTML5, YouTube and Vimeo media player.
|
||||
|
||||
[Donate to support Plyr](#donate)
|
||||
|
||||
[Checkout the demo](https://plyr.io)
|
||||
|
||||
[](https://plyr.io)
|
||||
@ -132,10 +134,10 @@ Include the `plyr.js` script before the closing `</body>` tag and then call `ply
|
||||
<script>plyr.setup();</script>
|
||||
```
|
||||
|
||||
If you want to use our CDN for the JavaScript, you can use the following:
|
||||
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript, you can use the following:
|
||||
|
||||
```html
|
||||
<script src="https://cdn.plyr.io/2.0.10/plyr.js"></script>
|
||||
<script src="https://cdn.plyr.io/2.0.12/plyr.js"></script>
|
||||
```
|
||||
|
||||
### CSS
|
||||
@ -145,14 +147,14 @@ Include the `plyr.css` stylsheet into your `<head>`
|
||||
<link rel="stylesheet" href="path/to/plyr.css">
|
||||
```
|
||||
|
||||
If you want to use our CDN for the default CSS, you can use the following:
|
||||
If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/2.0.10/plyr.css">
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/2.0.12/plyr.css">
|
||||
```
|
||||
|
||||
### SVG Sprite
|
||||
The SVG sprite is loaded automatically from our CDN. To change this, see the [options](#Options) below. For reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/2.0.10/plyr.svg`.
|
||||
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/2.0.12/plyr.svg`.
|
||||
|
||||
## Advanced
|
||||
|
||||
@ -284,6 +286,12 @@ Note the single quotes encapsulating the JSON and double quotes on the object ke
|
||||
<td><code>plyr</code></td>
|
||||
<td>Specify the id prefix for the icons used in the default controls (e.g. "plyr-play" would be "plyr"). This is to prevent clashes if you're using your own SVG sprite but with the default controls. Most people can ignore this option.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>blankUrl</code></td>
|
||||
<td>String</td>
|
||||
<td><code>https://cdn.selz.com/plyr/blank.mp4</code></td>
|
||||
<td>Specify a URL or path to a blank video file used to properly cancel network requests. See <a href="https://github.com/Selz/plyr/issues/174">issue #174</a> for more info.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>debug</code></td>
|
||||
<td>Boolean</td>
|
||||
@ -672,7 +680,12 @@ player.source({
|
||||
srclang:'en',
|
||||
src: '/path/to/captions.vtt',
|
||||
default: true
|
||||
}]
|
||||
}],
|
||||
loopKeyEvents: {
|
||||
toggleLoop: 76,
|
||||
loopin: 73,
|
||||
loopout: 79
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
@ -988,6 +1001,21 @@ By default, a player will bind the following keyboard shortcuts when it has focu
|
||||
<td>✔</td>
|
||||
<td>Toggle captions</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>l</code></td>
|
||||
<td></td>
|
||||
<td>Toggle Loop All/No Loop</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>i</code></td>
|
||||
<td></td>
|
||||
<td>Set the start marker of the loop</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>o</code></td>
|
||||
<td></td>
|
||||
<td>Set the end marker of the loop</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@ -1030,7 +1058,7 @@ Fullscreen in Plyr is supported by all browsers that [currently support it](http
|
||||
|
||||
² Native player used (no support for `<progress>` or `<input type="range">`) but the API is supported (v1.0.28+)
|
||||
|
||||
³ IE10 has no native fullscreen support, fallback can be used (see options)
|
||||
³ IE10 has no native fullscreen support, fallback can be used (see [options](#options))
|
||||
|
||||
The `enabled` option can be used to disable certain User Agents. For example, if you don't want to use Plyr for smartphones, you could use:
|
||||
|
||||
@ -1050,6 +1078,10 @@ If you find anything weird with Plyr, please let us know using the GitHub issues
|
||||
## Author
|
||||
Plyr is developed by [@sam_potts](https://twitter.com/sam_potts) / [sampotts.me](http://sampotts.me) with help from the awesome [contributors](https://github.com/Selz/plyr/graphs/contributors)
|
||||
|
||||
## Donate
|
||||
Plyr costs money to run, not my time - I donate that for free but domains, hosting and more. Any help is appreciated...
|
||||
[Donate to support Plyr](https://www.paypal.me/pottsy/20usd)
|
||||
|
||||
## Mentions
|
||||
- [ProductHunt](https://www.producthunt.com/tech/plyr)
|
||||
- [The Changelog](http://thechangelog.com/plyr-simple-html5-media-player-custom-controls-webvtt-captions/)
|
||||
@ -1084,5 +1116,10 @@ Also these links helped created Plyr:
|
||||
- [Media Events - W3.org](http://www.w3.org/2010/05/video/mediaevents.html)
|
||||
- [Styling the `<progress>` element - hongkiat.com](http://www.hongkiat.com/blog/html5-progress-bar/)
|
||||
|
||||
## Thanks
|
||||
[](https://www.fastly.com/)
|
||||
|
||||
Thanks to [Fastly](https://www.fastly.com/) for providing the CDN services.
|
||||
|
||||
## Copyright and License
|
||||
[The MIT license](license.md).
|
||||
|
223
src/js/plyr.js
223
src/js/plyr.js
@ -37,9 +37,15 @@
|
||||
enabled: true,
|
||||
debug: false,
|
||||
autoplay: false,
|
||||
loop: false,
|
||||
loopin: 0,
|
||||
loopout: null,
|
||||
loop: {
|
||||
active: false,
|
||||
start: 0,
|
||||
end: null,
|
||||
indicator: {
|
||||
start: 0,
|
||||
end: 0
|
||||
}
|
||||
},
|
||||
seekTime: 10,
|
||||
volume: 10,
|
||||
volumeMin: 0,
|
||||
@ -57,8 +63,10 @@
|
||||
hideControls: true,
|
||||
showPosterOnEnd: false,
|
||||
disableContextMenu: true,
|
||||
qualityOptions: false,
|
||||
keyboardShorcuts: {
|
||||
quality: {
|
||||
options: false
|
||||
},
|
||||
keyboardShortcuts: {
|
||||
focused: true,
|
||||
global: false
|
||||
},
|
||||
@ -102,7 +110,8 @@
|
||||
progress: {
|
||||
container: '.plyr__progress',
|
||||
buffer: '.plyr__progress--buffer',
|
||||
played: '.plyr__progress--played'
|
||||
played: '.plyr__progress--played',
|
||||
looped: '.plyr__progress-loop'
|
||||
},
|
||||
captions: '.plyr__captions',
|
||||
currentTime: '.plyr__time--current',
|
||||
@ -175,10 +184,10 @@
|
||||
speed: 'Speed',
|
||||
quality: 'Quality',
|
||||
loop: 'Loop',
|
||||
loopin: 'Loop in',
|
||||
loopout: 'Loop out',
|
||||
loopall: 'Loop all',
|
||||
loopclear: 'No Loop',
|
||||
loopStart: 'Loop start',
|
||||
loopEnd: 'Loop end',
|
||||
loopAll: 'Loop all',
|
||||
loopNone: 'No Loop',
|
||||
},
|
||||
types: {
|
||||
embed: ['youtube', 'vimeo', 'soundcloud'],
|
||||
@ -915,6 +924,7 @@
|
||||
/* beautify ignore:start */
|
||||
html.push(
|
||||
'<span class="plyr__progress">',
|
||||
'<div class="plyr__progress-loop"></div>',
|
||||
'<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>',
|
||||
@ -1033,12 +1043,19 @@
|
||||
'</button>',
|
||||
'</li>',
|
||||
'<li role="tab">',
|
||||
|
||||
showQuality,
|
||||
|
||||
'<button type="button" class="plyr__control plyr__control--forward" id="plyr-settings-{id}-quality-toggle" aria-haspopup="true" aria-controls="plyr-settings-{id}-quality" aria-expanded="false">',
|
||||
config.i18n.quality +
|
||||
'<span class="plyr__menu__value">{quality}</span>'
|
||||
'</button>',
|
||||
|
||||
'</li>',
|
||||
'<li role="tab">',
|
||||
'<button type="button" class="plyr__control plyr__control--forward" id="plyr-settings-{id}-loop-toggle" aria-haspopup="true" aria-controls="plyr-settings-{id}-loop" aria-expanded="false">',
|
||||
config.i18n.loop +
|
||||
'<span class="plyr__menu__value" data-menu="loop"></span>',
|
||||
config.i18n.loop +
|
||||
'<span class="plyr__menu__value" data-menu="loop">{loop}</span>',
|
||||
'</button>',
|
||||
'</li>',
|
||||
'</ul>',
|
||||
@ -1156,26 +1173,26 @@
|
||||
'</button>',
|
||||
'</li>',
|
||||
'<li>',
|
||||
'<button type="button" class="plyr__control" data-plyr="loop" data-loop__type="loopall">',
|
||||
config.i18n.loopall,
|
||||
'<span data-loop__value="loopall"></span>',
|
||||
'<button type="button" class="plyr__control" data-plyr="loop" data-plyr-loop="all">',
|
||||
config.i18n.loopAll,
|
||||
'<span></span>',
|
||||
'</button>',
|
||||
'</li>',
|
||||
'<li>',
|
||||
'<button type="button" class="plyr__control" data-plyr="loop" data-loop__type="loopin">',
|
||||
config.i18n.loopin + ': ',
|
||||
'<span data-loop__value="loopin"></span>',
|
||||
'<button type="button" class="plyr__control" data-plyr="loop" data-plyr-loop="start">',
|
||||
config.i18n.loopStart,
|
||||
'<span></span>',
|
||||
'</button>',
|
||||
'</li>',
|
||||
'<li>',
|
||||
'<button type="button" class="plyr__control" data-plyr="loop" data-loop__type="loopout">',
|
||||
config.i18n.loopout + ': ',
|
||||
'<span data-loop__value="loopout"></span>',
|
||||
'<button type="button" class="plyr__control" data-plyr="loop" data-plyr-loop="end">',
|
||||
config.i18n.loopEnd,
|
||||
'<span></span>',
|
||||
'</button>',
|
||||
'</li>',
|
||||
'<li>',
|
||||
'<button type="button" class="plyr__control" data-plyr="loop" data-loop__type="loopclear">',
|
||||
config.i18n.loopclear,
|
||||
'<button type="button" class="plyr__control" data-plyr="loop" data-plyr-loop="none">',
|
||||
config.i18n.loopNone,
|
||||
'</button>',
|
||||
'</li>',
|
||||
'</ul>',
|
||||
@ -1794,9 +1811,9 @@
|
||||
fullscreen: getElement(config.selectors.buttons.fullscreen),
|
||||
settings: getElement(config.selectors.buttons.settings),
|
||||
pip: getElement(config.selectors.buttons.pip),
|
||||
speed: document.querySelectorAll(config.selectors.buttons.speed),
|
||||
loop: document.querySelectorAll(config.selectors.buttons.loop),
|
||||
captions_lang: getElements(config.selectors.buttons.captions_lang)
|
||||
lang: getElement(config.selectors.buttons.captions_lang),
|
||||
speed: getElement(config.selectors.buttons.speed),
|
||||
loop: getElement(config.selectors.buttons.loop)
|
||||
};
|
||||
|
||||
// Inputs
|
||||
@ -2296,7 +2313,7 @@
|
||||
// https://github.com/vimeo/player.js
|
||||
plyr.embed = new window.Vimeo.Player(container, {
|
||||
id: parseInt(mediaId),
|
||||
loop: config.loop,
|
||||
loop: config.loop.active,
|
||||
autoplay: config.autoplay,
|
||||
byline: false,
|
||||
portrait: false,
|
||||
@ -2493,46 +2510,82 @@
|
||||
}
|
||||
|
||||
// Toggle loop
|
||||
function toggleLoop(toggle) {
|
||||
if (['loopin', 'loopout', 'loopall'].indexOf(toggle) === -1) {
|
||||
toggle = 'loopclear';
|
||||
// TODO: Set the indicator on load as user may pass loop as config
|
||||
function toggleLoop(type) {
|
||||
// Set default to be a true toggle
|
||||
if (!inArray(['start', 'end', 'all', 'none', 'toggle'], type)) {
|
||||
type = 'toggle';
|
||||
}
|
||||
|
||||
var currentTime = Number(plyr.media.currentTime);
|
||||
|
||||
switch (toggle) {
|
||||
case 'loopin':
|
||||
if (config.loopout && config.loopout <= currentTime) {
|
||||
config.loopout = null;
|
||||
switch (type) {
|
||||
case 'start':
|
||||
if (config.loop.end && config.loop.end <= currentTime) {
|
||||
config.loop.end = null;
|
||||
}
|
||||
config.loopin = currentTime;
|
||||
config.loop.start = currentTime;
|
||||
config.loop.indicator.start = plyr.progress.played.value;
|
||||
break;
|
||||
case 'loopout':
|
||||
if (config.loopin >= currentTime) {
|
||||
|
||||
case 'end':
|
||||
if (config.loop.start >= currentTime) {
|
||||
return;
|
||||
}
|
||||
config.loopout = currentTime;
|
||||
config.loop.end = currentTime;
|
||||
config.loop.indicator.end = plyr.progress.played.value;
|
||||
break;
|
||||
case 'loopall':
|
||||
config.loopin = 0;
|
||||
config.loopout = plyr.media.duration - 2;
|
||||
|
||||
case 'all':
|
||||
config.loop.start = 0;
|
||||
config.loop.end = plyr.media.duration - 2;
|
||||
config.loop.indicator.start = 0;
|
||||
config.loop.indicator.end = 100;
|
||||
break;
|
||||
|
||||
case 'toggle':
|
||||
if (config.loop.active) {
|
||||
config.loop.start = 0;
|
||||
config.loop.end = null;
|
||||
} else {
|
||||
config.loop.start = 0;
|
||||
config.loop.end = plyr.media.duration - 2;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
config.loopin = 0;
|
||||
config.loopout = null;
|
||||
config.loop.start = 0;
|
||||
config.loop.end = null;
|
||||
break;
|
||||
}
|
||||
|
||||
//check if can loop
|
||||
config.loop = is.number(config.loopin) && is.number(config.loopout);
|
||||
var loopin = updateTimeDisplay(config.loopin, document.querySelector('[data-loop__value="loopin"]'));
|
||||
var loopout = is.number(config.loopout) ? updateTimeDisplay(config.loopout + 2, document.querySelector('[data-loop__value="loopout"]')) : document.querySelector('[data-loop__value="loopout"]').innerHTML = '';
|
||||
if (config.loop) {
|
||||
document.querySelector('[data-menu="loop"]').innerHTML = loopin + ' - ' + loopout;
|
||||
// Check if can loop
|
||||
config.loop.active = is.number(config.loop.start) && is.number(config.loop.end);
|
||||
var start = updateTimeDisplay(config.loop.start, getElement('[data-plyr-loop="start"]'));
|
||||
var end = null;
|
||||
|
||||
if (is.number(config.loop.end)) {
|
||||
// Find the <span> inside button
|
||||
end = updateTimeDisplay(config.loop.end, document.querySelector('[data-loop__value="loopout"]'));
|
||||
} else {
|
||||
document.querySelector('[data-menu="loop"]').innerHTML = config.i18n.loopclear;
|
||||
// Find the <span> inside button
|
||||
//end = document.querySelector('[data-loop__value="loopout"]').innerHTML = '';
|
||||
}
|
||||
|
||||
if (config.loop.active) {
|
||||
// TODO: Improve the design of the loop indicator and put styling in CSS where it's meant to be
|
||||
//getElement('[data-menu="loop"]').innerHTML = start + ' - ' + end;
|
||||
//getElement(config.selectors.progress.looped).style.position = 'absolute';
|
||||
//getElement(config.selectors.progress.looped).style.left = config.loopinPositionPercentage + '%';
|
||||
//getElement(config.selectors.progress.looped).style.width = (config.loopoutPositionPercentage - config.loopinPositionPercentage) + '%';
|
||||
//getElement(config.selectors.progress.looped).style.background = '#ffbb00';
|
||||
//getElement(config.selectors.progress.looped).style.height = '3px';
|
||||
//getElement(config.selectors.progress.looped).style.top = '3px';
|
||||
//getElement(config.selectors.progress.looped).style['border-radius'] = '100px';
|
||||
} else {
|
||||
//getElement('[data-menu="loop"]').innerHTML = config.i18n.loopNone;
|
||||
//getElement(config.selectors.progress.looped).style.width = '0px';
|
||||
}
|
||||
}
|
||||
|
||||
// Speed-up
|
||||
@ -2546,6 +2599,7 @@
|
||||
warn('Invalid speeds format');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is.number(speed)) {
|
||||
var index = config.speeds.indexOf(config.currentSpeed);
|
||||
|
||||
@ -3026,8 +3080,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (is.number(config.loopin) && is.number(config.loopout) && plyr.media.currentTime >= config.loopout) {
|
||||
seek(config.loopin);
|
||||
if (is.number(config.loop.start) && is.number(config.loop.end) && plyr.media.currentTime >= config.loop.end) {
|
||||
seek(config.loop.start);
|
||||
}
|
||||
|
||||
setProgress(progress, value);
|
||||
@ -3089,10 +3143,14 @@
|
||||
plyr.secs = ('0' + plyr.secs).slice(-2);
|
||||
plyr.mins = ('0' + plyr.mins).slice(-2);
|
||||
|
||||
var txt = (displayHours ? plyr.hours + ':' : '') + plyr.mins + ':' + plyr.secs;
|
||||
// Generate display
|
||||
var display = (displayHours ? plyr.hours + ':' : '') + plyr.mins + ':' + plyr.secs;
|
||||
|
||||
// Render
|
||||
element.innerHTML = txt;
|
||||
return txt;
|
||||
element.innerHTML = display;
|
||||
|
||||
// Return for looping
|
||||
return display;
|
||||
}
|
||||
|
||||
// Show the duration on metadataloaded
|
||||
@ -3395,7 +3453,7 @@
|
||||
if ('poster' in source) {
|
||||
plyr.media.setAttribute('poster', source.poster);
|
||||
}
|
||||
if (config.loop) {
|
||||
if (config.loop.active) {
|
||||
plyr.media.setAttribute('loop', '');
|
||||
}
|
||||
}
|
||||
@ -3519,16 +3577,16 @@
|
||||
}
|
||||
|
||||
// Keyboard shortcuts
|
||||
if (config.keyboardShorcuts.focused) {
|
||||
if (config.keyboardShortcuts.focused) {
|
||||
var last = null;
|
||||
|
||||
// Handle global presses
|
||||
if (config.keyboardShorcuts.global) {
|
||||
if (config.keyboardShortcuts.global) {
|
||||
on(window, 'keydown keyup', function(event) {
|
||||
var code = getKeyCode(event),
|
||||
focused = getFocusElement(),
|
||||
allowed = [48, 49, 50, 51, 52, 53, 54, 56, 57, 75, 77, 70, 67],
|
||||
count = get().length;
|
||||
var code = getKeyCode(event);
|
||||
var focused = getFocusElement();
|
||||
var allowed = [48, 49, 50, 51, 52, 53, 54, 56, 57, 75, 77, 70, 67, 73, 76, 79];
|
||||
var count = get().length;
|
||||
|
||||
// Only handle global key press if there's only one player
|
||||
// and the key is in the allowed keys
|
||||
@ -3545,9 +3603,9 @@
|
||||
}
|
||||
|
||||
function handleKey(event) {
|
||||
var code = getKeyCode(event),
|
||||
pressed = event.type === 'keydown',
|
||||
held = pressed && code === last;
|
||||
var code = getKeyCode(event);
|
||||
var pressed = event.type === 'keydown';
|
||||
var held = pressed && code === last;
|
||||
|
||||
// If the event is bubbled from the media element
|
||||
// Firefox doesn't get the keycode for whatever reason
|
||||
@ -3573,7 +3631,7 @@
|
||||
// Reset on keyup
|
||||
if (pressed) {
|
||||
// Which keycodes should we prevent default
|
||||
var preventDefault = [48, 49, 50, 51, 52, 53, 54, 56, 57, 32, 75, 38, 40, 77, 39, 37, 70, 67];
|
||||
var preventDefault = [48, 49, 50, 51, 52, 53, 54, 56, 57, 32, 75, 38, 40, 77, 39, 37, 70, 67, 73, 76, 79];
|
||||
var checkFocus = [38, 40];
|
||||
|
||||
if (inArray(checkFocus, code)) {
|
||||
@ -3628,7 +3686,7 @@
|
||||
case 77:
|
||||
// M key
|
||||
if (!held) {
|
||||
toggleMute()
|
||||
toggleMute();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -3653,6 +3711,18 @@
|
||||
toggleCaptions();
|
||||
}
|
||||
break;
|
||||
|
||||
case 73:
|
||||
toggleLoop('start');
|
||||
break;
|
||||
|
||||
case 76:
|
||||
toggleLoop();
|
||||
break;
|
||||
|
||||
case 79:
|
||||
toggleLoop('end');
|
||||
break;
|
||||
}
|
||||
|
||||
// Escape is handle natively when in full screen
|
||||
@ -3723,11 +3793,12 @@
|
||||
// Fullscreen
|
||||
proxy(plyr.buttons.fullscreen, 'click', config.listeners.fullscreen, toggleFullscreen);
|
||||
|
||||
// Loop
|
||||
// Looping
|
||||
proxy(plyr.buttons.loop, 'click', config.listeners.loop, function(event) {
|
||||
var loopValue = event.target.getAttribute('data-loop__value') || event.target.getAttribute('data-loop__type');
|
||||
if (['loopin', 'loopout', 'loopall', 'loopclear'].indexOf(loopValue) > -1) {
|
||||
toggleLoop(loopValue);
|
||||
var value = event.target.getAttribute('data-loop__value') || event.target.getAttribute('data-loop__type');
|
||||
|
||||
if (inArray(['start', 'end', 'all', 'none'], value)) {
|
||||
toggleLoop(value);
|
||||
}
|
||||
});
|
||||
|
||||
@ -3737,10 +3808,10 @@
|
||||
}
|
||||
|
||||
// Captions
|
||||
on(plyr.buttons.captions, 'click', toggleCaptions);
|
||||
on(plyr.buttons.captions_menu, 'click', toggleCaptions);
|
||||
// Captions language
|
||||
proxy(plyr.buttons.captions_lang, 'click', config.listeners.captions_lang, function(e) {
|
||||
proxy(plyr.buttons.captions, 'click', config.listeners.captions toggleCaptions);
|
||||
// ?? on(plyr.buttons.captions_menu, 'click', toggleCaptions);
|
||||
// Language
|
||||
proxy(plyr.buttons.lang, 'click', config.listeners.lang, function(e) {
|
||||
var langIndex = e.target.attributes.getNamedItem("data-index").value;
|
||||
setCaptionIndex(langIndex);
|
||||
});
|
||||
@ -4226,7 +4297,7 @@
|
||||
return plyr.media.paused;
|
||||
},
|
||||
isLooping: function() {
|
||||
return config.loopin && config.loopout;
|
||||
return config.loop.active;
|
||||
},
|
||||
on: function(event, callback) {
|
||||
on(plyr.container, event, callback);
|
||||
|
@ -198,7 +198,11 @@
|
||||
.plyr__video-embed {
|
||||
padding-bottom: 56.25%; /* 16:9 */
|
||||
height: 0;
|
||||
border-radius: inherit;
|
||||
// Require overflow and z-index to force border-radius
|
||||
overflow: hidden;
|
||||
z-index: 0;
|
||||
|
||||
|
||||
iframe {
|
||||
position: absolute;
|
||||
@ -208,7 +212,6 @@
|
||||
height: 100%;
|
||||
border: 0;
|
||||
user-select: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
// Vimeo hack
|
||||
@ -291,16 +294,14 @@
|
||||
.plyr__menu {
|
||||
margin-left: (@plyr-control-spacing / 2);
|
||||
|
||||
&:first-child {
|
||||
&:first-child,
|
||||
&:first-child + [data-plyr="pause"] {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
.plyr__volume {
|
||||
margin-left: (@plyr-control-spacing / 2);
|
||||
}
|
||||
[data-plyr="pause"] {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
@media (min-width: @plyr-bp-screen-sm) {
|
||||
> .plyr__control,
|
||||
@ -343,6 +344,7 @@
|
||||
height: @plyr-control-icon-size;
|
||||
display: block;
|
||||
fill: currentColor;
|
||||
pointer-events: none;
|
||||
}
|
||||
// Hide toggle icons by default
|
||||
.icon--exit-fullscreen,
|
||||
@ -363,6 +365,7 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
padding: (@plyr-control-spacing * 5) @plyr-control-spacing @plyr-control-spacing;
|
||||
background: linear-gradient(fade(@plyr-video-controls-bg, 0%), fade(@plyr-video-controls-bg, 70%));
|
||||
border-bottom-left-radius: inherit;
|
||||
@ -423,6 +426,7 @@
|
||||
height: 20px;
|
||||
display: block;
|
||||
fill: currentColor;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
@ -921,6 +925,10 @@
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.plyr__video-embed {
|
||||
// Revert overflow change
|
||||
overflow: visible;
|
||||
}
|
||||
.plyr__controls {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
|
@ -61,14 +61,14 @@
|
||||
height: ($plyr-range-thumb-height * $plyr-range-thumb-active-scale);
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding: 0;
|
||||
vertical-align: middle;
|
||||
|
||||
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background: transparent;
|
||||
|
||||
|
||||
// WebKit
|
||||
&::-webkit-slider-runnable-track {
|
||||
@include plyr-range-track();
|
||||
@ -86,7 +86,7 @@
|
||||
&::-moz-range-thumb {
|
||||
@include plyr-range-thumb();
|
||||
}
|
||||
|
||||
|
||||
// Microsoft
|
||||
&::-ms-track {
|
||||
height: $plyr-range-track-height;
|
||||
@ -104,7 +104,7 @@
|
||||
&::-ms-thumb {
|
||||
@include plyr-range-thumb();
|
||||
// For some reason, Edge uses the -webkit margin above
|
||||
margin-top: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
&::-ms-tooltip {
|
||||
display: none;
|
||||
@ -116,11 +116,11 @@
|
||||
}
|
||||
&::-moz-focus-outer {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
&.tab-focus:focus {
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
|
||||
// Pressed styles
|
||||
&:active {
|
||||
&::-webkit-slider-thumb {
|
||||
@ -181,9 +181,12 @@
|
||||
.plyr__video-embed {
|
||||
padding-bottom: 56.25%; /* 16:9 */
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
border-radius: inherit;
|
||||
|
||||
// Require overflow and z-index to force border-radius
|
||||
overflow: hidden;
|
||||
z-index: 0;
|
||||
|
||||
iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@ -264,26 +267,25 @@
|
||||
// Playback controls
|
||||
.plyr__controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
|
||||
// Spacing
|
||||
> button,
|
||||
> .plyr__control,
|
||||
.plyr__progress,
|
||||
.plyr__time {
|
||||
.plyr__time,
|
||||
.plyr__menu {
|
||||
margin-left: ($plyr-control-spacing / 2);
|
||||
|
||||
&:first-child {
|
||||
&:first-child,
|
||||
&:first-child + [data-plyr="pause"] {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
.plyr__volume {
|
||||
margin-left: ($plyr-control-spacing / 2);
|
||||
}
|
||||
[data-plyr="pause"] {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
// Buttons
|
||||
button {
|
||||
@ -305,6 +307,7 @@
|
||||
height: $plyr-control-icon-size;
|
||||
display: block;
|
||||
fill: currentColor;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// Default focus
|
||||
@ -328,7 +331,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
// Hide controls
|
||||
// Hide controls
|
||||
.plyr--hide-controls .plyr__controls {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
@ -398,6 +401,7 @@
|
||||
height: 20px;
|
||||
display: block;
|
||||
fill: currentColor;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
@ -475,7 +479,7 @@
|
||||
height: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
|
||||
// The background triangle
|
||||
bottom: -$plyr-tooltip-arrow-size;
|
||||
border-right: $plyr-tooltip-arrow-size solid transparent;
|
||||
@ -624,16 +628,16 @@
|
||||
}
|
||||
&::-moz-progress-bar {
|
||||
transition: width .2s ease;
|
||||
}
|
||||
}
|
||||
&::-ms-fill {
|
||||
transition: width .2s ease;
|
||||
}
|
||||
}
|
||||
}
|
||||
.plyr--video .plyr__progress--buffer,
|
||||
.plyr--video .plyr__volume--display {
|
||||
background: $plyr-video-range-track-bg;
|
||||
}
|
||||
.plyr--video .plyr__progress--buffer {
|
||||
.plyr--video .plyr__progress--buffer {
|
||||
color: $plyr-video-progress-buffered-bg;
|
||||
}
|
||||
.plyr--audio .plyr__progress--buffer,
|
||||
@ -740,6 +744,10 @@
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.plyr__video-embed {
|
||||
// Revert overflow change
|
||||
overflow: visible;
|
||||
}
|
||||
.plyr__controls {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
|
Reference in New Issue
Block a user