Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6c251794c8 | |||
| 76917751e3 | |||
| e75a9b89b0 | |||
| a0fe61011f | |||
| 84a1b03d7d | |||
| b9177e7892 | |||
| fd12247a62 | |||
| 20a71300a5 | |||
| 70c5b24678 | |||
| a87e87f93c | |||
| 1b54ff0ad3 | |||
| 3075e1eda2 | |||
| 8d1e014a40 | |||
| 0c52fe0c7c | |||
| bb25f8d02a | |||
| 42c955c5eb |
+1
-1
@@ -4,7 +4,7 @@
|
||||
"plyr.css": ["src/less/plyr.less"]
|
||||
},
|
||||
"sass": {
|
||||
"plyr.css": ["src/less/plyr.sass"]
|
||||
"plyr.css": ["src/sass/plyr.sass"]
|
||||
},
|
||||
"js": {
|
||||
"plyr.js": ["src/js/plyr.js"]
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# Changelog
|
||||
|
||||
## v1.5.5
|
||||
- Fixed controls.md example
|
||||
- Bug fix for docs error page
|
||||
- Bug fix for controls tooltips
|
||||
|
||||
## v1.5.4
|
||||
- Minor bug fix for clicking video to play/pause after source change
|
||||
|
||||
## v1.5.3
|
||||
- Minor bug fix for occasional display of 0:00 as the media duration
|
||||
|
||||
## v1.5.2
|
||||
- `handlers` option renamed to `listeners`
|
||||
- Added event listeners for all types to the plyr container (playback, fullscreen, captions etc - see docs)
|
||||
|
||||
+35
-35
@@ -46,64 +46,64 @@ You can include only the controls you need when specifying custom html.
|
||||
This is an example `html` option with all controls.
|
||||
|
||||
```javascript
|
||||
["<div class='player-controls'>",
|
||||
"<div class='player-progress'>",
|
||||
"<label for='seek{id}' class='sr-only'>Seek</label>",
|
||||
"<input id='seek{id}' class='player-progress-seek' type='range' min='0' max='100' step='0.5' value='0' data-player='seek'>",
|
||||
"<progress class='player-progress-played' max='100' value='0'>",
|
||||
["<div class='plyr__controls'>",
|
||||
"<div 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.5' value='0' data-plyr='seek'>",
|
||||
"<progress class='plyr__progress--played' max='100' value='0'>",
|
||||
"<span>0</span>% played",
|
||||
"</progress>",
|
||||
"<progress class='player-progress-buffer' max='100' value='0'>",
|
||||
"<progress class='plyr__progress--buffer' max='100' value='0'>",
|
||||
"<span>0</span>% buffered",
|
||||
"</progress>",
|
||||
"</div>",
|
||||
"<span class='player-controls-left'>",
|
||||
"<button type='button' data-player='restart'>",
|
||||
"<span class='plyr__controls--left'>",
|
||||
"<button type='button' data-plyr='restart'>",
|
||||
"<svg><use xlink:href='#icon-restart'></use></svg>",
|
||||
"<span class='sr-only'>Restart</span>",
|
||||
"<span class='plyr__sr-only'>Restart</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-player='rewind'>",
|
||||
"<button type='button' data-plyr='rewind'>",
|
||||
"<svg><use xlink:href='#icon-rewind'></use></svg>",
|
||||
"<span class='sr-only'>Rewind {seektime} secs</span>",
|
||||
"<span class='plyr__sr-only'>Rewind {seektime} secs</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-player='play'>",
|
||||
"<button type='button' data-plyr='play'>",
|
||||
"<svg><use xlink:href='#icon-play'></use></svg>",
|
||||
"<span class='sr-only'>Play</span>",
|
||||
"<span class='plyr__sr-only'>Play</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-player='pause'>",
|
||||
"<button type='button' data-plyr='pause'>",
|
||||
"<svg><use xlink:href='#icon-pause'></use></svg>",
|
||||
"<span class='sr-only'>Pause</span>",
|
||||
"<span class='plyr__sr-only'>Pause</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-player='fast-forward'>",
|
||||
"<button type='button' data-plyr='fast-forward'>",
|
||||
"<svg><use xlink:href='#icon-fast-forward'></use></svg>",
|
||||
"<span class='sr-only'>Forward {seektime} secs</span>",
|
||||
"<span class='plyr__sr-only'>Forward {seektime} secs</span>",
|
||||
"</button>",
|
||||
"<span class='player-time'>",
|
||||
"<span class='sr-only'>Current time</span>",
|
||||
"<span class='player-current-time'>00:00</span>",
|
||||
"<span class='plyr__time'>",
|
||||
"<span class='plyr__sr-only'>Current time</span>",
|
||||
"<span class='plyr__current-time'>00:00</span>",
|
||||
"</span>",
|
||||
"<span class='player-time'>",
|
||||
"<span class='sr-only'>Duration</span>",
|
||||
"<span class='player-duration'>00:00</span>",
|
||||
"<span class='plyr__time'>",
|
||||
"<span class='plyr__sr-only'>Duration</span>",
|
||||
"<span class='plyr__duration'>00:00</span>",
|
||||
"</span>",
|
||||
"</span>",
|
||||
"<span class='player-controls-right'>",
|
||||
"<button type='button' data-player='mute'>",
|
||||
"<svg class='icon-muted'><use xlink:href='#icon-muted'></use></svg>",
|
||||
"<span class='plyr__controls--right'>",
|
||||
"<button type='button' data-plyr='mute'>",
|
||||
"<svg class='icon--muted'><use xlink:href='#icon-muted'></use></svg>",
|
||||
"<svg><use xlink:href='#icon-volume'></use></svg>",
|
||||
"<span class='sr-only'>Toggle Mute</span>",
|
||||
"<span class='plyr__sr-only'>Toggle Mute</span>",
|
||||
"</button>",
|
||||
"<label for='volume{id}' class='sr-only'>Volume</label>",
|
||||
"<input id='volume{id}' class='player-volume' type='range' min='0' max='10' value='5' data-player='volume'>",
|
||||
"<button type='button' data-player='captions'>",
|
||||
"<svg class='icon-captions-on'><use xlink:href='#icon-captions-on'></use></svg>",
|
||||
"<label for='volume{id}' class='plyr__sr-only'>Volume</label>",
|
||||
"<input id='volume{id}' class='plyr__volume' type='range' min='0' max='10' value='5' data-plyr='volume'>",
|
||||
"<button type='button' data-plyr='captions'>",
|
||||
"<svg class='icon--captions-on'><use xlink:href='#icon-captions-on'></use></svg>",
|
||||
"<svg><use xlink:href='#icon-captions-off'></use></svg>",
|
||||
"<span class='sr-only'>Toggle Captions</span>",
|
||||
"<span class='plyr__sr-only'>Toggle Captions</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-player='fullscreen'>",
|
||||
"<svg class='icon-exit-fullscreen'><use xlink:href='#icon-exit-fullscreen'></use></svg>",
|
||||
"<button type='button' data-plyr='fullscreen'>",
|
||||
"<svg class='icon--exit-fullscreen'><use xlink:href='#icon-exit-fullscreen'></use></svg>",
|
||||
"<svg><use xlink:href='#icon-enter-fullscreen'></use></svg>",
|
||||
"<span class='sr-only'>Toggle Fullscreen</span>",
|
||||
"<span class='plyr__sr-only'>Toggle Fullscreen</span>",
|
||||
"</button>",
|
||||
"</span>",
|
||||
"</div>"].join("\n");
|
||||
|
||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -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,n=arguments.length;for(i=0;n>i;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",n=e.Element[i],s=Object,o=String[i].trim||function(){return this.replace(/^\s+|\s+$/g,"")},r=Array[i].indexOf||function(e){for(var t=0,i=this.length;i>t;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=o.call(e.getAttribute("class")||""),i=t?t.split(/\s+/):[],n=0,s=i.length;s>n;n++)this.push(i[n]);this._updateClassName=function(){e.setAttribute("class",this.toString())}},u=l[i]=[],p=function(){return new l(this)};if(a[i]=Error[i],u.item=function(e){return this[e]||null},u.contains=function(e){return e+="",-1!==c(this,e)},u.add=function(){var e,t=arguments,i=0,n=t.length,s=!1;do e=t[i]+"",-1===c(this,e)&&(this.push(e),s=!0);while(++i<n);s&&this._updateClassName()},u.remove=function(){var e,t,i=arguments,n=0,s=i.length,o=!1;do for(e=i[n]+"",t=c(this,e);-1!==t;)this.splice(t,1),o=!0,t=c(this,e);while(++n<s);o&&this._updateClassName()},u.toggle=function(e,t){e+="";var i=this.contains(e),n=i?t!==!0&&"remove":t!==!1&&"add";return n&&this[n](e),t===!0||t===!1?t:!i},u.toString=function(){return this.join(" ")},s.defineProperty){var d={get:p,enumerable:!0,configurable:!0};try{s.defineProperty(n,t,d)}catch(h){-2146823252===h.number&&(d.enumerable=!1,s.defineProperty(n,t,d))}}else s[i].__defineGetter__&&n.__defineGetter__(t,p)}}(self)),plyr.setup(".js-media-player",{debug:!0,title:"Video demo",tooltips:!0,captions:{defaultActive:!0},onSetup:function(){console.log("✓ Setup done")}}),shr.setup({count:{classname:"btn__count"}}),function(){function e(e,t,i){if(e)if(e.classList)e.classList[i?"add":"remove"](t);else{var n=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=n+(i?" "+t:"")}}function t(t){if(t in n){var o=document.querySelector(".js-media-player").plyr;switch(t){case n.video:o.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.0/example_captions_en.vtt","default":!0}]});break;case n.audio:o.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:o.source({type:"video",title:"View From A Blue Moon",sources:[{src:"bTqVqk7FSmY",type:"youtube"}]});break;case n.vimeo:o.source({type:"video",title:"View From A Blue Moon",sources:[{src:"143418951",type:"vimeo"}]})}s=t;for(var r=i.length-1;r>=0;r--)e(i[r].parentElement,"active",!1);e(document.querySelector('[data-source="'+t+'"]').parentElement,"active",!0)}}for(var i=document.querySelectorAll("[data-source]"),n={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},s=window.location.hash.replace("#",""),o=window.history&&window.history.pushState,r=i.length-1;r>=0;r--)i[r].addEventListener("click",function(){var e=this.getAttribute("data-source");t(e),o&&history.pushState({type:e},"","#"+e)});if(window.addEventListener("popstate",function(e){e.state&&"type"in e.state&&t(e.state.type)}),o){var a=!s.length;a&&(s=n.video),s in n&&history.replaceState({type:s},"",a?"":"#"+s),a||t(s)}}(),document.domain.indexOf("plyr.io")>-1&&(!function(e,t,i,n,s,o,r){e.GoogleAnalyticsObject=s,e[s]=e[s]||function(){(e[s].q=e[s].q||[]).push(arguments)},e[s].l=1*new Date,o=t.createElement(i),r=t.getElementsByTagName(i)[0],o.async=1,o.src=n,r.parentNode.insertBefore(o,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;s>i;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],n=Object,o=String[i].trim||function(){return this.replace(/^\s+|\s+$/g,"")},r=Array[i].indexOf||function(e){for(var t=0,i=this.length;i>t;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=o.call(e.getAttribute("class")||""),i=t?t.split(/\s+/):[],s=0,n=i.length;n>s;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+="",-1!==c(this,e)},u.add=function(){var e,t=arguments,i=0,s=t.length,n=!1;do e=t[i]+"",-1===c(this,e)&&(this.push(e),n=!0);while(++i<s);n&&this._updateClassName()},u.remove=function(){var e,t,i=arguments,s=0,n=i.length,o=!1;do for(e=i[s]+"",t=c(this,e);-1!==t;)this.splice(t,1),o=!0,t=c(this,e);while(++s<n);o&&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(" ")},n.defineProperty){var p={get:d,enumerable:!0,configurable:!0};try{n.defineProperty(s,t,p)}catch(h){-2146823252===h.number&&(p.enumerable=!1,n.defineProperty(s,t,p))}}else n[i].__defineGetter__&&s.__defineGetter__(t,d)}}(self)),plyr.setup(".js-media-player",{debug:!0,title:"Video demo",tooltips:!0,captions:{defaultActive:!0}}),shr.setup({count:{classname:"btn__count"}}),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){if(t in s&&t!=n&&(n.length||t!=s.video)){var o=document.querySelector(".js-media-player").plyr;switch(t){case s.video:o.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.vtt","default":!0}]});break;case s.audio:o.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 s.youtube:o.source({type:"video",title:"View From A Blue Moon",sources:[{src:"bTqVqk7FSmY",type:"youtube"}]});break;case s.vimeo:o.source({type:"video",title:"View From A Blue Moon",sources:[{src:"143418951",type:"vimeo"}]})}n=t;for(var r=i.length-1;r>=0;r--)e(i[r].parentElement,"active",!1);e(document.querySelector('[data-source="'+t+'"]').parentElement,"active",!0)}}for(var i=document.querySelectorAll("[data-source]"),s={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},n=window.location.hash.replace("#",""),o=window.history&&window.history.pushState,r=i.length-1;r>=0;r--)i[r].addEventListener("click",function(){var e=this.getAttribute("data-source");t(e),o&&history.pushState({type:e},"","#"+e)});if(window.addEventListener("popstate",function(e){e.state&&"type"in e.state&&t(e.state.type)}),o){var a=!n.length;a&&(n=s.video),n in s&&history.replaceState({type:n},"",a?"":"#"+n),a||t(n)}}(),document.domain.indexOf("plyr.io")>-1&&(!function(e,t,i,s,n,o,r){e.GoogleAnalyticsObject=n,e[n]=e[n]||function(){(e[n].q=e[n].q||[]).push(arguments)},e[n].l=1*new Date,o=t.createElement(i),r=t.getElementsByTagName(i)[0],o.async=1,o.src=s,r.parentNode.insertBefore(o,r)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),ga("create","UA-40881672-11","auto"),ga("send","pageview"));
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
<main>
|
||||
<h1>Doh.</h1>
|
||||
<p>Looks like something went wrong.</p>
|
||||
<a href="http://plyr.io" class="btn">Back to plyr.io</a>
|
||||
<a href="http://plyr.io" class="btn btn--primary">Back to plyr.io</a>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@
|
||||
<source src="https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.webm" type="video/webm">
|
||||
|
||||
<!-- Text track file -->
|
||||
<track kind="captions" label="English" srclang="en" src="https://cdn.selz.com/plyr/1.0/example_captions_en.vtt" default>
|
||||
<track kind="captions" label="English" srclang="en" src="https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.vtt" default>
|
||||
|
||||
<!-- Fallback for browsers that don't support the <video> element -->
|
||||
<a href="https://cdn.selz.com/plyr/1.0/movie.mp4">Download</a>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 171 KiB |
+8
-5
@@ -11,9 +11,6 @@ plyr.setup('.js-media-player', {
|
||||
tooltips: true,
|
||||
captions: {
|
||||
defaultActive: true
|
||||
},
|
||||
onSetup: function() {
|
||||
console.log('✓ Setup done');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -85,10 +82,13 @@ shr.setup({
|
||||
|
||||
// Set a new source
|
||||
function newSource(type) {
|
||||
if(!(type in types)) {
|
||||
|
||||
// Bail if new type isn't known, it's the current type, or current type is empty (video is default) and new type is video
|
||||
if(!(type in types) || type == currentType || (!currentType.length && type == types.video)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get plyr instance
|
||||
var player = document.querySelector('.js-media-player').plyr;
|
||||
|
||||
switch(type) {
|
||||
@@ -109,7 +109,7 @@ shr.setup({
|
||||
kind: 'captions',
|
||||
label: 'English',
|
||||
srclang:'en',
|
||||
src: 'https://cdn.selz.com/plyr/1.0/example_captions_en.vtt',
|
||||
src: 'https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.vtt',
|
||||
default: true
|
||||
}]
|
||||
});
|
||||
@@ -153,12 +153,15 @@ shr.setup({
|
||||
break;
|
||||
}
|
||||
|
||||
// Set the current type for next time
|
||||
currentType = type;
|
||||
|
||||
// Remove active classes
|
||||
for (var x = buttons.length - 1; x >= 0; x--) {
|
||||
toggleClass(buttons[x].parentElement, 'active', false);
|
||||
}
|
||||
|
||||
// Set active on parent
|
||||
toggleClass(document.querySelector('[data-source="'+ type +'"]').parentElement, 'active', true);
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -253,6 +253,7 @@ gulp.task("docs", function () {
|
||||
|
||||
// Upload error.html to cdn (as well as docs site)
|
||||
gulp.src([paths.docs.root + "error.html"])
|
||||
.pipe(replace(localpath, "https://" + aws.cdn.bucket + "/" + version))
|
||||
.pipe(gzip())
|
||||
.pipe(s3(aws.cdn, options.docs));
|
||||
});
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "plyr",
|
||||
"version": "1.5.2",
|
||||
"version": "1.5.5",
|
||||
"description": "A simple HTML5 media player using custom controls",
|
||||
"homepage": "http://plyr.io",
|
||||
"main": "gulpfile.js",
|
||||
|
||||
@@ -15,8 +15,9 @@ We wanted a lightweight, accessible and customizable media player that supports
|
||||
- **Semantic** - uses the *right* elements. `<input type="range">` for volume and `<progress>` for progress and well, `<button>`s for buttons. There's no `<span>` or `<a href="#">` button hacks
|
||||
- **Responsive** - as you'd expect these days
|
||||
- **HTML Video & Audio** - support for both formats
|
||||
- **[Embedded Video](#embeds)** - support for YouTube and Vimeo (beta)
|
||||
- **[Embedded Video](#embeds)** - support for YouTube and Vimeo video playback
|
||||
- **[API](#api)** - toggle playback, volume, seeking, and more
|
||||
- **[Universal events](#events)** - no messing around with Vimeo and YouTube APIs, all events are universal across formats
|
||||
- **[Fullscreen](#fullscreen)** - supports native fullscreen with fallback to "full window" modes
|
||||
- **i18n support** - support for internationalization of controls
|
||||
- **No dependencies** - written in "vanilla" JavaScript, no jQuery required
|
||||
@@ -39,7 +40,7 @@ If you have any cool ideas or features, please let me know by [creating an issue
|
||||
|
||||
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.5.2/plyr.js` to `https://cdn.plyr.io/1.5.2/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.5.5/plyr.js` to `https://cdn.plyr.io/1.5.5/plyr.js`
|
||||
|
||||
### Bower
|
||||
If bower is your thang, you can grab Plyr using:
|
||||
@@ -59,11 +60,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.5.2/plyr.css">
|
||||
<script src="https://cdn.plyr.io/1.5.2/plyr.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/1.5.5/plyr.css">
|
||||
<script src="https://cdn.plyr.io/1.5.5/plyr.js"></script>
|
||||
```
|
||||
|
||||
You can also access the `sprite.svg` file at `https://cdn.plyr.io/1.5.2/sprite.svg`.
|
||||
You can also access the `sprite.svg` file at `https://cdn.plyr.io/1.5.5/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.sass` file included in `/src` in your build to save a request.
|
||||
@@ -161,7 +162,7 @@ More info on CORS here:
|
||||
Here's an example of a default setup:
|
||||
|
||||
```html
|
||||
<script src="https://cdn.plyr.io/1.5.2/plyr.js"></script>
|
||||
<script src="https://cdn.plyr.io/1.5.5/plyr.js"></script>
|
||||
<script>plyr.setup();</script>
|
||||
```
|
||||
|
||||
@@ -276,10 +277,10 @@ Options must be passed as an object to the `setup()` method as above.
|
||||
<td>See <code>plyr.js</code> in <code>/src</code> for more info. You probably don't need to change any of these.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>handlers</code></td>
|
||||
<td><code>listeners</code></td>
|
||||
<td>Object</td>
|
||||
<td>—</td>
|
||||
<td>Allows early binding of handlers to Plyr's controls. See <code>controls</code> above for list of controls and see <code>plyr.js</code> in <code>/src</code> for more info.</td>
|
||||
<td>Allows early binding of event listeners to the controls. See <code>controls</code> above for list of controls and see <code>plyr.js</code> in <code>/src</code> for more info.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>classes</code></td>
|
||||
@@ -613,19 +614,19 @@ You can listen for events on the element you setup Plyr on. Some events only app
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/canplay" title="/en-US/docs/Web/Events/canplay">canplay</a></code></td>
|
||||
<td><code>canplay</code></td>
|
||||
<td>✔</td>
|
||||
<td>Sent when enough data is available that the media can be played, at least for a couple of frames. This corresponds to the <code>HAVE_ENOUGH_DATA</code> <code>readyState</code>.</td>
|
||||
<td>Sent when enough data is available that the media can be played, at least for a couple of frames. This corresponds to the <code>HAVE_ENOUGH_DATA</code> <code>readyState</code>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/canplaythrough" title="/en-US/docs/Web/Events/canplaythrough">canplaythrough</a></code></td>
|
||||
<td><code>canplaythrough</code></td>
|
||||
<td></td>
|
||||
<td>Sent when the ready state changes to <code>CAN_PLAY_THROUGH</code>, indicating that the entire media can be played without interruption, assuming the download rate remains at least at the current level. <strong>Note</strong>: Manually setting the <code>currentTime</code> will eventually fire a <code>canplaythrough</code> event in firefox. Other browsers might not fire this event.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/emptied" title="/en-US/docs/Web/Events/emptied">emptied</a></code></td>
|
||||
<td><code>emptied</code></td>
|
||||
<td>✔</td>
|
||||
<td>The media has become empty; for example, this event is sent if the media has already been loaded (or partially loaded), and the <a href="/En/XPCOM_Interface_Reference/NsIDOMHTMLMediaElement" class="internal" title="en/nsIDOMHTMLMediaElement"><code>load()</code></a> method is called to reload it.</td>
|
||||
<td>The media has become empty; for example, this event is sent if the media has already been loaded (or partially loaded), and the <code>load()</code> method is called to reload it.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>ended</code></td>
|
||||
@@ -635,70 +636,70 @@ You can listen for events on the element you setup Plyr on. Some events only app
|
||||
<tr>
|
||||
<td><code>error</code></td>
|
||||
<td>✔</td>
|
||||
<td>Sent when an error occurs. The element's <code>error</code> attribute contains more information. See <a href="/en-US/docs/Web/Guide/HTML/Using_HTML5_audio_and_video#Error_handling">Error handling</a> for details.</td>
|
||||
<td>Sent when an error occurs. The element's <code>error</code> attribute contains more information.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/loadeddata" title="/en-US/docs/Web/Events/loadeddata">loadeddata</a></code></td>
|
||||
<td><code>loadeddata/code></td>
|
||||
<td>✔</td>
|
||||
<td>The first frame of the media has finished loading.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/loadedmetadata" title="/en-US/docs/Web/Events/loadedmetadata">loadedmetadata</a></code></td>
|
||||
<td><code>loadedmetadata</code></td>
|
||||
<td>✔</td>
|
||||
<td>The media's metadata has finished loading; all attributes now contain as much useful information as they're going to.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/loadstart" title="/en-US/docs/Web/Events/loadstart">loadstart</a></code></td>
|
||||
<td><code>loadstart</code></td>
|
||||
<td>✔</td>
|
||||
<td>Sent when loading of the media begins.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/pause" title="/en-US/docs/Web/Events/pause">pause</a></code></td>
|
||||
<td><code>pause</code></td>
|
||||
<td></td>
|
||||
<td>Sent when playback is paused.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/play" title="/en-US/docs/Web/Events/play">play</a></code></td>
|
||||
<td><code>play</code></td>
|
||||
<td></td>
|
||||
<td>Sent when playback of the media starts after having been paused; that is, when playback is resumed after a prior <code>pause</code> event.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/playing" title="/en-US/docs/Web/Events/playing">playing</a></code></td>
|
||||
<td><code>playing</code></td>
|
||||
<td></td>
|
||||
<td>Sent when the media begins to play (either for the first time, after having been paused, or after ending and then restarting).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/progress" title="/en-US/docs/Web/Events/progress">progress</a></code></td>
|
||||
<td><code>progress</code></td>
|
||||
<td></td>
|
||||
<td>Sent periodically to inform interested parties of progress downloading the media. Information about the current amount of the media that has been downloaded is available in the media element's <code>buffered</code> attribute.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/seeked" title="/en-US/docs/Web/Events/seeked">seeked</a></code></td>
|
||||
<td><code>seeked</code></td>
|
||||
<td>✔</td>
|
||||
<td>Sent when a seek operation completes.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/seeking" title="/en-US/docs/Web/Events/seeking">seeking</a></code></td>
|
||||
<td><code>seeking</code></td>
|
||||
<td>✔</td>
|
||||
<td>Sent when a seek operation begins.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/stalled" title="/en-US/docs/Web/Events/stalled">stalled</a></code></td>
|
||||
<td><code>stalled</code></td>
|
||||
<td>✔</td>
|
||||
<td>Sent when the user agent is trying to fetch media data, but data is unexpectedly not forthcoming.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/timeupdate" title="/en-US/docs/Web/Events/timeupdate">timeupdate</a></code></td>
|
||||
<td><code>timeupdate</code></td>
|
||||
<td></td>
|
||||
<td>The time indicated by the element's <code>currentTime</code> attribute has changed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/volumechange" title="/en-US/docs/Web/Events/volumechange">volumechange</a></code></td>
|
||||
<td><code>volumechange</code></td>
|
||||
<td></td>
|
||||
<td>Sent when the audio volume changes (both when the volume is set and when the <code>muted</code> attribute is changed).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><a href="/en-US/docs/Web/Events/waiting" title="/en-US/docs/Web/Events/waiting">waiting</a></code></td>
|
||||
<td><code>waiting</code></td>
|
||||
<td>✔</td>
|
||||
<td>Sent when the requested operation (such as playback) is delayed pending the completion of another operation (such as a seek).</td>
|
||||
</tr>
|
||||
@@ -725,6 +726,8 @@ You can listen for events on the element you setup Plyr on. Some events only app
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
Details borrowed from: [https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events)
|
||||
|
||||
Here's an example of binding an event listener:
|
||||
|
||||
```javascript
|
||||
@@ -735,23 +738,7 @@ document.querySelector(".js-plyr").addEventListener("playing", function() {
|
||||
|
||||
## Embeds
|
||||
|
||||
Currently only YouTube is supported. Vimeo will be coming soon. Some HTML5 media events are triggered on the `media` property of the `plyr` object:
|
||||
- `play`
|
||||
- `pause`
|
||||
- `timeupdate`
|
||||
- `progress`
|
||||
|
||||
Due to the way the YouTube API works, the `timeupdate` and `progress` events are triggered by polling every 200ms so the event may trigger without an actual value change. Buffering progress is `media.buffered` in the `plyr` object. It is a a number between 0 and 1 that specifies the percentage of the video that the player shows as buffered.
|
||||
|
||||
```javascript
|
||||
document.querySelector(".js-plyr").plyr.media.addEventListener("play", function() {
|
||||
console.log("play");
|
||||
});
|
||||
```
|
||||
|
||||
The `.source()` API method can also be used but the video id must be passed as the argument.
|
||||
|
||||
Currently caption control is not supported but I will work on this.
|
||||
YouTube and Vimeo are currently supported and function much like a HTML5 video. Check the relevant documentation sections for any differences.
|
||||
|
||||
## Fullscreen
|
||||
|
||||
|
||||
+27
-21
@@ -1,6 +1,6 @@
|
||||
// ==========================================================================
|
||||
// Plyr
|
||||
// plyr.js v1.5.0
|
||||
// plyr.js v1.5.3
|
||||
// https://github.com/selz/plyr
|
||||
// License: The MIT License (MIT)
|
||||
// ==========================================================================
|
||||
@@ -46,7 +46,7 @@
|
||||
container: null,
|
||||
wrapper: '.plyr__controls'
|
||||
},
|
||||
labels: '[data-plyr] .sr-only, label .sr-only',
|
||||
labels: '[data-plyr]',
|
||||
buttons: {
|
||||
seek: '[data-plyr="seek"]',
|
||||
play: '[data-plyr="play"]',
|
||||
@@ -787,6 +787,9 @@
|
||||
else {
|
||||
plyr.captionsContainer.innerHTML = '';
|
||||
}
|
||||
|
||||
// Force redraw
|
||||
// var redraw = plyr.captionsContainer.offsetHeight;
|
||||
}
|
||||
|
||||
// Display captions container and button (for initialization)
|
||||
@@ -929,7 +932,7 @@
|
||||
|
||||
// Setup tooltips
|
||||
if (config.tooltips) {
|
||||
var labels = _getElements(config.selectors.labels);
|
||||
var labels = _getElements(config.selectors.labels + ' .' + config.classes.hidden);
|
||||
|
||||
for (var i = labels.length - 1; i >= 0; i--) {
|
||||
var label = labels[i];
|
||||
@@ -1472,6 +1475,9 @@
|
||||
// Display a cue, if there is one
|
||||
if (this.activeCues[0] && this.activeCues[0].hasOwnProperty('text')) {
|
||||
plyr.captionsContainer.appendChild(this.activeCues[0].getCueAsHTML().trim());
|
||||
|
||||
// Force redraw
|
||||
// var redraw = plyr.captionsContainer.offsetHeight;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -2320,22 +2326,6 @@
|
||||
|
||||
// Captions
|
||||
_on(plyr.buttons.captions, 'click', _toggleCaptions);
|
||||
|
||||
// Click video
|
||||
if (plyr.type === 'video' && config.click) {
|
||||
_on(plyr.videoContainer, 'click', function() {
|
||||
if (plyr.media.paused) {
|
||||
_play();
|
||||
}
|
||||
else if (plyr.media.ended) {
|
||||
_seek();
|
||||
_play();
|
||||
}
|
||||
else {
|
||||
_pause();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Listen for media events
|
||||
@@ -2347,7 +2337,7 @@
|
||||
_on(plyr.media, 'timeupdate', _seekManualCaptions);
|
||||
|
||||
// Display duration
|
||||
_on(plyr.media, 'loadedmetadata', _displayDuration);
|
||||
_on(plyr.media, 'durationchange loadedmetadata', _displayDuration);
|
||||
|
||||
// Handle the media finishing
|
||||
_on(plyr.media, 'ended', function() {
|
||||
@@ -2372,6 +2362,22 @@
|
||||
// Loading
|
||||
_on(plyr.media, 'waiting canplay seeked', _checkLoading);
|
||||
|
||||
// Click video
|
||||
if (plyr.type === 'video' && config.click) {
|
||||
_on(plyr.videoContainer, 'click', function() {
|
||||
if (plyr.media.paused) {
|
||||
_play();
|
||||
}
|
||||
else if (plyr.media.ended) {
|
||||
_seek();
|
||||
_play();
|
||||
}
|
||||
else {
|
||||
_pause();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Proxy events to container
|
||||
_on(plyr.media, config.events.join(' '), function(event) {
|
||||
_triggerEvent(plyr.container, event.type);
|
||||
@@ -2680,7 +2686,7 @@
|
||||
}));
|
||||
|
||||
// Custom event polyfill
|
||||
//
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
|
||||
(function () {
|
||||
function CustomEvent (event, params) {
|
||||
params = params || { bubbles: false, cancelable: false, detail: undefined };
|
||||
|
||||
Reference in New Issue
Block a user