diff --git a/changelog.md b/changelog.md index 46547433..9d42eb8d 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,11 @@ # Changelog +## v2.0.14 +- CDN URL updates. Sorry, still working on V3 as hard as I can... + +## v2.0.13 +- Repo moved and Vimeo demo fix + ## v2.0.12 - Ability to set custom `blankUrl` for source changes (https://github.com/sampotts/plyr/pull/504) - Ability to set caption button listener (https://github.com/sampotts/plyr/pull/468) diff --git a/demo/dist/demo.css b/demo/dist/demo.css index a9b2f5bc..392b0c17 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}@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;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 +/*! normalize.css v2.1.3 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden],template{display:none}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}a{background:0 0}a:focus{outline:thin dotted}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}hr{-webkit-box-sizing:content-box;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}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}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]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;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/static/fonts/avenir-medium.woff2) format("woff2"),url(//cdn.plyr.io/static/fonts/avenir-medium.woff) format("woff");font-style:normal;font-weight:500}@font-face{font-family:Avenir;src:url(//cdn.plyr.io/static/fonts/avenir-bold.woff2) format("woff2"),url(//cdn.plyr.io/static/fonts/avenir-bold.woff) format("woff");font-style:normal;font-weight:700}html{font-size:100%}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}h1,h2{letter-spacing:-.025em;color:#3498db;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{display:block;padding:0 10px;font-size:14px;font-size:.875rem}li,ul{list-style:none;margin:0;padding:0}a{text-decoration:none;color:#3498db;border-bottom:1px dotted currentColor;-webkit-transition:background .3s ease,color .3s ease,border .3s ease;transition:background .3s ease,color .3s ease,border .3s ease}a:focus,a:hover{color:#343f4a;border-bottom-color:transparent}a:focus{outline:thin dotted #343f4a;outline-offset:1px}a.logo{border:0}.color--vimeo{color:#19b7ed}.color--youtube{color:#cc181e}*,::after,::before{-webkit-box-sizing:border-box;box-sizing:border-box}[hidden]{display:none}html{height:100%;background:#f2f5f7 fixed}body{margin:0;padding:10px}header{padding:20px;margin-bottom:20px}header p{font-size:18px;font-size:1.125rem}@media (min-width:480px){header{padding-top:60px;padding-bottom:60px}}section{max-width:1200px;margin:0 auto 20px}@media (min-width:480px){section{margin-bottom:40px}}.icon{fill:currentColor;width:18px;height:18px;vertical-align:-3px}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{list-style:none;margin:0;padding:0;font-size:0}nav li{display:inline-block;margin-top:10px;font-size:16px;font-size:1rem;white-space:nowrap}nav li+li{margin-left:20px}.btn__bar{position:relative;margin:0 auto 20px;max-width:1200px;white-space:nowrap}.btn__bar::before{content:"";position:absolute;top:50%;left:0;right:0;height:1px;background:#dbe3e8}.btn__bar ul{position:relative;z-index:1;display:inline-block;-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{-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.2);box-shadow:inset 0 1px 1px rgba(0,0,0,.2);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;vertical-align:middle;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:-webkit-gradient(linear,left top,left bottom,from(#f8fafb),to(#e9eef1));background:linear-gradient(#f8fafb,#e9eef1);border:1px solid #cbd0d3;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05);text-shadow:0 1px 1px #fff;color:#55646b;-webkit-transition:background .1s ease,color .1s ease;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:-webkit-gradient(linear,left top,left bottom,from(#3498db),to(#258cd1));background-image:linear-gradient(#3498db,#258cd1);background-color:#3498db;border-color:#217dbb;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.15);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{content:"";position:absolute;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%;vertical-align:middle}video{max-width:100%;vertical-align:middle}.plyr{margin:0 auto;border-radius:6px}.plyr--audio{max-width:520px}.plyr__video-wrapper::after{content:"";pointer-events:none;position:absolute;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 e21530ec..5c035bd1 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,s=arguments.length;for(i=0;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 +"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;i=0;a--)e(s[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 o=i[0],s=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=s.length-1;c>=0;c--)s[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,o,s,n,r){e.GoogleAnalyticsObject=s,e[s]=e[s]||function(){(e[s].q=e[s].q||[]).push(arguments)},e[s].l=1*new Date,n=t.createElement(i),r=t.getElementsByTagName(i)[0],n.async=1,n.src="//www.google-analytics.com/analytics.js",r.parentNode.insertBefore(n,r)}(window,document,"script",0,"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 b21fa6cc..98f626ad 100644 --- a/demo/index.html +++ b/demo/index.html @@ -1,88 +1,99 @@ - - - Plyr - A simple HTML5 media player - - - - - + + + Plyr - A simple HTML5 media player + + + - - - - -
-

Plyr

-

A simple, accessible HTML5 media player by @sam_potts

- -
+ + -
- -
- +
+ +
+
-
+ + - - + + Download + - - + +
+
- - + + - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/demo/src/less/lib/fontface.less b/demo/src/less/lib/fontface.less index a7da5ad9..70ad4486 100644 --- a/demo/src/less/lib/fontface.less +++ b/demo/src/less/lib/fontface.less @@ -4,15 +4,15 @@ @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: @font-weight-base; + src: url("//cdn.plyr.io/static/fonts/avenir-medium.woff2") format("woff2"), + url("//cdn.plyr.io/static/fonts/avenir-medium.woff") format("woff"); + font-style: normal; + font-weight: @font-weight-base; } @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: @font-weight-bold; -} \ No newline at end of file + src: url("//cdn.plyr.io/static/fonts/avenir-bold.woff2") format("woff2"), + url("//cdn.plyr.io/static/fonts/avenir-bold.woff") format("woff"); + font-style: normal; + font-weight: @font-weight-bold; +} diff --git a/dist/plyr.css b/dist/plyr.css index e92820ce..1ca2a7fd 100644 --- a/dist/plyr.css +++ b/dist/plyr.css @@ -1 +1 @@ -.plyr input[type=range]:focus,.plyr:focus{outline:0}.plyr .plyr__video-embed iframe,.plyr__tooltip{pointer-events:none}@keyframes plyr-progress{to{background-position:25px 0}}.plyr{position:relative;max-width:100%;min-width:200px;font-family:Avenir,'Avenir Next','Helvetica Neue','Segoe UI',Helvetica,Arial,sans-serif;direction:ltr}.plyr,.plyr *,.plyr ::after,.plyr ::before{box-sizing:border-box}.plyr a,.plyr button,.plyr input,.plyr label{-ms-touch-action:manipulation;touch-action:manipulation}.plyr audio,.plyr video{width:100%;height:auto;vertical-align:middle;border-radius:inherit}.plyr input[type=range]{display:block;height:20px;width:100%;margin:0;padding:0;vertical-align:middle;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;border:none;background:0 0}.plyr input[type=range]::-webkit-slider-runnable-track{height:8px;background:0 0;border:0;border-radius:4px;-webkit-user-select:none;user-select:none}.plyr input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;margin-top:-4px;position:relative;height:16px;width:16px;background:#fff;border:2px solid transparent;border-radius:100%;transition:background .2s ease,border .2s ease,transform .2s ease;box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(0,0,0,.15);box-sizing:border-box}.plyr input[type=range]::-moz-range-track{height:8px;background:0 0;border:0;border-radius:4px;-moz-user-select:none;user-select:none}.plyr input[type=range]::-moz-range-thumb{position:relative;height:16px;width:16px;background:#fff;border:2px solid transparent;border-radius:100%;transition:background .2s ease,border .2s ease,transform .2s ease;box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(0,0,0,.15);box-sizing:border-box}.plyr input[type=range]::-ms-track{height:8px;background:0 0;border:0;color:transparent}.plyr input[type=range]::-ms-fill-upper{height:8px;background:0 0;border:0;border-radius:4px;-ms-user-select:none;user-select:none}.plyr input[type=range]::-ms-fill-lower{height:8px;border:0;border-radius:4px;-ms-user-select:none;user-select:none;background:#3498db}.plyr input[type=range]::-ms-thumb{position:relative;height:16px;width:16px;background:#fff;border:2px solid transparent;border-radius:100%;transition:background .2s ease,border .2s ease,transform .2s ease;box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(0,0,0,.15);box-sizing:border-box;margin-top:0}.plyr input[type=range]::-ms-tooltip{display:none}.plyr input[type=range]::-moz-focus-outer{border:0}.plyr input[type=range].tab-focus:focus{outline-offset:3px}.plyr input[type=range]:active::-webkit-slider-thumb{background:#3498db;border-color:#fff;transform:scale(1.25)}.plyr input[type=range]:active::-moz-range-thumb{background:#3498db;border-color:#fff;transform:scale(1.25)}.plyr input[type=range]:active::-ms-thumb{background:#3498db;border-color:#fff;transform:scale(1.25)}.plyr--video input[type=range].tab-focus:focus{outline:rgba(255,255,255,.5) dotted 1px}.plyr--audio input[type=range].tab-focus:focus{outline:rgba(86,93,100,.5) dotted 1px}.plyr__sr-only{clip:rect(1px,1px,1px,1px);overflow:hidden;position:absolute!important;padding:0!important;border:0!important;height:1px!important;width:1px!important}.plyr__video-wrapper{position:relative;background:#000;border-radius:inherit}.plyr__video-embed{padding-bottom:56.25%;height:0;border-radius:inherit;overflow:hidden;z-index:0}.plyr__video-embed iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.plyr__video-embed>div{position:relative;padding-bottom:200%;transform:translateY(-35.95%)}.plyr video::-webkit-media-text-track-container{display:none}.plyr__captions{display:none;position:absolute;bottom:0;left:0;width:100%;padding:20px;transform:translateY(-40px);transition:transform .3s ease;color:#fff;font-size:16px;text-align:center;font-weight:400}.plyr__captions span{border-radius:2px;padding:3px 10px;background:rgba(0,0,0,.7);-webkit-box-decoration-break:clone;box-decoration-break:clone;line-height:150%}.plyr__captions span:empty{display:none}@media (min-width:768px){.plyr__captions{font-size:24px}}.plyr--captions-active .plyr__captions{display:block}.plyr--hide-controls .plyr__captions{transform:translateY(-15px)}@media (min-width:1024px){.plyr--fullscreen-active .plyr__captions{font-size:32px}}.plyr ::-webkit-media-controls{display:none}.plyr__controls{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;line-height:1;text-align:center}.plyr__controls .plyr__progress,.plyr__controls .plyr__time,.plyr__controls>button{margin-left:5px}.plyr__controls .plyr__progress:first-child,.plyr__controls .plyr__time:first-child,.plyr__controls>button:first-child{margin-left:0}.plyr__controls .plyr__volume{margin-left:5px}.plyr__controls [data-plyr=pause]{margin-left:0}.plyr__controls button{position:relative;display:inline-block;-ms-flex-negative:0;flex-shrink:0;overflow:visible;vertical-align:middle;padding:7px;border:0;background:0 0;border-radius:3px;cursor:pointer;transition:background .3s ease,color .3s ease,opacity .3s ease;color:inherit}.plyr__controls button svg{width:18px;height:18px;display:block;fill:currentColor}.plyr__controls button:focus{outline:0}.plyr__controls .icon--captions-on,.plyr__controls .icon--exit-fullscreen,.plyr__controls .icon--muted{display:none}@media (min-width:480px){.plyr__controls .plyr__progress,.plyr__controls .plyr__time,.plyr__controls>button{margin-left:10px}}.plyr--hide-controls .plyr__controls{opacity:0;pointer-events:none}.plyr--video .plyr__controls{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:50px 10px 10px;background:linear-gradient(rgba(0,0,0,0),rgba(0,0,0,.5));border-bottom-left-radius:inherit;border-bottom-right-radius:inherit;color:#fff;transition:opacity .3s ease}.plyr--video .plyr__controls button.tab-focus:focus,.plyr--video .plyr__controls button:hover{background:#3498db;color:#fff}.plyr--audio .plyr__controls{padding:10px;border-radius:inherit;background:#fff;border:1px solid #dbe3e8;color:#565D64}.plyr--audio .plyr__controls button.tab-focus:focus,.plyr--audio .plyr__controls button:hover,.plyr__play-large{background:#3498db;color:#fff}.plyr__play-large{display:none;position:absolute;z-index:1;top:50%;left:50%;transform:translate(-50%,-50%);padding:10px;border:4px solid currentColor;border-radius:100%;box-shadow:0 1px 1px rgba(0,0,0,.15);transition:all .3s ease}.plyr__play-large svg{position:relative;left:2px;width:20px;height:20px;display:block;fill:currentColor}.plyr__play-large:focus{outline:rgba(255,255,255,.5) dotted 1px}.plyr .plyr__play-large{display:inline-block}.plyr--audio .plyr__play-large,.plyr--playing .plyr__controls [data-plyr=play],.plyr__controls [data-plyr=pause]{display:none}.plyr--playing .plyr__play-large{opacity:0;visibility:hidden}.plyr--playing .plyr__controls [data-plyr=pause]{display:inline-block}.plyr--captions-active .plyr__controls .icon--captions-on,.plyr--fullscreen-active .icon--exit-fullscreen,.plyr--muted .plyr__controls .icon--muted{display:block}.plyr [data-plyr=captions],.plyr [data-plyr=fullscreen],.plyr--captions-active .plyr__controls .icon--captions-on+svg,.plyr--fullscreen-active .icon--exit-fullscreen+svg,.plyr--muted .plyr__controls .icon--muted+svg{display:none}.plyr--captions-enabled [data-plyr=captions],.plyr--fullscreen-enabled [data-plyr=fullscreen]{display:inline-block}.plyr__tooltip{position:absolute;z-index:2;bottom:100%;margin-bottom:10px;padding:5px 7.5px;opacity:0;background:rgba(0,0,0,.7);border-radius:3px;color:#fff;font-size:14px;line-height:1.3;transform:translate(-50%,10px) scale(.8);transform-origin:50% 100%;transition:transform .2s .1s ease,opacity .2s .1s ease}.plyr__tooltip::before{content:'';position:absolute;width:0;height:0;left:50%;transform:translateX(-50%);bottom:-4px;border-right:4px solid transparent;border-top:4px solid rgba(0,0,0,.7);border-left:4px solid transparent;z-index:2}.plyr button.tab-focus:focus .plyr__tooltip,.plyr button:hover .plyr__tooltip,.plyr__tooltip--visible{opacity:1;transform:translate(-50%,0) scale(1)}.plyr button:hover .plyr__tooltip{z-index:3}.plyr__controls button:first-child .plyr__tooltip{left:0;transform:translate(0,10px) scale(.8);transform-origin:0 100%}.plyr__controls button:first-child .plyr__tooltip::before{left:16px}.plyr__controls button:last-child .plyr__tooltip{right:0;transform:translate(0,10px) scale(.8);transform-origin:100% 100%}.plyr__controls button:last-child .plyr__tooltip::before{left:auto;right:16px;transform:translateX(50%)}.plyr__controls button:first-child .plyr__tooltip--visible,.plyr__controls button:first-child.tab-focus:focus .plyr__tooltip,.plyr__controls button:first-child:hover .plyr__tooltip,.plyr__controls button:last-child .plyr__tooltip--visible,.plyr__controls button:last-child.tab-focus:focus .plyr__tooltip,.plyr__controls button:last-child:hover .plyr__tooltip{transform:translate(0,0) scale(1)}.plyr__progress{position:relative;display:none;-ms-flex:1;flex:1}.plyr__progress input[type=range]{position:relative;z-index:2}.plyr__progress input[type=range]::-webkit-slider-runnable-track{background:0 0}.plyr__progress input[type=range]::-moz-range-track{background:0 0}.plyr__progress input[type=range]::-ms-fill-upper{background:0 0}.plyr__progress .plyr__tooltip{left:0}.plyr .plyr__progress{display:inline-block}.plyr__progress--buffer,.plyr__progress--played,.plyr__volume--display{position:absolute;left:0;top:50%;width:100%;height:8px;margin:-4px 0 0;padding:0;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;border-radius:100px}.plyr__progress--buffer::-webkit-progress-bar,.plyr__progress--played::-webkit-progress-bar,.plyr__volume--display::-webkit-progress-bar{background:0 0}.plyr__progress--buffer::-webkit-progress-value,.plyr__progress--played::-webkit-progress-value,.plyr__volume--display::-webkit-progress-value{background:currentColor;border-radius:100px;min-width:8px}.plyr__progress--buffer::-moz-progress-bar,.plyr__progress--played::-moz-progress-bar,.plyr__volume--display::-moz-progress-bar{background:currentColor;border-radius:100px;min-width:8px}.plyr__progress--buffer::-ms-fill,.plyr__progress--played::-ms-fill,.plyr__volume--display::-ms-fill{border-radius:100px}.plyr__progress--played,.plyr__volume--display{z-index:1;color:#3498db;background:0 0;transition:none}.plyr__progress--played::-webkit-progress-value,.plyr__volume--display::-webkit-progress-value{min-width:8px;max-width:99%;border-top-right-radius:0;border-bottom-right-radius:0;transition:none}.plyr__progress--played::-moz-progress-bar,.plyr__volume--display::-moz-progress-bar{min-width:8px;max-width:99%;border-top-right-radius:0;border-bottom-right-radius:0;transition:none}.plyr__progress--played::-ms-fill,.plyr__volume--display::-ms-fill{display:none}.plyr__progress--buffer::-webkit-progress-value{transition:width .2s ease}.plyr__progress--buffer::-moz-progress-bar{transition:width .2s ease}.plyr__progress--buffer::-ms-fill{transition:width .2s ease}.plyr--video .plyr__progress--buffer,.plyr--video .plyr__volume--display{background:rgba(255,255,255,.25)}.plyr--video .plyr__progress--buffer{color:rgba(255,255,255,.25)}.plyr--audio .plyr__progress--buffer,.plyr--audio .plyr__volume--display{background:rgba(198,214,219,.66)}.plyr--audio .plyr__progress--buffer{color:rgba(198,214,219,.66)}.plyr--loading .plyr__progress--buffer{animation:plyr-progress 1s linear infinite;background-size:25px 25px;background-repeat:repeat-x;background-image:linear-gradient(-45deg,rgba(0,0,0,.15) 25%,transparent 25%,transparent 50%,rgba(0,0,0,.15) 50%,rgba(0,0,0,.15) 75%,transparent 75%,transparent);color:transparent}.plyr--video.plyr--loading .plyr__progress--buffer{background-color:rgba(255,255,255,.25)}.plyr--audio.plyr--loading .plyr__progress--buffer{background-color:rgba(198,214,219,.66)}.plyr__time{display:inline-block;vertical-align:middle;font-size:14px}.plyr__time+.plyr__time{display:none}@media (min-width:768px){.plyr__time+.plyr__time{display:inline-block}}.plyr__time+.plyr__time::before{content:'\2044';margin-right:10px}.plyr__volume{display:none}.plyr .plyr__volume{-ms-flex:1;flex:1;position:relative}.plyr .plyr__volume input[type=range]{position:relative;z-index:2}@media (min-width:480px){.plyr .plyr__volume{display:block;max-width:60px}}@media (min-width:768px){.plyr .plyr__volume{max-width:100px}}.plyr--is-ios .plyr__volume,.plyr--is-ios [data-plyr=mute]{display:none!important}.plyr--fullscreen-active{position:fixed;top:0;left:0;right:0;bottom:0;height:100%;width:100%;z-index:10000000;background:#000;border-radius:0!important}.plyr--fullscreen-active video{height:100%}.plyr--fullscreen-active .plyr__video-wrapper{height:100%;width:100%}.plyr--fullscreen-active .plyr__video-embed{overflow:visible}.plyr--fullscreen-active .plyr__controls{position:absolute;bottom:0;left:0;right:0}.plyr--fullscreen-active.plyr--vimeo .plyr__video-wrapper{height:0;top:50%;transform:translateY(-50%)} \ No newline at end of file +@-webkit-keyframes plyr-progress{to{background-position:25px 0}}@keyframes plyr-progress{to{background-position:25px 0}}.plyr{position:relative;max-width:100%;min-width:200px;font-family:Avenir,'Avenir Next','Helvetica Neue','Segoe UI',Helvetica,Arial,sans-serif;direction:ltr}.plyr,.plyr *,.plyr ::after,.plyr ::before{-webkit-box-sizing:border-box;box-sizing:border-box}.plyr a,.plyr button,.plyr input,.plyr label{-ms-touch-action:manipulation;touch-action:manipulation}.plyr:focus{outline:0}.plyr audio,.plyr video{width:100%;height:auto;vertical-align:middle;border-radius:inherit}.plyr input[type=range]{display:block;height:20px;width:100%;margin:0;padding:0;vertical-align:middle;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;border:none;background:0 0}.plyr input[type=range]::-webkit-slider-runnable-track{height:8px;background:0 0;border:0;border-radius:4px;-webkit-user-select:none;user-select:none}.plyr input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;margin-top:-4px;position:relative;height:16px;width:16px;background:#fff;border:2px solid transparent;border-radius:100%;-webkit-transition:background .2s ease,border .2s ease,-webkit-transform .2s ease;transition:background .2s ease,border .2s ease,-webkit-transform .2s ease;transition:background .2s ease,border .2s ease,transform .2s ease;transition:background .2s ease,border .2s ease,transform .2s ease,-webkit-transform .2s ease;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(0,0,0,.15);box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(0,0,0,.15);-webkit-box-sizing:border-box;box-sizing:border-box}.plyr input[type=range]::-moz-range-track{height:8px;background:0 0;border:0;border-radius:4px;-moz-user-select:none;user-select:none}.plyr input[type=range]::-moz-range-thumb{position:relative;height:16px;width:16px;background:#fff;border:2px solid transparent;border-radius:100%;-webkit-transition:background .2s ease,border .2s ease,-webkit-transform .2s ease;transition:background .2s ease,border .2s ease,-webkit-transform .2s ease;transition:background .2s ease,border .2s ease,transform .2s ease;transition:background .2s ease,border .2s ease,transform .2s ease,-webkit-transform .2s ease;box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(0,0,0,.15);box-sizing:border-box}.plyr input[type=range]::-ms-track{height:8px;background:0 0;border:0;color:transparent}.plyr input[type=range]::-ms-fill-upper{height:8px;background:0 0;border:0;border-radius:4px;-ms-user-select:none;user-select:none}.plyr input[type=range]::-ms-fill-lower{height:8px;background:0 0;border:0;border-radius:4px;-ms-user-select:none;user-select:none;background:#3498db}.plyr input[type=range]::-ms-thumb{position:relative;height:16px;width:16px;background:#fff;border:2px solid transparent;border-radius:100%;-webkit-transition:background .2s ease,border .2s ease,-webkit-transform .2s ease;transition:background .2s ease,border .2s ease,-webkit-transform .2s ease;transition:background .2s ease,border .2s ease,transform .2s ease;transition:background .2s ease,border .2s ease,transform .2s ease,-webkit-transform .2s ease;box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(0,0,0,.15);box-sizing:border-box;margin-top:0}.plyr input[type=range]::-ms-tooltip{display:none}.plyr input[type=range]:focus{outline:0}.plyr input[type=range]::-moz-focus-outer{border:0}.plyr input[type=range].tab-focus:focus{outline-offset:3px}.plyr input[type=range]:active::-webkit-slider-thumb{background:#3498db;border-color:#fff;-webkit-transform:scale(1.25);transform:scale(1.25)}.plyr input[type=range]:active::-moz-range-thumb{background:#3498db;border-color:#fff;transform:scale(1.25)}.plyr input[type=range]:active::-ms-thumb{background:#3498db;border-color:#fff;transform:scale(1.25)}.plyr--video input[type=range].tab-focus:focus{outline:1px dotted rgba(255,255,255,.5)}.plyr--audio input[type=range].tab-focus:focus{outline:1px dotted rgba(86,93,100,.5)}.plyr__sr-only{clip:rect(1px,1px,1px,1px);overflow:hidden;position:absolute!important;padding:0!important;border:0!important;height:1px!important;width:1px!important}.plyr__video-wrapper{position:relative;background:#000;border-radius:inherit}.plyr__video-embed{padding-bottom:56.25%;height:0;border-radius:inherit;overflow:hidden;z-index:0}.plyr__video-embed iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.plyr__video-embed>div{position:relative;padding-bottom:200%;-webkit-transform:translateY(-35.95%);transform:translateY(-35.95%)}.plyr .plyr__video-embed iframe{pointer-events:none}.plyr video::-webkit-media-text-track-container{display:none}.plyr__captions{display:none;position:absolute;bottom:0;left:0;width:100%;padding:20px;-webkit-transform:translateY(-40px);transform:translateY(-40px);-webkit-transition:-webkit-transform .3s ease;transition:-webkit-transform .3s ease;transition:transform .3s ease;transition:transform .3s ease,-webkit-transform .3s ease;color:#fff;font-size:16px;text-align:center;font-weight:400}.plyr__captions span{border-radius:2px;padding:3px 10px;background:rgba(0,0,0,.7);-webkit-box-decoration-break:clone;box-decoration-break:clone;line-height:150%}.plyr__captions span:empty{display:none}@media (min-width:768px){.plyr__captions{font-size:24px}}.plyr--captions-active .plyr__captions{display:block}.plyr--hide-controls .plyr__captions{-webkit-transform:translateY(-15px);transform:translateY(-15px)}@media (min-width:1024px){.plyr--fullscreen-active .plyr__captions{font-size:32px}}.plyr ::-webkit-media-controls{display:none}.plyr__controls{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;line-height:1;text-align:center}.plyr__controls .plyr__progress,.plyr__controls .plyr__time,.plyr__controls>button{margin-left:5px}.plyr__controls .plyr__progress:first-child,.plyr__controls .plyr__time:first-child,.plyr__controls>button:first-child{margin-left:0}.plyr__controls .plyr__volume{margin-left:5px}.plyr__controls [data-plyr=pause]{margin-left:0}.plyr__controls button{position:relative;display:inline-block;-ms-flex-negative:0;flex-shrink:0;overflow:visible;vertical-align:middle;padding:7px;border:0;background:0 0;border-radius:3px;cursor:pointer;-webkit-transition:background .3s ease,color .3s ease,opacity .3s ease;transition:background .3s ease,color .3s ease,opacity .3s ease;color:inherit}.plyr__controls button svg{width:18px;height:18px;display:block;fill:currentColor}.plyr__controls button:focus{outline:0}.plyr__controls .icon--captions-on,.plyr__controls .icon--exit-fullscreen,.plyr__controls .icon--muted{display:none}@media (min-width:480px){.plyr__controls .plyr__progress,.plyr__controls .plyr__time,.plyr__controls>button{margin-left:10px}}.plyr--hide-controls .plyr__controls{opacity:0;pointer-events:none}.plyr--video .plyr__controls{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:50px 10px 10px;background:-webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,0)),to(rgba(0,0,0,.5)));background:linear-gradient(rgba(0,0,0,0),rgba(0,0,0,.5));border-bottom-left-radius:inherit;border-bottom-right-radius:inherit;color:#fff;-webkit-transition:opacity .3s ease;transition:opacity .3s ease}.plyr--video .plyr__controls button.tab-focus:focus,.plyr--video .plyr__controls button:hover{background:#3498db;color:#fff}.plyr--audio .plyr__controls{padding:10px;border-radius:inherit;background:#fff;border:1px solid #dbe3e8;color:#565d64}.plyr--audio .plyr__controls button.tab-focus:focus,.plyr--audio .plyr__controls button:hover{background:#3498db;color:#fff}.plyr__play-large{display:none;position:absolute;z-index:1;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);padding:10px;background:#3498db;border:4px solid currentColor;border-radius:100%;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.15);box-shadow:0 1px 1px rgba(0,0,0,.15);color:#fff;-webkit-transition:all .3s ease;transition:all .3s ease}.plyr__play-large svg{position:relative;left:2px;width:20px;height:20px;display:block;fill:currentColor}.plyr__play-large:focus{outline:1px dotted rgba(255,255,255,.5)}.plyr .plyr__play-large{display:inline-block}.plyr--audio .plyr__play-large{display:none}.plyr--playing .plyr__play-large{opacity:0;visibility:hidden}.plyr--playing .plyr__controls [data-plyr=play],.plyr__controls [data-plyr=pause]{display:none}.plyr--playing .plyr__controls [data-plyr=pause]{display:inline-block}.plyr--captions-active .plyr__controls .icon--captions-on,.plyr--fullscreen-active .icon--exit-fullscreen,.plyr--muted .plyr__controls .icon--muted{display:block}.plyr--captions-active .plyr__controls .icon--captions-on+svg,.plyr--fullscreen-active .icon--exit-fullscreen+svg,.plyr--muted .plyr__controls .icon--muted+svg{display:none}.plyr [data-plyr=captions],.plyr [data-plyr=fullscreen]{display:none}.plyr--captions-enabled [data-plyr=captions],.plyr--fullscreen-enabled [data-plyr=fullscreen]{display:inline-block}.plyr__tooltip{position:absolute;z-index:2;bottom:100%;margin-bottom:10px;padding:5px 7.5px;pointer-events:none;opacity:0;background:rgba(0,0,0,.7);border-radius:3px;color:#fff;font-size:14px;line-height:1.3;-webkit-transform:translate(-50%,10px) scale(.8);transform:translate(-50%,10px) scale(.8);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;-webkit-transition:opacity .2s .1s ease,-webkit-transform .2s .1s ease;transition:opacity .2s .1s ease,-webkit-transform .2s .1s ease;transition:transform .2s .1s ease,opacity .2s .1s ease;transition:transform .2s .1s ease,opacity .2s .1s ease,-webkit-transform .2s .1s ease}.plyr__tooltip::before{content:'';position:absolute;width:0;height:0;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%);bottom:-4px;border-right:4px solid transparent;border-top:4px solid rgba(0,0,0,.7);border-left:4px solid transparent;z-index:2}.plyr button.tab-focus:focus .plyr__tooltip,.plyr button:hover .plyr__tooltip,.plyr__tooltip--visible{opacity:1;-webkit-transform:translate(-50%,0) scale(1);transform:translate(-50%,0) scale(1)}.plyr button:hover .plyr__tooltip{z-index:3}.plyr__controls button:first-child .plyr__tooltip{left:0;-webkit-transform:translate(0,10px) scale(.8);transform:translate(0,10px) scale(.8);-webkit-transform-origin:0 100%;transform-origin:0 100%}.plyr__controls button:first-child .plyr__tooltip::before{left:16px}.plyr__controls button:last-child .plyr__tooltip{right:0;-webkit-transform:translate(0,10px) scale(.8);transform:translate(0,10px) scale(.8);-webkit-transform-origin:100% 100%;transform-origin:100% 100%}.plyr__controls button:last-child .plyr__tooltip::before{left:auto;right:16px;-webkit-transform:translateX(50%);transform:translateX(50%)}.plyr__controls button:first-child .plyr__tooltip--visible,.plyr__controls button:first-child.tab-focus:focus .plyr__tooltip,.plyr__controls button:first-child:hover .plyr__tooltip,.plyr__controls button:last-child .plyr__tooltip--visible,.plyr__controls button:last-child.tab-focus:focus .plyr__tooltip,.plyr__controls button:last-child:hover .plyr__tooltip{-webkit-transform:translate(0,0) scale(1);transform:translate(0,0) scale(1)}.plyr__progress{position:relative;display:none;-webkit-box-flex:1;-ms-flex:1;flex:1}.plyr__progress input[type=range]{position:relative;z-index:2}.plyr__progress input[type=range]::-webkit-slider-runnable-track{background:0 0}.plyr__progress input[type=range]::-moz-range-track{background:0 0}.plyr__progress input[type=range]::-ms-fill-upper{background:0 0}.plyr__progress .plyr__tooltip{left:0}.plyr .plyr__progress{display:inline-block}.plyr__progress--buffer,.plyr__progress--played,.plyr__volume--display{position:absolute;left:0;top:50%;width:100%;height:8px;margin:-4px 0 0;padding:0;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;border-radius:100px}.plyr__progress--buffer::-webkit-progress-bar,.plyr__progress--played::-webkit-progress-bar,.plyr__volume--display::-webkit-progress-bar{background:0 0}.plyr__progress--buffer::-webkit-progress-value,.plyr__progress--played::-webkit-progress-value,.plyr__volume--display::-webkit-progress-value{background:currentColor;border-radius:100px;min-width:8px}.plyr__progress--buffer::-moz-progress-bar,.plyr__progress--played::-moz-progress-bar,.plyr__volume--display::-moz-progress-bar{background:currentColor;border-radius:100px;min-width:8px}.plyr__progress--buffer::-ms-fill,.plyr__progress--played::-ms-fill,.plyr__volume--display::-ms-fill{border-radius:100px}.plyr__progress--played,.plyr__volume--display{z-index:1;color:#3498db;background:0 0;-webkit-transition:none;transition:none}.plyr__progress--played::-webkit-progress-value,.plyr__volume--display::-webkit-progress-value{min-width:8px;max-width:99%;border-top-right-radius:0;border-bottom-right-radius:0;-webkit-transition:none;transition:none}.plyr__progress--played::-moz-progress-bar,.plyr__volume--display::-moz-progress-bar{min-width:8px;max-width:99%;border-top-right-radius:0;border-bottom-right-radius:0;-webkit-transition:none;transition:none}.plyr__progress--played::-ms-fill,.plyr__volume--display::-ms-fill{display:none}.plyr__progress--buffer::-webkit-progress-value{-webkit-transition:width .2s ease;transition:width .2s ease}.plyr__progress--buffer::-moz-progress-bar{-webkit-transition:width .2s ease;transition:width .2s ease}.plyr__progress--buffer::-ms-fill{-webkit-transition:width .2s ease;transition:width .2s ease}.plyr--video .plyr__progress--buffer,.plyr--video .plyr__volume--display{background:rgba(255,255,255,.25)}.plyr--video .plyr__progress--buffer{color:rgba(255,255,255,.25)}.plyr--audio .plyr__progress--buffer,.plyr--audio .plyr__volume--display{background:rgba(198,214,219,.66)}.plyr--audio .plyr__progress--buffer{color:rgba(198,214,219,.66)}.plyr--loading .plyr__progress--buffer{-webkit-animation:plyr-progress 1s linear infinite;animation:plyr-progress 1s linear infinite;background-size:25px 25px;background-repeat:repeat-x;background-image:linear-gradient(-45deg,rgba(0,0,0,.15) 25%,transparent 25%,transparent 50%,rgba(0,0,0,.15) 50%,rgba(0,0,0,.15) 75%,transparent 75%,transparent);color:transparent}.plyr--video.plyr--loading .plyr__progress--buffer{background-color:rgba(255,255,255,.25)}.plyr--audio.plyr--loading .plyr__progress--buffer{background-color:rgba(198,214,219,.66)}.plyr__time{display:inline-block;vertical-align:middle;font-size:14px}.plyr__time+.plyr__time{display:none}@media (min-width:768px){.plyr__time+.plyr__time{display:inline-block}}.plyr__time+.plyr__time::before{content:'\2044';margin-right:10px}.plyr__volume{display:none}.plyr .plyr__volume{-webkit-box-flex:1;-ms-flex:1;flex:1;position:relative}.plyr .plyr__volume input[type=range]{position:relative;z-index:2}@media (min-width:480px){.plyr .plyr__volume{display:block;max-width:60px}}@media (min-width:768px){.plyr .plyr__volume{max-width:100px}}.plyr--is-ios .plyr__volume,.plyr--is-ios [data-plyr=mute]{display:none!important}.plyr--fullscreen-active{position:fixed;top:0;left:0;right:0;bottom:0;height:100%;width:100%;z-index:10000000;background:#000;border-radius:0!important}.plyr--fullscreen-active video{height:100%}.plyr--fullscreen-active .plyr__video-wrapper{height:100%;width:100%}.plyr--fullscreen-active .plyr__video-embed{overflow:visible}.plyr--fullscreen-active .plyr__controls{position:absolute;bottom:0;left:0;right:0}.plyr--fullscreen-active.plyr--vimeo .plyr__video-wrapper{height:0;top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)} \ No newline at end of file diff --git a/dist/plyr.js b/dist/plyr.js index 8016e06a..1dc794bb 100644 --- a/dist/plyr.js +++ b/dist/plyr.js @@ -1,2 +1 @@ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=t(e,document):"function"==typeof define&&define.amd?define([],function(){return t(e,document)}):e.plyr=t(e,document)}("undefined"!=typeof window?window:this,function(e,t){"use strict";function n(){var e,n,r,a=navigator.userAgent,s=navigator.appName,o=""+parseFloat(navigator.appVersion),i=parseInt(navigator.appVersion,10),l=!1,u=!1,c=!1,d=!1;return navigator.appVersion.indexOf("Windows NT")!==-1&&navigator.appVersion.indexOf("rv:11")!==-1?(l=!0,s="IE",o="11"):(n=a.indexOf("MSIE"))!==-1?(l=!0,s="IE",o=a.substring(n+5)):(n=a.indexOf("Chrome"))!==-1?(c=!0,s="Chrome",o=a.substring(n+7)):(n=a.indexOf("Safari"))!==-1?(d=!0,s="Safari",o=a.substring(n+7),(n=a.indexOf("Version"))!==-1&&(o=a.substring(n+8))):(n=a.indexOf("Firefox"))!==-1?(u=!0,s="Firefox",o=a.substring(n+8)):(e=a.lastIndexOf(" ")+1)<(n=a.lastIndexOf("/"))&&(s=a.substring(e,n),o=a.substring(n+1),s.toLowerCase()===s.toUpperCase()&&(s=navigator.appName)),(r=o.indexOf(";"))!==-1&&(o=o.substring(0,r)),(r=o.indexOf(" "))!==-1&&(o=o.substring(0,r)),i=parseInt(""+o,10),isNaN(i)&&(o=""+parseFloat(navigator.appVersion),i=parseInt(navigator.appVersion,10)),{name:s,version:i,isIE:l,isFirefox:u,isChrome:c,isSafari:d,isIos:/(iPad|iPhone|iPod)/g.test(navigator.platform),isIphone:/(iPhone|iPod)/g.test(navigator.userAgent),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 a(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 s(e,t){return Array.prototype.indexOf&&e.indexOf(t)!==-1}function o(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,a=e[n],s=a.parentNode,o=a.nextSibling;return r.appendChild(a),o?s.insertBefore(r,o):s.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,O.boolean(t[n])&&t[n]?"":t[n])}function d(e,n,r){var a=t.createElement(e);c(a,r),u(n,a)}function p(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))}function y(e,n){var r=Element.prototype,a=r.matches||r.webkitMatchesSelector||r.mozMatchesSelector||r.msMatchesSelector||function(e){return[].indexOf.call(t.querySelectorAll(e),this)!==-1};return a.call(e,n)}function b(e,t,n,r,a){g(e,t,function(t){n&&n.apply(e,[t]),r.apply(e,[t])},a)}function v(e,t,n,r,a){var s=t.split(" ");if(O.boolean(a)||(a=!1),e instanceof NodeList)for(var o=0;o','',''+E.i18n.play+"",""),e.push('
'),s(E.controls,"restart")&&e.push('"),s(E.controls,"rewind")&&e.push('"),s(E.controls,"play")&&e.push('",'"),s(E.controls,"fast-forward")&&e.push('"),s(E.controls,"progress")&&(e.push('','','','','',"0% "+E.i18n.buffered,""),E.tooltips.seek&&e.push('00:00'),e.push("")),s(E.controls,"current-time")&&e.push('',''+E.i18n.currentTime+"",'00:00',""),s(E.controls,"duration")&&e.push('',''+E.i18n.duration+"",'00:00',""),s(E.controls,"mute")&&e.push('"),s(E.controls,"volume")&&e.push('','",'','',""),s(E.controls,"captions")&&e.push('"),s(E.controls,"fullscreen")&&e.push('"),e.push("
"),e.join("")}function q(){if(Be.supported.full&&("audio"!==Be.type||E.fullscreen.allowAudio)&&E.fullscreen.enabled){var e=N.supportsFullScreen;e||E.fullscreen.fallback&&!X()?(Je((e?"Native":"Fallback")+" fullscreen enabled"),m(Be.container,E.classes.fullscreen.enabled,!0)):Je("Fullscreen not supported and fallback disabled"),Be.buttons&&Be.buttons.fullscreen&&k(Be.buttons.fullscreen,!1),$()}}function D(){if("video"===Be.type){B(E.selectors.captions)||Be.videoContainer.insertAdjacentHTML("afterbegin",'
'),Be.usingTextTracks=!1,Be.media.textTracks&&(Be.usingTextTracks=!0);for(var e,t="",n=Be.media.childNodes,r=0;r=10||Be.browser.isFirefox&&Be.browser.version>=31)&&(Je("Detected browser with known TextTrack issues - using manual fallback"),Be.usingTextTracks=!1),Be.usingTextTracks){Je("TextTracks supported");for(var o=0;o ");for(var r=0;rBe.captions.length-1){Be.subcount=Be.captions.length-1;break}Be.media.currentTime.toFixed(1)>=n(Be.captions[Be.subcount][0])&&Be.media.currentTime.toFixed(1)<=r(Be.captions[Be.subcount][0])?(Be.currentCaption=Be.captions[Be.subcount][1],H(Be.currentCaption)):H()}}function Y(){if(Be.buttons.captions){m(Be.container,E.classes.captions.enabled,!0);var e=Be.storage.captionsEnabled;O.boolean(e)||(e=E.captions.defaultActive),e&&(m(Be.container,E.classes.captions.active,!0),k(Be.buttons.captions,!0))}}function U(e){return Be.container.querySelectorAll(e)}function B(e){return U(e)[0]}function X(){try{return e.self!==e.top}catch(e){return!0}}function $(){function e(e){9===e.which&&Be.isFullscreen&&(e.target!==r||e.shiftKey?e.target===n&&e.shiftKey&&(e.preventDefault(),r.focus()):(e.preventDefault(),n.focus()))}var t=U("input:not([disabled]), button:not([disabled])"),n=t[0],r=t[t.length-1];g(Be.container,"keydown",e)}function J(e,t){if(O.string(t))d(e,Be.media,{src:t});else if(t.constructor===Array)for(var n=t.length-1;n>=0;n--)d(e,Be.media,t[n])}function z(){if(E.loadSprite){var e=V();e.absolute?(Je("AJAX loading absolute SVG sprite"+(Be.browser.isIE?" (due to IE)":"")),C(e.url,"sprite-plyr")):Je("Sprite will be used as external resource directly")}var n=E.html;Je("Injecting custom controls"),n||(n=R()),n=o(n,"{seektime}",E.seekTime),n=o(n,"{id}",Math.floor(1e4*Math.random()));var r;if(O.string(E.selectors.controls.container)&&(r=t.querySelector(E.selectors.controls.container)),O.htmlElement(r)||(r=Be.container),r.insertAdjacentHTML("beforeend",n),E.tooltips.controls)for(var a=U([E.selectors.controls.wrapper," ",E.selectors.labels," .",E.classes.hidden].join("")),s=a.length-1;s>=0;s--){var i=a[s];m(i,E.classes.hidden,!1),m(i,E.classes.tooltip,!0)}}function G(){try{return Be.controls=B(E.selectors.controls.wrapper),Be.buttons={},Be.buttons.seek=B(E.selectors.buttons.seek),Be.buttons.play=U(E.selectors.buttons.play),Be.buttons.pause=B(E.selectors.buttons.pause),Be.buttons.restart=B(E.selectors.buttons.restart),Be.buttons.rewind=B(E.selectors.buttons.rewind),Be.buttons.forward=B(E.selectors.buttons.forward),Be.buttons.fullscreen=B(E.selectors.buttons.fullscreen),Be.buttons.mute=B(E.selectors.buttons.mute),Be.buttons.captions=B(E.selectors.buttons.captions),Be.progress={},Be.progress.container=B(E.selectors.progress.container),Be.progress.buffer={},Be.progress.buffer.bar=B(E.selectors.progress.buffer),Be.progress.buffer.text=Be.progress.buffer.bar&&Be.progress.buffer.bar.getElementsByTagName("span")[0],Be.progress.played=B(E.selectors.progress.played),Be.progress.tooltip=Be.progress.container&&Be.progress.container.querySelector("."+E.classes.tooltip),Be.volume={},Be.volume.input=B(E.selectors.volume.input),Be.volume.display=B(E.selectors.volume.display),Be.duration=B(E.selectors.duration),Be.currentTime=B(E.selectors.currentTime),Be.seekTime=U(E.selectors.seekTime),!0}catch(e){return ze("It looks like there is a problem with your controls HTML"),Q(!0),!1}}function K(){m(Be.container,E.selectors.container.replace(".",""),Be.supported.full)}function Q(e){e&&s(E.types.html5,Be.type)?Be.media.setAttribute("controls",""):Be.media.removeAttribute("controls")}function Z(e){var t=E.i18n.play;if(O.string(E.title)&&E.title.length&&(t+=", "+E.title,Be.container.setAttribute("aria-label",E.title)),Be.supported.full&&Be.buttons.play)for(var n=Be.buttons.play.length-1;n>=0;n--)Be.buttons.play[n].setAttribute("aria-label",t);O.htmlElement(e)&&e.setAttribute("title",E.i18n.frameTitle.replace("{title}",E.title))}function ee(){var t=null;Be.storage={},L.supported&&E.storage.enabled&&(e.localStorage.removeItem("plyr-volume"),t=e.localStorage.getItem(E.storage.key),t&&(/^\d+(\.\d+)?$/.test(t)?te({volume:parseFloat(t)}):Be.storage=JSON.parse(t)))}function te(t){L.supported&&E.storage.enabled&&(x(Be.storage,t),e.localStorage.setItem(E.storage.key,JSON.stringify(Be.storage)))}function ne(){if(!Be.media)return void ze("No media element found!");if(Be.supported.full&&(m(Be.container,E.classes.type.replace("{0}",Be.type),!0),s(E.types.embed,Be.type)&&m(Be.container,E.classes.type.replace("{0}","video"),!0),m(Be.container,E.classes.stopped,E.autoplay),m(Be.container,E.classes.isIos,Be.browser.isIos),m(Be.container,E.classes.isTouch,Be.browser.isTouch),"video"===Be.type)){var e=t.createElement("div");e.setAttribute("class",E.classes.videoWrapper),i(Be.media,e),Be.videoContainer=e}s(E.types.embed,Be.type)&&re()}function re(){var n,r=t.createElement("div"),s=Be.type+"-"+Math.floor(1e4*Math.random());switch(Be.type){case"youtube":n=T(Be.embedId);break;case"vimeo":n=S(Be.embedId);break;default:n=Be.embedId}for(var o=U('[id^="'+Be.type+'-"]'),i=o.length-1;i>=0;i--)l(o[i]);if(m(Be.media,E.classes.videoWrapper,!0),m(Be.media,E.classes.embedWrapper,!0),"youtube"===Be.type)Be.media.appendChild(r),r.setAttribute("id",s),O.object(e.YT)?se(n,r):(a(E.urls.youtube.api),e.onYouTubeReadyCallbacks=e.onYouTubeReadyCallbacks||[],e.onYouTubeReadyCallbacks.push(function(){se(n,r)}),e.onYouTubeIframeAPIReady=function(){e.onYouTubeReadyCallbacks.forEach(function(e){e()})});else if("vimeo"===Be.type)if(Be.supported.full?Be.media.appendChild(r):r=Be.media,r.setAttribute("id",s),O.object(e.Vimeo))oe(n,r);else{a(E.urls.vimeo.api);var u=e.setInterval(function(){O.object(e.Vimeo)&&(e.clearInterval(u),oe(n,r))},50)}else if("soundcloud"===Be.type){var d=t.createElement("iframe");d.loaded=!1,g(d,"load",function(){d.loaded=!0}),c(d,{src:"https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/"+n,id:s}),r.appendChild(d),Be.media.appendChild(r),e.SC||a(E.urls.soundcloud.api);var p=e.setInterval(function(){e.SC&&d.loaded&&(e.clearInterval(p),ie.call(d))},50)}}function ae(){Be.supported.full&&(We(),Ye()),Z(B("iframe"))}function se(t,n){Be.embed=new e.YT.Player(n.id,{videoId:t,playerVars:{autoplay:E.autoplay?1:0,controls:Be.supported.full?0:1,rel:0,showinfo:0,iv_load_policy:3,cc_load_policy:E.captions.defaultActive?1:0,cc_lang_pref:"en",wmode:"transparent",modestbranding:1,disablekb:1,origin:"*"},events:{onError:function(e){A(Be.container,"error",!0,{code:e.data,embed:e.target})},onReady:function(t){var n=t.target;Be.media.play=function(){n.playVideo(),Be.media.paused=!1},Be.media.pause=function(){n.pauseVideo(),Be.media.paused=!0},Be.media.stop=function(){n.stopVideo(),Be.media.paused=!0},Be.media.duration=n.getDuration(),Be.media.paused=!0,Be.media.currentTime=0,Be.media.muted=n.isMuted(),E.title=n.getVideoData().title,Be.supported.full&&Be.media.querySelector("iframe").setAttribute("tabindex","-1"),ae(),A(Be.media,"timeupdate"),A(Be.media,"durationchange"),e.clearInterval(Xe.buffering),Xe.buffering=e.setInterval(function(){Be.media.buffered=n.getVideoLoadedFraction(),(null===Be.media.lastBuffered||Be.media.lastBufferedr&&(t=r),Ne(t);try{Be.media.currentTime=t.toFixed(4)}catch(e){}if(s(E.types.embed,Be.type)){switch(Be.type){case"youtube":Be.embed.seekTo(t);break;case"vimeo":Be.embed.setCurrentTime(t.toFixed(0));break;case"soundcloud":Be.embed.seekTo(1e3*t)}n&&ue(),A(Be.media,"timeupdate"),Be.media.seeking=!0,A(Be.media,"seeking")}Je("Seeking to "+Be.media.currentTime+" seconds"),W(t)}function fe(){var e=parseInt(E.duration),t=0;return null===Be.media.duration||isNaN(Be.media.duration)||(t=Be.media.duration),isNaN(e)?t:e}function ye(){m(Be.container,E.classes.playing,!Be.media.paused),m(Be.container,E.classes.stopped,Be.media.paused),Me(Be.media.paused)}function be(){P={x:e.pageXOffset||0,y:e.pageYOffset||0}}function ve(){e.scrollTo(P.x,P.y)}function ge(e){var n=N.supportsFullScreen;if(n){if(!e||e.type!==N.fullScreenEventName)return N.isFullScreen(Be.container)?N.cancelFullScreen():(be(),N.requestFullScreen(Be.container)),void(Be.isFullscreen=N.isFullScreen(Be.container));Be.isFullscreen=N.isFullScreen(Be.container)}else Be.isFullscreen=!Be.isFullscreen,t.body.style.overflow=Be.isFullscreen?"hidden":"";m(Be.container,E.classes.fullscreen.active,Be.isFullscreen),$(Be.isFullscreen),Be.buttons&&Be.buttons.fullscreen&&k(Be.buttons.fullscreen,Be.isFullscreen),A(Be.container,Be.isFullscreen?"enterfullscreen":"exitfullscreen",!0),!Be.isFullscreen&&n&&ve()}function he(e){if(O.boolean(e)||(e=!Be.media.muted),k(Be.buttons.mute,e),Be.media.muted=e,0===Be.media.volume&&ke(E.volume),s(E.types.embed,Be.type)){switch(Be.type){case"youtube":Be.embed[Be.media.muted?"mute":"unMute"]();break;case"vimeo":case"soundcloud":Be.embed.setVolume(Be.media.muted?0:parseFloat(E.volume/E.volumeMax))}A(Be.media,"volumechange")}}function ke(e){var t=E.volumeMax,n=E.volumeMin;if(O.undefined(e)&&(e=Be.storage.volume),(null===e||isNaN(e))&&(e=E.volume),e>t&&(e=t),e0&&he()}function we(e){var t=Be.media.muted?0:Be.media.volume*E.volumeMax;O.number(e)||(e=E.volumeStep),ke(t+e)}function xe(e){var t=Be.media.muted?0:Be.media.volume*E.volumeMax;O.number(e)||(e=E.volumeStep),ke(t-e)}function Te(){var e=Be.media.muted?0:Be.media.volume*E.volumeMax;Be.supported.full&&(Be.volume.input&&(Be.volume.input.value=e),Be.volume.display&&(Be.volume.display.value=e)),te({volume:e}),m(Be.container,E.classes.muted,0===e),Be.supported.full&&Be.buttons.mute&&k(Be.buttons.mute,0===e)}function Se(e){Be.supported.full&&Be.buttons.captions&&(O.boolean(e)||(e=Be.container.className.indexOf(E.classes.captions.active)===-1),Be.captionsEnabled=e,k(Be.buttons.captions,Be.captionsEnabled),m(Be.container,E.classes.captions.active,Be.captionsEnabled),A(Be.container,Be.captionsEnabled?"captionsenabled":"captionsdisabled",!0),te({captionsEnabled:Be.captionsEnabled}))}function _e(e){var t="waiting"===e.type;clearTimeout(Xe.loading),Xe.loading=setTimeout(function(){m(Be.container,E.classes.loading,t),Me(t)},t?250:0)}function Ee(e){if(Be.supported.full){var t=Be.progress.played,n=0,r=fe();if(e)switch(e.type){case"timeupdate":case"seeking":if(Be.controls.pressed)return;n=w(Be.media.currentTime,r),"timeupdate"===e.type&&Be.buttons.seek&&(Be.buttons.seek.value=n);break;case"playing":case"progress":t=Be.progress.buffer,n=function(){var e=Be.media.buffered;return e&&e.length?w(e.end(0),r):O.number(e)?100*e:0}()}Ce(t,n)}}function Ce(e,t){if(Be.supported.full){if(O.undefined(t)&&(t=0),O.undefined(e)){if(!Be.progress||!Be.progress.buffer)return;e=Be.progress.buffer}O.htmlElement(e)?e.value=t:e&&(e.bar&&(e.bar.value=t),e.text&&(e.text.innerHTML=t))}}function Fe(e,t){if(t){isNaN(e)&&(e=0),Be.secs=parseInt(e%60),Be.mins=parseInt(e/60%60),Be.hours=parseInt(e/60/60%60);var n=parseInt(fe()/60/60%60)>0;Be.secs=("0"+Be.secs).slice(-2),Be.mins=("0"+Be.mins).slice(-2),t.innerHTML=(n?Be.hours+":":"")+Be.mins+":"+Be.secs}}function Ae(){if(Be.supported.full){var e=fe()||0;!Be.duration&&E.displayDuration&&Be.media.paused&&Fe(e,Be.currentTime),Be.duration&&Fe(e,Be.duration),Pe()}}function Ie(e){Fe(Be.media.currentTime,Be.currentTime),e&&"timeupdate"===e.type&&Be.media.seeking||Ee(e)}function Ne(e){O.number(e)||(e=0);var t=fe(),n=w(e,t);Be.progress&&Be.progress.played&&(Be.progress.played.value=n),Be.buttons&&Be.buttons.seek&&(Be.buttons.seek.value=n)}function Pe(e){var t=fe();if(E.tooltips.seek&&Be.progress.container&&0!==t){var n=Be.progress.container.getBoundingClientRect(),r=0,a=E.classes.tooltip+"--visible";if(e)r=100/n.width*(e.pageX-n.left);else{if(!f(Be.progress.tooltip,a))return;r=Be.progress.tooltip.style.left.replace("%","")}r<0?r=0:r>100&&(r=100),Fe(t/100*r,Be.progress.tooltip),Be.progress.tooltip.style.left=r+"%",e&&s(["mouseenter","mouseleave"],e.type)&&m(Be.progress.tooltip,a,"mouseenter"===e.type)}}function Me(t){if(E.hideControls&&"audio"!==Be.type){var n=0,r=!1,a=t,o=f(Be.container,E.classes.loading);if(O.boolean(t)||(t&&t.type?(r="enterfullscreen"===t.type,a=s(["mousemove","touchstart","mouseenter","focus"],t.type),s(["mousemove","touchmove"],t.type)&&(n=2e3),"focus"===t.type&&(n=3e3)):a=f(Be.container,E.classes.hideControls)),e.clearTimeout(Xe.hover),a||Be.media.paused||o){if(m(Be.container,E.classes.hideControls,!1),Be.media.paused||o)return;Be.browser.isTouch&&(n=3e3)}a&&Be.media.paused||(Xe.hover=e.setTimeout(function(){(!Be.controls.pressed&&!Be.controls.hover||r)&&m(Be.container,E.classes.hideControls,!0)},n))}}function Oe(e){if(!O.undefined(e))return void Le(e);var t;switch(Be.type){case"youtube":t=Be.embed.getVideoUrl();break;case"vimeo":Be.embed.getVideoUrl.then(function(e){t=e});break;case"soundcloud":Be.embed.getCurrentSound(function(e){t=e.permalink_url});break;default:t=Be.media.currentSrc}return t||""}function Le(e){function n(){if(Be.embed=null,l(Be.media),"video"===Be.type&&Be.videoContainer&&l(Be.videoContainer),Be.container&&Be.container.removeAttribute("class"),"type"in e&&(Be.type=e.type,"video"===Be.type)){var n=e.sources[0];"type"in n&&s(E.types.embed,n.type)&&(Be.type=n.type)}switch(Be.supported=F(Be.type),Be.type){case"video":Be.media=t.createElement("video");break;case"audio":Be.media=t.createElement("audio");break;case"youtube":case"vimeo":case"soundcloud":Be.media=t.createElement("div"),Be.embedId=e.sources[0].src}u(Be.container,Be.media),O.boolean(e.autoplay)&&(E.autoplay=e.autoplay),s(E.types.html5,Be.type)&&(E.crossorigin&&Be.media.setAttribute("crossorigin",""),E.autoplay&&Be.media.setAttribute("autoplay",""),"poster"in e&&Be.media.setAttribute("poster",e.poster),E.loop&&Be.media.setAttribute("loop","")),m(Be.container,E.classes.fullscreen.active,Be.isFullscreen),m(Be.container,E.classes.captions.active,Be.captionsEnabled),K(),s(E.types.html5,Be.type)&&J("source",e.sources),ne(),s(E.types.html5,Be.type)&&("tracks"in e&&J("track",e.tracks),Be.media.load()),(s(E.types.html5,Be.type)||s(E.types.embed,Be.type)&&!Be.supported.full)&&(We(),Ye()),E.title=e.title,Z()}return O.object(e)&&"sources"in e&&e.sources.length?(m(Be.container,E.classes.ready,!1),ue(),Ne(),Ce(),qe(),void De(n,!1)):void ze("Invalid source format")}function je(e){"video"===Be.type&&Be.media.setAttribute("poster",e)}function Ve(){function n(){var e=ce(),t=Be.buttons[e?"play":"pause"],n=Be.buttons[e?"pause":"play"];if(n=n&&n.length>1?n[n.length-1]:n[0]){var r=f(t,E.classes.tabFocus);setTimeout(function(){n.focus(),r&&(m(t,E.classes.tabFocus,!1),m(n,E.classes.tabFocus,!0))},100)}}function r(){var e=t.activeElement;return e=e&&e!==t.body?t.querySelector(":focus"):null}function a(e){return e.keyCode?e.keyCode:e.which}function o(e){for(var t in Be.buttons){var n=Be.buttons[t];if(O.nodeList(n))for(var r=0;r0)&&(t?xe(n):we(n)),(e.deltaY>0||e.deltaX<0)&&(t?we(n):xe(n))})}function Re(){if(g(Be.media,"timeupdate seeking",Ie),g(Be.media,"timeupdate",W),g(Be.media,"durationchange loadedmetadata",Ae),g(Be.media,"ended",function(){"video"===Be.type&&E.showPosterOnEnd&&("video"===Be.type&&H(),me(),Be.media.load())}),g(Be.media,"progress playing",Ee),g(Be.media,"volumechange",Te),g(Be.media,"play pause ended",ye),g(Be.media,"waiting canplay seeked",_e),E.clickToPlay&&"audio"!==Be.type){var e=B("."+E.classes.videoWrapper);if(!e)return;e.style.cursor="pointer",g(e,"click",function(){E.hideControls&&Be.browser.isTouch&&!Be.media.paused||(Be.media.paused?le():Be.media.ended?(me(),le()):ue())})}E.disableContextMenu&&g(Be.media,"contextmenu",function(e){e.preventDefault()}),g(Be.media,E.events.concat(["keyup","keydown"]).join(" "),function(e){A(Be.container,e.type,!0)})}function qe(){if(s(E.types.html5,Be.type)){for(var e=Be.media.querySelectorAll("source"),t=0;t=10&&(c=!0);break;case"soundcloud":u=!0,c=!a&&!o;break;default:u=i&&l,c=u&&!a}return{basic:u,full:c}}function A(e,n){function r(e,t){f(t,M.classes.hook)||a.push({target:e,media:t})}var a=[],s=[],o=[M.selectors.html5,M.selectors.embed].join(",");if(O.string(e)?e=t.querySelectorAll(e):O.htmlElement(e)?e=[e]:O.nodeList(e)||O.array(e)||O.string(e)||(O.undefined(n)&&O.object(e)&&(n=e),e=t.querySelectorAll(o)),O.nodeList(e)&&(e=Array.prototype.slice.call(e)),!F().basic||!e.length)return!1;for(var i=0;i=0;n--){var r=n>0?t.cloneNode(!0):t,a=e[n],s=a.parentNode,o=a.nextSibling;return r.appendChild(a),o?s.insertBefore(r,o):s.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,M.boolean(t[n])&&t[n]?"":t[n])}function d(e,n,r){var a=t.createElement(e);c(a,r),u(n,a)}function p(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))}function y(e,n){var r=Element.prototype;return(r.matches||r.webkitMatchesSelector||r.mozMatchesSelector||r.msMatchesSelector||function(e){return-1!==[].indexOf.call(t.querySelectorAll(e),this)}).call(e,n)}function b(e,t,n,r,a){g(e,t,function(t){n&&n.apply(e,[t]),r.apply(e,[t])},a)}function v(e,t,n,r,a){var s=t.split(" ");if(M.boolean(a)||(a=!1),e instanceof NodeList)for(var o=0;o','',''+E.i18n.play+"",""),e.push('
'),s(E.controls,"restart")&&e.push('"),s(E.controls,"rewind")&&e.push('"),s(E.controls,"play")&&e.push('",'"),s(E.controls,"fast-forward")&&e.push('"),s(E.controls,"progress")&&(e.push('','','','','',"0% "+E.i18n.buffered,""),E.tooltips.seek&&e.push('00:00'),e.push("")),s(E.controls,"current-time")&&e.push('',''+E.i18n.currentTime+"",'00:00',""),s(E.controls,"duration")&&e.push('',''+E.i18n.duration+"",'00:00',""),s(E.controls,"mute")&&e.push('"),s(E.controls,"volume")&&e.push('','",'','',""),s(E.controls,"captions")&&e.push('"),s(E.controls,"fullscreen")&&e.push('"),e.push("
"),e.join("")}function q(){if(We.supported.full&&("audio"!==We.type||E.fullscreen.allowAudio)&&E.fullscreen.enabled){var e=I.supportsFullScreen;e||E.fullscreen.fallback&&!X()?(Be((e?"Native":"Fallback")+" fullscreen enabled"),m(We.container,E.classes.fullscreen.enabled,!0)):Be("Fullscreen not supported and fallback disabled"),We.buttons&&We.buttons.fullscreen&&k(We.buttons.fullscreen,!1),$()}}function D(){if("video"===We.type){B(E.selectors.captions)||We.videoContainer.insertAdjacentHTML("afterbegin",'
'),We.usingTextTracks=!1,We.media.textTracks&&(We.usingTextTracks=!0);for(var e,t="",n=We.media.childNodes,r=0;r=10||We.browser.isFirefox&&We.browser.version>=31)&&(Be("Detected browser with known TextTrack issues - using manual fallback"),We.usingTextTracks=!1),We.usingTextTracks){Be("TextTracks supported");for(var o=0;oWe.captions.length-1){We.subcount=We.captions.length-1;break}We.media.currentTime.toFixed(1)>=function(e){return t(e,0)}(We.captions[We.subcount][0])&&We.media.currentTime.toFixed(1)<=n(We.captions[We.subcount][0])?(We.currentCaption=We.captions[We.subcount][1],H(We.currentCaption)):H()}}function Y(){if(We.buttons.captions){m(We.container,E.classes.captions.enabled,!0);var e=We.storage.captionsEnabled;M.boolean(e)||(e=E.captions.defaultActive),e&&(m(We.container,E.classes.captions.active,!0),k(We.buttons.captions,!0))}}function U(e){return We.container.querySelectorAll(e)}function B(e){return U(e)[0]}function X(){try{return e.self!==e.top}catch(e){return!0}}function $(){var e=U("input:not([disabled]), button:not([disabled])"),t=e[0],n=e[e.length-1];g(We.container,"keydown",function(e){9===e.which&&We.isFullscreen&&(e.target!==n||e.shiftKey?e.target===t&&e.shiftKey&&(e.preventDefault(),n.focus()):(e.preventDefault(),t.focus()))})}function J(e,t){if(M.string(t))d(e,We.media,{src:t});else if(t.constructor===Array)for(var n=t.length-1;n>=0;n--)d(e,We.media,t[n])}function z(){if(E.loadSprite){var e=V();e.absolute?(Be("AJAX loading absolute SVG sprite"+(We.browser.isIE?" (due to IE)":"")),C(e.url,"sprite-plyr")):Be("Sprite will be used as external resource directly")}var n=E.html;Be("Injecting custom controls"),n||(n=R()),n=o(n=o(n,"{seektime}",E.seekTime),"{id}",Math.floor(1e4*Math.random()));var r;if(M.string(E.selectors.controls.container)&&(r=t.querySelector(E.selectors.controls.container)),M.htmlElement(r)||(r=We.container),r.insertAdjacentHTML("beforeend",n),E.tooltips.controls)for(var a=U([E.selectors.controls.wrapper," ",E.selectors.labels," .",E.classes.hidden].join("")),s=a.length-1;s>=0;s--){var i=a[s];m(i,E.classes.hidden,!1),m(i,E.classes.tooltip,!0)}}function G(){try{return We.controls=B(E.selectors.controls.wrapper),We.buttons={},We.buttons.seek=B(E.selectors.buttons.seek),We.buttons.play=U(E.selectors.buttons.play),We.buttons.pause=B(E.selectors.buttons.pause),We.buttons.restart=B(E.selectors.buttons.restart),We.buttons.rewind=B(E.selectors.buttons.rewind),We.buttons.forward=B(E.selectors.buttons.forward),We.buttons.fullscreen=B(E.selectors.buttons.fullscreen),We.buttons.mute=B(E.selectors.buttons.mute),We.buttons.captions=B(E.selectors.buttons.captions),We.progress={},We.progress.container=B(E.selectors.progress.container),We.progress.buffer={},We.progress.buffer.bar=B(E.selectors.progress.buffer),We.progress.buffer.text=We.progress.buffer.bar&&We.progress.buffer.bar.getElementsByTagName("span")[0],We.progress.played=B(E.selectors.progress.played),We.progress.tooltip=We.progress.container&&We.progress.container.querySelector("."+E.classes.tooltip),We.volume={},We.volume.input=B(E.selectors.volume.input),We.volume.display=B(E.selectors.volume.display),We.duration=B(E.selectors.duration),We.currentTime=B(E.selectors.currentTime),We.seekTime=U(E.selectors.seekTime),!0}catch(e){return Xe("It looks like there is a problem with your controls HTML"),Q(!0),!1}}function K(){m(We.container,E.selectors.container.replace(".",""),We.supported.full)}function Q(e){e&&s(E.types.html5,We.type)?We.media.setAttribute("controls",""):We.media.removeAttribute("controls")}function Z(e){var t=E.i18n.play;if(M.string(E.title)&&E.title.length&&(t+=", "+E.title,We.container.setAttribute("aria-label",E.title)),We.supported.full&&We.buttons.play)for(var n=We.buttons.play.length-1;n>=0;n--)We.buttons.play[n].setAttribute("aria-label",t);M.htmlElement(e)&&e.setAttribute("title",E.i18n.frameTitle.replace("{title}",E.title))}function ee(){var t=null;We.storage={},O.supported&&E.storage.enabled&&(e.localStorage.removeItem("plyr-volume"),(t=e.localStorage.getItem(E.storage.key))&&(/^\d+(\.\d+)?$/.test(t)?te({volume:parseFloat(t)}):We.storage=JSON.parse(t)))}function te(t){O.supported&&E.storage.enabled&&(x(We.storage,t),e.localStorage.setItem(E.storage.key,JSON.stringify(We.storage)))}function ne(){if(We.media){if(We.supported.full&&(m(We.container,E.classes.type.replace("{0}",We.type),!0),s(E.types.embed,We.type)&&m(We.container,E.classes.type.replace("{0}","video"),!0),m(We.container,E.classes.stopped,E.autoplay),m(We.container,E.classes.isIos,We.browser.isIos),m(We.container,E.classes.isTouch,We.browser.isTouch),"video"===We.type)){var e=t.createElement("div");e.setAttribute("class",E.classes.videoWrapper),i(We.media,e),We.videoContainer=e}s(E.types.embed,We.type)&&re()}else Xe("No media element found!")}function re(){var n,r=t.createElement("div"),s=We.type+"-"+Math.floor(1e4*Math.random());switch(We.type){case"youtube":n=T(We.embedId);break;case"vimeo":n=S(We.embedId);break;default:n=We.embedId}for(var o=U('[id^="'+We.type+'-"]'),i=o.length-1;i>=0;i--)l(o[i]);if(m(We.media,E.classes.videoWrapper,!0),m(We.media,E.classes.embedWrapper,!0),"youtube"===We.type)We.media.appendChild(r),r.setAttribute("id",s),M.object(e.YT)?se(n,r):(a(E.urls.youtube.api),e.onYouTubeReadyCallbacks=e.onYouTubeReadyCallbacks||[],e.onYouTubeReadyCallbacks.push(function(){se(n,r)}),e.onYouTubeIframeAPIReady=function(){e.onYouTubeReadyCallbacks.forEach(function(e){e()})});else if("vimeo"===We.type)if(We.supported.full?We.media.appendChild(r):r=We.media,r.setAttribute("id",s),M.object(e.Vimeo))oe(n,r);else{a(E.urls.vimeo.api);var u=e.setInterval(function(){M.object(e.Vimeo)&&(e.clearInterval(u),oe(n,r))},50)}else if("soundcloud"===We.type){var d=t.createElement("iframe");d.loaded=!1,g(d,"load",function(){d.loaded=!0}),c(d,{src:"https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/"+n,id:s}),r.appendChild(d),We.media.appendChild(r),e.SC||a(E.urls.soundcloud.api);var p=e.setInterval(function(){e.SC&&d.loaded&&(e.clearInterval(p),ie.call(d))},50)}}function ae(){We.supported.full&&(qe(),De()),Z(B("iframe"))}function se(t,n){We.embed=new e.YT.Player(n.id,{videoId:t,playerVars:{autoplay:E.autoplay?1:0,controls:We.supported.full?0:1,rel:0,showinfo:0,iv_load_policy:3,cc_load_policy:E.captions.defaultActive?1:0,cc_lang_pref:"en",wmode:"transparent",modestbranding:1,disablekb:1,origin:"*"},events:{onError:function(e){L(We.container,"error",!0,{code:e.data,embed:e.target})},onReady:function(t){var n=t.target;We.media.play=function(){n.playVideo(),We.media.paused=!1},We.media.pause=function(){n.pauseVideo(),We.media.paused=!0},We.media.stop=function(){n.stopVideo(),We.media.paused=!0},We.media.duration=n.getDuration(),We.media.paused=!0,We.media.currentTime=0,We.media.muted=n.isMuted(),E.title=n.getVideoData().title,We.supported.full&&We.media.querySelector("iframe").setAttribute("tabindex","-1"),ae(),L(We.media,"timeupdate"),L(We.media,"durationchange"),e.clearInterval(Ye.buffering),Ye.buffering=e.setInterval(function(){We.media.buffered=n.getVideoLoadedFraction(),(null===We.media.lastBuffered||We.media.lastBufferedr&&(t=r),Ne(t);try{We.media.currentTime=t.toFixed(4)}catch(e){}if(s(E.types.embed,We.type)){switch(We.type){case"youtube":We.embed.seekTo(t);break;case"vimeo":We.embed.setCurrentTime(t.toFixed(0));break;case"soundcloud":We.embed.seekTo(1e3*t)}n&&ue(),L(We.media,"timeupdate"),We.media.seeking=!0,L(We.media,"seeking")}Be("Seeking to "+We.media.currentTime+" seconds"),W(t)}function fe(){var e=parseInt(E.duration),t=0;return null===We.media.duration||isNaN(We.media.duration)||(t=We.media.duration),isNaN(e)?t:e}function ye(){m(We.container,E.classes.playing,!We.media.paused),m(We.container,E.classes.stopped,We.media.paused),Me(We.media.paused)}function be(){N={x:e.pageXOffset||0,y:e.pageYOffset||0}}function ve(){e.scrollTo(N.x,N.y)}function ge(e){var n=I.supportsFullScreen;if(n){if(!e||e.type!==I.fullScreenEventName)return I.isFullScreen(We.container)?I.cancelFullScreen():(be(),I.requestFullScreen(We.container)),void(We.isFullscreen=I.isFullScreen(We.container));We.isFullscreen=I.isFullScreen(We.container)}else We.isFullscreen=!We.isFullscreen,t.body.style.overflow=We.isFullscreen?"hidden":"";m(We.container,E.classes.fullscreen.active,We.isFullscreen),$(We.isFullscreen),We.buttons&&We.buttons.fullscreen&&k(We.buttons.fullscreen,We.isFullscreen),L(We.container,We.isFullscreen?"enterfullscreen":"exitfullscreen",!0),!We.isFullscreen&&n&&ve()}function he(e){if(M.boolean(e)||(e=!We.media.muted),k(We.buttons.mute,e),We.media.muted=e,0===We.media.volume&&ke(E.volume),s(E.types.embed,We.type)){switch(We.type){case"youtube":We.embed[We.media.muted?"mute":"unMute"]();break;case"vimeo":case"soundcloud":We.embed.setVolume(We.media.muted?0:parseFloat(E.volume/E.volumeMax))}L(We.media,"volumechange")}}function ke(e){var t=E.volumeMax,n=E.volumeMin;if(M.undefined(e)&&(e=We.storage.volume),(null===e||isNaN(e))&&(e=E.volume),e>t&&(e=t),e0&&he()}function we(e){var t=We.media.muted?0:We.media.volume*E.volumeMax;M.number(e)||(e=E.volumeStep),ke(t+e)}function xe(e){var t=We.media.muted?0:We.media.volume*E.volumeMax;M.number(e)||(e=E.volumeStep),ke(t-e)}function Te(){var e=We.media.muted?0:We.media.volume*E.volumeMax;We.supported.full&&(We.volume.input&&(We.volume.input.value=e),We.volume.display&&(We.volume.display.value=e)),te({volume:e}),m(We.container,E.classes.muted,0===e),We.supported.full&&We.buttons.mute&&k(We.buttons.mute,0===e)}function Se(e){We.supported.full&&We.buttons.captions&&(M.boolean(e)||(e=-1===We.container.className.indexOf(E.classes.captions.active)),We.captionsEnabled=e,k(We.buttons.captions,We.captionsEnabled),m(We.container,E.classes.captions.active,We.captionsEnabled),L(We.container,We.captionsEnabled?"captionsenabled":"captionsdisabled",!0),te({captionsEnabled:We.captionsEnabled}))}function _e(e){var t="waiting"===e.type;clearTimeout(Ye.loading),Ye.loading=setTimeout(function(){m(We.container,E.classes.loading,t),Me(t)},t?250:0)}function Ee(e){if(We.supported.full){var t=We.progress.played,n=0,r=fe();if(e)switch(e.type){case"timeupdate":case"seeking":if(We.controls.pressed)return;n=w(We.media.currentTime,r),"timeupdate"===e.type&&We.buttons.seek&&(We.buttons.seek.value=n);break;case"playing":case"progress":t=We.progress.buffer,n=function(){var e=We.media.buffered;return e&&e.length?w(e.end(0),r):M.number(e)?100*e:0}()}Ce(t,n)}}function Ce(e,t){if(We.supported.full){if(M.undefined(t)&&(t=0),M.undefined(e)){if(!We.progress||!We.progress.buffer)return;e=We.progress.buffer}M.htmlElement(e)?e.value=t:e&&(e.bar&&(e.bar.value=t),e.text&&(e.text.innerHTML=t))}}function Fe(e,t){if(t){isNaN(e)&&(e=0),We.secs=parseInt(e%60),We.mins=parseInt(e/60%60),We.hours=parseInt(e/60/60%60);var n=parseInt(fe()/60/60%60)>0;We.secs=("0"+We.secs).slice(-2),We.mins=("0"+We.mins).slice(-2),t.innerHTML=(n?We.hours+":":"")+We.mins+":"+We.secs}}function Ae(){if(We.supported.full){var e=fe()||0;!We.duration&&E.displayDuration&&We.media.paused&&Fe(e,We.currentTime),We.duration&&Fe(e,We.duration),Pe()}}function Ie(e){Fe(We.media.currentTime,We.currentTime),e&&"timeupdate"===e.type&&We.media.seeking||Ee(e)}function Ne(e){M.number(e)||(e=0);var t=w(e,fe());We.progress&&We.progress.played&&(We.progress.played.value=t),We.buttons&&We.buttons.seek&&(We.buttons.seek.value=t)}function Pe(e){var t=fe();if(E.tooltips.seek&&We.progress.container&&0!==t){var n=We.progress.container.getBoundingClientRect(),r=0,a=E.classes.tooltip+"--visible";if(e)r=100/n.width*(e.pageX-n.left);else{if(!f(We.progress.tooltip,a))return;r=We.progress.tooltip.style.left.replace("%","")}r<0?r=0:r>100&&(r=100),Fe(t/100*r,We.progress.tooltip),We.progress.tooltip.style.left=r+"%",e&&s(["mouseenter","mouseleave"],e.type)&&m(We.progress.tooltip,a,"mouseenter"===e.type)}}function Me(t){if(E.hideControls&&"audio"!==We.type){var n=0,r=!1,a=t,o=f(We.container,E.classes.loading);if(M.boolean(t)||(t&&t.type?(r="enterfullscreen"===t.type,a=s(["mousemove","touchstart","mouseenter","focus"],t.type),s(["mousemove","touchmove"],t.type)&&(n=2e3),"focus"===t.type&&(n=3e3)):a=f(We.container,E.classes.hideControls)),e.clearTimeout(Ye.hover),a||We.media.paused||o){if(m(We.container,E.classes.hideControls,!1),We.media.paused||o)return;We.browser.isTouch&&(n=3e3)}a&&We.media.paused||(Ye.hover=e.setTimeout(function(){(!We.controls.pressed&&!We.controls.hover||r)&&m(We.container,E.classes.hideControls,!0)},n))}}function Oe(e){M.object(e)&&"sources"in e&&e.sources.length?(m(We.container,E.classes.ready,!1),ue(),Ne(),Ce(),Ve(),Re(function(){if(We.embed=null,l(We.media),"video"===We.type&&We.videoContainer&&l(We.videoContainer),We.container&&We.container.removeAttribute("class"),"type"in e&&(We.type=e.type,"video"===We.type)){var n=e.sources[0];"type"in n&&s(E.types.embed,n.type)&&(We.type=n.type)}switch(We.supported=F(We.type),We.type){case"video":We.media=t.createElement("video");break;case"audio":We.media=t.createElement("audio");break;case"youtube":case"vimeo":case"soundcloud":We.media=t.createElement("div"),We.embedId=e.sources[0].src}u(We.container,We.media),M.boolean(e.autoplay)&&(E.autoplay=e.autoplay),s(E.types.html5,We.type)&&(E.crossorigin&&We.media.setAttribute("crossorigin",""),E.autoplay&&We.media.setAttribute("autoplay",""),"poster"in e&&We.media.setAttribute("poster",e.poster),E.loop&&We.media.setAttribute("loop","")),m(We.container,E.classes.fullscreen.active,We.isFullscreen),m(We.container,E.classes.captions.active,We.captionsEnabled),K(),s(E.types.html5,We.type)&&J("source",e.sources),ne(),s(E.types.html5,We.type)&&("tracks"in e&&J("track",e.tracks),We.media.load()),(s(E.types.html5,We.type)||s(E.types.embed,We.type)&&!We.supported.full)&&(qe(),De()),E.title=e.title,Z()},!1)):Xe("Invalid source format")}function Le(){function n(){var e=ce(),t=We.buttons[e?"play":"pause"],n=We.buttons[e?"pause":"play"];if(n=n&&n.length>1?n[n.length-1]:n[0]){var r=f(t,E.classes.tabFocus);setTimeout(function(){n.focus(),r&&(m(t,E.classes.tabFocus,!1),m(n,E.classes.tabFocus,!0))},100)}}function r(){var e=t.activeElement;return e=e&&e!==t.body?t.querySelector(":focus"):null}function a(e){return e.keyCode?e.keyCode:e.which}function o(e){for(var t in We.buttons){var n=We.buttons[t];if(M.nodeList(n))for(var r=0;r0)&&(t?xe(n):we(n)),(e.deltaY>0||e.deltaX<0)&&(t?we(n):xe(n))})}function je(){if(g(We.media,"timeupdate seeking",Ie),g(We.media,"timeupdate",W),g(We.media,"durationchange loadedmetadata",Ae),g(We.media,"ended",function(){"video"===We.type&&E.showPosterOnEnd&&("video"===We.type&&H(),me(),We.media.load())}),g(We.media,"progress playing",Ee),g(We.media,"volumechange",Te),g(We.media,"play pause ended",ye),g(We.media,"waiting canplay seeked",_e),E.clickToPlay&&"audio"!==We.type){var e=B("."+E.classes.videoWrapper);if(!e)return;e.style.cursor="pointer",g(e,"click",function(){E.hideControls&&We.browser.isTouch&&!We.media.paused||(We.media.paused?le():We.media.ended?(me(),le()):ue())})}E.disableContextMenu&&g(We.media,"contextmenu",function(e){e.preventDefault()}),g(We.media,E.events.concat(["keyup","keydown"]).join(" "),function(e){L(We.container,e.type,!0)})}function Ve(){if(s(E.types.html5,We.type)){for(var e=We.media.querySelectorAll("source"),t=0;t=10&&(c=!0);break;case"soundcloud":u=!0,c=!a&&!o;break;default:c=(u=i&&l)&&!a}return{basic:u,full:c}}function A(e){if(M.string(e)?e=t.querySelector(e):M.undefined(e)&&(e=t.body),M.htmlElement(e)){var n=e.querySelectorAll("."+P.classes.setup),r=[];return Array.prototype.slice.call(n).forEach(function(e){M.object(e.plyr)&&r.push(e.plyr)}),r}return[]}var I,N={x:0,y:0},P={enabled:!0,debug:!1,autoplay:!1,loop:!1,seekTime:10,volume:10,volumeMin:0,volumeMax:10,volumeStep:1,duration:null,displayDuration:!0,loadSprite:!0,iconPrefix:"plyr",iconUrl:"https://cdn.plyr.io/2.0.13/plyr.svg",blankUrl:"https://cdn.plyr.io/static/blank.mp4",clickToPlay:!0,hideControls:!0,showPosterOnEnd:!1,disableContextMenu:!0,keyboardShorcuts:{focused:!0,global:!1},tooltips:{controls:!1,seek:!0},selectors:{html5:"video, audio",embed:"[data-type]",editable:"input, textarea, select, [contenteditable]",container:".plyr",controls:{container:null,wrapper:".plyr__controls"},labels:"[data-plyr]",buttons:{seek:'[data-plyr="seek"]',play:'[data-plyr="play"]',pause:'[data-plyr="pause"]',restart:'[data-plyr="restart"]',rewind:'[data-plyr="rewind"]',forward:'[data-plyr="fast-forward"]',mute:'[data-plyr="mute"]',captions:'[data-plyr="captions"]',fullscreen:'[data-plyr="fullscreen"]'},volume:{input:'[data-plyr="volume"]',display:".plyr__volume--display"},progress:{container:".plyr__progress",buffer:".plyr__progress--buffer",played:".plyr__progress--played"},captions:".plyr__captions",currentTime:".plyr__time--current",duration:".plyr__time--duration"},classes:{setup:"plyr--setup",ready:"plyr--ready",videoWrapper:"plyr__video-wrapper",embedWrapper:"plyr__video-embed",type:"plyr--{0}",stopped:"plyr--stopped",playing:"plyr--playing",muted:"plyr--muted",loading:"plyr--loading",hover:"plyr--hover",tooltip:"plyr__tooltip",hidden:"plyr__sr-only",hideControls:"plyr--hide-controls",isIos:"plyr--is-ios",isTouch:"plyr--is-touch",captions:{enabled:"plyr--captions-enabled",active:"plyr--captions-active"},fullscreen:{enabled:"plyr--fullscreen-enabled",active:"plyr--fullscreen-active"},tabFocus:"tab-focus"},captions:{defaultActive:!1},fullscreen:{enabled:!0,fallback:!0,allowAudio:!1},storage:{enabled:!0,key:"plyr"},controls:["play-large","play","progress","current-time","mute","volume","captions","fullscreen"],i18n:{restart:"Restart",rewind:"Rewind {seektime} secs",play:"Play",pause:"Pause",forward:"Forward {seektime} secs",played:"played",buffered:"buffered",currentTime:"Current time",duration:"Duration",volume:"Volume",toggleMute:"Toggle Mute",toggleCaptions:"Toggle Captions",toggleFullscreen:"Toggle Fullscreen",frameTitle:"Player for {title}"},types:{embed:["youtube","vimeo","soundcloud"],html5:["video","audio"]},urls:{vimeo:{api:"https://player.vimeo.com/api/player.js"},youtube:{api:"https://www.youtube.com/iframe_api"},soundcloud:{api:"https://w.soundcloud.com/player/api.js"}},listeners:{seek:null,play:null,pause:null,restart:null,rewind:null,forward:null,mute:null,volume:null,captions:null,fullscreen:null},events:["ready","ended","progress","stalled","playing","waiting","canplay","canplaythrough","loadstart","loadeddata","loadedmetadata","timeupdate","volumechange","play","pause","error","seeking","seeked","emptied"],logPrefix:"[Plyr]"},M={object:function(e){return null!==e&&"object"==typeof e},array:function(e){return null!==e&&"object"==typeof e&&e.constructor===Array},number:function(e){return null!==e&&("number"==typeof e&&!isNaN(e-0)||"object"==typeof e&&e.constructor===Number)},string:function(e){return null!==e&&("string"==typeof e||"object"==typeof e&&e.constructor===String)},boolean:function(e){return null!==e&&"boolean"==typeof e},nodeList:function(e){return null!==e&&e instanceof NodeList},htmlElement:function(e){return null!==e&&e instanceof HTMLElement},function:function(e){return null!==e&&"function"==typeof e},undefined:function(e){return null!==e&&void 0===e}},O={supported:function(){try{e.localStorage.setItem("___test","OK");var t=e.localStorage.getItem("___test");return e.localStorage.removeItem("___test"),"OK"===t}catch(e){return!1}return!1}()};return{setup:function(e,n){function r(e,t){f(t,P.classes.hook)||a.push({target:e,media:t})}var a=[],s=[],o=[P.selectors.html5,P.selectors.embed].join(",");if(M.string(e)?e=t.querySelectorAll(e):M.htmlElement(e)?e=[e]:M.nodeList(e)||M.array(e)||M.string(e)||(M.undefined(n)&&M.object(e)&&(n=e),e=t.querySelectorAll(o)),M.nodeList(e)&&(e=Array.prototype.slice.call(e)),!F().basic||!e.length)return!1;for(var i=0;i" + "name": "plyr", + "version": "2.0.14", + "description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player", + "homepage": "http://plyr.io", + "main": "src/js/plyr.js", + "dependencies": {}, + "devDependencies": { + "gulp": "^3.9.1", + "gulp-autoprefixer": "^3.1.0", + "gulp-clean-css": "^2.0.6", + "gulp-concat": "^2.3.3", + "gulp-less": "^3.0.5", + "gulp-open": "^2.0.0", + "gulp-rename": "^1.2.0", + "gulp-replace": "^0.5.3", + "gulp-s3": "^0.3.0", + "gulp-sass": "^2.3.1", + "gulp-size": "^2.1.0", + "gulp-svgmin": "^1.2.2", + "gulp-svgstore": "^5.0.5", + "gulp-uglify": "^1.5.3", + "gulp-util": "^3.0.7", + "run-sequence": "^1.1.5", + "through2": "^2.0.1" + }, + "keywords": ["HTML5 Video", "HTML5 Audio", "Media Player", "DASH", "Shaka", "WordPress", "HLS"], + "repository": { + "type": "git", + "url": "git://github.com/sampotts/plyr.git" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/sampotts/plyr/issues" + }, + "directories": { + "doc": "readme.md" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "Sam Potts " } diff --git a/readme.md b/readme.md index a3aa6298..3ffd6387 100644 --- a/readme.md +++ b/readme.md @@ -5,7 +5,7 @@ A simple, accessible and customizable HTML5, YouTube and Vimeo media player. [Checkout the demo](https://plyr.io) -[![Image of Plyr](https://cdn.selz.com/plyr/plyr_v1.8.9.png)](https://plyr.io) +[![Image of Plyr](https://cdn.plyr.io/demo/screenshot.png)](https://plyr.io) ## Why? We wanted a lightweight, accessible and customizable media player that supports [*modern*](#browser-support) browsers. Sure, there are many other players out there but we wanted to keep things simple, using the right elements for the job. @@ -137,7 +137,7 @@ Include the `plyr.js` script before the closing `` tag and then call `ply If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the JavaScript, you can use the following: ```html - + ``` ### CSS @@ -150,11 +150,11 @@ Include the `plyr.css` stylsheet into your `` If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for the default CSS, you can use the following: ```html - + ``` ### SVG Sprite -The SVG sprite is loaded automatically from our CDN (provided by [Fastly](https://www.fastly.com/)). To change this, see the [options](#options) below. For reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/2.0.13/plyr.svg`. +The SVG sprite is loaded automatically from our CDN (provided by [Fastly](https://www.fastly.com/)). To change this, see the [options](#options) below. For reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/2.0.14/plyr.svg`. ## Advanced diff --git a/src/js/plyr.js b/src/js/plyr.js index 352e0114..9f3420fe 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1,192 +1,213 @@ // ========================================================================== // Plyr -// plyr.js v2.0.13 +// plyr.js v2.0.14 // https://github.com/sampotts/plyr // License: The MIT License (MIT) // ========================================================================== // Credits: http://paypal.github.io/accessible-html5-video-player/ // ========================================================================== -;(function(root, factory) { - 'use strict'; +(function(root, factory) { + "use strict"; /*global define,module*/ - if (typeof module === 'object' && typeof module.exports === 'object') { + if (typeof module === "object" && typeof module.exports === "object") { // Node, CommonJS-like module.exports = factory(root, document); - } else if (typeof define === 'function' && define.amd) { + } else if (typeof define === "function" && define.amd) { // AMD - define([], function () { return factory(root, document); }); + define([], function() { + return factory(root, document); + }); } else { // Browser globals (root is window) root.plyr = factory(root, document); } -}(typeof window !== 'undefined' ? window : this, function(window, document) { - 'use strict'; +})(typeof window !== "undefined" ? window : this, function(window, document) { + "use strict"; // Globals var fullscreen, - scroll = { x: 0, y: 0 }, - - // Default config - defaults = { - enabled: true, - debug: false, - autoplay: false, - loop: false, - seekTime: 10, - volume: 10, - volumeMin: 0, - volumeMax: 10, - volumeStep: 1, - duration: null, - displayDuration: true, - loadSprite: true, - iconPrefix: 'plyr', - iconUrl: 'https://cdn.plyr.io/2.0.13/plyr.svg', - blankUrl: 'https://cdn.selz.com/plyr/blank.mp4', - clickToPlay: true, - hideControls: true, - showPosterOnEnd: false, - disableContextMenu: true, - keyboardShorcuts: { - focused: true, - global: false - }, - tooltips: { - controls: false, - seek: true - }, - selectors: { - html5: 'video, audio', - embed: '[data-type]', - editable: 'input, textarea, select, [contenteditable]', - container: '.plyr', - controls: { - container: null, - wrapper: '.plyr__controls' + scroll = { x: 0, y: 0 }, + // Default config + defaults = { + enabled: true, + debug: false, + autoplay: false, + loop: false, + seekTime: 10, + volume: 10, + volumeMin: 0, + volumeMax: 10, + volumeStep: 1, + duration: null, + displayDuration: true, + loadSprite: true, + iconPrefix: "plyr", + iconUrl: "https://cdn.plyr.io/2.0.14/plyr.svg", + blankUrl: "https://cdn.plyr.io/static/blank.mp4", + clickToPlay: true, + hideControls: true, + showPosterOnEnd: false, + disableContextMenu: true, + keyboardShorcuts: { + focused: true, + global: false }, - labels: '[data-plyr]', - buttons: { - seek: '[data-plyr="seek"]', - play: '[data-plyr="play"]', - pause: '[data-plyr="pause"]', - restart: '[data-plyr="restart"]', - rewind: '[data-plyr="rewind"]', - forward: '[data-plyr="fast-forward"]', - mute: '[data-plyr="mute"]', - captions: '[data-plyr="captions"]', - fullscreen: '[data-plyr="fullscreen"]' + tooltips: { + controls: false, + seek: true }, - volume: { - input: '[data-plyr="volume"]', - display: '.plyr__volume--display' + selectors: { + html5: "video, audio", + embed: "[data-type]", + editable: "input, textarea, select, [contenteditable]", + container: ".plyr", + controls: { + container: null, + wrapper: ".plyr__controls" + }, + labels: "[data-plyr]", + buttons: { + seek: '[data-plyr="seek"]', + play: '[data-plyr="play"]', + pause: '[data-plyr="pause"]', + restart: '[data-plyr="restart"]', + rewind: '[data-plyr="rewind"]', + forward: '[data-plyr="fast-forward"]', + mute: '[data-plyr="mute"]', + captions: '[data-plyr="captions"]', + fullscreen: '[data-plyr="fullscreen"]' + }, + volume: { + input: '[data-plyr="volume"]', + display: ".plyr__volume--display" + }, + progress: { + container: ".plyr__progress", + buffer: ".plyr__progress--buffer", + played: ".plyr__progress--played" + }, + captions: ".plyr__captions", + currentTime: ".plyr__time--current", + duration: ".plyr__time--duration" }, - progress: { - container: '.plyr__progress', - buffer: '.plyr__progress--buffer', - played: '.plyr__progress--played' + classes: { + setup: "plyr--setup", + ready: "plyr--ready", + videoWrapper: "plyr__video-wrapper", + embedWrapper: "plyr__video-embed", + type: "plyr--{0}", + stopped: "plyr--stopped", + playing: "plyr--playing", + muted: "plyr--muted", + loading: "plyr--loading", + hover: "plyr--hover", + tooltip: "plyr__tooltip", + hidden: "plyr__sr-only", + hideControls: "plyr--hide-controls", + isIos: "plyr--is-ios", + isTouch: "plyr--is-touch", + captions: { + enabled: "plyr--captions-enabled", + active: "plyr--captions-active" + }, + fullscreen: { + enabled: "plyr--fullscreen-enabled", + active: "plyr--fullscreen-active" + }, + tabFocus: "tab-focus" }, - captions: '.plyr__captions', - currentTime: '.plyr__time--current', - duration: '.plyr__time--duration' - }, - classes: { - setup: 'plyr--setup', - ready: 'plyr--ready', - videoWrapper: 'plyr__video-wrapper', - embedWrapper: 'plyr__video-embed', - type: 'plyr--{0}', - stopped: 'plyr--stopped', - playing: 'plyr--playing', - muted: 'plyr--muted', - loading: 'plyr--loading', - hover: 'plyr--hover', - tooltip: 'plyr__tooltip', - hidden: 'plyr__sr-only', - hideControls: 'plyr--hide-controls', - isIos: 'plyr--is-ios', - isTouch: 'plyr--is-touch', captions: { - enabled: 'plyr--captions-enabled', - active: 'plyr--captions-active' + defaultActive: false }, fullscreen: { - enabled: 'plyr--fullscreen-enabled', - active: 'plyr--fullscreen-active' + enabled: true, + fallback: true, + allowAudio: false }, - tabFocus: 'tab-focus' - }, - captions: { - defaultActive: false - }, - fullscreen: { - enabled: true, - fallback: true, - allowAudio: false - }, - storage: { - enabled: true, - key: 'plyr' - }, - controls: ['play-large', 'play', 'progress', 'current-time', 'mute', 'volume', 'captions', 'fullscreen'], - i18n: { - restart: 'Restart', - rewind: 'Rewind {seektime} secs', - play: 'Play', - pause: 'Pause', - forward: 'Forward {seektime} secs', - played: 'played', - buffered: 'buffered', - currentTime: 'Current time', - duration: 'Duration', - volume: 'Volume', - toggleMute: 'Toggle Mute', - toggleCaptions: 'Toggle Captions', - toggleFullscreen: 'Toggle Fullscreen', - frameTitle: 'Player for {title}' - }, - types: { - embed: ['youtube', 'vimeo', 'soundcloud'], - html5: ['video', 'audio'] - }, - // URLs - urls: { - vimeo: { - api: 'https://player.vimeo.com/api/player.js', + storage: { + enabled: true, + key: "plyr" }, - youtube: { - api: 'https://www.youtube.com/iframe_api' + controls: ["play-large", "play", "progress", "current-time", "mute", "volume", "captions", "fullscreen"], + i18n: { + restart: "Restart", + rewind: "Rewind {seektime} secs", + play: "Play", + pause: "Pause", + forward: "Forward {seektime} secs", + played: "played", + buffered: "buffered", + currentTime: "Current time", + duration: "Duration", + volume: "Volume", + toggleMute: "Toggle Mute", + toggleCaptions: "Toggle Captions", + toggleFullscreen: "Toggle Fullscreen", + frameTitle: "Player for {title}" }, - soundcloud: { - api: 'https://w.soundcloud.com/player/api.js' - } - }, - // Custom control listeners - listeners: { - seek: null, - play: null, - pause: null, - restart: null, - rewind: null, - forward: null, - mute: null, - volume: null, - captions: null, - fullscreen: null - }, - // Events to watch on HTML5 media elements - events: ['ready', 'ended', 'progress', 'stalled', 'playing', 'waiting', 'canplay', 'canplaythrough', 'loadstart', 'loadeddata', 'loadedmetadata', 'timeupdate', 'volumechange', 'play', 'pause', 'error', 'seeking', 'seeked', 'emptied'], - // Logging - logPrefix: '[Plyr]' - }; + types: { + embed: ["youtube", "vimeo", "soundcloud"], + html5: ["video", "audio"] + }, + // URLs + urls: { + vimeo: { + api: "https://player.vimeo.com/api/player.js" + }, + youtube: { + api: "https://www.youtube.com/iframe_api" + }, + soundcloud: { + api: "https://w.soundcloud.com/player/api.js" + } + }, + // Custom control listeners + listeners: { + seek: null, + play: null, + pause: null, + restart: null, + rewind: null, + forward: null, + mute: null, + volume: null, + captions: null, + fullscreen: null + }, + // Events to watch on HTML5 media elements + events: [ + "ready", + "ended", + "progress", + "stalled", + "playing", + "waiting", + "canplay", + "canplaythrough", + "loadstart", + "loadeddata", + "loadedmetadata", + "timeupdate", + "volumechange", + "play", + "pause", + "error", + "seeking", + "seeked", + "emptied" + ], + // Logging + logPrefix: "[Plyr]" + }; // Credits: http://paypal.github.io/accessible-html5-video-player/ // Unfortunately, due to mixed support, UA sniffing is required function _browserSniff() { var ua = navigator.userAgent, name = navigator.appName, - fullVersion = '' + parseFloat(navigator.appVersion), + fullVersion = "" + parseFloat(navigator.appVersion), majorVersion = parseInt(navigator.appVersion, 10), nameOffset, verOffset, @@ -196,37 +217,37 @@ isChrome = false, isSafari = false; - if ((navigator.appVersion.indexOf('Windows NT') !== -1) && (navigator.appVersion.indexOf('rv:11') !== -1)) { + if (navigator.appVersion.indexOf("Windows NT") !== -1 && navigator.appVersion.indexOf("rv:11") !== -1) { // MSIE 11 isIE = true; - name = 'IE'; - fullVersion = '11'; - } else if ((verOffset = ua.indexOf('MSIE')) !== -1) { + name = "IE"; + fullVersion = "11"; + } else if ((verOffset = ua.indexOf("MSIE")) !== -1) { // MSIE isIE = true; - name = 'IE'; + name = "IE"; fullVersion = ua.substring(verOffset + 5); - } else if ((verOffset = ua.indexOf('Chrome')) !== -1) { + } else if ((verOffset = ua.indexOf("Chrome")) !== -1) { // Chrome isChrome = true; - name = 'Chrome'; + name = "Chrome"; fullVersion = ua.substring(verOffset + 7); - } else if ((verOffset = ua.indexOf('Safari')) !== -1) { + } else if ((verOffset = ua.indexOf("Safari")) !== -1) { // Safari isSafari = true; - name = 'Safari'; + name = "Safari"; fullVersion = ua.substring(verOffset + 7); - if ((verOffset = ua.indexOf('Version')) !== -1) { + if ((verOffset = ua.indexOf("Version")) !== -1) { fullVersion = ua.substring(verOffset + 8); } - } else if ((verOffset = ua.indexOf('Firefox')) !== -1) { + } else if ((verOffset = ua.indexOf("Firefox")) !== -1) { // Firefox isFirefox = true; - name = 'Firefox'; + name = "Firefox"; fullVersion = ua.substring(verOffset + 8); - } else if ((nameOffset = ua.lastIndexOf(' ') + 1) < (verOffset = ua.lastIndexOf('/'))) { + } else if ((nameOffset = ua.lastIndexOf(" ") + 1) < (verOffset = ua.lastIndexOf("/"))) { // In most other browsers, 'name/version' is at the end of userAgent - name = ua.substring(nameOffset,verOffset); + name = ua.substring(nameOffset, verOffset); fullVersion = ua.substring(verOffset + 1); if (name.toLowerCase() === name.toUpperCase()) { @@ -235,31 +256,31 @@ } // Trim the fullVersion string at semicolon/space if present - if ((ix = fullVersion.indexOf(';')) !== -1) { + if ((ix = fullVersion.indexOf(";")) !== -1) { fullVersion = fullVersion.substring(0, ix); } - if ((ix = fullVersion.indexOf(' ')) !== -1) { + if ((ix = fullVersion.indexOf(" ")) !== -1) { fullVersion = fullVersion.substring(0, ix); } // Get major version - majorVersion = parseInt('' + fullVersion, 10); + majorVersion = parseInt("" + fullVersion, 10); if (isNaN(majorVersion)) { - fullVersion = '' + parseFloat(navigator.appVersion); + fullVersion = "" + parseFloat(navigator.appVersion); majorVersion = parseInt(navigator.appVersion, 10); } // Return data return { - name: name, - version: majorVersion, - isIE: isIE, - isFirefox: isFirefox, - isChrome: isChrome, - isSafari: isSafari, - isIos: /(iPad|iPhone|iPod)/g.test(navigator.platform), - isIphone: /(iPhone|iPod)/g.test(navigator.userAgent), - isTouch: 'ontouchstart' in document.documentElement + name: name, + version: majorVersion, + isIE: isIE, + isFirefox: isFirefox, + isChrome: isChrome, + isSafari: isSafari, + isIos: /(iPad|iPhone|iPod)/g.test(navigator.platform), + isIphone: /(iPhone|iPod)/g.test(navigator.userAgent), + isTouch: "ontouchstart" in document.documentElement }; } @@ -269,19 +290,30 @@ function _supportMime(plyr, mimeType) { var media = plyr.media; - if (plyr.type === 'video') { + if (plyr.type === "video") { // Check type switch (mimeType) { - case 'video/webm': return !!(media.canPlayType && media.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/no/, '')); - case 'video/mp4': return !!(media.canPlayType && media.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/, '')); - case 'video/ogg': return !!(media.canPlayType && media.canPlayType('video/ogg; codecs="theora"').replace(/no/, '')); + case "video/webm": + return !!( + media.canPlayType && media.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/no/, "") + ); + case "video/mp4": + return !!( + media.canPlayType && + media.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/, "") + ); + case "video/ogg": + return !!(media.canPlayType && media.canPlayType('video/ogg; codecs="theora"').replace(/no/, "")); } - } else if (plyr.type === 'audio') { + } else if (plyr.type === "audio") { // Check type switch (mimeType) { - case 'audio/mpeg': return !!(media.canPlayType && media.canPlayType('audio/mpeg;').replace(/no/, '')); - case 'audio/ogg': return !!(media.canPlayType && media.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/, '')); - case 'audio/wav': return !!(media.canPlayType && media.canPlayType('audio/wav; codecs="1"').replace(/no/, '')); + case "audio/mpeg": + return !!(media.canPlayType && media.canPlayType("audio/mpeg;").replace(/no/, "")); + case "audio/ogg": + return !!(media.canPlayType && media.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/, "")); + case "audio/wav": + return !!(media.canPlayType && media.canPlayType('audio/wav; codecs="1"').replace(/no/, "")); } } @@ -295,20 +327,20 @@ return; } - var tag = document.createElement('script'); + var tag = document.createElement("script"); tag.src = source; - var firstScriptTag = document.getElementsByTagName('script')[0]; + var firstScriptTag = document.getElementsByTagName("script")[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); } // Element exists in an array function _inArray(haystack, needle) { - return Array.prototype.indexOf && (haystack.indexOf(needle) !== -1); + return Array.prototype.indexOf && haystack.indexOf(needle) !== -1; } // Replace all function _replaceAll(string, find, replace) { - return string.replace(new RegExp(find.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g, '\\$1'), 'g'), replace); + return string.replace(new RegExp(find.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g, "\\$1"), "g"), replace); } // Wrap an element @@ -321,11 +353,11 @@ // Loops backwards to prevent having to clone the wrapper on the // first element (see `child` below). for (var i = elements.length - 1; i >= 0; i--) { - var child = (i > 0) ? wrapper.cloneNode(true) : wrapper; + var child = i > 0 ? wrapper.cloneNode(true) : wrapper; var element = elements[i]; // Cache the current parent and sibling. - var parent = element.parentNode; + var parent = element.parentNode; var sibling = element.nextSibling; // Wrap the element (is automatically removed from its current @@ -376,7 +408,7 @@ // Set attributes function _setAttributes(element, attributes) { for (var key in attributes) { - element.setAttribute(key, (_is.boolean(attributes[key]) && attributes[key]) ? '' : attributes[key]); + element.setAttribute(key, _is.boolean(attributes[key]) && attributes[key] ? "" : attributes[key]); } } @@ -394,17 +426,17 @@ // Get a classname from selector function _getClassname(selector) { - return selector.replace('.', ''); + return selector.replace(".", ""); } // Toggle class on an element function _toggleClass(element, className, state) { if (element) { if (element.classList) { - element.classList[state ? 'add' : 'remove'](className); + element.classList[state ? "add" : "remove"](className); } else { - var name = (' ' + element.className + ' ').replace(/\s+/g, ' ').replace(' ' + className + ' ', ''); - element.className = name + (state ? ' ' + className : ''); + var name = (" " + element.className + " ").replace(/\s+/g, " ").replace(" " + className + " ", ""); + element.className = name + (state ? " " + className : ""); } } } @@ -415,7 +447,7 @@ if (element.classList) { return element.classList.contains(className); } else { - return new RegExp('(\\s|^)' + className + '(\\s|$)').test(element.className); + return new RegExp("(\\s|^)" + className + "(\\s|$)").test(element.className); } } return false; @@ -425,26 +457,36 @@ function _matches(element, selector) { var p = Element.prototype; - var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) { - return [].indexOf.call(document.querySelectorAll(s), this) !== -1; - }; + var f = + p.matches || + p.webkitMatchesSelector || + p.mozMatchesSelector || + p.msMatchesSelector || + function(s) { + return [].indexOf.call(document.querySelectorAll(s), this) !== -1; + }; return f.call(element, selector); } // Bind along with custom handler function _proxyListener(element, eventName, userListener, defaultListener, useCapture) { - _on(element, eventName, function(event) { - if (userListener) { - userListener.apply(element, [event]); - } - defaultListener.apply(element, [event]); - }, useCapture); + _on( + element, + eventName, + function(event) { + if (userListener) { + userListener.apply(element, [event]); + } + defaultListener.apply(element, [event]); + }, + useCapture + ); } // Toggle event listener function _toggleListener(element, events, callback, toggle, useCapture) { - var eventList = events.split(' '); + var eventList = events.split(" "); // Whether the listener is a capturing listener or not // Default to false @@ -464,7 +506,7 @@ // If a single node is passed, bind the event listener for (var i = 0; i < eventList.length; i++) { - element[toggle ? 'addEventListener' : 'removeEventListener'](eventList[i], callback, useCapture); + element[toggle ? "addEventListener" : "removeEventListener"](eventList[i], callback, useCapture); } } @@ -496,8 +538,8 @@ // Create and dispatch the event var event = new CustomEvent(type, { - bubbles: bubbles, - detail: properties + bubbles: bubbles, + detail: properties }); // Dispatch the event @@ -513,10 +555,10 @@ } // Get state - state = (_is.boolean(state) ? state : !target.getAttribute('aria-pressed')); + state = _is.boolean(state) ? state : !target.getAttribute("aria-pressed"); // Set the attribute on target - target.setAttribute('aria-pressed', state); + target.setAttribute("aria-pressed", state); return state; } @@ -526,7 +568,7 @@ if (current === 0 || max === 0 || isNaN(current) || isNaN(max)) { return 0; } - return ((current / max) * 100).toFixed(2); + return (current / max * 100).toFixed(2); } // Deep extend/merge destination object with N more objects @@ -548,7 +590,7 @@ // First object is the destination var destination = Array.prototype.shift.call(objects), - length = objects.length; + length = objects.length; // Loop through all objects to merge for (var i = 0; i < length; i++) { @@ -570,19 +612,26 @@ // Check variable types var _is = { object: function(input) { - return input !== null && typeof(input) === 'object'; + 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 input !== null && (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 input !== null && (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 input !== null && typeof input === 'boolean'; + return input !== null && typeof input === "boolean"; }, nodeList: function(input) { return input !== null && input instanceof NodeList; @@ -591,52 +640,54 @@ return input !== null && input instanceof HTMLElement; }, function: function(input) { - return input !== null && typeof input === 'function'; + return input !== null && typeof input === "function"; }, undefined: function(input) { - return input !== null && typeof input === 'undefined'; + return input !== null && typeof input === "undefined"; } }; // Parse YouTube ID from url function _parseYouTubeId(url) { var regex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/; - return (url.match(regex)) ? RegExp.$2 : url; + return url.match(regex) ? RegExp.$2 : url; } // Parse Vimeo ID from url function _parseVimeoId(url) { var regex = /^.*(vimeo.com\/|video\/)(\d+).*/; - return (url.match(regex)) ? RegExp.$2 : url; + return url.match(regex) ? RegExp.$2 : url; } // Fullscreen API function _fullscreen() { var fullscreen = { supportsFullScreen: false, - isFullScreen: function() { return false; }, + isFullScreen: function() { + return false; + }, requestFullScreen: function() {}, cancelFullScreen: function() {}, - fullScreenEventName: '', + fullScreenEventName: "", element: null, - prefix: '' + prefix: "" }, - browserPrefixes = 'webkit o moz ms khtml'.split(' '); + browserPrefixes = "webkit o moz ms khtml".split(" "); // Check for native support if (!_is.undefined(document.cancelFullScreen)) { fullscreen.supportsFullScreen = true; } else { // Check for fullscreen support by vendor prefix - for (var i = 0, il = browserPrefixes.length; i < il; i++ ) { + for (var i = 0, il = browserPrefixes.length; i < il; i++) { fullscreen.prefix = browserPrefixes[i]; - if (!_is.undefined(document[fullscreen.prefix + 'CancelFullScreen'])) { + if (!_is.undefined(document[fullscreen.prefix + "CancelFullScreen"])) { fullscreen.supportsFullScreen = true; break; } else if (!_is.undefined(document.msExitFullscreen) && document.msFullscreenEnabled) { // Special case for MS (when isn't it?) - fullscreen.prefix = 'ms'; + fullscreen.prefix = "ms"; fullscreen.supportsFullScreen = true; break; } @@ -647,32 +698,37 @@ if (fullscreen.supportsFullScreen) { // Yet again Microsoft awesomeness, // Sometimes the prefix is 'ms', sometimes 'MS' to keep you on your toes - fullscreen.fullScreenEventName = (fullscreen.prefix === 'ms' ? 'MSFullscreenChange' : fullscreen.prefix + 'fullscreenchange'); + fullscreen.fullScreenEventName = + fullscreen.prefix === "ms" ? "MSFullscreenChange" : fullscreen.prefix + "fullscreenchange"; fullscreen.isFullScreen = function(element) { if (_is.undefined(element)) { element = document.body; } switch (this.prefix) { - case '': + case "": return document.fullscreenElement === element; - case 'moz': + case "moz": return document.mozFullScreenElement === element; default: - return document[this.prefix + 'FullscreenElement'] === element; + return document[this.prefix + "FullscreenElement"] === element; } }; fullscreen.requestFullScreen = function(element) { if (_is.undefined(element)) { element = document.body; } - return (this.prefix === '') ? element.requestFullScreen() : element[this.prefix + (this.prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')](); + return this.prefix === "" + ? element.requestFullScreen() + : element[this.prefix + (this.prefix === "ms" ? "RequestFullscreen" : "RequestFullScreen")](); }; fullscreen.cancelFullScreen = function() { - return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + (this.prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen')](); + return this.prefix === "" + ? document.cancelFullScreen() + : document[this.prefix + (this.prefix === "ms" ? "ExitFullscreen" : "CancelFullScreen")](); }; fullscreen.element = function() { - return (this.prefix === '') ? document.fullscreenElement : document[this.prefix + 'FullscreenElement']; + return this.prefix === "" ? document.fullscreenElement : document[this.prefix + "FullscreenElement"]; }; } @@ -682,26 +738,21 @@ // Local storage var _storage = { supported: (function() { - if (!('localStorage' in window)) { - return false; - } - // Try to use it (it might be disabled, e.g. user is in private/porn mode) // see: https://github.com/sampotts/plyr/issues/131 try { // Add test item - window.localStorage.setItem('___test', 'OK'); + window.localStorage.setItem("___test", "OK"); // Get the test item - var result = window.localStorage.getItem('___test'); + var result = window.localStorage.getItem("___test"); // Clean up - window.localStorage.removeItem('___test'); + window.localStorage.removeItem("___test"); // Check if value matches - return (result === 'OK'); - } - catch (e) { + return result === "OK"; + } catch (e) { return false; } @@ -712,8 +763,8 @@ // Player instance function Plyr(media, config) { var plyr = this, - timers = {}, - api; + timers = {}, + api; // Set media plyr.media = media; @@ -721,9 +772,14 @@ // Trigger events, with plyr instance passed function _triggerEvent(element, type, bubbles, properties) { - _event(element, type, bubbles, _extend({}, properties, { - plyr: api - })); + _event( + element, + type, + bubbles, + _extend({}, properties, { + plyr: api + }) + ); } // Debugging @@ -738,94 +794,100 @@ console[type].apply(console, args); } } - var _log = function() { _console('log', arguments) }, - _warn = function() { _console('warn', arguments) }; + var _log = function() { + _console("log", arguments); + }, + _warn = function() { + _console("warn", arguments); + }; // Log config options - _log('Config', config); + _log("Config", config); // Get icon URL function _getIconUrl() { return { - url: config.iconUrl, - absolute: (config.iconUrl.indexOf("http") === 0) || plyr.browser.isIE + url: config.iconUrl, + absolute: config.iconUrl.indexOf("http") === 0 || plyr.browser.isIE }; } // Build the default HTML function _buildControls() { // Create html array - var html = [], - iconUrl = _getIconUrl(), - iconPath = (!iconUrl.absolute ? iconUrl.url : '') + '#' + config.iconPrefix; + var html = [], + iconUrl = _getIconUrl(), + iconPath = (!iconUrl.absolute ? iconUrl.url : "") + "#" + config.iconPrefix; // Larger overlaid play button - if (_inArray(config.controls, 'play-large')) { + if (_inArray(config.controls, "play-large")) { html.push( '' + '', + '' + config.i18n.play + "", + "" ); } html.push('
'); // Restart button - if (_inArray(config.controls, 'restart')) { + if (_inArray(config.controls, "restart")) { html.push( '' + '', + '' + config.i18n.restart + "", + "" ); } // Rewind button - if (_inArray(config.controls, 'rewind')) { + if (_inArray(config.controls, "rewind")) { html.push( '' + '', + '' + config.i18n.rewind + "", + "" ); } // Play Pause button // TODO: This should be a toggle button really? - if (_inArray(config.controls, 'play')) { + if (_inArray(config.controls, "play")) { html.push( '', + '', + '' + config.i18n.play + "", + "", '' + '', + '' + config.i18n.pause + "", + "" ); } // Fast forward button - if (_inArray(config.controls, 'fast-forward')) { + if (_inArray(config.controls, "fast-forward")) { html.push( '' + '', + '' + config.i18n.forward + "", + "" ); } // Progress - if (_inArray(config.controls, 'progress')) { + if (_inArray(config.controls, "progress")) { // Create progress - html.push('', + html.push( + '', '', '', '', '', - '0% ' + config.i18n.buffered, - ''); + "0% " + config.i18n.buffered, + "" + ); // Seek tooltip if (config.tooltips.seek) { @@ -833,77 +895,87 @@ } // Close - html.push(''); + html.push(""); } // Media current time display - if (_inArray(config.controls, 'current-time')) { + if (_inArray(config.controls, "current-time")) { html.push( '', - '' + config.i18n.currentTime + '', - '00:00', - '' + '' + config.i18n.currentTime + "", + '00:00', + "" ); } // Media duration display - if (_inArray(config.controls, 'duration')) { + if (_inArray(config.controls, "duration")) { html.push( '', - '' + config.i18n.duration + '', - '00:00', - '' + '' + config.i18n.duration + "", + '00:00', + "" ); } // Toggle mute button - if (_inArray(config.controls, 'mute')) { + if (_inArray(config.controls, "mute")) { html.push( '' + '', + '', + '' + config.i18n.toggleMute + "", + "" ); } // Volume range control - if (_inArray(config.controls, 'volume')) { + if (_inArray(config.controls, "volume")) { html.push( '', - '', - '', - '', - '' + '", + '', + '', + "" ); } // Toggle captions button - if (_inArray(config.controls, 'captions')) { + if (_inArray(config.controls, "captions")) { html.push( '' + '', + '', + '' + config.i18n.toggleCaptions + "", + "" ); } // Toggle fullscreen button - if (_inArray(config.controls, 'fullscreen')) { + if (_inArray(config.controls, "fullscreen")) { html.push( '' + '', + '', + '' + config.i18n.toggleFullscreen + "", + "" ); } // Close everything - html.push('
'); + html.push(""); - return html.join(''); + return html.join(""); } // Setup fullscreen @@ -912,17 +984,17 @@ return; } - if ((plyr.type !== 'audio' || config.fullscreen.allowAudio) && config.fullscreen.enabled) { + if ((plyr.type !== "audio" || config.fullscreen.allowAudio) && config.fullscreen.enabled) { // Check for native support var nativeSupport = fullscreen.supportsFullScreen; if (nativeSupport || (config.fullscreen.fallback && !_inFrame())) { - _log((nativeSupport ? 'Native' : 'Fallback') + ' fullscreen enabled'); + _log((nativeSupport ? "Native" : "Fallback") + " fullscreen enabled"); // Add styling hook _toggleClass(plyr.container, config.classes.fullscreen.enabled, true); } else { - _log('Fullscreen not supported and fallback disabled'); + _log("Fullscreen not supported and fallback disabled"); } // Toggle state @@ -938,13 +1010,16 @@ // Setup captions function _setupCaptions() { // Bail if not HTML5 video - if (plyr.type !== 'video') { + if (plyr.type !== "video") { return; } // Inject the container if (!_getElement(config.selectors.captions)) { - plyr.videoContainer.insertAdjacentHTML('afterbegin', '
'); + plyr.videoContainer.insertAdjacentHTML( + "afterbegin", + '
' + ); } // Determine if HTML5 textTracks is supported @@ -954,26 +1029,26 @@ } // Get URL of caption file if exists - var captionSrc = '', + var captionSrc = "", kind, children = plyr.media.childNodes; for (var i = 0; i < children.length; i++) { - if (children[i].nodeName.toLowerCase() === 'track') { + if (children[i].nodeName.toLowerCase() === "track") { kind = children[i].kind; - if (kind === 'captions' || kind === 'subtitles') { - captionSrc = children[i].getAttribute('src'); + if (kind === "captions" || kind === "subtitles") { + captionSrc = children[i].getAttribute("src"); } } } // Record if caption file exists or not plyr.captionExists = true; - if (captionSrc === '') { + if (captionSrc === "") { plyr.captionExists = false; - _log('No caption track found'); + _log("No caption track found"); } else { - _log('Caption track found; URI: ' + captionSrc); + _log("Caption track found; URI: " + captionSrc); } // If no caption file exists, hide container for caption text @@ -984,7 +1059,7 @@ // This doesn't seem to work in Safari 7+, so the elements are removed from the dom below var tracks = plyr.media.textTracks; for (var x = 0; x < tracks.length; x++) { - tracks[x].mode = 'hidden'; + tracks[x].mode = "hidden"; } // Enable UI @@ -992,11 +1067,12 @@ // Disable unsupported browsers than report false positive // Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1033144 - if ((plyr.browser.isIE && plyr.browser.version >= 10) || - (plyr.browser.isFirefox && plyr.browser.version >= 31)) { - + if ( + (plyr.browser.isIE && plyr.browser.version >= 10) || + (plyr.browser.isFirefox && plyr.browser.version >= 31) + ) { // Debugging - _log('Detected browser with known TextTrack issues - using manual fallback'); + _log("Detected browser with known TextTrack issues - using manual fallback"); // Set to false so skips to 'manual' captioning plyr.usingTextTracks = false; @@ -1005,15 +1081,15 @@ // Rendering caption tracks // Native support required - http://caniuse.com/webvtt if (plyr.usingTextTracks) { - _log('TextTracks supported'); + _log("TextTracks supported"); for (var y = 0; y < tracks.length; y++) { var track = tracks[y]; - if (track.kind === 'captions' || track.kind === 'subtitles') { - _on(track, 'cuechange', function() { + if (track.kind === "captions" || track.kind === "subtitles") { + _on(track, "cuechange", function() { // Display a cue, if there is one - if (this.activeCues[0] && 'text' in this.activeCues[0]) { + if (this.activeCues[0] && "text" in this.activeCues[0]) { _setCaption(this.activeCues[0].getCueAsHTML()); } else { _setCaption(); @@ -1023,13 +1099,13 @@ } } else { // Caption tracks not natively supported - _log('TextTracks not supported so rendering captions manually'); + _log("TextTracks not supported so rendering captions manually"); // Render captions from array at appropriate time - plyr.currentCaption = ''; + plyr.currentCaption = ""; plyr.captions = []; - if (captionSrc !== '') { + if (captionSrc !== "") { // Create XMLHttpRequest Object var xhr = new XMLHttpRequest(); @@ -1042,16 +1118,16 @@ //According to webvtt spec, line terminator consists of one of the following // CRLF (U+000D U+000A), LF (U+000A) or CR (U+000D) - var lineSeparator = '\r\n'; - if(req.indexOf(lineSeparator+lineSeparator) === -1) { - if(req.indexOf('\r\r') !== -1){ - lineSeparator = '\r'; + var lineSeparator = "\r\n"; + if (req.indexOf(lineSeparator + lineSeparator) === -1) { + if (req.indexOf("\r\r") !== -1) { + lineSeparator = "\r"; } else { - lineSeparator = '\n'; + lineSeparator = "\n"; } } - captions = req.split(lineSeparator+lineSeparator); + captions = req.split(lineSeparator + lineSeparator); for (var r = 0; r < captions.length; r++) { caption = captions[r]; @@ -1072,14 +1148,14 @@ // Remove first element ('VTT') plyr.captions.shift(); - _log('Successfully loaded the caption file via AJAX'); + _log("Successfully loaded the caption file via AJAX"); } else { - _warn(config.logPrefix + 'There was a problem loading the caption file via AJAX'); + _warn(config.logPrefix + "There was a problem loading the caption file via AJAX"); } } }; - xhr.open('get', captionSrc, true); + xhr.open("get", captionSrc, true); xhr.send(); } @@ -1091,14 +1167,14 @@ function _setCaption(caption) { /* jshint unused:false */ var container = _getElement(config.selectors.captions), - content = document.createElement('span'); + content = document.createElement("span"); // Empty the container - container.innerHTML = ''; + container.innerHTML = ""; // Default to empty if (_is.undefined(caption)) { - caption = ''; + caption = ""; } // Set the span content @@ -1121,8 +1197,8 @@ // Utilities for caption time codes function _timecodeCommon(tc, pos) { var tcpair = []; - tcpair = tc.split(' --> '); - for(var i = 0; i < tcpair.length; i++) { + tcpair = tc.split(" --> "); + for (var i = 0; i < tcpair.length; i++) { // WebVTT allows for extra meta data after the timestamp line // So get rid of this if it exists tcpair[i] = tcpair[i].replace(/(\d+:\d+:\d+\.\d+).*/, "$1"); @@ -1142,15 +1218,15 @@ var tc1 = [], tc2 = [], seconds; - tc1 = tc.split(','); - tc2 = tc1[0].split(':'); - seconds = Math.floor(tc2[0]*60*60) + Math.floor(tc2[1]*60) + Math.floor(tc2[2]); + tc1 = tc.split(","); + tc2 = tc1[0].split(":"); + seconds = Math.floor(tc2[0] * 60 * 60) + Math.floor(tc2[1] * 60) + Math.floor(tc2[2]); return seconds; } } // If it's not video, or we're using textTracks, bail. - if (plyr.usingTextTracks || plyr.type !== 'video' || !plyr.supported.full) { + if (plyr.usingTextTracks || plyr.type !== "video" || !plyr.supported.full) { return; } @@ -1176,9 +1252,11 @@ } // Check if the next caption is in the current time range - if (plyr.media.currentTime.toFixed(1) >= _timecodeMin(plyr.captions[plyr.subcount][0]) && - plyr.media.currentTime.toFixed(1) <= _timecodeMax(plyr.captions[plyr.subcount][0])) { - plyr.currentCaption = plyr.captions[plyr.subcount][1]; + if ( + plyr.media.currentTime.toFixed(1) >= _timecodeMin(plyr.captions[plyr.subcount][0]) && + plyr.media.currentTime.toFixed(1) <= _timecodeMax(plyr.captions[plyr.subcount][0]) + ) { + plyr.currentCaption = plyr.captions[plyr.subcount][1]; // Render the caption _setCaption(plyr.currentCaption); @@ -1224,17 +1302,16 @@ function _inFrame() { try { return window.self !== window.top; - } - catch (e) { + } catch (e) { return true; } } // Trap focus inside container function _focusTrap() { - var tabbables = _getElements('input:not([disabled]), button:not([disabled])'), - first = tabbables[0], - last = tabbables[tabbables.length - 1]; + var tabbables = _getElements("input:not([disabled]), button:not([disabled])"), + first = tabbables[0], + last = tabbables[tabbables.length - 1]; function _checkFocus(event) { // If it is TAB @@ -1252,13 +1329,13 @@ } // Bind the handler - _on(plyr.container, 'keydown', _checkFocus); + _on(plyr.container, "keydown", _checkFocus); } // Add elements to HTML5 media (source, tracks, etc) function _insertChildElements(type, attributes) { if (_is.string(attributes)) { - _insertElement(type, plyr.media, { src: attributes }); + _insertElement(type, plyr.media, { src: attributes }); } else if (attributes.constructor === Array) { for (var i = attributes.length - 1; i >= 0; i--) { _insertElement(type, plyr.media, attributes[i]); @@ -1274,10 +1351,10 @@ // Only load external sprite using AJAX if (iconUrl.absolute) { - _log('AJAX loading absolute SVG sprite' + (plyr.browser.isIE ? ' (due to IE)' : '')); + _log("AJAX loading absolute SVG sprite" + (plyr.browser.isIE ? " (due to IE)" : "")); loadSprite(iconUrl.url, "sprite-plyr"); } else { - _log('Sprite will be used as external resource directly'); + _log("Sprite will be used as external resource directly"); } } @@ -1285,7 +1362,7 @@ var html = config.html; // Insert custom video controls - _log('Injecting custom controls'); + _log("Injecting custom controls"); // If no controls are specified, create default if (!html) { @@ -1293,10 +1370,10 @@ } // Replace seek time instances - html = _replaceAll(html, '{seektime}', config.seekTime); + html = _replaceAll(html, "{seektime}", config.seekTime); // Replace all id references with random numbers - html = _replaceAll(html, '{id}', Math.floor(Math.random() * (10000))); + html = _replaceAll(html, "{id}", Math.floor(Math.random() * 10000)); // Controls container var target; @@ -1308,15 +1385,19 @@ // Inject into the container by default if (!_is.htmlElement(target)) { - target = plyr.container + target = plyr.container; } // Inject controls HTML - target.insertAdjacentHTML('beforeend', html); + target.insertAdjacentHTML("beforeend", html); // Setup tooltips if (config.tooltips.controls) { - var labels = _getElements([config.selectors.controls.wrapper, ' ', config.selectors.labels, ' .', config.classes.hidden].join('')); + var labels = _getElements( + [config.selectors.controls.wrapper, " ", config.selectors.labels, " .", config.classes.hidden].join( + "" + ) + ); for (var i = labels.length - 1; i >= 0; i--) { var label = labels[i]; @@ -1330,51 +1411,52 @@ // Find the UI controls and store references function _findElements() { try { - plyr.controls = _getElement(config.selectors.controls.wrapper); + plyr.controls = _getElement(config.selectors.controls.wrapper); // Buttons plyr.buttons = {}; - plyr.buttons.seek = _getElement(config.selectors.buttons.seek); - plyr.buttons.play = _getElements(config.selectors.buttons.play); - plyr.buttons.pause = _getElement(config.selectors.buttons.pause); - plyr.buttons.restart = _getElement(config.selectors.buttons.restart); - plyr.buttons.rewind = _getElement(config.selectors.buttons.rewind); - plyr.buttons.forward = _getElement(config.selectors.buttons.forward); - plyr.buttons.fullscreen = _getElement(config.selectors.buttons.fullscreen); + plyr.buttons.seek = _getElement(config.selectors.buttons.seek); + plyr.buttons.play = _getElements(config.selectors.buttons.play); + plyr.buttons.pause = _getElement(config.selectors.buttons.pause); + plyr.buttons.restart = _getElement(config.selectors.buttons.restart); + plyr.buttons.rewind = _getElement(config.selectors.buttons.rewind); + plyr.buttons.forward = _getElement(config.selectors.buttons.forward); + plyr.buttons.fullscreen = _getElement(config.selectors.buttons.fullscreen); // Inputs - plyr.buttons.mute = _getElement(config.selectors.buttons.mute); - plyr.buttons.captions = _getElement(config.selectors.buttons.captions); + plyr.buttons.mute = _getElement(config.selectors.buttons.mute); + plyr.buttons.captions = _getElement(config.selectors.buttons.captions); // Progress plyr.progress = {}; - plyr.progress.container = _getElement(config.selectors.progress.container); + plyr.progress.container = _getElement(config.selectors.progress.container); // Progress - Buffering - plyr.progress.buffer = {}; - plyr.progress.buffer.bar = _getElement(config.selectors.progress.buffer); - plyr.progress.buffer.text = plyr.progress.buffer.bar && plyr.progress.buffer.bar.getElementsByTagName('span')[0]; + plyr.progress.buffer = {}; + plyr.progress.buffer.bar = _getElement(config.selectors.progress.buffer); + plyr.progress.buffer.text = + plyr.progress.buffer.bar && plyr.progress.buffer.bar.getElementsByTagName("span")[0]; // Progress - Played - plyr.progress.played = _getElement(config.selectors.progress.played); + plyr.progress.played = _getElement(config.selectors.progress.played); // Seek tooltip - plyr.progress.tooltip = plyr.progress.container && plyr.progress.container.querySelector('.' + config.classes.tooltip); + plyr.progress.tooltip = + plyr.progress.container && plyr.progress.container.querySelector("." + config.classes.tooltip); // Volume - plyr.volume = {}; - plyr.volume.input = _getElement(config.selectors.volume.input); - plyr.volume.display = _getElement(config.selectors.volume.display); + plyr.volume = {}; + plyr.volume.input = _getElement(config.selectors.volume.input); + plyr.volume.display = _getElement(config.selectors.volume.display); // Timing - plyr.duration = _getElement(config.selectors.duration); - plyr.currentTime = _getElement(config.selectors.currentTime); - plyr.seekTime = _getElements(config.selectors.seekTime); + plyr.duration = _getElement(config.selectors.duration); + plyr.currentTime = _getElement(config.selectors.currentTime); + plyr.seekTime = _getElements(config.selectors.seekTime); return true; - } - catch(e) { - _warn('It looks like there is a problem with your controls HTML'); + } catch (e) { + _warn("It looks like there is a problem with your controls HTML"); // Restore native video controls _toggleNativeControls(true); @@ -1385,15 +1467,15 @@ // Toggle style hook function _toggleStyleHook() { - _toggleClass(plyr.container, config.selectors.container.replace('.', ''), plyr.supported.full); + _toggleClass(plyr.container, config.selectors.container.replace(".", ""), plyr.supported.full); } // Toggle native controls function _toggleNativeControls(toggle) { if (toggle && _inArray(config.types.html5, plyr.type)) { - plyr.media.setAttribute('controls', ''); + plyr.media.setAttribute("controls", ""); } else { - plyr.media.removeAttribute('controls'); + plyr.media.removeAttribute("controls"); } } @@ -1404,23 +1486,23 @@ // If there's a media title set, use that for the label if (_is.string(config.title) && config.title.length) { - label += ', ' + config.title; + label += ", " + config.title; // Set container label - plyr.container.setAttribute('aria-label', config.title); + plyr.container.setAttribute("aria-label", config.title); } // If there's a play button, set label if (plyr.supported.full && plyr.buttons.play) { for (var i = plyr.buttons.play.length - 1; i >= 0; i--) { - plyr.buttons.play[i].setAttribute('aria-label', label); + plyr.buttons.play[i].setAttribute("aria-label", label); } } // Set iframe title // https://github.com/sampotts/plyr/issues/124 if (_is.htmlElement(iframe)) { - iframe.setAttribute('title', config.i18n.frameTitle.replace('{title}', config.title)); + iframe.setAttribute("title", config.i18n.frameTitle.replace("{title}", config.title)); } } @@ -1436,7 +1518,7 @@ // Clean up old volume // https://github.com/sampotts/plyr/issues/171 - window.localStorage.removeItem('plyr-volume'); + window.localStorage.removeItem("plyr-volume"); // load value from the current key value = window.localStorage.getItem(config.storage.key); @@ -1448,7 +1530,7 @@ // If value is a number, it's probably volume from an older // version of plyr. See: https://github.com/sampotts/plyr/pull/313 // Update the key to be JSON - _updateStorage({volume: parseFloat(value)}); + _updateStorage({ volume: parseFloat(value) }); } else { // Assume it's JSON from this or a later version of plyr plyr.storage = JSON.parse(value); @@ -1473,18 +1555,18 @@ function _setupMedia() { // If there's no media, bail if (!plyr.media) { - _warn('No media element found!'); + _warn("No media element found!"); return; } if (plyr.supported.full) { // Add type class - _toggleClass(plyr.container, config.classes.type.replace('{0}', plyr.type), true); + _toggleClass(plyr.container, config.classes.type.replace("{0}", plyr.type), true); // Add video class for embeds // This will require changes if audio embeds are added if (_inArray(config.types.embed, plyr.type)) { - _toggleClass(plyr.container, config.classes.type.replace('{0}', 'video'), true); + _toggleClass(plyr.container, config.classes.type.replace("{0}", "video"), true); } // If there's no autoplay attribute, assume the video is stopped and add state class @@ -1497,10 +1579,10 @@ _toggleClass(plyr.container, config.classes.isTouch, plyr.browser.isTouch); // Inject the player wrapper - if (plyr.type === 'video') { + if (plyr.type === "video") { // Create the wrapper div - var wrapper = document.createElement('div'); - wrapper.setAttribute('class', config.classes.videoWrapper); + var wrapper = document.createElement("div"); + wrapper.setAttribute("class", config.classes.videoWrapper); // Wrap the video in a container _wrap(plyr.media, wrapper); @@ -1518,17 +1600,17 @@ // Setup YouTube/Vimeo function _setupEmbed() { - var container = document.createElement('div'), + var container = document.createElement("div"), mediaId, - id = plyr.type + '-' + Math.floor(Math.random() * (10000)); + id = plyr.type + "-" + Math.floor(Math.random() * 10000); // Parse IDs from URLs if supplied switch (plyr.type) { - case 'youtube': + case "youtube": mediaId = _parseYouTubeId(plyr.embedId); break; - case 'vimeo': + case "vimeo": mediaId = _parseVimeoId(plyr.embedId); break; @@ -1546,12 +1628,12 @@ _toggleClass(plyr.media, config.classes.videoWrapper, true); _toggleClass(plyr.media, config.classes.embedWrapper, true); - if (plyr.type === 'youtube') { + if (plyr.type === "youtube") { // Create the YouTube container plyr.media.appendChild(container); // Set ID - container.setAttribute('id', id); + container.setAttribute("id", id); // Setup API if (_is.object(window.YT)) { @@ -1564,14 +1646,18 @@ window.onYouTubeReadyCallbacks = window.onYouTubeReadyCallbacks || []; // Add to queue - window.onYouTubeReadyCallbacks.push(function() { _youTubeReady(mediaId, container); }); + window.onYouTubeReadyCallbacks.push(function() { + _youTubeReady(mediaId, container); + }); // Set callback to process queue - window.onYouTubeIframeAPIReady = function () { - window.onYouTubeReadyCallbacks.forEach(function(callback) { callback(); }); + window.onYouTubeIframeAPIReady = function() { + window.onYouTubeReadyCallbacks.forEach(function(callback) { + callback(); + }); }; } - } else if (plyr.type === 'vimeo') { + } else if (plyr.type === "vimeo") { // Vimeo needs an extra div to hide controls on desktop (which has full support) if (plyr.supported.full) { plyr.media.appendChild(container); @@ -1580,7 +1666,7 @@ } // Set ID - container.setAttribute('id', id); + container.setAttribute("id", id); // Load the API if not already if (!_is.object(window.Vimeo)) { @@ -1596,18 +1682,20 @@ } else { _vimeoReady(mediaId, container); } - } else if (plyr.type === 'soundcloud') { + } else if (plyr.type === "soundcloud") { // TODO: Currently unsupported and undocumented // Inject the iframe - var soundCloud = document.createElement('iframe'); + var soundCloud = document.createElement("iframe"); // Watch for iframe load soundCloud.loaded = false; - _on(soundCloud, 'load', function() { soundCloud.loaded = true; }); + _on(soundCloud, "load", function() { + soundCloud.loaded = true; + }); _setAttributes(soundCloud, { - 'src': 'https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/' + mediaId, - 'id': id + src: "https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/" + mediaId, + id: id }); container.appendChild(soundCloud); @@ -1637,7 +1725,7 @@ } // Set title - _setTitle(_getElement('iframe')); + _setTitle(_getElement("iframe")); } // Handle YouTube API ready @@ -1647,26 +1735,26 @@ plyr.embed = new window.YT.Player(container.id, { videoId: videoId, playerVars: { - autoplay: (config.autoplay ? 1 : 0), - controls: (plyr.supported.full ? 0 : 1), - rel: 0, - showinfo: 0, + autoplay: config.autoplay ? 1 : 0, + controls: plyr.supported.full ? 0 : 1, + rel: 0, + showinfo: 0, iv_load_policy: 3, - cc_load_policy: (config.captions.defaultActive ? 1 : 0), - cc_lang_pref: 'en', - wmode: 'transparent', + cc_load_policy: config.captions.defaultActive ? 1 : 0, + cc_lang_pref: "en", + wmode: "transparent", modestbranding: 1, - disablekb: 1, - origin: '*' // https://code.google.com/p/gdata-issues/issues/detail?id=5788#c45 + disablekb: 1, + origin: "*" // https://code.google.com/p/gdata-issues/issues/detail?id=5788#c45 }, events: { - 'onError': function(event) { - _triggerEvent(plyr.container, 'error', true, { - code: event.data, - embed: event.target + onError: function(event) { + _triggerEvent(plyr.container, "error", true, { + code: event.data, + embed: event.target }); }, - 'onReady': function(event) { + onReady: function(event) { // Get the instance var instance = event.target; @@ -1693,17 +1781,17 @@ // Set the tabindex if (plyr.supported.full) { - plyr.media.querySelector('iframe').setAttribute('tabindex', '-1'); + plyr.media.querySelector("iframe").setAttribute("tabindex", "-1"); } // Update UI _embedReady(); // Trigger timeupdate - _triggerEvent(plyr.media, 'timeupdate'); + _triggerEvent(plyr.media, "timeupdate"); // Trigger timeupdate - _triggerEvent(plyr.media, 'durationchange'); + _triggerEvent(plyr.media, "durationchange"); // Reset timer window.clearInterval(timers.buffering); @@ -1715,7 +1803,7 @@ // Trigger progress only when we actually buffer something if (plyr.media.lastBuffered === null || plyr.media.lastBuffered < plyr.media.buffered) { - _triggerEvent(plyr.media, 'progress'); + _triggerEvent(plyr.media, "progress"); } // Set last buffer point @@ -1726,11 +1814,11 @@ window.clearInterval(timers.buffering); // Trigger event - _triggerEvent(plyr.media, 'canplaythrough'); + _triggerEvent(plyr.media, "canplaythrough"); } }, 200); }, - 'onStateChange': function(event) { + onStateChange: function(event) { // Get the instance var instance = event.target; @@ -1747,7 +1835,7 @@ switch (event.data) { case 0: plyr.media.paused = true; - _triggerEvent(plyr.media, 'ended'); + _triggerEvent(plyr.media, "ended"); break; case 1: @@ -1755,12 +1843,12 @@ // If we were seeking, fire seeked event if (plyr.media.seeking) { - _triggerEvent(plyr.media, 'seeked'); + _triggerEvent(plyr.media, "seeked"); } plyr.media.seeking = false; - _triggerEvent(plyr.media, 'play'); - _triggerEvent(plyr.media, 'playing'); + _triggerEvent(plyr.media, "play"); + _triggerEvent(plyr.media, "playing"); // Poll to get playback progress timers.playing = window.setInterval(function() { @@ -1768,7 +1856,7 @@ plyr.media.currentTime = instance.getCurrentTime(); // Trigger timeupdate - _triggerEvent(plyr.media, 'timeupdate'); + _triggerEvent(plyr.media, "timeupdate"); }, 100); // Check duration again due to YouTube bug @@ -1776,18 +1864,18 @@ // https://code.google.com/p/gdata-issues/issues/detail?id=8690 if (plyr.media.duration !== instance.getDuration()) { plyr.media.duration = instance.getDuration(); - _triggerEvent(plyr.media, 'durationchange'); + _triggerEvent(plyr.media, "durationchange"); } break; case 2: plyr.media.paused = true; - _triggerEvent(plyr.media, 'pause'); + _triggerEvent(plyr.media, "pause"); break; } - _triggerEvent(plyr.container, 'statechange', false, { + _triggerEvent(plyr.container, "statechange", false, { code: event.data }); } @@ -1800,12 +1888,12 @@ // Setup instance // https://github.com/vimeo/player.js plyr.embed = new window.Vimeo.Player(container, { - id: parseInt(mediaId), - loop: config.loop, - autoplay: config.autoplay, - byline: false, - portrait: false, - title: false + id: parseInt(mediaId), + loop: config.loop, + autoplay: config.autoplay, + byline: false, + portrait: false, + title: false }); // Create a faux HTML5 API using the Vimeo API @@ -1832,14 +1920,14 @@ plyr.media.currentTime = value; // Trigger timeupdate - _triggerEvent(plyr.media, 'timeupdate'); + _triggerEvent(plyr.media, "timeupdate"); }); plyr.embed.getDuration().then(function(value) { plyr.media.duration = value; // Trigger timeupdate - _triggerEvent(plyr.media, 'durationchange'); + _triggerEvent(plyr.media, "durationchange"); }); // TODO: Captions @@ -1847,50 +1935,50 @@ plyr.embed.enableTextTrack('en'); }*/ - plyr.embed.on('loaded', function() { + plyr.embed.on("loaded", function() { // Fix keyboard focus issues // https://github.com/sampotts/plyr/issues/317 if (_is.htmlElement(plyr.embed.element) && plyr.supported.full) { - plyr.embed.element.setAttribute('tabindex', '-1'); + plyr.embed.element.setAttribute("tabindex", "-1"); } }); - plyr.embed.on('play', function() { + plyr.embed.on("play", function() { plyr.media.paused = false; - _triggerEvent(plyr.media, 'play'); - _triggerEvent(plyr.media, 'playing'); + _triggerEvent(plyr.media, "play"); + _triggerEvent(plyr.media, "playing"); }); - plyr.embed.on('pause', function() { + plyr.embed.on("pause", function() { plyr.media.paused = true; - _triggerEvent(plyr.media, 'pause'); + _triggerEvent(plyr.media, "pause"); }); - plyr.embed.on('timeupdate', function(data) { + plyr.embed.on("timeupdate", function(data) { plyr.media.seeking = false; plyr.media.currentTime = data.seconds; - _triggerEvent(plyr.media, 'timeupdate'); + _triggerEvent(plyr.media, "timeupdate"); }); - plyr.embed.on('progress', function(data) { + plyr.embed.on("progress", function(data) { plyr.media.buffered = data.percent; - _triggerEvent(plyr.media, 'progress'); + _triggerEvent(plyr.media, "progress"); if (parseInt(data.percent) === 1) { // Trigger event - _triggerEvent(plyr.media, 'canplaythrough'); + _triggerEvent(plyr.media, "canplaythrough"); } }); - plyr.embed.on('seeked', function() { + plyr.embed.on("seeked", function() { plyr.media.seeking = false; - _triggerEvent(plyr.media, 'seeked'); - _triggerEvent(plyr.media, 'play'); + _triggerEvent(plyr.media, "seeked"); + _triggerEvent(plyr.media, "play"); }); - plyr.embed.on('ended', function() { + plyr.embed.on("ended", function() { plyr.media.paused = true; - _triggerEvent(plyr.media, 'ended'); + _triggerEvent(plyr.media, "ended"); }); } @@ -1920,7 +2008,7 @@ plyr.media.currentTime = 0; plyr.embed.getDuration(function(value) { - plyr.media.duration = value/1000; + plyr.media.duration = value / 1000; // Update UI _embedReady(); @@ -1930,53 +2018,53 @@ plyr.media.currentTime = value; // Trigger timeupdate - _triggerEvent(plyr.media, 'timeupdate'); + _triggerEvent(plyr.media, "timeupdate"); }); plyr.embed.bind(window.SC.Widget.Events.PLAY, function() { plyr.media.paused = false; - _triggerEvent(plyr.media, 'play'); - _triggerEvent(plyr.media, 'playing'); + _triggerEvent(plyr.media, "play"); + _triggerEvent(plyr.media, "playing"); }); plyr.embed.bind(window.SC.Widget.Events.PAUSE, function() { plyr.media.paused = true; - _triggerEvent(plyr.media, 'pause'); + _triggerEvent(plyr.media, "pause"); }); plyr.embed.bind(window.SC.Widget.Events.PLAY_PROGRESS, function(data) { plyr.media.seeking = false; - plyr.media.currentTime = data.currentPosition/1000; - _triggerEvent(plyr.media, 'timeupdate'); + plyr.media.currentTime = data.currentPosition / 1000; + _triggerEvent(plyr.media, "timeupdate"); }); plyr.embed.bind(window.SC.Widget.Events.LOAD_PROGRESS, function(data) { plyr.media.buffered = data.loadProgress; - _triggerEvent(plyr.media, 'progress'); + _triggerEvent(plyr.media, "progress"); if (parseInt(data.loadProgress) === 1) { // Trigger event - _triggerEvent(plyr.media, 'canplaythrough'); + _triggerEvent(plyr.media, "canplaythrough"); } }); plyr.embed.bind(window.SC.Widget.Events.FINISH, function() { plyr.media.paused = true; - _triggerEvent(plyr.media, 'ended'); + _triggerEvent(plyr.media, "ended"); }); }); } // Play media function _play() { - if ('play' in plyr.media) { + if ("play" in plyr.media) { plyr.media.play(); } } // Pause media function _pause() { - if ('pause' in plyr.media) { + if ("pause" in plyr.media) { plyr.media.pause(); } } @@ -2018,16 +2106,16 @@ // Seek to time // The input parameter can be an event or a number function _seek(input) { - var targetTime = 0, - paused = plyr.media.paused, - duration = _getDuration(); + var targetTime = 0, + paused = plyr.media.paused, + duration = _getDuration(); if (_is.number(input)) { targetTime = input; - } else if (_is.object(input) && _inArray(['input', 'change'], input.type)) { + } else if (_is.object(input) && _inArray(["input", "change"], input.type)) { // It's the seek slider // Seek to the selected time - targetTime = ((input.target.value / input.target.max) * duration); + targetTime = input.target.value / input.target.max * duration; } // Normalise targetTime @@ -2044,22 +2132,21 @@ // Try/catch incase the media isn't set and we're calling seek() from source() and IE moans try { plyr.media.currentTime = targetTime.toFixed(4); - } - catch(e) {} + } catch (e) {} // Embeds if (_inArray(config.types.embed, plyr.type)) { - switch(plyr.type) { - case 'youtube': + switch (plyr.type) { + case "youtube": plyr.embed.seekTo(targetTime); break; - case 'vimeo': + case "vimeo": // Round to nearest second for vimeo plyr.embed.setCurrentTime(targetTime.toFixed(0)); break; - case 'soundcloud': + case "soundcloud": plyr.embed.seekTo(targetTime * 1000); break; } @@ -2069,17 +2156,17 @@ } // Trigger timeupdate - _triggerEvent(plyr.media, 'timeupdate'); + _triggerEvent(plyr.media, "timeupdate"); // Set seeking flag plyr.media.seeking = true; // Trigger seeking - _triggerEvent(plyr.media, 'seeking'); + _triggerEvent(plyr.media, "seeking"); } // Logging - _log('Seeking to ' + plyr.media.currentTime + ' seconds'); + _log("Seeking to " + plyr.media.currentTime + " seconds"); // Special handling for 'manual' captions _seekManualCaptions(targetTime); @@ -2089,9 +2176,8 @@ function _getDuration() { // It should be a number, but parse it just incase var duration = parseInt(config.duration), - - // True duration - mediaDuration = 0; + // True duration + mediaDuration = 0; // Only if duration available if (plyr.media.duration !== null && !isNaN(plyr.media.duration)) { @@ -2099,7 +2185,7 @@ } // If custom duration is funky, use regular duration - return (isNaN(duration) ? mediaDuration : duration); + return isNaN(duration) ? mediaDuration : duration; } // Check playing state @@ -2156,7 +2242,7 @@ plyr.isFullscreen = !plyr.isFullscreen; // Bind/unbind escape key - document.body.style.overflow = plyr.isFullscreen ? 'hidden' : ''; + document.body.style.overflow = plyr.isFullscreen ? "hidden" : ""; } // Set class hook @@ -2171,7 +2257,7 @@ } // Trigger an event - _triggerEvent(plyr.container, plyr.isFullscreen ? 'enterfullscreen' : 'exitfullscreen', true); + _triggerEvent(plyr.container, plyr.isFullscreen ? "enterfullscreen" : "exitfullscreen", true); // Restore scroll position if (!plyr.isFullscreen && nativeSupport) { @@ -2200,19 +2286,19 @@ // Embeds if (_inArray(config.types.embed, plyr.type)) { // YouTube - switch(plyr.type) { - case 'youtube': - plyr.embed[plyr.media.muted ? 'mute' : 'unMute'](); + switch (plyr.type) { + case "youtube": + plyr.embed[plyr.media.muted ? "mute" : "unMute"](); break; - case 'vimeo': - case 'soundcloud': + case "vimeo": + case "soundcloud": plyr.embed.setVolume(plyr.media.muted ? 0 : parseFloat(config.volume / config.volumeMax)); break; } // Trigger volumechange for embeds - _triggerEvent(plyr.media, 'volumechange'); + _triggerEvent(plyr.media, "volumechange"); } } @@ -2250,19 +2336,19 @@ // Embeds if (_inArray(config.types.embed, plyr.type)) { - switch(plyr.type) { - case 'youtube': + switch (plyr.type) { + case "youtube": plyr.embed.setVolume(plyr.media.volume * 100); break; - case 'vimeo': - case 'soundcloud': + case "vimeo": + case "soundcloud": plyr.embed.setVolume(plyr.media.volume); break; } // Trigger volumechange for embeds - _triggerEvent(plyr.media, 'volumechange'); + _triggerEvent(plyr.media, "volumechange"); } // Toggle muted state @@ -2275,7 +2361,7 @@ // Increase volume function _increaseVolume(step) { - var volume = plyr.media.muted ? 0 : (plyr.media.volume * config.volumeMax); + var volume = plyr.media.muted ? 0 : plyr.media.volume * config.volumeMax; if (!_is.number(step)) { step = config.volumeStep; @@ -2286,7 +2372,7 @@ // Decrease volume function _decreaseVolume(step) { - var volume = plyr.media.muted ? 0 : (plyr.media.volume * config.volumeMax); + var volume = plyr.media.muted ? 0 : plyr.media.volume * config.volumeMax; if (!_is.number(step)) { step = config.volumeStep; @@ -2298,7 +2384,7 @@ // Update volume UI and storage function _updateVolume() { // Get the current volume - var volume = plyr.media.muted ? 0 : (plyr.media.volume * config.volumeMax); + var volume = plyr.media.muted ? 0 : plyr.media.volume * config.volumeMax; // Update the if present if (plyr.supported.full) { @@ -2311,14 +2397,14 @@ } // Update the volume in storage - _updateStorage({volume: volume}); + _updateStorage({ volume: volume }); // Toggle class if muted - _toggleClass(plyr.container, config.classes.muted, (volume === 0)); + _toggleClass(plyr.container, config.classes.muted, volume === 0); // Update checkbox for mute state if (plyr.supported.full && plyr.buttons.mute) { - _toggleState(plyr.buttons.mute, (volume === 0)); + _toggleState(plyr.buttons.mute, volume === 0); } } @@ -2331,7 +2417,7 @@ // If the method is called without parameter, toggle based on current value if (!_is.boolean(show)) { - show = (plyr.container.className.indexOf(config.classes.captions.active) === -1); + show = plyr.container.className.indexOf(config.classes.captions.active) === -1; } // Set global @@ -2344,15 +2430,15 @@ _toggleClass(plyr.container, config.classes.captions.active, plyr.captionsEnabled); // Trigger an event - _triggerEvent(plyr.container, plyr.captionsEnabled ? 'captionsenabled' : 'captionsdisabled', true); + _triggerEvent(plyr.container, plyr.captionsEnabled ? "captionsenabled" : "captionsdisabled", true); // Save captions state to localStorage - _updateStorage({captionsEnabled: plyr.captionsEnabled}); + _updateStorage({ captionsEnabled: plyr.captionsEnabled }); } // Check if media is loading function _checkLoading(event) { - var loading = (event.type === 'waiting'); + var loading = event.type === "waiting"; // Clear timer clearTimeout(timers.loading); @@ -2364,7 +2450,7 @@ // Show controls if loading, hide if done _toggleControls(loading); - }, (loading ? 250 : 0)); + }, loading ? 250 : 0); } // Update elements @@ -2373,15 +2459,15 @@ return; } - var progress = plyr.progress.played, - value = 0, - duration = _getDuration(); + var progress = plyr.progress.played, + value = 0, + duration = _getDuration(); if (event) { switch (event.type) { // Video playing - case 'timeupdate': - case 'seeking': + case "timeupdate": + case "seeking": if (plyr.controls.pressed) { return; } @@ -2389,17 +2475,17 @@ value = _getPercentage(plyr.media.currentTime, duration); // Set seek range value only if it's a 'natural' time event - if (event.type === 'timeupdate' && plyr.buttons.seek) { + if (event.type === "timeupdate" && plyr.buttons.seek) { plyr.buttons.seek.value = value; } break; // Check buffer status - case 'playing': - case 'progress': - progress = plyr.progress.buffer; - value = (function() { + case "playing": + case "progress": + progress = plyr.progress.buffer; + value = (function() { var buffered = plyr.media.buffered; if (buffered && buffered.length) { @@ -2407,7 +2493,7 @@ return _getPercentage(buffered.end(0), duration); } else if (_is.number(buffered)) { // YouTube returns between 0 and 1 - return (buffered * 100); + return buffered * 100; } return 0; @@ -2468,17 +2554,17 @@ plyr.secs = parseInt(time % 60); plyr.mins = parseInt((time / 60) % 60); - plyr.hours = parseInt(((time / 60) / 60) % 60); + plyr.hours = parseInt((time / 60 / 60) % 60); // Do we need to display hours? - var displayHours = (parseInt(((_getDuration() / 60) / 60) % 60) > 0); + var displayHours = parseInt((_getDuration() / 60 / 60) % 60) > 0; // Ensure it's two digits. For example, 03 rather than 3. - plyr.secs = ('0' + plyr.secs).slice(-2); - plyr.mins = ('0' + plyr.mins).slice(-2); + plyr.secs = ("0" + plyr.secs).slice(-2); + plyr.mins = ("0" + plyr.mins).slice(-2); // Render - element.innerHTML = (displayHours ? plyr.hours + ':' : '') + plyr.mins + ':' + plyr.secs; + element.innerHTML = (displayHours ? plyr.hours + ":" : "") + plyr.mins + ":" + plyr.secs; } // Show the duration on metadataloaded @@ -2510,7 +2596,7 @@ _updateTimeDisplay(plyr.media.currentTime, plyr.currentTime); // Ignore updates while seeking - if (event && event.type === 'timeupdate' && plyr.media.seeking) { + if (event && event.type === "timeupdate" && plyr.media.seeking) { return; } @@ -2525,8 +2611,8 @@ time = 0; } - var duration = _getDuration(), - value = _getPercentage(time, duration); + var duration = _getDuration(), + value = _getPercentage(time, duration); // Update progress if (plyr.progress && plyr.progress.played) { @@ -2549,19 +2635,19 @@ } // Calculate percentage - var clientRect = plyr.progress.container.getBoundingClientRect(), - percent = 0, - visible = config.classes.tooltip + '--visible'; + var clientRect = plyr.progress.container.getBoundingClientRect(), + percent = 0, + visible = config.classes.tooltip + "--visible"; // Determine percentage, if already visible if (!event) { if (_hasClass(plyr.progress.tooltip, visible)) { - percent = plyr.progress.tooltip.style.left.replace('%', ''); + percent = plyr.progress.tooltip.style.left.replace("%", ""); } else { return; } } else { - percent = ((100 / clientRect.width) * (event.pageX - clientRect.left)); + percent = 100 / clientRect.width * (event.pageX - clientRect.left); } // Set bounds @@ -2572,22 +2658,22 @@ } // Display the time a click would seek to - _updateTimeDisplay(((duration / 100) * percent), plyr.progress.tooltip); + _updateTimeDisplay(duration / 100 * percent, plyr.progress.tooltip); // Set position plyr.progress.tooltip.style.left = percent + "%"; // Show/hide the tooltip // If the event is a moues in/out and percentage is inside bounds - if (event && _inArray(['mouseenter', 'mouseleave'], event.type)) { - _toggleClass(plyr.progress.tooltip, visible, (event.type === 'mouseenter')); + if (event && _inArray(["mouseenter", "mouseleave"], event.type)) { + _toggleClass(plyr.progress.tooltip, visible, event.type === "mouseenter"); } } // Show the player controls in fullscreen mode function _toggleControls(toggle) { // Don't hide if config says not to, it's audio, or not ready or loading - if (!config.hideControls || plyr.type === 'audio') { + if (!config.hideControls || plyr.type === "audio") { return; } @@ -2600,18 +2686,18 @@ if (!_is.boolean(toggle)) { if (toggle && toggle.type) { // Is the enter fullscreen event - isEnterFullscreen = (toggle.type === 'enterfullscreen'); + isEnterFullscreen = toggle.type === "enterfullscreen"; // Whether to show controls - show = _inArray(['mousemove', 'touchstart', 'mouseenter', 'focus'], toggle.type); + show = _inArray(["mousemove", "touchstart", "mouseenter", "focus"], toggle.type); // Delay hiding on move events - if (_inArray(['mousemove', 'touchmove'], toggle.type)) { + if (_inArray(["mousemove", "touchmove"], toggle.type)) { delay = 2000; } // Delay a little more for keyboard users - if (toggle.type === 'focus') { + if (toggle.type === "focus") { delay = 3000; } } else { @@ -2661,18 +2747,18 @@ // Return the current source var url; - switch(plyr.type) { - case 'youtube': + switch (plyr.type) { + case "youtube": url = plyr.embed.getVideoUrl(); break; - case 'vimeo': - plyr.embed.getVideoUrl.then(function (value) { + case "vimeo": + plyr.embed.getVideoUrl.then(function(value) { url = value; }); break; - case 'soundcloud': + case "soundcloud": plyr.embed.getCurrentSound(function(object) { url = object.permalink_url; }); @@ -2683,14 +2769,14 @@ break; } - return url || ''; + return url || ""; } // Update source // Sources are not checked for support so be careful function _updateSource(source) { - if (!_is.object(source) || !('sources' in source) || !source.sources.length) { - _warn('Invalid source format'); + if (!_is.object(source) || !("sources" in source) || !source.sources.length) { + _warn("Invalid source format"); return; } @@ -2718,24 +2804,24 @@ _remove(plyr.media); // Remove video container - if (plyr.type === 'video' && plyr.videoContainer) { + if (plyr.type === "video" && plyr.videoContainer) { _remove(plyr.videoContainer); } // Reset class name if (plyr.container) { - plyr.container.removeAttribute('class'); + plyr.container.removeAttribute("class"); } // Set the type - if ('type' in source) { + if ("type" in source) { plyr.type = source.type; // Get child type for video (it might be an embed) - if (plyr.type === 'video') { + if (plyr.type === "video") { var firstSource = source.sources[0]; - if ('type' in firstSource && _inArray(config.types.embed, firstSource.type)) { + if ("type" in firstSource && _inArray(config.types.embed, firstSource.type)) { plyr.type = firstSource.type; } } @@ -2745,19 +2831,19 @@ plyr.supported = supported(plyr.type); // Create new markup - switch(plyr.type) { - case 'video': - plyr.media = document.createElement('video'); + switch (plyr.type) { + case "video": + plyr.media = document.createElement("video"); break; - case 'audio': - plyr.media = document.createElement('audio'); + case "audio": + plyr.media = document.createElement("audio"); break; - case 'youtube': - case 'vimeo': - case 'soundcloud': - plyr.media = document.createElement('div'); + case "youtube": + case "vimeo": + case "soundcloud": + plyr.media = document.createElement("div"); plyr.embedId = source.sources[0].src; break; } @@ -2773,16 +2859,16 @@ // Set attributes for audio and video if (_inArray(config.types.html5, plyr.type)) { if (config.crossorigin) { - plyr.media.setAttribute('crossorigin', ''); + plyr.media.setAttribute("crossorigin", ""); } if (config.autoplay) { - plyr.media.setAttribute('autoplay', ''); + plyr.media.setAttribute("autoplay", ""); } - if ('poster' in source) { - plyr.media.setAttribute('poster', source.poster); + if ("poster" in source) { + plyr.media.setAttribute("poster", source.poster); } if (config.loop) { - plyr.media.setAttribute('loop', ''); + plyr.media.setAttribute("loop", ""); } } @@ -2793,7 +2879,7 @@ // Set new sources for html5 if (_inArray(config.types.html5, plyr.type)) { - _insertChildElements('source', source.sources); + _insertChildElements("source", source.sources); } // Set up from scratch @@ -2802,8 +2888,8 @@ // HTML5 stuff if (_inArray(config.types.html5, plyr.type)) { // Setup captions - if ('tracks' in source) { - _insertChildElements('track', source.tracks); + if ("tracks" in source) { + _insertChildElements("track", source.tracks); } // Load HTML5 sources @@ -2811,7 +2897,10 @@ } // If HTML5 or embed but not fully supported, setupInterface and call ready now - if (_inArray(config.types.html5, plyr.type) || (_inArray(config.types.embed, plyr.type) && !plyr.supported.full)) { + if ( + _inArray(config.types.html5, plyr.type) || + (_inArray(config.types.embed, plyr.type) && !plyr.supported.full) + ) { // Setup interface _setupInterface(); @@ -2831,23 +2920,23 @@ // Update poster function _updatePoster(source) { - if (plyr.type === 'video') { - plyr.media.setAttribute('poster', source); + if (plyr.type === "video") { + plyr.media.setAttribute("poster", source); } } // Listen for control events function _controlListeners() { // IE doesn't support input event, so we fallback to change - var inputEvent = (plyr.browser.isIE ? 'change' : 'input'); + var inputEvent = plyr.browser.isIE ? "change" : "input"; // Click play/pause helper function togglePlay() { var play = _togglePlay(); // Determine which buttons - var trigger = plyr.buttons[play ? 'play' : 'pause'], - target = plyr.buttons[play ? 'pause' : 'play']; + var trigger = plyr.buttons[play ? "play" : "pause"], + target = plyr.buttons[play ? "pause" : "play"]; // Get the last play button to account for the large play button if (target && target.length > 1) { @@ -2878,7 +2967,7 @@ if (!focused || focused === document.body) { focused = null; } else { - focused = document.querySelector(':focus'); + focused = document.querySelector(":focus"); } return focused; @@ -2896,10 +2985,10 @@ if (_is.nodeList(element)) { for (var i = 0; i < element.length; i++) { - _toggleClass(element[i], config.classes.tabFocus, (element[i] === focused)); + _toggleClass(element[i], config.classes.tabFocus, element[i] === focused); } } else { - _toggleClass(element, config.classes.tabFocus, (element === focused)); + _toggleClass(element, config.classes.tabFocus, element === focused); } } } @@ -2910,29 +2999,33 @@ // Handle global presses if (config.keyboardShorcuts.global) { - _on(window, 'keydown keyup', function(event) { + _on(window, "keydown keyup", function(event) { var code = getKeyCode(event), - focused = getFocusElement(), - allowed = [48,49,50,51,52,53,54,56,57,75,77,70,67], - count = get().length; + focused = getFocusElement(), + allowed = [48, 49, 50, 51, 52, 53, 54, 56, 57, 75, 77, 70, 67], + count = get().length; // Only handle global key press if there's only one player // and the key is in the allowed keys // and if the focused element is not editable (e.g. text input) // and any that accept key input http://webaim.org/techniques/keyboard/ - if (count === 1 && _inArray(allowed, code) && (!_is.htmlElement(focused) || !_matches(focused, config.selectors.editable))) { + if ( + count === 1 && + _inArray(allowed, code) && + (!_is.htmlElement(focused) || !_matches(focused, config.selectors.editable)) + ) { handleKey(event); } }); } // Handle presses on focused - _on(plyr.container, 'keydown keyup', handleKey); + _on(plyr.container, "keydown keyup", handleKey); } function handleKey(event) { var code = getKeyCode(event), - pressed = event.type === 'keydown', + pressed = event.type === "keydown", held = pressed && code === last; // If the event is bubbled from the media element @@ -2952,14 +3045,14 @@ } // Divide the max duration into 10th's and times by the number value - _seek((duration / 10) * (code - 48)); + _seek(duration / 10 * (code - 48)); } // Handle the key on keydown // Reset on keyup if (pressed) { // Which keycodes should we prevent default - var preventDefault = [48,49,50,51,52,53,54,56,57,32,75,38,40,77,39,37,70,67]; + var preventDefault = [48, 49, 50, 51, 52, 53, 54, 56, 57, 32, 75, 38, 40, 77, 39, 37, 70, 67]; // If the code is found prevent default (e.g. prevent scrolling for arrows) if (_inArray(preventDefault, code)) { @@ -2967,7 +3060,7 @@ event.stopPropagation(); } - switch(code) { + switch (code) { // 0-9 case 48: case 49: @@ -2978,24 +3071,50 @@ case 54: case 55: case 56: - case 57: if (!held) { seekByKey(); } break; + case 57: + if (!held) { + seekByKey(); + } + break; // Space and K key case 32: - case 75: if (!held) { _togglePlay(); } break; + case 75: + if (!held) { + _togglePlay(); + } + break; // Arrow up - case 38: _increaseVolume(); break; + case 38: + _increaseVolume(); + break; // Arrow down - case 40: _decreaseVolume(); break; + case 40: + _decreaseVolume(); + break; // M key - case 77: if (!held) { _toggleMute() } break; + case 77: + if (!held) { + _toggleMute(); + } + break; // Arrow forward - case 39: _forward(); break; + case 39: + _forward(); + break; // Arrow back - case 37: _rewind(); break; + case 37: + _rewind(); + break; // F key - case 70: _toggleFullscreen(); break; + case 70: + _toggleFullscreen(); + break; // C key - case 67: if (!held) { _toggleCaptions(); } break; + case 67: + if (!held) { + _toggleCaptions(); + } + break; } // Escape is handle natively when in full screen @@ -3012,7 +3131,7 @@ } // Focus/tab management - _on(window, 'keyup', function(event) { + _on(window, "keyup", function(event) { var code = getKeyCode(event), focused = getFocusElement(); @@ -3020,31 +3139,31 @@ checkTabFocus(focused); } }); - _on(document.body, 'click', function() { - _toggleClass(_getElement('.' + config.classes.tabFocus), config.classes.tabFocus, false); + _on(document.body, "click", function() { + _toggleClass(_getElement("." + config.classes.tabFocus), config.classes.tabFocus, false); }); for (var button in plyr.buttons) { var element = plyr.buttons[button]; - _on(element, 'blur', function() { - _toggleClass(element, 'tab-focus', false); + _on(element, "blur", function() { + _toggleClass(element, "tab-focus", false); }); } // Play - _proxyListener(plyr.buttons.play, 'click', config.listeners.play, togglePlay); + _proxyListener(plyr.buttons.play, "click", config.listeners.play, togglePlay); // Pause - _proxyListener(plyr.buttons.pause, 'click', config.listeners.pause, togglePlay); + _proxyListener(plyr.buttons.pause, "click", config.listeners.pause, togglePlay); // Restart - _proxyListener(plyr.buttons.restart, 'click', config.listeners.restart, _seek); + _proxyListener(plyr.buttons.restart, "click", config.listeners.restart, _seek); // Rewind - _proxyListener(plyr.buttons.rewind, 'click', config.listeners.rewind, _rewind); + _proxyListener(plyr.buttons.rewind, "click", config.listeners.rewind, _rewind); // Fast forward - _proxyListener(plyr.buttons.forward, 'click', config.listeners.forward, _forward); + _proxyListener(plyr.buttons.forward, "click", config.listeners.forward, _forward); // Seek _proxyListener(plyr.buttons.seek, inputEvent, config.listeners.seek, _seek); @@ -3055,10 +3174,10 @@ }); // Mute - _proxyListener(plyr.buttons.mute, 'click', config.listeners.mute, _toggleMute); + _proxyListener(plyr.buttons.mute, "click", config.listeners.mute, _toggleMute); // Fullscreen - _proxyListener(plyr.buttons.fullscreen, 'click', config.listeners.fullscreen, _toggleFullscreen); + _proxyListener(plyr.buttons.fullscreen, "click", config.listeners.fullscreen, _toggleFullscreen); // Handle user exiting fullscreen by escaping etc if (fullscreen.supportsFullScreen) { @@ -3066,38 +3185,42 @@ } // Captions - _proxyListener(plyr.buttons.captions, 'click', config.listeners.captions, _toggleCaptions); + _proxyListener(plyr.buttons.captions, "click", config.listeners.captions, _toggleCaptions); // Seek tooltip - _on(plyr.progress.container, 'mouseenter mouseleave mousemove', _updateSeekTooltip); + _on(plyr.progress.container, "mouseenter mouseleave mousemove", _updateSeekTooltip); // Toggle controls visibility based on mouse movement if (config.hideControls) { // Toggle controls on mouse events and entering fullscreen - _on(plyr.container, 'mouseenter mouseleave mousemove touchstart touchend touchcancel touchmove enterfullscreen', _toggleControls); + _on( + plyr.container, + "mouseenter mouseleave mousemove touchstart touchend touchcancel touchmove enterfullscreen", + _toggleControls + ); // Watch for cursor over controls so they don't hide when trying to interact - _on(plyr.controls, 'mouseenter mouseleave', function(event) { - plyr.controls.hover = event.type === 'mouseenter'; + _on(plyr.controls, "mouseenter mouseleave", function(event) { + plyr.controls.hover = event.type === "mouseenter"; }); - // Watch for cursor over controls so they don't hide when trying to interact - _on(plyr.controls, 'mousedown mouseup touchstart touchend touchcancel', function(event) { - plyr.controls.pressed = _inArray(['mousedown', 'touchstart'], event.type); + // Watch for cursor over controls so they don't hide when trying to interact + _on(plyr.controls, "mousedown mouseup touchstart touchend touchcancel", function(event) { + plyr.controls.pressed = _inArray(["mousedown", "touchstart"], event.type); }); // Focus in/out on controls - _on(plyr.controls, 'focus blur', _toggleControls, true); + _on(plyr.controls, "focus blur", _toggleControls, true); } // Adjust volume on scroll - _on(plyr.volume.input, 'wheel', function(event) { + _on(plyr.volume.input, "wheel", function(event) { event.preventDefault(); // Detect "natural" scroll - suppored on OS X Safari only // Other browsers on OS X will be inverted until support improves var inverted = event.webkitDirectionInvertedFromDevice, - step = (config.volumeStep / 5); + step = config.volumeStep / 5; // Scroll down (or up on natural) to decrease if (event.deltaY < 0 || event.deltaX > 0) { @@ -3122,20 +3245,20 @@ // Listen for media events function _mediaListeners() { // Time change on media - _on(plyr.media, 'timeupdate seeking', _timeUpdate); + _on(plyr.media, "timeupdate seeking", _timeUpdate); // Update manual captions - _on(plyr.media, 'timeupdate', _seekManualCaptions); + _on(plyr.media, "timeupdate", _seekManualCaptions); // Display duration - _on(plyr.media, 'durationchange loadedmetadata', _displayDuration); + _on(plyr.media, "durationchange loadedmetadata", _displayDuration); // Handle the media finishing - _on(plyr.media, 'ended', function() { + _on(plyr.media, "ended", function() { // Show poster on end - if (plyr.type === 'video' && config.showPosterOnEnd) { + if (plyr.type === "video" && config.showPosterOnEnd) { // Clear - if (plyr.type === 'video') { + if (plyr.type === "video") { _setCaption(); } @@ -3148,21 +3271,21 @@ }); // Check for buffer progress - _on(plyr.media, 'progress playing', _updateProgress); + _on(plyr.media, "progress playing", _updateProgress); // Handle native mute - _on(plyr.media, 'volumechange', _updateVolume); + _on(plyr.media, "volumechange", _updateVolume); // Handle native play/pause - _on(plyr.media, 'play pause ended', _checkPlaying); + _on(plyr.media, "play pause ended", _checkPlaying); // Loading - _on(plyr.media, 'waiting canplay seeked', _checkLoading); + _on(plyr.media, "waiting canplay seeked", _checkLoading); // Click video - if (config.clickToPlay && plyr.type !== 'audio') { + if (config.clickToPlay && plyr.type !== "audio") { // Re-fetch the wrapper - var wrapper = _getElement('.' + config.classes.videoWrapper); + var wrapper = _getElement("." + config.classes.videoWrapper); // Bail if there's no wrapper (this should never happen) if (!wrapper) { @@ -3173,7 +3296,7 @@ wrapper.style.cursor = "pointer"; // On click play, pause ore restart - _on(wrapper, 'click', function() { + _on(wrapper, "click", function() { // Touch devices will just show controls (if we're hiding controls) if (config.hideControls && plyr.browser.isTouch && !plyr.media.paused) { return; @@ -3192,12 +3315,14 @@ // Disable right click if (config.disableContextMenu) { - _on(plyr.media, 'contextmenu', function(event) { event.preventDefault(); }); + _on(plyr.media, "contextmenu", function(event) { + event.preventDefault(); + }); } // Proxy events to container // Bubble up key events for Edge - _on(plyr.media, config.events.concat(['keyup', 'keydown']).join(' '), function(event) { + _on(plyr.media, config.events.concat(["keyup", "keydown"]).join(" "), function(event) { _triggerEvent(plyr.container, event.type, true); }); } @@ -3210,7 +3335,7 @@ } // Remove child sources - var sources = plyr.media.querySelectorAll('source'); + var sources = plyr.media.querySelectorAll("source"); for (var i = 0; i < sources.length; i++) { _remove(sources[i]); } @@ -3218,7 +3343,7 @@ // Set blank video src attribute // This is to prevent a MEDIA_ERR_SRC_NOT_SUPPORTED error // Info: http://stackoverflow.com/questions/32231579/how-to-properly-dispose-of-an-html5-video-and-close-socket-or-connection - plyr.media.setAttribute('src', config.blankUrl); + plyr.media.setAttribute("src", config.blankUrl); // Load the new empty source // This will cancel existing requests @@ -3226,7 +3351,7 @@ plyr.media.load(); // Debugging - _log('Cancelled network requests'); + _log("Cancelled network requests"); } // Destroy an instance @@ -3240,7 +3365,7 @@ // Type specific stuff switch (plyr.type) { - case 'youtube': + case "youtube": // Clear timers window.clearInterval(timers.buffering); window.clearInterval(timers.playing); @@ -3253,7 +3378,7 @@ break; - case 'vimeo': + case "vimeo": // Destroy Vimeo API // then clean up (wait, to prevent postmessage errors) plyr.embed.unload().then(cleanUp); @@ -3263,8 +3388,8 @@ break; - case 'video': - case 'audio': + case "video": + case "audio": // Restore native video controls _toggleNativeControls(true); @@ -3299,10 +3424,10 @@ plyr.container.parentNode.replaceChild(original, plyr.container); // Allow overflow (set on fullscreen) - document.body.style.overflow = ''; + document.body.style.overflow = ""; // Event - _triggerEvent(original, 'destroyed', true); + _triggerEvent(original, "destroyed", true); } } @@ -3330,18 +3455,18 @@ // Set media type based on tag or data attribute // Supported: video, audio, vimeo, youtube var tagName = media.tagName.toLowerCase(); - if (tagName === 'div') { - plyr.type = media.getAttribute('data-type'); - plyr.embedId = media.getAttribute('data-video-id'); + if (tagName === "div") { + plyr.type = media.getAttribute("data-type"); + plyr.embedId = media.getAttribute("data-video-id"); // Clean up - media.removeAttribute('data-type'); - media.removeAttribute('data-video-id'); + media.removeAttribute("data-type"); + media.removeAttribute("data-video-id"); } else { - plyr.type = tagName; - config.crossorigin = (media.getAttribute('crossorigin') !== null); - config.autoplay = (config.autoplay || (media.getAttribute('autoplay') !== null)); - config.loop = (config.loop || (media.getAttribute('loop') !== null)); + plyr.type = tagName; + 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 @@ -3353,23 +3478,26 @@ } // Wrap media - plyr.container = _wrap(media, document.createElement('div')); + plyr.container = _wrap(media, document.createElement("div")); // Allow focus to be captured - plyr.container.setAttribute('tabindex', 0); + plyr.container.setAttribute("tabindex", 0); // Add style hook _toggleStyleHook(); // Debug info - _log('' + plyr.browser.name + ' ' + plyr.browser.version); + _log("" + plyr.browser.name + " " + plyr.browser.version); // Setup media _setupMedia(); // Setup interface // If embed but not fully supported, setupInterface (to avoid flash of controls) and call ready now - if (_inArray(config.types.html5, plyr.type) || (_inArray(config.types.embed, plyr.type) && !plyr.supported.full)) { + if ( + _inArray(config.types.html5, plyr.type) || + (_inArray(config.types.embed, plyr.type) && !plyr.supported.full) + ) { // Setup UI _setupInterface(); @@ -3388,7 +3516,7 @@ function _setupInterface() { // Don't setup interface if no support if (!plyr.supported.full) { - _warn('Basic support only', plyr.type); + _warn("Basic support only", plyr.type); // Remove controls _remove(_getElement(config.selectors.controls.wrapper)); @@ -3444,44 +3572,76 @@ } api = { - getOriginal: function() { return original; }, - getContainer: function() { return plyr.container }, - getEmbed: function() { return plyr.embed; }, - getMedia: function() { return plyr.media; }, - getType: function() { return plyr.type; }, - getDuration: _getDuration, - getCurrentTime: function() { return plyr.media.currentTime; }, - getVolume: function() { return plyr.media.volume; }, - isMuted: function() { return plyr.media.muted; }, - isReady: function() { return _hasClass(plyr.container, config.classes.ready); }, - isLoading: function() { return _hasClass(plyr.container, config.classes.loading); }, - isPaused: function() { return plyr.media.paused; }, - on: function(event, callback) { _on(plyr.container, event, callback); return this; }, - play: _play, - pause: _pause, - stop: function() { _pause(); _seek(); }, - restart: _seek, - rewind: _rewind, - forward: _forward, - seek: _seek, - source: _source, - poster: _updatePoster, - setVolume: _setVolume, - togglePlay: _togglePlay, - toggleMute: _toggleMute, - toggleCaptions: _toggleCaptions, - toggleFullscreen: _toggleFullscreen, - toggleControls: _toggleControls, - isFullscreen: function() { return plyr.isFullscreen || false; }, - support: function(mimeType) { return _supportMime(plyr, mimeType); }, - destroy: _destroy + getOriginal: function() { + return original; + }, + getContainer: function() { + return plyr.container; + }, + getEmbed: function() { + return plyr.embed; + }, + getMedia: function() { + return plyr.media; + }, + getType: function() { + return plyr.type; + }, + getDuration: _getDuration, + getCurrentTime: function() { + return plyr.media.currentTime; + }, + getVolume: function() { + return plyr.media.volume; + }, + isMuted: function() { + return plyr.media.muted; + }, + isReady: function() { + return _hasClass(plyr.container, config.classes.ready); + }, + isLoading: function() { + return _hasClass(plyr.container, config.classes.loading); + }, + isPaused: function() { + return plyr.media.paused; + }, + on: function(event, callback) { + _on(plyr.container, event, callback); + return this; + }, + play: _play, + pause: _pause, + stop: function() { + _pause(); + _seek(); + }, + restart: _seek, + rewind: _rewind, + forward: _forward, + seek: _seek, + source: _source, + poster: _updatePoster, + setVolume: _setVolume, + togglePlay: _togglePlay, + toggleMute: _toggleMute, + toggleCaptions: _toggleCaptions, + toggleFullscreen: _toggleFullscreen, + toggleControls: _toggleControls, + isFullscreen: function() { + return plyr.isFullscreen || false; + }, + support: function(mimeType) { + return _supportMime(plyr, mimeType); + }, + destroy: _destroy }; // Everything done function _ready() { // Ready event at end of execution stack window.setTimeout(function() { - _triggerEvent(plyr.media, 'ready'); + _triggerEvent(plyr.media, "ready"); }, 0); // Set class hook on media element @@ -3515,21 +3675,21 @@ var x = new XMLHttpRequest(); // If the id is set and sprite exists, bail - if (_is.string(id) && _is.htmlElement(document.querySelector('#' + id))) { + if (_is.string(id) && _is.htmlElement(document.querySelector("#" + id))) { return; } // Create placeholder (to prevent loading twice) - var container = document.createElement('div'); - container.setAttribute('hidden', ''); + var container = document.createElement("div"); + container.setAttribute("hidden", ""); if (_is.string(id)) { - container.setAttribute('id', id); + container.setAttribute("id", id); } document.body.insertBefore(container, document.body.childNodes[0]); // Check for CORS support - if ('withCredentials' in x) { - x.open('GET', url, true); + if ("withCredentials" in x) { + x.open("GET", url, true); } else { return; } @@ -3537,43 +3697,43 @@ // Inject hidden div with sprite on load x.onload = function() { container.innerHTML = x.responseText; - } + }; x.send(); } // Check for support function supported(type) { - var browser = _browserSniff(), - isOldIE = (browser.isIE && browser.version <= 9), - isIos = browser.isIos, - isIphone = browser.isIphone, - audioSupport = !!document.createElement('audio').canPlayType, - videoSupport = !!document.createElement('video').canPlayType, - basic = false, - full = false; + var browser = _browserSniff(), + isOldIE = browser.isIE && browser.version <= 9, + isIos = browser.isIos, + isIphone = browser.isIphone, + audioSupport = !!document.createElement("audio").canPlayType, + videoSupport = !!document.createElement("video").canPlayType, + basic = false, + full = false; switch (type) { - case 'video': + case "video": basic = videoSupport; - full = (basic && (!isOldIE && !isIphone)); + full = basic && (!isOldIE && !isIphone); break; - case 'audio': + case "audio": basic = audioSupport; - full = (basic && !isOldIE); + full = basic && !isOldIE; break; // Vimeo does not seem to be supported on iOS via API // Issue raised https://github.com/vimeo/player.js/issues/87 - case 'vimeo': + case "vimeo": basic = true; - full = (!isOldIE && !isIos); + full = !isOldIE && !isIos; break; - case 'youtube': + case "youtube": basic = true; - full = (!isOldIE && !isIos); + full = !isOldIE && !isIos; // YouTube seems to work on iOS 10+ on iPad if (isIos && !isIphone && browser.version >= 10) { @@ -3582,37 +3742,37 @@ break; - case 'soundcloud': + case "soundcloud": basic = true; - full = (!isOldIE && !isIphone); + full = !isOldIE && !isIphone; break; default: - basic = (audioSupport && videoSupport); - full = (basic && !isOldIE); + basic = audioSupport && videoSupport; + full = basic && !isOldIE; } return { - basic: basic, - full: full + basic: basic, + full: full }; } // Setup function function setup(targets, options) { // Get the players - var players = [], - instances = [], - selector = [defaults.selectors.html5, defaults.selectors.embed].join(','); + var players = [], + instances = [], + selector = [defaults.selectors.html5, defaults.selectors.embed].join(","); // Select the elements if (_is.string(targets)) { // String selector passed targets = document.querySelectorAll(targets); - } else if (_is.htmlElement(targets)) { + } else if (_is.htmlElement(targets)) { // Single HTMLElement passed targets = [targets]; - } else if (!_is.nodeList(targets) && !_is.array(targets) && !_is.string(targets)) { + } else if (!_is.nodeList(targets) && !_is.array(targets) && !_is.string(targets)) { // No selector passed, possibly options as first argument // If options are the first argument if (_is.undefined(options) && _is.object(targets)) { @@ -3641,9 +3801,9 @@ // Always wrap in a
for styling //container: _wrap(media, document.createElement('div')), // Could be a container or the media itself - target: target, + target: target, // This should be the