From 9d109bf02dc6ae6bfe356bfe25c2acb8915c05dd Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Sat, 20 Aug 2016 18:02:02 +1000 Subject: [PATCH] Refactoring and bug fixing --- demo/dist/demo.css | 2 +- demo/dist/demo.js | 2 +- demo/index.html | 3 +- demo/src/js/main.js | 4 +- demo/src/less/components/base.less | 5 +- demo/src/less/components/examples.less | 5 - dist/plyr.js | 4 +- package.json | 2 +- readme.md | 5 - src/js/plyr.js | 655 ++++++++++++++----------- 10 files changed, 382 insertions(+), 305 deletions(-) diff --git a/demo/dist/demo.css b/demo/dist/demo.css index 302747cb..cf8073a7 100644 --- a/demo/dist/demo.css +++ b/demo/dist/demo.css @@ -1 +1 @@ -/*! normalize.css v2.1.3 | MIT License | git.io/normalize */a.logo,img,legend{border:0}a,h1,h2{color:#3498db}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,small,summary{display:block}body,figure,li,ul{margin:0}[hidden],template{display:none}li,nav ul,ul{list-style:none;padding:0}legend,li,nav ul,ul{padding:0}.btn__bar,sub,sup{position:relative}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}a{background:0 0;text-decoration:none;border-bottom:1px dotted currentColor;transition:background .3s ease,color .3s ease,border .3s ease}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}hr{box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}.btn__bar,nav li{white-space:nowrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}sub,sup{font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}svg:not(:root){overflow:hidden}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@-webkit-keyframes fade-in{0%{opacity:0}100%{opacity:1}}@keyframes fade-in{0%{opacity:0}100%{opacity:1}}@font-face{font-family:Avenir;src:url(//cdn.plyr.io/fonts/avenir-medium.woff2) format("woff2"),url(//cdn.plyr.io/fonts/avenir-medium.woff) format("woff");font-style:normal;font-weight:500}@font-face{font-family:Avenir;src:url(//cdn.plyr.io/fonts/avenir-bold.woff2) format("woff2"),url(//cdn.plyr.io/fonts/avenir-bold.woff) format("woff");font-style:normal;font-weight:700}html{font-size:100%;height:100%;background:fixed #f2f5f7}body{font-family:Avenir,"Helvetica Neue",Helvetica,Arial,sans-serif;line-height:1.5;text-align:center;color:#55646b;font-weight:500;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;padding:10px}h1,h2{letter-spacing:-.025em;margin:0 0 10px;line-height:1.2;font-weight:700}h1{font-size:64px;font-size:4rem}p,small{margin:0 0 20px}small{padding:0 10px;font-size:14px;font-size:.875rem}a:focus,a:hover{color:#343f4a;border-bottom-color:transparent}a:focus{outline:#343f4a dotted thin;outline-offset:1px}.color--vimeo{color:#19b7ed}.color--youtube{color:#cc181e}*,::after,::before{box-sizing:border-box}.btn__bar ul,nav li{display:inline-block}header{padding:20px;margin-bottom:20px}header p{font-size:18px;font-size:1.125rem}section{padding-bottom:20px}@media (min-width:480px){header{padding-top:60px;padding-bottom:60px}section{padding-bottom:40px}}.icon{fill:currentColor;width:18px;height:18px;vertical-align:-3px}.btn,.btn__count,.error main,video{vertical-align:middle}a svg,button svg,label svg{pointer-events:none}.btn .icon,a .icon{margin-right:10px}.btn:not(.btn-large) .icon{width:16px;height:16px}nav ul{margin:0;font-size:0}nav li{margin-top:10px;font-size:16px;font-size:1rem}nav li+li{margin-left:20px}.btn__bar{margin:0 auto 20px;max-width:1200px}.btn__bar::before{content:"";position:absolute;top:50%;left:0;right:0;height:1px;background:#dbe3e8}.btn__bar ul{position:relative;z-index:1;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn__bar li{margin:0}.btn__bar li:first-child .btn{border-radius:4px 0 0 4px}.btn__bar li:last-child .btn{border-radius:0 4px 4px 0}.btn__bar li+li .btn{margin-left:-1px}.btn__bar li.active .btn{position:relative;z-index:1}.btn__bar li.active .btn .icon{color:inherit}.btn__bar li.active+li .btn:hover{z-index:0}.btn__bar .btn{position:relative;display:block;border-radius:0}.btn__bar .btn:focus,.btn__bar .btn:hover{z-index:1}@media (min-width:560px){.btn__bar{margin-bottom:40px}}.btn,.btn__count{display:inline-block;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-weight:700}.btn{padding:10px 12px;background:linear-gradient(#f8fafb,#e9eef1);border:1px solid #cbd0d3;box-shadow:0 1px 1px rgba(0,0,0,.05);text-shadow:0 1px 1px #fff;color:#55646b;transition:background .1s ease,color .1s ease;font-size:14px;font-size:.875rem}.btn:focus,.btn:hover{border-color:#b5bcc0;color:#55646b;outline:0}.btn--large{padding:10px 20px;font-size:16px;font-size:1rem}.btn--primary,.btn__bar li.active .btn{background-image:linear-gradient(#3498db,#258cd1);background-color:#3498db;border-color:#217dbb;box-shadow:0 1px 1px rgba(0,0,0,.15);text-shadow:0 1px 1px rgba(0,0,0,.1);color:#fff}.btn--primary:focus,.btn--primary:hover{color:#fff;border-color:#196090}.btn--youtube .icon{color:#cc181e}.btn--vimeo .icon{color:#19b7ed}.btn--twitter .icon{color:#4BAAF4}.btn__count{position:relative;margin-left:10px;padding:10px 15px;background:#fff;border:1px solid #cbd0d3}.btn__count::before,.plyr__video-wrapper::after{content:"";position:absolute}.btn__count::before{display:block;width:8px;height:8px;left:1px;top:50%;margin-top:-4px;background:inherit;border:inherit;border-width:1px 0 0 1px;-webkit-transform:rotate(-45deg) translate(-50%,-50%);transform:rotate(-45deg) translate(-50%,-50%)}.error body,html.error{height:100%}.error body{width:100%;display:table;table-layout:fixed}.error main{display:table-cell;width:100%}section{margin:0 auto 20px;max-width:1200px}video{max-width:100%}.plyr{margin:0 auto;border-radius:6px}.plyr--audio{max-width:520px}.plyr__video-wrapper::after{pointer-events:none;top:0;bottom:0;left:0;right:0;border:1px solid rgba(0,0,0,.15);border-radius:inherit}.plyr__cite{display:none;margin-top:20px}.plyr__cite .icon{margin-right:5px}.plyr--audio~ul .plyr__cite--audio,.plyr--video:not(.plyr--youtube):not(.plyr--vimeo)~ul .plyr__cite--video,.plyr--vimeo~ul .plyr__cite--vimeo,.plyr--youtube~ul .plyr__cite--youtube{display:block} \ No newline at end of file +/*! normalize.css v2.1.3 | MIT License | git.io/normalize */a.logo,img,legend{border:0}a,h1,h2{color:#3498db}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,small,summary{display:block}body,figure,li,ul{margin:0}[hidden],template{display:none}li,nav ul,ul{list-style:none;padding:0}legend,li,nav ul,ul{padding:0}.btn__bar,sub,sup{position:relative}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}a{background:0 0;text-decoration:none;border-bottom:1px dotted currentColor;transition:background .3s ease,color .3s ease,border .3s ease}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}hr{box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}.btn__bar,nav li{white-space:nowrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}sub,sup{font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}svg:not(:root){overflow:hidden}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@-webkit-keyframes fade-in{0%{opacity:0}100%{opacity:1}}@keyframes fade-in{0%{opacity:0}100%{opacity:1}}@font-face{font-family:Avenir;src:url(//cdn.plyr.io/fonts/avenir-medium.woff2) format("woff2"),url(//cdn.plyr.io/fonts/avenir-medium.woff) format("woff");font-style:normal;font-weight:500}@font-face{font-family:Avenir;src:url(//cdn.plyr.io/fonts/avenir-bold.woff2) format("woff2"),url(//cdn.plyr.io/fonts/avenir-bold.woff) format("woff");font-style:normal;font-weight:700}html{font-size:100%;height:100%;background:fixed #f2f5f7}body{font-family:Avenir,"Helvetica Neue",Helvetica,Arial,sans-serif;line-height:1.5;text-align:center;color:#55646b;font-weight:500;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;padding:10px}h1,h2{letter-spacing:-.025em;margin:0 0 10px;line-height:1.2;font-weight:700}h1{font-size:64px;font-size:4rem}p,small{margin:0 0 20px}small{padding:0 10px;font-size:14px;font-size:.875rem}a:focus,a:hover{color:#343f4a;border-bottom-color:transparent}a:focus{outline:#343f4a dotted thin;outline-offset:1px}.color--vimeo{color:#19b7ed}.color--youtube{color:#cc181e}*,::after,::before{box-sizing:border-box}.btn__bar ul,nav li{display:inline-block}header{padding:20px;margin-bottom:20px}header p{font-size:18px;font-size:1.125rem}section{max-width:1200px;margin:0 auto 20px}@media (min-width:480px){header{padding-top:60px;padding-bottom:60px}section{margin-bottom:40px}}.icon{fill:currentColor;width:18px;height:18px;vertical-align:-3px}.btn,.btn__count,.error main,video{vertical-align:middle}a svg,button svg,label svg{pointer-events:none}.btn .icon,a .icon{margin-right:10px}.btn:not(.btn-large) .icon{width:16px;height:16px}nav ul{margin:0;font-size:0}nav li{margin-top:10px;font-size:16px;font-size:1rem}nav li+li{margin-left:20px}.btn__bar{margin:0 auto 20px;max-width:1200px}.btn__bar::before{content:"";position:absolute;top:50%;left:0;right:0;height:1px;background:#dbe3e8}.btn__bar ul{position:relative;z-index:1;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn__bar li{margin:0}.btn__bar li:first-child .btn{border-radius:4px 0 0 4px}.btn__bar li:last-child .btn{border-radius:0 4px 4px 0}.btn__bar li+li .btn{margin-left:-1px}.btn__bar li.active .btn{position:relative;z-index:1}.btn__bar li.active .btn .icon{color:inherit}.btn__bar li.active+li .btn:hover{z-index:0}.btn__bar .btn{position:relative;display:block;border-radius:0}.btn__bar .btn:focus,.btn__bar .btn:hover{z-index:1}@media (min-width:560px){.btn__bar{margin-bottom:40px}}.btn,.btn__count{display:inline-block;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-weight:700}.btn{padding:10px 12px;background:linear-gradient(#f8fafb,#e9eef1);border:1px solid #cbd0d3;box-shadow:0 1px 1px rgba(0,0,0,.05);text-shadow:0 1px 1px #fff;color:#55646b;transition:background .1s ease,color .1s ease;font-size:14px;font-size:.875rem}.btn:focus,.btn:hover{border-color:#b5bcc0;color:#55646b;outline:0}.btn--large{padding:10px 20px;font-size:16px;font-size:1rem}.btn--primary,.btn__bar li.active .btn{background-image:linear-gradient(#3498db,#258cd1);background-color:#3498db;border-color:#217dbb;box-shadow:0 1px 1px rgba(0,0,0,.15);text-shadow:0 1px 1px rgba(0,0,0,.1);color:#fff}.btn--primary:focus,.btn--primary:hover{color:#fff;border-color:#196090}.btn--youtube .icon{color:#cc181e}.btn--vimeo .icon{color:#19b7ed}.btn--twitter .icon{color:#4BAAF4}.btn__count{position:relative;margin-left:10px;padding:10px 15px;background:#fff;border:1px solid #cbd0d3}.btn__count::before,.plyr__video-wrapper::after{content:"";position:absolute}.btn__count::before{display:block;width:8px;height:8px;left:1px;top:50%;margin-top:-4px;background:inherit;border:inherit;border-width:1px 0 0 1px;-webkit-transform:rotate(-45deg) translate(-50%,-50%);transform:rotate(-45deg) translate(-50%,-50%)}.error body,html.error{height:100%}.error body{width:100%;display:table;table-layout:fixed}.error main{display:table-cell;width:100%}video{max-width:100%}.plyr{margin:0 auto;border-radius:6px}.plyr--audio{max-width:520px}.plyr__video-wrapper::after{pointer-events:none;top:0;bottom:0;left:0;right:0;border:1px solid rgba(0,0,0,.15);border-radius:inherit}.plyr__cite{display:none;margin-top:20px}.plyr__cite .icon{margin-right:5px}.plyr--audio~ul .plyr__cite--audio,.plyr--video:not(.plyr--youtube):not(.plyr--vimeo)~ul .plyr__cite--video,.plyr--vimeo~ul .plyr__cite--vimeo,.plyr--youtube~ul .plyr__cite--youtube{display:block} \ No newline at end of file diff --git a/demo/dist/demo.js b/demo/dist/demo.js index c30c1cd3..fdb89c46 100644 --- a/demo/dist/demo.js +++ b/demo/dist/demo.js @@ -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,o=arguments.length;for(i=0;o>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",o=e.Element[i],n=Object,s=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=s.call(e.getAttribute("class")||""),i=t?t.split(/\s+/):[],o=0,n=i.length;n>o;o++)this.push(i[o]);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,o=t.length,n=!1;do e=t[i]+"",-1===c(this,e)&&(this.push(e),n=!0);while(++i=0;a--)e(n[a].parentElement,"active",!1);e(document.querySelector('[data-source="'+t+'"]').parentElement,"active",!0)}}document.body.addEventListener("ready",function(e){console.log(e)});var i=plyr.setup({debug:!0,title:"Video demo",iconUrl:"../dist/plyr.svg",tooltips:{controls:!0},captions:{defaultActive:!0}});plyr.loadSprite("dist/demo.svg");for(var o=i[0].plyr,n=document.querySelectorAll("[data-source]"),s={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},r=window.location.hash.replace("#",""),a=window.history&&window.history.pushState,c=n.length-1;c>=0;c--)n[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=s.video),r in s&&history.replaceState({type:r},"",l?"":"#"+r),r!==s.video&&t(r,!0)}}(),document.domain.indexOf("plyr.io")>-1&&(!function(e,t,i,o,n,s,r){e.GoogleAnalyticsObject=n,e[n]=e[n]||function(){(e[n].q=e[n].q||[]).push(arguments)},e[n].l=1*new Date,s=t.createElement(i),r=t.getElementsByTagName(i)[0],s.async=1,s.src=o,r.parentNode.insertBefore(s,r)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),ga("create","UA-40881672-11","auto"),ga("send","pageview")); \ No newline at end of file +"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],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;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=n.call(e.getAttribute("class")||""),i=t?t.split(/\s+/):[],s=0,o=i.length;o>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,o=!1;do e=t[i]+"",-1===c(this,e)&&(this.push(e),o=!0);while(++i=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}});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")); \ No newline at end of file diff --git a/demo/index.html b/demo/index.html index 0c9b83af..d8ea6c2f 100644 --- a/demo/index.html +++ b/demo/index.html @@ -73,7 +73,8 @@ - + + diff --git a/demo/src/js/main.js b/demo/src/js/main.js index bdd7febe..3337df88 100644 --- a/demo/src/js/main.js +++ b/demo/src/js/main.js @@ -8,7 +8,7 @@ // General functions ;(function() { - document.body.addEventListener('ready', function(event) { console.log(event); }); + //document.body.addEventListener('ready', function(event) { console.log(event); }); // Setup the player var instances = plyr.setup({ @@ -25,7 +25,7 @@ plyr.loadSprite('dist/demo.svg'); // Plyr returns an array regardless - var player = instances[0].plyr; + var player = instances[0]; // Setup type toggle var buttons = document.querySelectorAll('[data-source]'), diff --git a/demo/src/less/components/base.less b/demo/src/less/components/base.less index c584b57e..502196cf 100644 --- a/demo/src/less/components/base.less +++ b/demo/src/less/components/base.less @@ -39,9 +39,10 @@ header { // Sections section { - padding-bottom: @padding-base; + max-width: @example-width-video; + margin: 0 auto @padding-base; @media (min-width: @screen-sm) { - padding-bottom: (@padding-base * 2); + margin-bottom: (@padding-base * 2); } } \ No newline at end of file diff --git a/demo/src/less/components/examples.less b/demo/src/less/components/examples.less index 8649c023..a9e72d21 100644 --- a/demo/src/less/components/examples.less +++ b/demo/src/less/components/examples.less @@ -2,11 +2,6 @@ // Examples // ========================================================================== -section { - margin: 0 auto @padding-base; - max-width: @example-width-video; -} - // For non supported browsers video { max-width: 100%; diff --git a/dist/plyr.js b/dist/plyr.js index fe051eda..f8d7208b 100644 --- a/dist/plyr.js +++ b/dist/plyr.js @@ -1,2 +1,2 @@ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=t(e,document):"function"==typeof define&&define.amd?define(null,function(){t(e,document)}):e.plyr=t(e,document)}("undefined"!=typeof window?window:this,function(e,t){"use strict";function n(){var e,n,r,s=navigator.userAgent,o=navigator.appName,a=""+parseFloat(navigator.appVersion),i=parseInt(navigator.appVersion,10),l=!1,u=!1,c=!1,p=!1;return-1!==navigator.appVersion.indexOf("Windows NT")&&-1!==navigator.appVersion.indexOf("rv:11")?(l=!0,o="IE",a="11"):-1!==(n=s.indexOf("MSIE"))?(l=!0,o="IE",a=s.substring(n+5)):-1!==(n=s.indexOf("Chrome"))?(c=!0,o="Chrome",a=s.substring(n+7)):-1!==(n=s.indexOf("Safari"))?(p=!0,o="Safari",a=s.substring(n+7),-1!==(n=s.indexOf("Version"))&&(a=s.substring(n+8))):-1!==(n=s.indexOf("Firefox"))?(u=!0,o="Firefox",a=s.substring(n+8)):(e=s.lastIndexOf(" ")+1)<(n=s.lastIndexOf("/"))&&(o=s.substring(e,n),a=s.substring(n+1),o.toLowerCase()==o.toUpperCase()&&(o=navigator.appName)),-1!==(r=a.indexOf(";"))&&(a=a.substring(0,r)),-1!==(r=a.indexOf(" "))&&(a=a.substring(0,r)),i=parseInt(""+a,10),isNaN(i)&&(a=""+parseFloat(navigator.appVersion),i=parseInt(navigator.appVersion,10)),{name:o,version:i,isIE:l,isFirefox:u,isChrome:c,isSafari:p,isIos:/(iPad|iPhone|iPod)/g.test(navigator.platform),isTouch:"ontouchstart"in t.documentElement}}function r(e,t){var n=e.media;if("video"==e.type)switch(t){case"video/webm":return!(!n.canPlayType||!n.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/no/,""));case"video/mp4":return!(!n.canPlayType||!n.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/,""));case"video/ogg":return!(!n.canPlayType||!n.canPlayType('video/ogg; codecs="theora"').replace(/no/,""))}else if("audio"==e.type)switch(t){case"audio/mpeg":return!(!n.canPlayType||!n.canPlayType("audio/mpeg;").replace(/no/,""));case"audio/ogg":return!(!n.canPlayType||!n.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/,""));case"audio/wav":return!(!n.canPlayType||!n.canPlayType('audio/wav; codecs="1"').replace(/no/,""))}return!1}function s(e){if(!t.querySelectorAll('script[src="'+e+'"]').length){var n=t.createElement("script");n.src=e;var r=t.getElementsByTagName("script")[0];r.parentNode.insertBefore(n,r)}}function o(e,t){return Array.prototype.indexOf&&-1!=e.indexOf(t)}function a(e,t,n){return e.replace(new RegExp(t.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g,"\\$1"),"g"),n)}function i(e,t){e.length||(e=[e]);for(var n=e.length-1;n>=0;n--){var r=n>0?t.cloneNode(!0):t,s=e[n],o=s.parentNode,a=s.nextSibling;return r.appendChild(s),a?o.insertBefore(r,a):o.appendChild(r),r}}function l(e){for(var t=e.parentNode;e.firstChild;)t.insertBefore(e.firstChild,e);t.removeChild(e)}function u(e){e&&e.parentNode.removeChild(e)}function c(e,t){e.insertBefore(t,e.firstChild)}function p(e,t){for(var n in t)e.setAttribute(n,L["boolean"](t[n])&&t[n]?"":t[n])}function d(e,n,r){var s=t.createElement(e);p(s,r),c(n,s)}function m(e){return e.replace(".","")}function f(e,t,n){if(e)if(e.classList)e.classList[n?"add":"remove"](t);else{var r=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=r+(n?" "+t:"")}}function y(e,t){return e?e.classList?e.classList.contains(t):new RegExp("(\\s|^)"+t+"(\\s|$)").test(e.className):!1}function b(e,n){var r=Element.prototype,s=r.matches||r.webkitMatchesSelector||r.mozMatchesSelector||r.msMatchesSelector||function(e){return-1!==[].indexOf.call(t.querySelectorAll(e),this)};return s.call(e,n)}function v(e,t,n,r){e&&k(e,t,n,!0,r)}function g(e,t,n,r){e&&k(e,t,n,!1,r)}function h(e,t,n,r,s){v(e,t,function(t){n&&n.apply(e,[t]),r.apply(e,[t])},s)}function k(e,t,n,r,s){var o=t.split(" ");if(L["boolean"](s)||(s=!1),e instanceof NodeList)for(var a=0;ar;r++){var s=e[r];for(var o in s)s[o]&&s[o].constructor&&s[o].constructor===Object?(t[o]=t[o]||{},_(t[o],s[o])):t[o]=s[o]}return t}}function S(){var e={supportsFullScreen:!1,isFullScreen:function(){return!1},requestFullScreen:function(){},cancelFullScreen:function(){},fullScreenEventName:"",element:null,prefix:""},n="webkit moz o ms khtml".split(" ");if(L.undefined(t.cancelFullScreen))for(var r=0,s=n.length;s>r;r++){if(e.prefix=n[r],!L.undefined(t[e.prefix+"CancelFullScreen"])){e.supportsFullScreen=!0;break}if(!L.undefined(t.msExitFullscreen)&&t.msFullscreenEnabled){e.prefix="ms",e.supportsFullScreen=!0;break}}else e.supportsFullScreen=!0;return e.supportsFullScreen&&(e.fullScreenEventName="ms"==e.prefix?"MSFullscreenChange":e.prefix+"fullscreenchange",e.isFullScreen=function(e){switch(L.undefined(e)&&(e=t.body),this.prefix){case"":return t.fullscreenElement==e;case"moz":return t.mozFullScreenElement==e;default:return t[this.prefix+"FullscreenElement"]==e}},e.requestFullScreen=function(e){return L.undefined(e)&&(e=t.body),""===this.prefix?e.requestFullScreen():e[this.prefix+("ms"==this.prefix?"RequestFullscreen":"RequestFullScreen")]()},e.cancelFullScreen=function(){return""===this.prefix?t.cancelFullScreen():t[this.prefix+("ms"==this.prefix?"ExitFullscreen":"CancelFullScreen")]()},e.element=function(){return""===this.prefix?t.fullscreenElement:t[this.prefix+"FullscreenElement"]}),e}function C(){var t={supported:function(){if(!("localStorage"in e))return!1;try{e.localStorage.setItem("___test","OK");var t=e.localStorage.getItem("___test");return e.localStorage.removeItem("___test"),"OK"===t}catch(n){return!1}return!1}()};return t}function E(b,k){function _(){k.debug&&e.console&&console.log.apply(console,arguments)}function E(){k.debug&&e.console&&console.warn.apply(console,arguments)}function I(){return{url:k.iconUrl,absolute:0===k.iconUrl.indexOf("http")||qe.browser.isIE}}function P(){var e=[],t=I(),n=(t.absolute?"":t.url)+"#"+k.iconPrefix;return o(k.controls,"play-large")&&e.push('"),e.push('
'),o(k.controls,"restart")&&e.push('"),o(k.controls,"rewind")&&e.push('"),o(k.controls,"play")&&e.push('",'"),o(k.controls,"fast-forward")&&e.push('"),o(k.controls,"progress")&&(e.push('','','','','',"0% "+k.i18n.buffered,""),k.tooltips.seek&&e.push('00:00'),e.push("")),o(k.controls,"current-time")&&e.push('',''+k.i18n.currentTime+"",'00:00',""),o(k.controls,"duration")&&e.push('',''+k.i18n.duration+"",'00:00',""),o(k.controls,"mute")&&e.push('"),o(k.controls,"volume")&&e.push('','",'','',""),o(k.controls,"captions")&&e.push('"),o(k.controls,"fullscreen")&&e.push('"),e.push("
"),e.join("")}function O(){if(qe.supported.full&&("audio"!=qe.type||k.fullscreen.allowAudio)&&k.fullscreen.enabled){var e=N.supportsFullScreen;e||k.fullscreen.fallback&&!W()?(_((e?"Native":"Fallback")+" fullscreen enabled"),f(qe.container,k.classes.fullscreen.enabled,!0)):_("Fullscreen not supported and fallback disabled"),qe.buttons&&qe.buttons.fullscreen&&T(qe.buttons.fullscreen,!1),Y()}}function j(){if("video"===qe.type){H(k.selectors.captions)||qe.videoContainer.insertAdjacentHTML("afterbegin",'
'),qe.usingTextTracks=!1,qe.media.textTracks&&(qe.usingTextTracks=!0);for(var e,t="",n=qe.media.childNodes,r=0;r=10||qe.browser.isFirefox&&qe.browser.version>=31)&&(_("Detected browser with known TextTrack issues - using manual fallback"),qe.usingTextTracks=!1),qe.usingTextTracks){_("TextTracks supported");for(var a=0;a ");for(var r=0;rqe.captions.length-1){qe.subcount=qe.captions.length-1;break}qe.media.currentTime.toFixed(1)>=n(qe.captions[qe.subcount][0])&&qe.media.currentTime.toFixed(1)<=r(qe.captions[qe.subcount][0])?(qe.currentCaption=qe.captions[qe.subcount][1],V(qe.currentCaption)):V()}}function R(){qe.buttons.captions&&(f(qe.container,k.classes.captions.enabled,!0),k.captions.defaultActive&&(f(qe.container,k.classes.captions.active,!0),T(qe.buttons.captions,!0)))}function D(e){return qe.container.querySelectorAll(e)}function H(e){return D(e)[0]}function W(){try{return e.self!==e.top}catch(t){return!0}}function Y(){function e(e){9===e.which&&qe.isFullscreen&&(e.target!==r||e.shiftKey?e.target===n&&e.shiftKey&&(e.preventDefault(),r.focus()):(e.preventDefault(),n.focus()))}var t=D("input:not([disabled]), button:not([disabled])"),n=t[0],r=t[t.length-1];v(qe.container,"keydown",e)}function X(e,t){if(L.string(t))d(e,qe.media,{src:t});else if(t.constructor===Array)for(var n=t.length-1;n>=0;n--)d(e,qe.media,t[n])}function B(){if(k.loadSprite){var e=I();e.absolute?(_("AJAX loading absolute SVG sprite"+(qe.browser.isIE?" (due to IE)":"")),F(e.url,"sprite-plyr")):_("Sprite will be used as external resource directly")}var n=k.html;_("Injecting custom controls"),n||(n=P()),n=a(n,"{seektime}",k.seekTime),n=a(n,"{id}",Math.floor(1e4*Math.random()));var r;if(null!==k.selectors.controls.container&&(r=k.selectors.controls.container,L.string(r)&&(r=t.querySelector(r))),L.htmlElement(r)||(r=qe.container),r.insertAdjacentHTML("beforeend",n),k.tooltips.controls)for(var s=D([k.selectors.controls.wrapper," ",k.selectors.labels," .",k.classes.hidden].join("")),o=s.length-1;o>=0;o--){var i=s[o];f(i,k.classes.hidden,!1),f(i,k.classes.tooltip,!0)}}function U(){try{return qe.controls=H(k.selectors.controls.wrapper),qe.buttons={},qe.buttons.seek=H(k.selectors.buttons.seek),qe.buttons.play=D(k.selectors.buttons.play),qe.buttons.pause=H(k.selectors.buttons.pause),qe.buttons.restart=H(k.selectors.buttons.restart),qe.buttons.rewind=H(k.selectors.buttons.rewind),qe.buttons.forward=H(k.selectors.buttons.forward),qe.buttons.fullscreen=H(k.selectors.buttons.fullscreen),qe.buttons.mute=H(k.selectors.buttons.mute),qe.buttons.captions=H(k.selectors.buttons.captions),qe.progress={},qe.progress.container=H(k.selectors.progress.container),qe.progress.buffer={},qe.progress.buffer.bar=H(k.selectors.progress.buffer),qe.progress.buffer.text=qe.progress.buffer.bar&&qe.progress.buffer.bar.getElementsByTagName("span")[0],qe.progress.played=H(k.selectors.progress.played),qe.progress.tooltip=qe.progress.container&&qe.progress.container.querySelector("."+k.classes.tooltip),qe.volume={},qe.volume.input=H(k.selectors.volume.input),qe.volume.display=H(k.selectors.volume.display),qe.duration=H(k.selectors.duration),qe.currentTime=H(k.selectors.currentTime),qe.seekTime=D(k.selectors.seekTime),!0}catch(e){return E("It looks like there is a problem with your controls HTML"),G(!0),!1}}function z(){f(qe.container,k.selectors.container.replace(".",""),qe.supported.full)}function G(e){e&&o(k.types.html5,qe.type)?qe.media.setAttribute("controls",""):qe.media.removeAttribute("controls")}function J(e){var t=k.i18n.play;if(!L.undefined(k.title)&&k.title.length&&(t+=", "+k.title),qe.supported.full&&qe.buttons.play)for(var n=qe.buttons.play.length-1;n>=0;n--)qe.buttons.play[n].setAttribute("aria-label",t);L.htmlElement(e)&&e.setAttribute("title",k.i18n.frameTitle.replace("{title}",k.title))}function K(){if(!qe.media)return void E("No media element found!");if(qe.supported.full&&(f(qe.container,k.classes.type.replace("{0}",qe.type),!0),o(k.types.embed,qe.type)&&f(qe.container,k.classes.type.replace("{0}","video"),!0),f(qe.container,k.classes.stopped,k.autoplay),f(qe.container,k.classes.isIos,qe.browser.isIos),f(qe.container,k.classes.isTouch,qe.browser.isTouch),"video"===qe.type)){var e=t.createElement("div");e.setAttribute("class",k.classes.videoWrapper),i(qe.media,e),qe.videoContainer=e}o(k.types.embed,qe.type)&&($(),qe.embedId=null)}function $(){for(var n=t.createElement("div"),r=qe.embedId,o=qe.type+"-"+Math.floor(1e4*Math.random()),a=D('[id^="'+qe.type+'-"]'),i=a.length-1;i>=0;i--)u(a[i]);if(f(qe.media,k.classes.videoWrapper,!0),f(qe.media,k.classes.embedWrapper,!0),"youtube"===qe.type)qe.media.appendChild(n),n.setAttribute("id",o),L.object(e.YT)?Z(r,n):(s(k.urls.youtube.api),e.onYouTubeReadyCallbacks=e.onYouTubeReadyCallbacks||[],e.onYouTubeReadyCallbacks.push(function(){Z(r,n)}),e.onYouTubeIframeAPIReady=function(){e.onYouTubeReadyCallbacks.forEach(function(e){e()})});else if("vimeo"===qe.type)if(qe.supported.full?qe.media.appendChild(n):n=qe.media,n.setAttribute("id",o),L.object(e.Vimeo))ee(r,n);else{s(k.urls.vimeo.api);var l=e.setInterval(function(){L.object(e.Vimeo)&&(e.clearInterval(l),ee(r,n))},50)}else if("soundcloud"===qe.type){var c=t.createElement("iframe");c.loaded=!1,v(c,"load",function(){c.loaded=!0}),p(c,{src:"https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/"+r,id:o}),n.appendChild(c),qe.media.appendChild(n),e.SC||s(k.urls.soundcloud.api);var d=e.setInterval(function(){e.SC&&c.loaded&&(e.clearInterval(d),te.call(c))},50)}}function Q(){qe.container.plyr.embed=qe.embed,qe.supported.full&&Ve(),J(H("iframe"))}function Z(t,n){"timer"in qe||(qe.timer={}),qe.embed=new e.YT.Player(n.id,{videoId:t,playerVars:{autoplay:k.autoplay?1:0,controls:qe.supported.full?0:1,rel:0,showinfo:0,iv_load_policy:3,cc_load_policy:k.captions.defaultActive?1:0,cc_lang_pref:"en",wmode:"transparent",modestbranding:1,disablekb:1,origin:"*"},events:{onError:function(e){w(qe.container,"error",!0,{code:e.data,embed:e.target})},onReady:function(t){var n=t.target;qe.media.play=function(){n.playVideo(),qe.media.paused=!1},qe.media.pause=function(){n.pauseVideo(),qe.media.paused=!0},qe.media.stop=function(){n.stopVideo(),qe.media.paused=!0},qe.media.duration=n.getDuration(),qe.media.paused=!0,qe.media.currentTime=n.getCurrentTime(),qe.media.muted=n.isMuted(),k.title=n.getVideoData().title,w(qe.media,"timeupdate"),e.clearInterval(qe.timer.buffering),qe.timer.buffering=e.setInterval(function(){qe.media.buffered=n.getVideoLoadedFraction(),w(qe.media,"progress"),1===qe.media.buffered&&(e.clearInterval(qe.timer.buffering),w(qe.media,"canplaythrough"))},200),Q(),_e()},onStateChange:function(t){var n=t.target;switch(e.clearInterval(qe.timer.playing),t.data){case 0:qe.media.paused=!0,w(qe.media,"ended");break;case 1:qe.media.paused=!1,qe.media.seeking=!1,w(qe.media,"play"),w(qe.media,"playing"),qe.timer.playing=e.setInterval(function(){qe.media.currentTime=n.getCurrentTime(),w(qe.media,"timeupdate")},100);break;case 2:qe.media.paused=!0,w(qe.media,"pause")}w(qe.container,"statechange",!1,{code:t.data})}}})}function ee(t,n){qe.embed=new e.Vimeo.Player(n.id,{id:t,loop:k.loop,autoplay:k.autoplay,byline:!1,portrait:!1,title:!1}),qe.media.play=function(){qe.embed.play(),qe.media.paused=!1},qe.media.pause=function(){qe.embed.pause(),qe.media.paused=!0},qe.media.stop=function(){qe.embed.stop(),qe.media.paused=!0},qe.media.paused=!0,qe.media.currentTime=0,Q(),qe.embed.getCurrentTime().then(function(e){qe.media.currentTime=e,w(qe.media,"timeupdate")}),qe.embed.getDuration().then(function(e){qe.media.duration=e,_e()}),qe.embed.on("loaded",function(){L.htmlElement(qe.embed.element)&&qe.embed.element.setAttribute("tabindex","-1")}),qe.embed.on("play",function(){qe.media.paused=!1,w(qe.media,"play"),w(qe.media,"playing")}),qe.embed.on("pause",function(){qe.media.paused=!0,w(qe.media,"pause")}),qe.embed.on("timeupdate",function(e){qe.media.seeking=!1,qe.media.currentTime=e.seconds,w(qe.media,"timeupdate")}),qe.embed.on("progress",function(e){qe.media.buffered=e.percent,w(qe.media,"progress"),1===parseInt(e.percent)&&w(qe.media,"canplaythrough")}),qe.embed.on("ended",function(){qe.media.paused=!0,w(qe.media,"ended")})}function te(){qe.embed=e.SC.Widget(this),qe.embed.bind(e.SC.Widget.Events.READY,function(){qe.media.play=function(){qe.embed.play(),qe.media.paused=!1},qe.media.pause=function(){qe.embed.pause(),qe.media.paused=!0},qe.media.stop=function(){qe.embed.seekTo(0),qe.embed.pause(),qe.media.paused=!0},qe.media.paused=!0,qe.media.currentTime=0,Q(),qe.embed.getPosition(function(e){qe.media.currentTime=e,w(qe.media,"timeupdate")}),qe.embed.getDuration(function(e){qe.media.duration=e/1e3,_e()}),qe.embed.bind(e.SC.Widget.Events.PLAY,function(){qe.media.paused=!1,w(qe.media,"play"),w(qe.media,"playing")}),qe.embed.bind(e.SC.Widget.Events.PAUSE,function(){qe.media.paused=!0,w(qe.media,"pause")}),qe.embed.bind(e.SC.Widget.Events.PLAY_PROGRESS,function(e){qe.media.seeking=!1,qe.media.currentTime=e.currentPosition/1e3,w(qe.media,"timeupdate")}),qe.embed.bind(e.SC.Widget.Events.LOAD_PROGRESS,function(e){qe.media.buffered=e.loadProgress,w(qe.media,"progress"),1===parseInt(e.loadProgress)&&w(qe.media,"canplaythrough")}),qe.embed.bind(e.SC.Widget.Events.FINISH,function(){qe.media.paused=!0,w(qe.media,"ended")}),k.autoplay&&qe.embed.play()})}function ne(){"play"in qe.media&&qe.media.play()}function re(){"pause"in qe.media&&qe.media.pause()}function se(e){e===!0?ne():e===!1?re():qe.media[qe.media.paused?"play":"pause"]()}function oe(e){L.number(e)||(e=k.seekTime),ie(qe.media.currentTime-e)}function ae(e){L.number(e)||(e=k.seekTime),ie(qe.media.currentTime+e)}function ie(e){var t=0,n=qe.media.paused,r=le();L.number(e)?t=e:L.object(e)&&o(["input","change"],e.type)&&(t=e.target.value/e.target.max*r),0>t?t=0:t>r&&(t=r),Ce(t);try{qe.media.currentTime=t.toFixed(4)}catch(s){}if(o(k.types.embed,qe.type)){switch(qe.type){case"youtube":qe.embed.seekTo(t);break;case"vimeo":qe.embed.setCurrentTime(t.toFixed(0));break;case"soundcloud":qe.embed.seekTo(1e3*t)}n&&re(),w(qe.media,"timeupdate"),qe.media.seeking=!0}_("Seeking to "+qe.media.currentTime+" seconds"),q(t)}function le(){var e=parseInt(k.duration),t=0;return null===qe.media.duration||isNaN(qe.media.duration)||(t=qe.media.duration),isNaN(e)?t:e}function ue(){f(qe.container,k.classes.playing,!qe.media.paused),f(qe.container,k.classes.stopped,qe.media.paused),Fe(qe.media.paused)}function ce(){M={x:e.pageXOffset||0,y:e.pageYOffset||0}}function pe(){e.scrollTo(M.x,M.y)}function de(e){var n=N.supportsFullScreen;e&&e.type===N.fullScreenEventName?qe.isFullscreen=N.isFullScreen(qe.container):n?(N.isFullScreen(qe.container)?N.cancelFullScreen():(ce(),N.requestFullScreen(qe.container)),qe.isFullscreen=N.isFullScreen(qe.container)):(qe.isFullscreen=!qe.isFullscreen,qe.isFullscreen?(v(t,"keyup",me),t.body.style.overflow="hidden"):(g(t,"keyup",me),t.body.style.overflow="")),f(qe.container,k.classes.fullscreen.active,qe.isFullscreen),qe.isFullscreen?qe.container.setAttribute("tabindex","-1"):qe.container.removeAttribute("tabindex"),Y(qe.isFullscreen),qe.buttons&&qe.buttons.fullscreen&&T(qe.buttons.fullscreen,qe.isFullscreen),w(qe.container,qe.isFullscreen?"enterfullscreen":"exitfullscreen",!0),!qe.isFullscreen&&n&&pe()}function me(e){27===(e.which||e.charCode||e.keyCode)&&qe.isFullscreen&&de()}function fe(e){if(L["boolean"](e)||(e=!qe.media.muted),T(qe.buttons.mute,e),qe.media.muted=e,0===qe.media.volume&&ye(k.volume),o(k.types.embed,qe.type)){switch(qe.type){case"youtube":qe.embed[qe.media.muted?"mute":"unMute"]();break;case"vimeo":case"soundcloud":qe.embed.setVolume(qe.media.muted?0:parseFloat(k.volume/k.volumeMax))}w(qe.media,"volumechange")}}function ye(t){var n=k.volumeMax,r=k.volumeMin;if(L.undefined(t)&&(t=k.volume,k.storage.enabled&&C().supported&&(t=e.localStorage.getItem(k.storage.key),e.localStorage.removeItem("plyr-volume"))),(null===t||isNaN(t))&&(t=k.volume),t>n&&(t=n),r>t&&(t=r),qe.media.volume=parseFloat(t/n),qe.volume.display&&(qe.volume.display.value=t),o(k.types.embed,qe.type)){switch(qe.type){case"youtube":qe.embed.setVolume(100*qe.media.volume);break;case"vimeo":case"soundcloud":qe.embed.setVolume(qe.media.volume)}w(qe.media,"volumechange")}qe.media.muted&&t>0&&fe()}function be(){var e=qe.media.muted?0:qe.media.volume*k.volumeMax;ye(e+k.volumeStep/5)}function ve(){var e=qe.media.muted?0:qe.media.volume*k.volumeMax;ye(e-k.volumeStep/5)}function ge(){var t=qe.media.muted?0:qe.media.volume*k.volumeMax;qe.supported.full&&(qe.volume.input&&(qe.volume.input.value=t),qe.volume.display&&(qe.volume.display.value=t)),k.storage.enabled&&C().supported&&!isNaN(t)&&e.localStorage.setItem(k.storage.key,t),f(qe.container,k.classes.muted,0===t),qe.supported.full&&qe.buttons.mute&&T(qe.buttons.mute,0===t)}function he(e){qe.supported.full&&qe.buttons.captions&&(L["boolean"](e)||(e=-1===qe.container.className.indexOf(k.classes.captions.active)),qe.captionsEnabled=e,T(qe.buttons.captions,qe.captionsEnabled),f(qe.container,k.classes.captions.active,qe.captionsEnabled),w(qe.container,qe.captionsEnabled?"captionsenabled":"captionsdisabled",!0))}function ke(e){var t="waiting"===e.type;clearTimeout(qe.timers.loading),qe.timers.loading=setTimeout(function(){f(qe.container,k.classes.loading,t)},t?250:0)}function we(e){if(qe.supported.full){var t=qe.progress.played,n=0,r=le();if(e)switch(e.type){case"timeupdate":case"seeking":if(qe.controls.pressed)return;n=x(qe.media.currentTime,r),"timeupdate"==e.type&&qe.buttons.seek&&(qe.buttons.seek.value=n);break;case"playing":case"progress":t=qe.progress.buffer,n=function(){var e=qe.media.buffered;return e&&e.length?x(e.end(0),r):L.number(e)?100*e:0}()}Te(t,n)}}function Te(e,t){if(qe.supported.full){if(L.undefined(t)&&(t=0),L.undefined(e)){if(!qe.progress||!qe.progress.buffer)return;e=qe.progress.buffer}L.htmlElement(e)?e.value=t:e&&(e.bar&&(e.bar.value=t),e.text&&(e.text.innerHTML=t))}}function xe(e,t){if(t){isNaN(e)&&(e=0),qe.secs=parseInt(e%60),qe.mins=parseInt(e/60%60),qe.hours=parseInt(e/60/60%60);var n=parseInt(le()/60/60%60)>0;qe.secs=("0"+qe.secs).slice(-2),qe.mins=("0"+qe.mins).slice(-2),t.innerHTML=(n?qe.hours+":":"")+qe.mins+":"+qe.secs}}function _e(){if(qe.supported.full){var e=le()||0;!qe.duration&&k.displayDuration&&qe.media.paused&&xe(e,qe.currentTime),qe.duration&&xe(e,qe.duration),Ee()}}function Se(e){xe(qe.media.currentTime,qe.currentTime),e&&"timeupdate"==e.type&&qe.media.seeking||we(e)}function Ce(e){L.number(e)||(e=0);var t=le(),n=x(e,t);qe.progress&&qe.progress.played&&(qe.progress.played.value=n),qe.buttons&&qe.buttons.seek&&(qe.buttons.seek.value=n)}function Ee(e){var t=le();if(k.tooltips.seek&&qe.progress.container&&0!==t){var n=qe.progress.container.getBoundingClientRect(),r=0,s=k.classes.tooltip+"--visible";if(e)r=100/n.width*(e.pageX-n.left);else{if(!y(qe.progress.tooltip,s))return;r=qe.progress.tooltip.style.left.replace("%","")}0>r?r=0:r>100&&(r=100),xe(t/100*r,qe.progress.tooltip),qe.progress.tooltip.style.left=r+"%",e&&o(["mouseenter","mouseleave"],e.type)&&f(qe.progress.tooltip,s,"mouseenter"===e.type)}}function Fe(t){if(k.hideControls&&"audio"!==qe.type){var n=0,r=!1,s=t;if(L["boolean"](t)||(t&&t.type?(r="enterfullscreen"===t.type,s=o(["mousemove","touchstart","mouseenter","focus"],t.type),o(["mousemove","touchmove"],t.type)&&(n=2e3),"focus"===t.type&&(n=3e3)):s=y(qe.container,k.classes.hideControls)),e.clearTimeout(qe.timers.hover),s||qe.media.paused){if(f(qe.container,k.classes.hideControls,!1),qe.media.paused)return;qe.browser.isTouch&&(n=3e3)}s&&qe.media.paused||(qe.timers.hover=e.setTimeout(function(){(!qe.controls.pressed&&!qe.controls.hover||r)&&f(qe.container,k.classes.hideControls,!0)},n))}}function Ae(e){if(!L.undefined(e))return void Ie(e);var t;switch(qe.type){case"youtube":t=qe.embed.getVideoUrl();break;case"vimeo":qe.embed.getVideoUrl.then(function(e){t=e});break;case"soundcloud":qe.embed.getCurrentSound(function(e){t=e.permalink_url});break;default:t=qe.media.currentSrc}return t||""}function Ie(n){if(!(L.object(n)&&"sources"in n&&n.sources.length))return void E("Invalid source format");if(re(),Ce(),Te(),Le(),"youtube"===qe.type?(qe.embed.destroy(),e.clearInterval(qe.timer.buffering),e.clearInterval(qe.timer.playing)):"video"===qe.type&&qe.videoContainer&&u(qe.videoContainer),qe.embed=null,u(qe.media),"type"in n&&(qe.type=n.type,"video"===qe.type)){var r=n.sources[0];"type"in r&&o(k.types.embed,r.type)&&(qe.type=r.type)}switch(qe.supported=A(qe.type),qe.type){case"video":qe.media=t.createElement("video");break;case"audio":qe.media=t.createElement("audio");break;case"youtube":case"vimeo":case"soundcloud":qe.media=t.createElement("div"),qe.embedId=n.sources[0].src}c(qe.container,qe.media),L["boolean"](n.autoplay)&&(k.autoplay=n.autoplay),o(k.types.html5,qe.type)&&(k.crossorigin&&qe.media.setAttribute("crossorigin",""),k.autoplay&&qe.media.setAttribute("autoplay",""),"poster"in n&&qe.media.setAttribute("poster",n.poster),k.loop&&qe.media.setAttribute("loop","")),qe.container.className=qe.originalClassName,f(qe.container,k.classes.fullscreen.active,qe.isFullscreen),f(qe.container,k.classes.captions.active,qe.captionsEnabled),z(),o(k.types.html5,qe.type)&&X("source",n.sources),K(),o(k.types.html5,qe.type)?("tracks"in n&&X("track",n.tracks),qe.media.load(),Ve(),_e()):o(k.types.embed,qe.type)&&!qe.supported.full&&Ve(),k.title=n.title,J(),qe.container.plyr.media=qe.media}function Ne(e){"video"===qe.type&&qe.media.setAttribute("poster",e)}function Me(){function n(){var e=qe.media.paused;e?ne():re();var t=qe.buttons[e?"play":"pause"],n=qe.buttons[e?"pause":"play"];if(n=n&&n.length>1?n[n.length-1]:n[0]){var r=y(t,k.classes.tabFocus);setTimeout(function(){n.focus(),r&&(f(t,k.classes.tabFocus,!1),f(n,k.classes.tabFocus,!0))},100)}}function r(){var e=t.activeElement;e&&e!=t.body?t.querySelector&&(e=t.querySelector(":focus")):e=null;for(var n in qe.buttons){var r=qe.buttons[n];if(L.nodeList(r))for(var s=0;s0)&&(t?ve():be()),(e.deltaY>0||e.deltaX<0)&&(t?be():ve())})}function Pe(){if(v(qe.media,"timeupdate seeking",Se),v(qe.media,"timeupdate",q),v(qe.media,"durationchange loadedmetadata",_e),v(qe.media,"ended",function(){"video"===qe.type&&V(),ue(),ie(0),_e(),"video"===qe.type&&k.showPosterOnEnd&&qe.media.load()}),v(qe.media,"progress playing",we), -v(qe.media,"volumechange",ge),v(qe.media,"play pause",ue),v(qe.media,"waiting canplay seeked",ke),k.clickToPlay&&"audio"!==qe.type){var e=H("."+k.classes.videoWrapper);if(!e)return;e.style.cursor="pointer",v(e,"click",function(){k.hideControls&&qe.browser.isTouch&&!qe.media.paused||(qe.media.paused?ne():qe.media.ended?(ie(),ne()):re())})}k.disableContextMenu&&v(qe.media,"contextmenu",function(e){e.preventDefault()}),v(qe.media,k.events.join(" "),function(e){w(qe.container,e.type,!0)})}function Le(){if(o(k.types.html5,qe.type)){for(var e=qe.media.querySelectorAll("source"),t=0;t1)for(var c=0;c=0;n--){var r=n>0?t.cloneNode(!0):t,s=e[n],o=s.parentNode,a=s.nextSibling;return r.appendChild(s),a?o.insertBefore(r,a):o.appendChild(r),r}}function l(e){e&&e.parentNode.removeChild(e)}function u(e,t){e.insertBefore(t,e.firstChild)}function c(e,t){for(var n in t)e.setAttribute(n,L["boolean"](t[n])&&t[n]?"":t[n])}function p(e,n,r){var s=t.createElement(e);c(s,r),u(n,s)}function d(e){return e.replace(".","")}function m(e,t,n){if(e)if(e.classList)e.classList[n?"add":"remove"](t);else{var r=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=r+(n?" "+t:"")}}function f(e,t){return e?e.classList?e.classList.contains(t):new RegExp("(\\s|^)"+t+"(\\s|$)").test(e.className):!1}function y(e,n){var r=Element.prototype,s=r.matches||r.webkitMatchesSelector||r.mozMatchesSelector||r.msMatchesSelector||function(e){return-1!==[].indexOf.call(t.querySelectorAll(e),this)};return s.call(e,n)}function b(e,t,n,r){e&&h(e,t,n,!0,r)}function v(e,t,n,r){e&&h(e,t,n,!1,r)}function g(e,t,n,r,s){b(e,t,function(t){n&&n.apply(e,[t]),r.apply(e,[t])},s)}function h(e,t,n,r,s){var o=t.split(" ");if(L["boolean"](s)||(s=!1),e instanceof NodeList)for(var a=0;ar;r++){var s=e[r];for(var o in s)s[o]&&s[o].constructor&&s[o].constructor===Object?(t[o]=t[o]||{},T(t[o],s[o])):t[o]=s[o]}return t}}function _(){var e={supportsFullScreen:!1,isFullScreen:function(){return!1},requestFullScreen:function(){},cancelFullScreen:function(){},fullScreenEventName:"",element:null,prefix:""},n="webkit moz o ms khtml".split(" ");if(L.undefined(t.cancelFullScreen))for(var r=0,s=n.length;s>r;r++){if(e.prefix=n[r],!L.undefined(t[e.prefix+"CancelFullScreen"])){e.supportsFullScreen=!0;break}if(!L.undefined(t.msExitFullscreen)&&t.msFullscreenEnabled){e.prefix="ms",e.supportsFullScreen=!0;break}}else e.supportsFullScreen=!0;return e.supportsFullScreen&&(e.fullScreenEventName="ms"==e.prefix?"MSFullscreenChange":e.prefix+"fullscreenchange",e.isFullScreen=function(e){switch(L.undefined(e)&&(e=t.body),this.prefix){case"":return t.fullscreenElement==e;case"moz":return t.mozFullScreenElement==e;default:return t[this.prefix+"FullscreenElement"]==e}},e.requestFullScreen=function(e){return L.undefined(e)&&(e=t.body),""===this.prefix?e.requestFullScreen():e[this.prefix+("ms"==this.prefix?"RequestFullscreen":"RequestFullScreen")]()},e.cancelFullScreen=function(){return""===this.prefix?t.cancelFullScreen():t[this.prefix+("ms"==this.prefix?"ExitFullscreen":"CancelFullScreen")]()},e.element=function(){return""===this.prefix?t.fullscreenElement:t[this.prefix+"FullscreenElement"]}),e}function S(){var t={supported:function(){if(!("localStorage"in e))return!1;try{e.localStorage.setItem("___test","OK");var t=e.localStorage.getItem("___test");return e.localStorage.removeItem("___test"),"OK"===t}catch(n){return!1}return!1}()};return t}function E(y,h){function E(t,n){h.debug&&e.console&&(n=Array.prototype.slice.call(n),L.string(h.logPrefix)&&h.logPrefix.length&&n.unshift(h.logPrefix),console[t].apply(console,n))}function A(){return{url:h.iconUrl,absolute:0===h.iconUrl.indexOf("http")||Re.browser.isIE}}function I(){var e=[],t=A(),n=(t.absolute?"":t.url)+"#"+h.iconPrefix;return o(h.controls,"play-large")&&e.push('"),e.push('
'),o(h.controls,"restart")&&e.push('"),o(h.controls,"rewind")&&e.push('"),o(h.controls,"play")&&e.push('",'"),o(h.controls,"fast-forward")&&e.push('"),o(h.controls,"progress")&&(e.push('','','','','',"0% "+h.i18n.buffered,""),h.tooltips.seek&&e.push('00:00'),e.push("")),o(h.controls,"current-time")&&e.push('',''+h.i18n.currentTime+"",'00:00',""),o(h.controls,"duration")&&e.push('',''+h.i18n.duration+"",'00:00',""),o(h.controls,"mute")&&e.push('"),o(h.controls,"volume")&&e.push('','",'','',""),o(h.controls,"captions")&&e.push('"),o(h.controls,"fullscreen")&&e.push('"),e.push("
"),e.join("")}function M(){if(Re.supported.full&&("audio"!=Re.type||h.fullscreen.allowAudio)&&h.fullscreen.enabled){var e=N.supportsFullScreen;e||h.fullscreen.fallback&&!H()?(We((e?"Native":"Fallback")+" fullscreen enabled"),m(Re.container,h.classes.fullscreen.enabled,!0)):We("Fullscreen not supported and fallback disabled"),Re.buttons&&Re.buttons.fullscreen&&w(Re.buttons.fullscreen,!1),W()}}function O(){if("video"===Re.type){D(h.selectors.captions)||Re.videoContainer.insertAdjacentHTML("afterbegin",'
'),Re.usingTextTracks=!1,Re.media.textTracks&&(Re.usingTextTracks=!0);for(var e,t="",n=Re.media.childNodes,r=0;r=10||Re.browser.isFirefox&&Re.browser.version>=31)&&(We("Detected browser with known TextTrack issues - using manual fallback"),Re.usingTextTracks=!1),Re.usingTextTracks){We("TextTracks supported");for(var a=0;a ");for(var r=0;rRe.captions.length-1){Re.subcount=Re.captions.length-1;break}Re.media.currentTime.toFixed(1)>=n(Re.captions[Re.subcount][0])&&Re.media.currentTime.toFixed(1)<=r(Re.captions[Re.subcount][0])?(Re.currentCaption=Re.captions[Re.subcount][1],j(Re.currentCaption)):j()}}function q(){if(Re.buttons.captions){m(Re.container,h.classes.captions.enabled,!0);var e=Re.storage.captionsEnabled;L["boolean"](e)||(e=h.captions.defaultActive),e&&(m(Re.container,h.classes.captions.active,!0),w(Re.buttons.captions,!0))}}function R(e){return Re.container.querySelectorAll(e)}function D(e){return R(e)[0]}function H(){try{return e.self!==e.top}catch(t){return!0}}function W(){function e(e){9===e.which&&Re.isFullscreen&&(e.target!==r||e.shiftKey?e.target===n&&e.shiftKey&&(e.preventDefault(),r.focus()):(e.preventDefault(),n.focus()))}var t=R("input:not([disabled]), button:not([disabled])"),n=t[0],r=t[t.length-1];b(Re.container,"keydown",e)}function Y(e,t){if(L.string(t))p(e,Re.media,{src:t});else if(t.constructor===Array)for(var n=t.length-1;n>=0;n--)p(e,Re.media,t[n])}function B(){if(h.loadSprite){var e=A();e.absolute?(We("AJAX loading absolute SVG sprite"+(Re.browser.isIE?" (due to IE)":"")),C(e.url,"sprite-plyr")):We("Sprite will be used as external resource directly")}var n=h.html;We("Injecting custom controls"),n||(n=I()),n=a(n,"{seektime}",h.seekTime),n=a(n,"{id}",Math.floor(1e4*Math.random()));var r;if(L.string(h.selectors.controls.container)&&(r=t.querySelector(h.selectors.controls.container)),L.htmlElement(r)||(r=Re.container),r.insertAdjacentHTML("beforeend",n),h.tooltips.controls)for(var s=R([h.selectors.controls.wrapper," ",h.selectors.labels," .",h.classes.hidden].join("")),o=s.length-1;o>=0;o--){var i=s[o];m(i,h.classes.hidden,!1),m(i,h.classes.tooltip,!0)}}function X(){try{return Re.controls=D(h.selectors.controls.wrapper),Re.buttons={},Re.buttons.seek=D(h.selectors.buttons.seek),Re.buttons.play=R(h.selectors.buttons.play),Re.buttons.pause=D(h.selectors.buttons.pause),Re.buttons.restart=D(h.selectors.buttons.restart),Re.buttons.rewind=D(h.selectors.buttons.rewind),Re.buttons.forward=D(h.selectors.buttons.forward),Re.buttons.fullscreen=D(h.selectors.buttons.fullscreen),Re.buttons.mute=D(h.selectors.buttons.mute),Re.buttons.captions=D(h.selectors.buttons.captions),Re.progress={},Re.progress.container=D(h.selectors.progress.container),Re.progress.buffer={},Re.progress.buffer.bar=D(h.selectors.progress.buffer),Re.progress.buffer.text=Re.progress.buffer.bar&&Re.progress.buffer.bar.getElementsByTagName("span")[0],Re.progress.played=D(h.selectors.progress.played),Re.progress.tooltip=Re.progress.container&&Re.progress.container.querySelector("."+h.classes.tooltip),Re.volume={},Re.volume.input=D(h.selectors.volume.input),Re.volume.display=D(h.selectors.volume.display),Re.duration=D(h.selectors.duration),Re.currentTime=D(h.selectors.currentTime),Re.seekTime=R(h.selectors.seekTime),!0}catch(e){return Ye("It looks like there is a problem with your controls HTML"),J(!0),!1}}function U(){m(Re.container,h.selectors.container.replace(".",""),Re.supported.full)}function J(e){e&&o(h.types.html5,Re.type)?Re.media.setAttribute("controls",""):Re.media.removeAttribute("controls")}function z(e){var t=h.i18n.play;if(!L.undefined(h.title)&&h.title.length&&(t+=", "+h.title),Re.supported.full&&Re.buttons.play)for(var n=Re.buttons.play.length-1;n>=0;n--)Re.buttons.play[n].setAttribute("aria-label",t);L.htmlElement(e)&&e.setAttribute("title",h.i18n.frameTitle.replace("{title}",h.title))}function $(){var t=null;Re.storage={},S().supported&&h.storage.enabled&&(e.localStorage.removeItem("plyr-volume"),t=e.localStorage.getItem(h.storage.key),t&&(/^\d+(\.\d+)?$/.test(t)?G({volume:parseFloat(t)}):Re.storage=JSON.parse(t)))}function G(t){S().supported&&h.storage.enabled&&(T(Re.storage,t),e.localStorage.setItem(h.storage.key,JSON.stringify(Re.storage)))}function K(){if(!Re.media)return void Ye("No media element found!");if(Re.supported.full&&(m(Re.container,h.classes.type.replace("{0}",Re.type),!0),o(h.types.embed,Re.type)&&m(Re.container,h.classes.type.replace("{0}","video"),!0),m(Re.container,h.classes.stopped,h.autoplay),m(Re.ontainer,h.classes.isIos,Re.browser.isIos),m(Re.container,h.classes.isTouch,Re.browser.isTouch),"video"===Re.type)){var e=t.createElement("div");e.setAttribute("class",h.classes.videoWrapper),i(Re.media,e),Re.videoContainer=e}o(h.types.embed,Re.type)&&Q()}function Q(){for(var n=t.createElement("div"),r=Re.embedId,o=Re.type+"-"+Math.floor(1e4*Math.random()),a=R('[id^="'+Re.type+'-"]'),i=a.length-1;i>=0;i--)l(a[i]);if(m(Re.media,h.classes.videoWrapper,!0),m(Re.media,h.classes.embedWrapper,!0),"youtube"===Re.type)Re.media.appendChild(n),n.setAttribute("id",o),L.object(e.YT)?ee(r,n):(s(h.urls.youtube.api),e.onYouTubeReadyCallbacks=e.onYouTubeReadyCallbacks||[],e.onYouTubeReadyCallbacks.push(function(){ee(r,n)}),e.onYouTubeIframeAPIReady=function(){e.onYouTubeReadyCallbacks.forEach(function(e){e()})});else if("vimeo"===Re.type)if(Re.supported.full?Re.media.appendChild(n):n=Re.media,n.setAttribute("id",o),L.object(e.Vimeo))te(r,n);else{s(h.urls.vimeo.api);var u=e.setInterval(function(){L.object(e.Vimeo)&&(e.clearInterval(u),te(r,n))},50)}else if("soundcloud"===Re.type){var p=t.createElement("iframe");p.loaded=!1,b(p,"load",function(){p.loaded=!0}),c(p,{src:"https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/"+r,id:o}),n.appendChild(p),Re.media.appendChild(n),e.SC||s(h.urls.soundcloud.api);var d=e.setInterval(function(){e.SC&&p.loaded&&(e.clearInterval(d),ne.call(p))},50)}}function Z(){Re.supported.full&&qe(),z(D("iframe"))}function ee(t,n){Re.embed=new e.YT.Player(n.id,{videoId:t,playerVars:{autoplay:h.autoplay?1:0,controls:Re.supported.full?0:1,rel:0,showinfo:0,iv_load_policy:3,cc_load_policy:h.captions.defaultActive?1:0,cc_lang_pref:"en",wmode:"transparent",modestbranding:1,disablekb:1,origin:"*"},events:{onError:function(e){k(n,"error",!0,{code:e.data,embed:e.target})},onReady:function(t){var n=t.target;Re.media.play=function(){n.playVideo(),Re.media.paused=!1},Re.media.pause=function(){n.pauseVideo(),Re.media.paused=!0},Re.media.stop=function(){n.stopVideo(),Re.media.paused=!0},Re.media.duration=n.getDuration(),Re.media.paused=!0,Re.media.currentTime=n.getCurrentTime(),Re.media.muted=n.isMuted(),h.title=n.getVideoData().title,Z(),k(Re.media,"timeupdate"),e.clearInterval(De.buffering),De.buffering=e.setInterval(function(){Re.media.buffered=n.getVideoLoadedFraction(),(null===Re.media.lastBuffered||Re.media.lastBufferedt?t=0:t>r&&(t=r),Ce(t);try{Re.media.currentTime=t.toFixed(4)}catch(s){}if(o(h.types.embed,Re.type)){switch(Re.type){case"youtube":Re.embed.seekTo(t);break;case"vimeo":Re.embed.setCurrentTime(t.toFixed(0));break;case"soundcloud":Re.embed.seekTo(1e3*t)}n&&se(),k(Re.media,"timeupdate"),Re.media.seeking=!0}We("Seeking to "+Re.media.currentTime+" seconds"),V(t)}function ue(){var e=parseInt(h.duration),t=0;return null===Re.media.duration||isNaN(Re.media.duration)||(t=Re.media.duration),isNaN(e)?t:e}function ce(){m(Re.container,h.classes.playing,!Re.media.paused),m(Re.container,h.classes.stopped,Re.media.paused),Ae(Re.media.paused)}function pe(){P={x:e.pageXOffset||0,y:e.pageYOffset||0}}function de(){e.scrollTo(P.x,P.y)}function me(e){var n=N.supportsFullScreen;e&&e.type===N.fullScreenEventName?Re.isFullscreen=N.isFullScreen(Re.container):n?(N.isFullScreen(Re.container)?N.cancelFullScreen():(pe(),N.requestFullScreen(Re.container)),Re.isFullscreen=N.isFullScreen(Re.container)):(Re.isFullscreen=!Re.isFullscreen,Re.isFullscreen?(b(t,"keyup",fe),t.body.style.overflow="hidden"):(v(t,"keyup",fe),t.body.style.overflow="")),m(Re.container,h.classes.fullscreen.active,Re.isFullscreen),Re.isFullscreen?Re.container.setAttribute("tabindex","-1"):Re.container.removeAttribute("tabindex"),W(Re.isFullscreen),Re.buttons&&Re.buttons.fullscreen&&w(Re.buttons.fullscreen,Re.isFullscreen),k(Re.container,Re.isFullscreen?"enterfullscreen":"exitfullscreen",!0),!Re.isFullscreen&&n&&de()}function fe(e){27===(e.which||e.charCode||e.keyCode)&&Re.isFullscreen&&me()}function ye(e){if(L["boolean"](e)||(e=!Re.media.muted),w(Re.buttons.mute,e),Re.media.muted=e,0===Re.media.volume&&be(h.volume),o(h.types.embed,Re.type)){switch(Re.type){case"youtube":Re.embed[Re.media.muted?"mute":"unMute"]();break;case"vimeo":case"soundcloud":Re.embed.setVolume(Re.media.muted?0:parseFloat(h.volume/h.volumeMax))}k(Re.media,"volumechange")}}function be(e){var t=h.volumeMax,n=h.volumeMin;if(L.undefined(e)&&(e=Re.storage.volume),(null===e||isNaN(e))&&(e=h.volume),e>t&&(e=t),n>e&&(e=n),Re.media.volume=parseFloat(e/t),Re.volume.display&&(Re.volume.display.value=e),o(h.types.embed,Re.type)){switch(Re.type){case"youtube":Re.embed.setVolume(100*Re.media.volume);break;case"vimeo":case"soundcloud":Re.embed.setVolume(Re.media.volume)}k(Re.media,"volumechange")}Re.media.muted&&e>0&&ye()}function ve(){var e=Re.media.muted?0:Re.media.volume*h.volumeMax;be(e+h.volumeStep/5)}function ge(){var e=Re.media.muted?0:Re.media.volume*h.volumeMax;be(e-h.volumeStep/5)}function he(){var e=Re.media.muted?0:Re.media.volume*h.volumeMax;Re.supported.full&&(Re.volume.input&&(Re.volume.input.value=e),Re.volume.display&&(Re.volume.display.value=e)),G({volume:e}),m(Re.container,h.classes.muted,0===e),Re.supported.full&&Re.buttons.mute&&w(Re.buttons.mute,0===e)}function ke(e){Re.supported.full&&Re.buttons.captions&&(L["boolean"](e)||(e=-1===Re.container.className.indexOf(h.classes.captions.active)),Re.captionsEnabled=e,w(Re.buttons.captions,Re.captionsEnabled),m(Re.container,h.classes.captions.active,Re.captionsEnabled),k(Re.container,Re.captionsEnabled?"captionsenabled":"captionsdisabled",!0),G({captionsEnabled:Re.captionsEnabled}))}function we(e){var t="waiting"===e.type;clearTimeout(De.loading),De.loading=setTimeout(function(){m(Re.container,h.classes.loading,t)},t?250:0)}function xe(e){if(Re.supported.full){var t=Re.progress.played,n=0,r=ue();if(e)switch(e.type){case"timeupdate":case"seeking":if(Re.controls.pressed)return;n=x(Re.media.currentTime,r),"timeupdate"==e.type&&Re.buttons.seek&&(Re.buttons.seek.value=n);break;case"playing":case"progress":t=Re.progress.buffer,n=function(){var e=Re.media.buffered;return e&&e.length?x(e.end(0),r):L.number(e)?100*e:0}()}Te(t,n)}}function Te(e,t){if(Re.supported.full){if(L.undefined(t)&&(t=0),L.undefined(e)){if(!Re.progress||!Re.progress.buffer)return;e=Re.progress.buffer}L.htmlElement(e)?e.value=t:e&&(e.bar&&(e.bar.value=t),e.text&&(e.text.innerHTML=t))}}function _e(e,t){if(t){isNaN(e)&&(e=0),Re.secs=parseInt(e%60),Re.mins=parseInt(e/60%60),Re.hours=parseInt(e/60/60%60);var n=parseInt(ue()/60/60%60)>0;Re.secs=("0"+Re.secs).slice(-2),Re.mins=("0"+Re.mins).slice(-2),t.innerHTML=(n?Re.hours+":":"")+Re.mins+":"+Re.secs}}function Se(){if(Re.supported.full){var e=ue()||0;!Re.duration&&h.displayDuration&&Re.media.paused&&_e(e,Re.currentTime),Re.duration&&_e(e,Re.duration),Fe()}}function Ee(e){_e(Re.media.currentTime,Re.currentTime),e&&"timeupdate"==e.type&&Re.media.seeking||xe(e)}function Ce(e){L.number(e)||(e=0);var t=ue(),n=x(e,t);Re.progress&&Re.progress.played&&(Re.progress.played.value=n),Re.buttons&&Re.buttons.seek&&(Re.buttons.seek.value=n)}function Fe(e){var t=ue();if(h.tooltips.seek&&Re.progress.container&&0!==t){var n=Re.progress.container.getBoundingClientRect(),r=0,s=h.classes.tooltip+"--visible";if(e)r=100/n.width*(e.pageX-n.left);else{if(!f(Re.progress.tooltip,s))return;r=Re.progress.tooltip.style.left.replace("%","")}0>r?r=0:r>100&&(r=100),_e(t/100*r,Re.progress.tooltip),Re.progress.tooltip.style.left=r+"%",e&&o(["mouseenter","mouseleave"],e.type)&&m(Re.progress.tooltip,s,"mouseenter"===e.type)}}function Ae(t){if(h.hideControls&&"audio"!==Re.type&&f(Re.container,h.classes.ready)){var n=0,r=!1,s=t;if(L["boolean"](t)||(t&&t.type?(r="enterfullscreen"===t.type,s=o(["mousemove","touchstart","mouseenter","focus"],t.type),o(["mousemove","touchmove"],t.type)&&(n=2e3),"focus"===t.type&&(n=3e3)):s=f(Re.container,h.classes.hideControls)),e.clearTimeout(De.hover),s||Re.media.paused){if(m(Re.container,h.classes.hideControls,!1),Re.media.paused)return;Re.browser.isTouch&&(n=3e3)}s&&Re.media.paused||(De.hover=e.setTimeout(function(){(!Re.controls.pressed&&!Re.controls.hover||r)&&m(Re.container,h.classes.hideControls,!0)},n))}}function Ie(e){if(!L.undefined(e))return void Ne(e);var t;switch(Re.type){case"youtube":t=Re.embed.getVideoUrl();break;case"vimeo":Re.embed.getVideoUrl.then(function(e){t=e});break;case"soundcloud":Re.embed.getCurrentSound(function(e){t=e.permalink_url});break;default:t=Re.media.currentSrc}return t||""}function Ne(e){function n(){if(Re.embed=null,"video"===Re.type&&Re.videoContainer&&l(Re.videoContainer),l(Re.media),Re.container&&Re.container.removeAttribute("class"),"type"in e&&(Re.type=e.type,"video"===Re.type)){var n=e.sources[0];"type"in n&&o(h.types.embed,n.type)&&(Re.type=n.type)}switch(Re.supported=F(Re.type),Re.type){case"video":Re.media=t.createElement("video");break;case"audio":Re.media=t.createElement("audio");break;case"youtube":case"vimeo":case"soundcloud":Re.media=t.createElement("div"),Re.embedId=e.sources[0].src}u(Re.container,Re.media),L["boolean"](e.autoplay)&&(h.autoplay=e.autoplay),o(h.types.html5,Re.type)&&(h.crossorigin&&Re.media.setAttribute("crossorigin",""),h.autoplay&&Re.media.setAttribute("autoplay",""),"poster"in e&&Re.media.setAttribute("poster",e.poster),h.loop&&Re.media.setAttribute("loop","")),m(Re.container,h.classes.fullscreen.active,Re.isFullscreen),m(Re.container,h.classes.captions.active,Re.captionsEnabled),U(),o(h.types.html5,Re.type)&&Y("source",e.sources),K(),o(h.types.html5,Re.type)?("tracks"in e&&Y("track",e.tracks),Re.media.load(),qe(),Se()):o(h.types.embed,Re.type)&&!Re.supported.full&&qe(),h.title=e.title,z()}return L.object(e)&&"sources"in e&&e.sources.length?(se(),Ce(),Te(),Oe(),void je(n,!1)):void Ye("Invalid source format")}function Pe(e){"video"===Re.type&&Re.media.setAttribute("poster",e)}function Me(){function n(){var e=Re.media.paused;e?re():se();var t=Re.buttons[e?"play":"pause"],n=Re.buttons[e?"pause":"play"];if(n=n&&n.length>1?n[n.length-1]:n[0]){var r=f(t,h.classes.tabFocus);setTimeout(function(){n.focus(),r&&(m(t,h.classes.tabFocus,!1),m(n,h.classes.tabFocus,!0))},100)}}function r(){var e=t.activeElement;e&&e!=t.body?t.querySelector&&(e=t.querySelector(":focus")):e=null;for(var n in Re.buttons){var r=Re.buttons[n];if(L.nodeList(r))for(var s=0;s0)&&(t?ge():ve()),(e.deltaY>0||e.deltaX<0)&&(t?ve():ge())})}function Le(){if(b(Re.media,"timeupdate seeking",Ee),b(Re.media,"timeupdate",V),b(Re.media,"durationchange loadedmetadata",Se),b(Re.media,"ended",function(){"video"===Re.type&&j(), +ce(),le(0),Se(),"video"===Re.type&&h.showPosterOnEnd&&Re.media.load()}),b(Re.media,"progress playing",xe),b(Re.media,"volumechange",he),b(Re.media,"play pause",ce),b(Re.media,"waiting canplay seeked",we),h.clickToPlay&&"audio"!==Re.type){var e=D("."+h.classes.videoWrapper);if(!e)return;e.style.cursor="pointer",b(e,"click",function(){h.hideControls&&Re.browser.isTouch&&!Re.media.paused||(Re.media.paused?re():Re.media.ended?(le(),re()):se())})}h.disableContextMenu&&b(Re.media,"contextmenu",function(e){e.preventDefault()}),b(Re.media,h.events.join(" "),function(e){k(Re.container,e.type,!0)})}function Oe(){if(o(h.types.html5,Re.type)){for(var e=Re.media.querySelectorAll("source"),t=0;t— Destroys the plyr UI and any media event listeners, effectively restoring to the previous state before setup() was called. - - restore() - — - Reverses the effects of the destroy() method, restoring the UI and listeners. - getCurrentTime() — diff --git a/src/js/plyr.js b/src/js/plyr.js index f01866bd..96b4870e 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -35,7 +35,7 @@ autoplay: false, loop: false, seekTime: 10, - volume: 5, + volume: 10, volumeMin: 0, volumeMax: 10, volumeStep: 1, @@ -86,6 +86,8 @@ duration: '.plyr__time--duration' }, classes: { + setup: 'plyr--setup', + ready: 'plyr--ready', videoWrapper: 'plyr__video-wrapper', embedWrapper: 'plyr__video-embed', type: 'plyr--{0}', @@ -168,7 +170,9 @@ fullscreen: null }, // Events to watch on HTML5 media elements - events: ['ended', 'progress', 'stalled', 'playing', 'waiting', 'canplay', 'canplaythrough', 'loadstart', 'loadeddata', 'loadedmetadata', 'timeupdate', 'volumechange', 'play', 'pause', 'error', 'seeking', 'emptied'] + events: ['ended', 'progress', 'stalled', 'playing', 'waiting', 'canplay', 'canplaythrough', 'loadstart', 'loadeddata', 'loadedmetadata', 'timeupdate', 'volumechange', 'play', 'pause', 'error', 'seeking', 'emptied'], + // Logging + logPrefix: '[Plyr]' }; // Credits: http://paypal.github.io/accessible-html5-video-player/ @@ -346,7 +350,7 @@ // Unwrap an element // http://plainjs.com/javascript/manipulation/unwrap-a-dom-element-35/ - function _unwrap(wrapper) { + /*function _unwrap(wrapper) { // Get the element's parent node var parent = wrapper.parentNode; @@ -357,7 +361,7 @@ // Remove the empty element parent.removeChild(wrapper); - } + }*/ // Remove an element function _remove(element) { @@ -575,25 +579,28 @@ return input !== null && typeof(input) === 'object'; }, array: function(input) { - return input !== null && typeof(input) === 'object' && input.constructor === Array; + return input !== null && (typeof(input) === 'object' && input.constructor === Array); }, number: function(input) { - return typeof(input) === 'number' && !isNaN(input - 0) || (typeof input == 'object' && input.constructor === Number); + return input !== null && (typeof(input) === 'number' && !isNaN(input - 0) || (typeof input == 'object' && input.constructor === Number)); }, string: function(input) { - return typeof input === 'string' || (typeof input == 'object' && input.constructor === String); + return input !== null && (typeof input === 'string' || (typeof input == 'object' && input.constructor === String)); }, boolean: function(input) { - return typeof input === 'boolean'; + return input !== null && typeof input === 'boolean'; }, nodeList: function(input) { - return input instanceof NodeList; + return input !== null && input instanceof NodeList; }, htmlElement: function(input) { - return input instanceof HTMLElement; + return input !== null && input instanceof HTMLElement; + }, + function: function(input) { + return input !== null && typeof input === 'function'; }, undefined: function(input) { - return typeof input === 'undefined'; + return input !== null && typeof input === 'undefined'; } }; @@ -702,25 +709,31 @@ } // Player instance - function Plyr(container, config) { - var plyr = this; - plyr.container = container; - plyr.timers = {}; + function Plyr(media, config) { + var plyr = this, + timers = {}; - // Log config options - _log(config); + // Set media + plyr.media = media; + var original = media.cloneNode(true); // Debugging - function _log() { + function _console(type, args) { if (config.debug && window.console) { - console.log.apply(console, arguments); - } - } - function _warn() { - if (config.debug && window.console) { - console.warn.apply(console, arguments); + args = Array.prototype.slice.call(args); + + if (_is.string(config.logPrefix) && config.logPrefix.length) { + args.unshift(config.logPrefix); + } + + console[type].apply(console, args); } } + var _log = function() { _console('log', arguments) }, + _warn = function() { _console('warn', arguments) }; + + // Log config options + _log('Config', config); // Get icon URL function _getIconUrl() { @@ -1048,7 +1061,7 @@ _log('Successfully loaded the caption file via AJAX'); } else { - _warn('There was a problem loading the caption file via AJAX'); + _warn(config.logPrefix + 'There was a problem loading the caption file via AJAX'); } } }; @@ -1076,7 +1089,7 @@ } // Set the span content - if (_is.undefined(caption)) { + if (_is.string(caption)) { content.innerHTML = caption.trim(); } else { @@ -1279,24 +1292,20 @@ html = _replaceAll(html, '{id}', Math.floor(Math.random() * (10000))); // Controls container - var container; + var target; // Inject to custom location - if (config.selectors.controls.container !== null) { - container = config.selectors.controls.container; - - if (_is.string(container)) { - container = document.querySelector(container); - } + if (_is.string(config.selectors.controls.container)) { + target = document.querySelector(config.selectors.controls.container); } // Inject into the container by default - if (!_is.htmlElement(container)) { - container = plyr.container + if (!_is.htmlElement(target)) { + target = plyr.container } // Inject controls HTML - container.insertAdjacentHTML('beforeend', html); + target.insertAdjacentHTML('beforeend', html); // Setup tooltips if (config.tooltips.controls) { @@ -1475,7 +1484,7 @@ _toggleClass(plyr.container, config.classes.stopped, config.autoplay); // Add iOS class - _toggleClass(plyr.container, config.classes.isIos, plyr.browser.isIos); + _toggleClass(plyr.ontainer, config.classes.isIos, plyr.browser.isIos); // Add touch class _toggleClass(plyr.container, config.classes.isTouch, plyr.browser.isTouch); @@ -1497,9 +1506,6 @@ // Embeds if (_inArray(config.types.embed, plyr.type)) { _setupEmbed(); - - // Clean up - plyr.embedId = null; } } @@ -1611,9 +1617,6 @@ // When embeds are ready function _embedReady() { - // Store reference to API - plyr.container.plyr.embed = plyr.embed; - // Setup the UI if full support if (plyr.supported.full) { _setupInterface(); @@ -1625,12 +1628,6 @@ // Handle YouTube API ready function _youTubeReady(videoId, container) { - // Setup timers object - // We have to poll YouTube for updates - if (!('timer' in plyr)) { - plyr.timer = {}; - } - // Setup instance // https://developers.google.com/youtube/iframe_api_reference plyr.embed = new window.YT.Player(container.id, { @@ -1650,7 +1647,7 @@ }, events: { 'onError': function(event) { - _triggerEvent(plyr.container, 'error', true, { + _triggerEvent(container, 'error', true, { code: event.data, embed: event.target }); @@ -1680,32 +1677,37 @@ // Set title config.title = instance.getVideoData().title; + // Update UI + _embedReady(); + // Trigger timeupdate _triggerEvent(plyr.media, 'timeupdate'); // Reset timer - window.clearInterval(plyr.timer.buffering); + window.clearInterval(timers.buffering); // Setup buffering - plyr.timer.buffering = window.setInterval(function() { + timers.buffering = window.setInterval(function() { // Get loaded % from YouTube plyr.media.buffered = instance.getVideoLoadedFraction(); - // Trigger progress - _triggerEvent(plyr.media, 'progress'); + // Trigger progress only when we actually buffer something + if (plyr.media.lastBuffered === null || plyr.media.lastBuffered < plyr.media.buffered) { + _triggerEvent(plyr.media, 'progress'); + } + + // Set last buffer point + plyr.media.lastBuffered = plyr.media.buffered; // Bail if we're at 100% if (plyr.media.buffered === 1) { - window.clearInterval(plyr.timer.buffering); + window.clearInterval(timers.buffering); // Trigger event _triggerEvent(plyr.media, 'canplaythrough'); } }, 200); - // Update UI - _embedReady(); - // Display duration if available _displayDuration(); }, @@ -1714,7 +1716,7 @@ var instance = event.target; // Reset timer - window.clearInterval(plyr.timer.playing); + window.clearInterval(timers.playing); // Handle events // -1 Unstarted @@ -1736,7 +1738,7 @@ _triggerEvent(plyr.media, 'playing'); // Poll to get playback progress - plyr.timer.playing = window.setInterval(function() { + timers.playing = window.setInterval(function() { // Set the current time plyr.media.currentTime = instance.getCurrentTime(); @@ -1752,7 +1754,7 @@ break; } - _triggerEvent(plyr.container, 'statechange', false, { + _triggerEvent(container, 'statechange', false, { code: event.data }); } @@ -1786,13 +1788,14 @@ plyr.embed.stop(); plyr.media.paused = true; }; + plyr.media.paused = true; plyr.media.currentTime = 0; // Update UI _embedReady(); - plyr.embed.getCurrentTime().then(function (value) { + plyr.embed.getCurrentTime().then(function(value) { plyr.media.currentTime = value; // Trigger timeupdate @@ -1811,12 +1814,14 @@ plyr.embed.enableTextTrack('en'); }*/ - // Fix keyboard focus issues - // https://github.com/Selz/plyr/issues/317 plyr.embed.on('loaded', function() { + // Fix keyboard focus issues + // https://github.com/Selz/plyr/issues/317 if(_is.htmlElement(plyr.embed.element) && plyr.supported.full) { plyr.embed.element.setAttribute('tabindex', '-1'); } + + //console.log(plyr.embed); }); plyr.embed.on('play', function() { @@ -1858,7 +1863,7 @@ plyr.embed = window.SC.Widget(this); // Setup on ready - plyr.embed.bind(window.SC.Widget.Events.READY, function() { + 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(); @@ -1873,6 +1878,7 @@ plyr.embed.pause(); plyr.media.paused = true; }; + plyr.media.paused = true; plyr.media.currentTime = 0; @@ -2333,10 +2339,10 @@ var loading = (event.type === 'waiting'); // Clear timer - clearTimeout(plyr.timers.loading); + clearTimeout(timers.loading); // Timer to prevent flicker when seeking - plyr.timers.loading = setTimeout(function() { + timers.loading = setTimeout(function() { _toggleClass(plyr.container, config.classes.loading, loading); }, (loading ? 250 : 0)); } @@ -2566,7 +2572,8 @@ // Show the player controls in fullscreen mode function _toggleControls(toggle) { - if (!config.hideControls || plyr.type === 'audio') { + // Don't hide if config says not to, it's audio, or not loaded/ready + if (!config.hideControls || plyr.type === 'audio' || !_hasClass(plyr.container, config.classes.ready)) { return; } @@ -2599,7 +2606,7 @@ } // Clear timer every movement - window.clearTimeout(plyr.timers.hover); + window.clearTimeout(timers.hover); // If the mouse is not over the controls, set a timeout to hide them if (show || plyr.media.paused) { @@ -2619,7 +2626,7 @@ // 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) { - plyr.timers.hover = window.setTimeout(function() { + timers.hover = window.setTimeout(function() { // If the mouse is over the controls (and not entering fullscreen), bail if ((plyr.controls.pressed || plyr.controls.hover) && !isEnterFullscreen) { return; @@ -2685,129 +2692,125 @@ // Cancel current network requests _cancelRequests(); - // Clean up YouTube stuff - if (plyr.type === 'youtube') { - // Destroy the embed instance - plyr.embed.destroy(); + // Destroy instance adn wait for callback + // Vimeo throws a wobbly if you don't wait + _destroy(setup, false); - // Clear timer - 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); - } + // Setup new source + function setup() { + // Remove embed object + plyr.embed = null; - // Remove embed object - plyr.embed = null; + // Remove video container + if (plyr.type === 'video' && plyr.videoContainer) { + _remove(plyr.videoContainer); + } - // Remove the old media - _remove(plyr.media); + // Remove the old media + _remove(plyr.media); - // Set the type - if ('type' in source) { - plyr.type = source.type; + // Reset class name + if (plyr.container) { + plyr.container.removeAttribute('class'); + } - // Get child type for video (it might be an embed) - if (plyr.type === 'video') { - var firstSource = source.sources[0]; + // Set the type + if ('type' in source) { + plyr.type = source.type; - if ('type' in firstSource && _inArray(config.types.embed, firstSource.type)) { - plyr.type = firstSource.type; + // Get child type for video (it might be an embed) + if (plyr.type === 'video') { + var firstSource = source.sources[0]; + + if ('type' in firstSource && _inArray(config.types.embed, firstSource.type)) { + plyr.type = firstSource.type; + } } } - } - // Check for support - plyr.supported = supported(plyr.type); + // Check for support + plyr.supported = supported(plyr.type); - // Create new markup - switch(plyr.type) { - case 'video': - plyr.media = document.createElement('video'); - break; + // Create new markup + switch(plyr.type) { + case 'video': + plyr.media = document.createElement('video'); + break; - case 'audio': - plyr.media = document.createElement('audio'); - break; + case 'audio': + plyr.media = document.createElement('audio'); + break; - case 'youtube': - case 'vimeo': - case 'soundcloud': - plyr.media = document.createElement('div'); - plyr.embedId = source.sources[0].src; - break; - } - - // Inject the new element - _prependChild(plyr.container, plyr.media); - - // Autoplay the new source? - if (_is.boolean(source.autoplay)) { - config.autoplay = source.autoplay; - } - - // Set attributes for audio video - if (_inArray(config.types.html5, plyr.type)) { - if (config.crossorigin) { - plyr.media.setAttribute('crossorigin', ''); - } - if (config.autoplay) { - plyr.media.setAttribute('autoplay', ''); - } - if ('poster' in source) { - plyr.media.setAttribute('poster', source.poster); - } - if (config.loop) { - plyr.media.setAttribute('loop', ''); - } - } - - // Classname reset - plyr.container.className = plyr.originalClassName; - - // Restore class hooks - _toggleClass(plyr.container, config.classes.fullscreen.active, plyr.isFullscreen); - _toggleClass(plyr.container, config.classes.captions.active, plyr.captionsEnabled); - _toggleStyleHook(); - - // Set new sources for html5 - if (_inArray(config.types.html5, plyr.type)) { - _insertChildElements('source', source.sources); - } - - // Set up from scratch - _setupMedia(); - - // HTML5 stuff - if (_inArray(config.types.html5, plyr.type)) { - // Setup captions - if ('tracks' in source) { - _insertChildElements('track', source.tracks); + case 'youtube': + case 'vimeo': + case 'soundcloud': + plyr.media = document.createElement('div'); + plyr.embedId = source.sources[0].src; + break; } - // Load HTML5 sources - plyr.media.load(); + // Inject the new element + _prependChild(plyr.container, plyr.media); - // Setup interface - _setupInterface(); + // Autoplay the new source? + if (_is.boolean(source.autoplay)) { + config.autoplay = source.autoplay; + } - // Display duration if available - _displayDuration(); + // Set attributes for audio and video + if (_inArray(config.types.html5, plyr.type)) { + if (config.crossorigin) { + plyr.media.setAttribute('crossorigin', ''); + } + if (config.autoplay) { + plyr.media.setAttribute('autoplay', ''); + } + if ('poster' in source) { + plyr.media.setAttribute('poster', source.poster); + } + if (config.loop) { + plyr.media.setAttribute('loop', ''); + } + } + + // Restore class hooks + _toggleClass(plyr.container, config.classes.fullscreen.active, plyr.isFullscreen); + _toggleClass(plyr.container, config.classes.captions.active, plyr.captionsEnabled); + _toggleStyleHook(); + + // Set new sources for html5 + if (_inArray(config.types.html5, plyr.type)) { + _insertChildElements('source', source.sources); + } + + // Set up from scratch + _setupMedia(); + + // HTML5 stuff + if (_inArray(config.types.html5, plyr.type)) { + // Setup captions + if ('tracks' in source) { + _insertChildElements('track', source.tracks); + } + + // Load HTML5 sources + plyr.media.load(); + + // Setup interface + _setupInterface(); + + // Display duration if available + _displayDuration(); + } + // If embed but not fully supported, setupInterface now + else if (_inArray(config.types.embed, plyr.type) && !plyr.supported.full) { + _setupInterface(); + } + + // Set aria title and iframe title + config.title = source.title; + _setTitle(); } - // If embed but not fully supported, setupInterface now - else if (_inArray(config.types.embed, plyr.type) && !plyr.supported.full) { - _setupInterface(); - } - - // Set aria title and iframe title - config.title = source.title; - _setTitle(); - - // Reset media objects - plyr.container.plyr.media = plyr.media; } // Update poster @@ -3106,49 +3109,79 @@ plyr.media.load(); // Debugging - _log("Cancelled network requests for old media"); + _log('Cancelled network requests for old media'); } // Destroy an instance // Event listeners are removed when elements are removed // http://stackoverflow.com/questions/12528049/if-a-dom-element-is-removed-are-its-listeners-also-removed-from-memory - function _destroy() { + function _destroy(callback, restore) { // Bail if the element is not initialized if (!plyr.init) { return null; } - // Reset container classname - plyr.container.setAttribute('class', _getClassname(config.selectors.container)); + // Type specific stuff + switch (plyr.type) { + case 'youtube': + // Clear timers + window.clearInterval(timers.buffering); + window.clearInterval(timers.playing); - // Remove init flag - plyr.init = false; + // Destroy YouTube API + plyr.embed.destroy(); - // Remove controls - _remove(_getElement(config.selectors.controls.wrapper)); + // Clean up + cleanUp(); + + break; - // YouTube - if (plyr.type === 'youtube') { - plyr.embed.destroy(); - return; + case 'vimeo': + // Destroy Vimeo API + // then clean up (wait, to prevent postmessage errors) + plyr.embed.unload().then(cleanUp); + + // Vimeo does not always return + window.setTimeout(cleanUp, 200); + + break; + + case 'video': + case 'audio': + // Restore native video controls + _toggleNativeControls(true); + + // Clean up + cleanUp(); + + break; } - // If video, we need to remove some more - if (plyr.type === 'video') { - // Remove captions container - _remove(_getElement(config.selectors.captions)); + function cleanUp() { + // Default to restore original element + if (!_is.boolean(restore)) { + restore = true; + } - // Remove video wrapper - _unwrap(plyr.videoContainer); + // Callback + if (_is.function(callback)) { + callback.call(original); + } + + // Bail if we don't need to restore the original element + if (!restore) { + return; + } + + // Remove init flag + plyr.init = false; + + // Replace the container with the original element provided + plyr.container.parentNode.replaceChild(original, plyr.container); + + // Event + _triggerEvent(original, 'destroyed', true); } - - // Restore native video controls - _toggleNativeControls(true); - - // Clone the media element to remove listeners - // http://stackoverflow.com/questions/19469881/javascript-remove-all-event-listeners-of-specific-type - var clone = plyr.media.cloneNode(true); - plyr.media.parentNode.replaceChild(clone, plyr.media); } // Setup a player @@ -3164,71 +3197,54 @@ // Sniff out the browser plyr.browser = _browserSniff(); - // Get the media element - plyr.media = plyr.container.querySelectorAll('audio, video')[0]; - - // Get the div placeholder for YouTube and Vimeo - if (!plyr.media) { - plyr.media = plyr.container.querySelectorAll('[data-type]')[0]; - } - // Bail if nothing to setup - if (!plyr.media) { + if (!_is.htmlElement(plyr.media)) { return; } // Load saved settings from localStorage _setupStorage(); - // Get original classname - plyr.originalClassName = plyr.container.className; - // Set media type based on tag or data attribute // Supported: video, audio, vimeo, youtube - var tagName = plyr.media.tagName.toLowerCase(); + var tagName = media.tagName.toLowerCase(); if (tagName === 'div') { - plyr.type = plyr.media.getAttribute('data-type'); - plyr.embedId = plyr.media.getAttribute('data-video-id'); + plyr.type = media.getAttribute('data-type'); + plyr.embedId = media.getAttribute('data-video-id'); // Clean up - plyr.media.removeAttribute('data-type'); - plyr.media.removeAttribute('data-video-id'); + media.removeAttribute('data-type'); + media.removeAttribute('data-video-id'); } else { plyr.type = tagName; - config.crossorigin = (plyr.media.getAttribute('crossorigin') !== null); - config.autoplay = (config.autoplay || (plyr.media.getAttribute('autoplay') !== null)); - config.loop = (config.loop || (plyr.media.getAttribute('loop') !== null)); + config.crossorigin = (media.getAttribute('crossorigin') !== null); + config.autoplay = (config.autoplay || (media.getAttribute('autoplay') !== null)); + config.loop = (config.loop || (media.getAttribute('loop') !== null)); } // Check for support plyr.supported = supported(plyr.type); + // If no native support, bail + if (!plyr.supported.basic) { + return; + } + + // Wrap media + plyr.container = _wrap(media, document.createElement('div')); + // Add style hook _toggleStyleHook(); - // If no native support, bail - if (!plyr.supported.basic) { - return false; - } - // Debug info - _log(plyr.browser.name + ' ' + plyr.browser.version); + _log('' + plyr.browser.name + ' ' + plyr.browser.version); // Setup media _setupMedia(); // Setup interface if (_inArray(config.types.html5, plyr.type)) { - // Bail if no support - if (!plyr.supported.full) { - // Successful setup - plyr.init = true; - - // Don't inject controls if no full support - return; - } - // Setup UI _setupInterface(); @@ -3252,7 +3268,7 @@ function _setupInterface() { // Don't setup interface if no support if (!plyr.supported.full) { - _warn('No full support for this media type (' + plyr.type + ')'); + _warn('Basic support only', plyr.type); // Remove controls _remove(_getElement(config.selectors.controls.wrapper)); @@ -3311,6 +3327,9 @@ // Ready event _triggerEvent(plyr.container, 'ready', true); + + // Class + _toggleClass(plyr.container, config.classes.ready, true); } // Initialize instance @@ -3322,9 +3341,15 @@ } return { - media: plyr.media, + getContainer: function() { return plyr.container }, + getEmbed: function() { return plyr.embed; }, + getMedia: function() { return plyr.media; }, + getType: function() { return plyr.type; }, + isReady: function() { return _hasClass(plyr.container, config.classes.ready); }, + on: function(event, callback) { _on(plyr.container, event, callback); }, play: _play, pause: _pause, + stop: function() { _pause(); _seek(); }, restart: _seek, rewind: _rewind, forward: _forward, @@ -3340,8 +3365,7 @@ isFullscreen: function() { return plyr.isFullscreen || false; }, support: function(mimeType) { return _supportMime(plyr, mimeType); }, destroy: _destroy, - restore: _init, - getCurrentTime: function() { return plyr.media.currentTime; } + getCurrentTime: function() { return media.currentTime; } }; } @@ -3350,10 +3374,18 @@ var x = new XMLHttpRequest(); // If the id is set and sprite exists, bail - if (_is.string(id) && document.querySelector('#' + id) !== null) { + if (_is.string(id) && _is.htmlElement(document.querySelector('#' + id))) { return; } + // Create placeholder (to prevent loading twice) + var c = document.createElement('div'); + c.setAttribute('hidden', ''); + if (_is.string(id)) { + c.setAttribute('id', id); + } + document.body.insertBefore(c, document.body.childNodes[0]); + // Check for CORS support if ('withCredentials' in x) { x.open('GET', url, true); @@ -3364,13 +3396,7 @@ // Inject hidden div with sprite on load x.onload = function() { - var c = document.createElement('div'); - c.setAttribute('hidden', ''); - if (_is.string(id)) { - c.setAttribute('id', id); - } c.innerHTML = x.responseText; - document.body.insertBefore(c, document.body.childNodes[0]); } x.send(); @@ -3418,8 +3444,8 @@ // Setup function function setup(targets, options) { // Get the players - var elements = [], - containers = [], + var players = [], + instances = [], selector = [defaults.selectors.html5, defaults.selectors.embed].join(','); // Select the elements @@ -3453,6 +3479,20 @@ return false; } + // Add to container list + function add(target, media) { + if (!_hasClass(media, defaults.classes.hook)) { + players.push({ + // Always wrap in a
for styling + //container: _wrap(media, document.createElement('div')), + // Could be a container or the media itself + target: target, + // This should be the