From 2150c44036e13073c6f7f07343009b6373846bdf Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Tue, 6 Feb 2018 00:24:48 +1100 Subject: [PATCH] Added backwards compatibility for
embeds --- .npmignore | 4 + changelog.md | 7 +- demo/dist/demo.js | 2 +- demo/dist/demo.js.map | 2 +- demo/index.local.html | 184 -------------------------------------- demo/src/js/demo.js | 2 +- dist/plyr.js | 2 +- dist/plyr.js.map | 2 +- readme.md | 53 ++++++++--- src/js/defaults.js | 8 ++ src/js/plugins/vimeo.js | 11 ++- src/js/plugins/youtube.js | 10 ++- src/js/plyr.js | 79 ++++++++-------- 13 files changed, 120 insertions(+), 246 deletions(-) create mode 100644 .npmignore delete mode 100644 demo/index.local.html diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..afba951f --- /dev/null +++ b/.npmignore @@ -0,0 +1,4 @@ +demo +.github +.vscode +*.code-workspace diff --git a/changelog.md b/changelog.md index 158d9683..2ebbda00 100644 --- a/changelog.md +++ b/changelog.md @@ -17,8 +17,8 @@ This is a massive release. A _mostly_ complete rewrite in ES6. What started out ### Other stuff -* Now using SASS exclusively. Sorry, LESS folk it just made sense to maintain one method as SASS is what the cool kids use -* Moved to ES6. All the rage these days +* Now using SASS exclusively. Sorry, LESS folk it just made sense to maintain one method as SASS is what the cool kids use. It may come back if we work out an automated way to convert the SASS +* Moved to ES6. All the rage these days. You'll need to look at polyfills. The demo uses [polyfill.io](https://polyfill.io) * Added basic looping support * Added an aspect ratio option for those that can't leave the 90s and want 4:3 * `controlshidden` and `controlsshown` events added for when the controls show or hide @@ -44,6 +44,7 @@ You gotta break eggs to make an omelette. Sadly, there's quite a few breaking ch * Setup now uses proper constructor, accepts a single selector/element/node and returns a single instance - much simpler than before * Much of the API is now using getters and setters rather than methods (where it makes sense) to match the HTML5 API - see the docs for more info +* The data attributes for the embeds are now `data-plyr-provider` and `data-plyr-embed-id` to prevent compatibility issues. These can be changed under `config.attributes.embed` if required * `blankUrl` -> `blankVideo` * `volume` is now `0` to `1` as per HTML5 spec * `keyboardShorcuts` (typo) is now just `keyboard` @@ -66,7 +67,7 @@ You gotta break eggs to make an omelette. Sadly, there's quite a few breaking ch ### Polyfilling -Because we're using the fancy new ES6 syntax, you will need to polyfill for vintage browsers if you want to use Plyr and still support them. Luckily there's a decent service for this that makes it painless, [https://polyfill.io](polyfill.io). +Because we're using the fancy new ES6 syntax, you will need to polyfill for vintage browsers if you want to use Plyr and still support them. Luckily there's a decent service for this that makes it painless, [polyfill.io](https://polyfill.io). ## v2.0.18 diff --git a/demo/dist/demo.js b/demo/dist/demo.js index 86a62847..fa11daee 100644 --- a/demo/dist/demo.js +++ b/demo/dist/demo.js @@ -1,3 +1,3 @@ -!function(){"use strict";var e,t,o,i,r,n;document.addEventListener("DOMContentLoaded",function(){window.shr&&window.shr.setup({count:{classname:"button__count"}});document.addEventListener("focusout",function(e){e.target.classList.remove("tab-focus")}),document.addEventListener("keydown",function(e){9===e.keyCode&&window.setTimeout(function(){document.activeElement.classList.add("tab-focus")},0)});var e=new window.Plyr("#player",{debug:!0,title:"View From A Blue Moon",keyboard:{global:!0},tooltips:{controls:!0},captions:{active:!0},keys:{google:"AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c"},ads:{enabled:!0}});window.player=e;var t=document.querySelectorAll("[data-source]"),o={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},i=window.location.hash.replace("#",""),r=window.history&&window.history.pushState;function n(e,t,o){e&&e.classList[o?"add":"remove"](t)}function a(r,a){if(r in o&&(a||r!==i)&&(i.length||r!==o.video)){switch(r){case o.video:e.source={type:"video",title:"View From A Blue Moon",sources:[{src:"https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4",type:"video/mp4"}],poster:"https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg",tracks:[{kind:"captions",label:"English",srclang:"en",src:"https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt",default:!0},{kind:"captions",label:"French",srclang:"fr",src:"https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt"}]};break;case o.audio:e.source={type:"audio",title:"Kishi Bashi – “It All Began With A Burst”",sources:[{src:"https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3",type:"audio/mp3"},{src:"https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg",type:"audio/ogg"}]};break;case o.youtube:e.source={type:"video",title:"View From A Blue Moon",sources:[{src:"https://youtube.com/watch?v=bTqVqk7FSmY",provider:"youtube"}]};break;case o.vimeo:e.source={type:"video",sources:[{src:"https://vimeo.com/76979871",provider:"vimeo"}]}}i=r,Array.from(t).forEach(function(e){return n(e.parentElement,"active",!1)}),n(document.querySelector('[data-source="'+r+'"]'),"active",!0),Array.from(document.querySelectorAll(".plyr__cite")).forEach(function(e){e.setAttribute("hidden","")}),document.querySelector(".plyr__cite--"+r).removeAttribute("hidden")}}if(Array.from(t).forEach(function(e){e.addEventListener("click",function(){var t=e.getAttribute("data-source");a(t),r&&window.history.pushState({type:t},"","#"+t)})}),window.addEventListener("popstate",function(e){e.state&&"type"in e.state&&a(e.state.type)}),r){var s=!i.length;s&&(i=o.video),i in o&&window.history.replaceState({type:i},"",s?"":"#"+i),i!==o.video&&a(i,!0)}}),"plyr.io"===window.location.host&&(e=window,t=document,o="script",i="ga",e.GoogleAnalyticsObject=i,e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,r=t.createElement(o),n=t.getElementsByTagName(o)[0],r.async=1,r.src="//www.google-analytics.com/analytics.js",n.parentNode.insertBefore(r,n),window.ga("create","UA-40881672-11","auto"),window.ga("send","pageview"))}(); +!function(){"use strict";var e,t,o,i,r,a;document.addEventListener("DOMContentLoaded",function(){window.shr&&window.shr.setup({count:{classname:"button__count"}});document.addEventListener("focusout",function(e){e.target.classList.remove("tab-focus")}),document.addEventListener("keydown",function(e){9===e.keyCode&&window.setTimeout(function(){document.activeElement.classList.add("tab-focus")},0)});var e=new Plyr("#player",{debug:!0,title:"View From A Blue Moon",keyboard:{global:!0},tooltips:{controls:!0},captions:{active:!0},keys:{google:"AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c"},ads:{enabled:!0}});window.player=e;var t=document.querySelectorAll("[data-source]"),o={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},i=window.location.hash.replace("#",""),r=window.history&&window.history.pushState;function a(e,t,o){e&&e.classList[o?"add":"remove"](t)}function n(r,n){if(r in o&&(n||r!==i)&&(i.length||r!==o.video)){switch(r){case o.video:e.source={type:"video",title:"View From A Blue Moon",sources:[{src:"https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4",type:"video/mp4"}],poster:"https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg",tracks:[{kind:"captions",label:"English",srclang:"en",src:"https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt",default:!0},{kind:"captions",label:"French",srclang:"fr",src:"https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt"}]};break;case o.audio:e.source={type:"audio",title:"Kishi Bashi – “It All Began With A Burst”",sources:[{src:"https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3",type:"audio/mp3"},{src:"https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg",type:"audio/ogg"}]};break;case o.youtube:e.source={type:"video",title:"View From A Blue Moon",sources:[{src:"https://youtube.com/watch?v=bTqVqk7FSmY",provider:"youtube"}]};break;case o.vimeo:e.source={type:"video",sources:[{src:"https://vimeo.com/76979871",provider:"vimeo"}]}}i=r,Array.from(t).forEach(function(e){return a(e.parentElement,"active",!1)}),a(document.querySelector('[data-source="'+r+'"]'),"active",!0),Array.from(document.querySelectorAll(".plyr__cite")).forEach(function(e){e.setAttribute("hidden","")}),document.querySelector(".plyr__cite--"+r).removeAttribute("hidden")}}if(Array.from(t).forEach(function(e){e.addEventListener("click",function(){var t=e.getAttribute("data-source");n(t),r&&window.history.pushState({type:t},"","#"+t)})}),window.addEventListener("popstate",function(e){e.state&&"type"in e.state&&n(e.state.type)}),r){var s=!i.length;s&&(i=o.video),i in o&&window.history.replaceState({type:i},"",s?"":"#"+i),i!==o.video&&n(i,!0)}}),"plyr.io"===window.location.host&&(e=window,t=document,o="script",i="ga",e.GoogleAnalyticsObject=i,e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,r=t.createElement(o),a=t.getElementsByTagName(o)[0],r.async=1,r.src="//www.google-analytics.com/analytics.js",a.parentNode.insertBefore(r,a),window.ga("create","UA-40881672-11","auto"),window.ga("send","pageview"))}(); //# sourceMappingURL=demo.js.map diff --git a/demo/dist/demo.js.map b/demo/dist/demo.js.map index 374ec6f9..16a23a72 100644 --- a/demo/dist/demo.js.map +++ b/demo/dist/demo.js.map @@ -1 +1 @@ -{"version":3,"sources":["demo/src/js/demo.js"],"names":["i","s","o","r","a","m","document","addEventListener","window","shr","setup","target","classList","remove","event","keyCode","setTimeout","activeElement","add","player","Plyr","buttons","querySelectorAll","types","currentType","location","hash","replace","historySupport","history","pushState","toggleClass","element","className","state","newSource","type","init","length","video","source","audio","youtube","vimeo","from","forEach","button","parentElement","querySelector","setAttribute","removeAttribute","getAttribute","replaceState","host","GoogleAnalyticsObject","q","push","arguments","l","Date","createElement","getElementsByTagName","async","src","parentNode","insertBefore","ga"],"mappings":"6BAmOcA,EAAGC,EAAGC,EAAMC,EAAGC,EAAGC,EA7NhCC,SAASC,iBAAiB,mBAAoB,WACtCC,OAAOC,YACAA,IAAIC,wBAEQ,4BASdH,iBAAiB,WAAY,cAC5BI,OAAOC,UAAUC,OAJN,wBAQZN,iBAAiB,UAAW,YACX,IAAlBO,EAAMC,gBAMHC,WAAW,oBACLC,cAAcL,UAAUM,IAhBpB,cAiBd,SAIDC,EAAS,IAAIX,OAAOY,KAAK,kBACpB,QACA,0CAGK,uBAGE,qBAGF,gBAGA,yDAGC,YAKVD,OAASA,MAGVE,EAAUf,SAASgB,iBAAiB,iBACpCC,SACK,cACA,gBACE,gBACF,SAEPC,EAAchB,OAAOiB,SAASC,KAAKC,QAAQ,IAAK,IAC9CC,EAAiBpB,OAAOqB,SAAWrB,OAAOqB,QAAQC,mBAG/CC,EAAYC,EAASC,EAAWC,GACjCF,KACQpB,UAAUsB,EAAQ,MAAQ,UAAUD,YAK3CE,EAAUC,EAAMC,MAEfD,KAAQb,IAAYc,GAAQD,IAASZ,KAAkBA,EAAYc,QAAUF,IAASb,EAAMgB,eAI1FH,QACCb,EAAMgB,QACAC,aACG,cACC,sCAEE,4EACC,qBAEF,qFAGM,iBACC,kBACE,SACJ,mFACI,SAGH,iBACC,iBACE,SACJ,wFAOhBjB,EAAMkB,QACAD,aACG,cACC,4EAGM,mFACC,kBAGD,mFACC,0BAOjBjB,EAAMmB,UACAF,aACG,cACC,sCAEE,mDACK,wBAMjBjB,EAAMoB,QACAH,aACG,sBAEG,sCACK,aAWZJ,QAGRQ,KAAKvB,GAASwB,QAAQ,mBAAUd,EAAYe,EAAOC,cAAe,UAAU,OAGtEzC,SAAS0C,+BAA+BZ,QAAW,UAAU,SAGnEQ,KAAKtC,SAASgB,iBAAiB,gBAAgBuB,QAAQ,cACpDI,aAAa,SAAU,eAEvBD,8BAA8BZ,GAAQc,gBAAgB,oBAI7DN,KAAKvB,GAASwB,QAAQ,cACjBtC,iBAAiB,QAAS,eACvB6B,EAAOU,EAAOK,aAAa,iBAEvBf,GAENR,UACOC,QAAQC,WAAYM,QAAQ,OAAQA,cAMhD7B,iBAAiB,WAAY,YAC5BO,EAAMoB,OAAS,SAAUpB,EAAMoB,SACrBpB,EAAMoB,MAAME,QAK1BR,EAAgB,KACVW,GAASf,EAAYc,OAGvBC,MACchB,EAAMgB,OAIpBf,KAAeD,UACRM,QAAQuB,mBAED5B,GAEV,GACAe,EAAQ,OAASf,GAKrBA,IAAgBD,EAAMgB,SACZf,GAAa,MAQN,YAAzBhB,OAAOiB,SAAS4B,OACNrD,EAaPQ,OAbUP,EAaFK,SAbKJ,EAaK,SAbCC,EAaoD,OAZpEmD,sBAAwBnD,IAC1B,GACIH,EAAA,IACA,YACKA,EAAA,GAAKuD,EAAIvD,EAAA,GAAKuD,OAASC,KAAKC,cAErC,GAAKC,EAAI,EAAI,IAAIC,OACb1D,EAAE2D,cAAc1D,KAChBD,EAAE4D,qBAAqB3D,GAAG,KAC5B4D,MAAQ,IACRC,IAEyB,4CADzBC,WAAWC,aAAa7D,EAAGC,UAE1B6D,GAAG,SAAU,iBAAkB,eAC/BA,GAAG,OAAQ","file":"demo.js","sourcesContent":["// ==========================================================================\n// Plyr.io demo\n// This code is purely for the https://plyr.io website\n// Please see readme.md in the root or github.com/sampotts/plyr\n// ==========================================================================\n\ndocument.addEventListener('DOMContentLoaded', () => {\n if (window.shr) {\n window.shr.setup({\n count: {\n classname: 'button__count',\n },\n });\n }\n\n // Setup tab focus\n const tabClassName = 'tab-focus';\n\n // Remove class on blur\n document.addEventListener('focusout', event => {\n event.target.classList.remove(tabClassName);\n });\n\n // Add classname to tabbed elements\n document.addEventListener('keydown', event => {\n if (event.keyCode !== 9) {\n return;\n }\n\n // Delay the adding of classname until the focus has changed\n // This event fires before the focusin event\n window.setTimeout(() => {\n document.activeElement.classList.add(tabClassName);\n }, 0);\n });\n\n // Setup the player\n const player = new window.Plyr('#player', {\n debug: true,\n title: 'View From A Blue Moon',\n // iconUrl: '../dist/plyr.svg',\n keyboard: {\n global: true,\n },\n tooltips: {\n controls: true,\n },\n captions: {\n active: true,\n },\n keys: {\n google: 'AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c',\n },\n ads: {\n enabled: true,\n },\n });\n\n // Expose for testing\n window.player = player;\n\n // Setup type toggle\n const buttons = document.querySelectorAll('[data-source]');\n const types = {\n video: 'video',\n audio: 'audio',\n youtube: 'youtube',\n vimeo: 'vimeo',\n };\n let currentType = window.location.hash.replace('#', '');\n const historySupport = window.history && window.history.pushState;\n\n // Toggle class on an element\n function toggleClass(element, className, state) {\n if (element) {\n element.classList[state ? 'add' : 'remove'](className);\n }\n }\n\n // Set a new source\n function newSource(type, init) {\n // Bail if new type isn't known, it's the current type, or current type is empty (video is default) and new type is video\n if (!(type in types) || (!init && type === currentType) || (!currentType.length && type === types.video)) {\n return;\n }\n\n switch (type) {\n case types.video:\n player.source = {\n type: 'video',\n title: 'View From A Blue Moon',\n sources: [{\n src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4',\n type: 'video/mp4',\n }],\n poster: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg',\n tracks: [\n {\n kind: 'captions',\n label: 'English',\n srclang: 'en',\n src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt',\n default: true,\n },\n {\n kind: 'captions',\n label: 'French',\n srclang: 'fr',\n src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt',\n },\n ],\n };\n\n break;\n\n case types.audio:\n player.source = {\n type: 'audio',\n title: 'Kishi Bashi – “It All Began With A Burst”',\n sources: [\n {\n src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3',\n type: 'audio/mp3',\n },\n {\n src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg',\n type: 'audio/ogg',\n },\n ],\n };\n\n break;\n\n case types.youtube:\n player.source = {\n type: 'video',\n title: 'View From A Blue Moon',\n sources: [{\n src: 'https://youtube.com/watch?v=bTqVqk7FSmY',\n provider: 'youtube',\n }],\n };\n\n break;\n\n case types.vimeo:\n player.source = {\n type: 'video',\n sources: [{\n src: 'https://vimeo.com/76979871',\n provider: 'vimeo',\n }],\n };\n\n break;\n\n default:\n break;\n }\n\n // Set the current type for next time\n currentType = type;\n\n // Remove active classes\n Array.from(buttons).forEach(button => toggleClass(button.parentElement, 'active', false));\n\n // Set active on parent\n toggleClass(document.querySelector(`[data-source=\"${type}\"]`), 'active', true);\n\n // Show cite\n Array.from(document.querySelectorAll('.plyr__cite')).forEach(cite => {\n cite.setAttribute('hidden', '');\n });\n document.querySelector(`.plyr__cite--${type}`).removeAttribute('hidden');\n }\n\n // Bind to each button\n Array.from(buttons).forEach(button => {\n button.addEventListener('click', () => {\n const type = button.getAttribute('data-source');\n\n newSource(type);\n\n if (historySupport) {\n window.history.pushState({ type }, '', `#${type}`);\n }\n });\n });\n\n // List for backwards/forwards\n window.addEventListener('popstate', event => {\n if (event.state && 'type' in event.state) {\n newSource(event.state.type);\n }\n });\n\n // On load\n if (historySupport) {\n const video = !currentType.length;\n\n // If there's no current type set, assume video\n if (video) {\n currentType = types.video;\n }\n\n // Replace current history state\n if (currentType in types) {\n window.history.replaceState(\n {\n type: currentType,\n },\n '',\n video ? '' : `#${currentType}`,\n );\n }\n\n // If it's not video, load the source\n if (currentType !== types.video) {\n newSource(currentType, true);\n }\n }\n});\n\n// Google analytics\n// For demo site (https://plyr.io) only\n/* eslint-disable */\nif (window.location.host === 'plyr.io') {\n (function(i, s, o, g, r, a, m) {\n i.GoogleAnalyticsObject = r;\n i[r] =\n i[r] ||\n function() {\n (i[r].q = i[r].q || []).push(arguments);\n };\n i[r].l = 1 * new Date();\n a = s.createElement(o);\n m = s.getElementsByTagName(o)[0];\n a.async = 1;\n a.src = g;\n m.parentNode.insertBefore(a, m);\n })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');\n window.ga('create', 'UA-40881672-11', 'auto');\n window.ga('send', 'pageview');\n}\n/* eslint-enable */\n"]} \ No newline at end of file +{"version":3,"sources":["demo/src/js/demo.js"],"names":["i","s","o","r","a","m","document","addEventListener","window","shr","setup","target","classList","remove","event","keyCode","setTimeout","activeElement","add","player","Plyr","buttons","querySelectorAll","types","currentType","location","hash","replace","historySupport","history","pushState","toggleClass","element","className","state","newSource","type","init","length","video","source","audio","youtube","vimeo","from","forEach","button","parentElement","querySelector","setAttribute","removeAttribute","getAttribute","replaceState","host","GoogleAnalyticsObject","q","push","arguments","l","Date","createElement","getElementsByTagName","async","src","parentNode","insertBefore","ga"],"mappings":"6BAmOcA,EAAGC,EAAGC,EAAMC,EAAGC,EAAGC,EA7NhCC,SAASC,iBAAiB,mBAAoB,WACtCC,OAAOC,YACAA,IAAIC,wBAEQ,4BASdH,iBAAiB,WAAY,cAC5BI,OAAOC,UAAUC,OAJN,wBAQZN,iBAAiB,UAAW,YACX,IAAlBO,EAAMC,gBAMHC,WAAW,oBACLC,cAAcL,UAAUM,IAhBpB,cAiBd,SAIDC,EAAS,IAAIC,KAAK,kBACb,QACA,0CAGK,uBAGE,qBAGF,gBAGA,yDAGC,YAKVD,OAASA,MAGVE,EAAUf,SAASgB,iBAAiB,iBACpCC,SACK,cACA,gBACE,gBACF,SAEPC,EAAchB,OAAOiB,SAASC,KAAKC,QAAQ,IAAK,IAC9CC,EAAiBpB,OAAOqB,SAAWrB,OAAOqB,QAAQC,mBAG/CC,EAAYC,EAASC,EAAWC,GACjCF,KACQpB,UAAUsB,EAAQ,MAAQ,UAAUD,YAK3CE,EAAUC,EAAMC,MAEfD,KAAQb,IAAYc,GAAQD,IAASZ,KAAkBA,EAAYc,QAAUF,IAASb,EAAMgB,eAI1FH,QACCb,EAAMgB,QACAC,aACG,cACC,sCAEE,4EACC,qBAEF,qFAGM,iBACC,kBACE,SACJ,mFACI,SAGH,iBACC,iBACE,SACJ,wFAOhBjB,EAAMkB,QACAD,aACG,cACC,4EAGM,mFACC,kBAGD,mFACC,0BAOjBjB,EAAMmB,UACAF,aACG,cACC,sCAEE,mDACK,wBAMjBjB,EAAMoB,QACAH,aACG,sBAEG,sCACK,aAWZJ,QAGRQ,KAAKvB,GAASwB,QAAQ,mBAAUd,EAAYe,EAAOC,cAAe,UAAU,OAGtEzC,SAAS0C,+BAA+BZ,QAAW,UAAU,SAGnEQ,KAAKtC,SAASgB,iBAAiB,gBAAgBuB,QAAQ,cACpDI,aAAa,SAAU,eAEvBD,8BAA8BZ,GAAQc,gBAAgB,oBAI7DN,KAAKvB,GAASwB,QAAQ,cACjBtC,iBAAiB,QAAS,eACvB6B,EAAOU,EAAOK,aAAa,iBAEvBf,GAENR,UACOC,QAAQC,WAAYM,QAAQ,OAAQA,cAMhD7B,iBAAiB,WAAY,YAC5BO,EAAMoB,OAAS,SAAUpB,EAAMoB,SACrBpB,EAAMoB,MAAME,QAK1BR,EAAgB,KACVW,GAASf,EAAYc,OAGvBC,MACchB,EAAMgB,OAIpBf,KAAeD,UACRM,QAAQuB,mBAED5B,GAEV,GACAe,EAAQ,OAASf,GAKrBA,IAAgBD,EAAMgB,SACZf,GAAa,MAQN,YAAzBhB,OAAOiB,SAAS4B,OACNrD,EAaPQ,OAbUP,EAaFK,SAbKJ,EAaK,SAbCC,EAaoD,OAZpEmD,sBAAwBnD,IAC1B,GACIH,EAAA,IACA,YACKA,EAAA,GAAKuD,EAAIvD,EAAA,GAAKuD,OAASC,KAAKC,cAErC,GAAKC,EAAI,EAAI,IAAIC,OACb1D,EAAE2D,cAAc1D,KAChBD,EAAE4D,qBAAqB3D,GAAG,KAC5B4D,MAAQ,IACRC,IAEyB,4CADzBC,WAAWC,aAAa7D,EAAGC,UAE1B6D,GAAG,SAAU,iBAAkB,eAC/BA,GAAG,OAAQ","file":"demo.js","sourcesContent":["// ==========================================================================\n// Plyr.io demo\n// This code is purely for the https://plyr.io website\n// Please see readme.md in the root or github.com/sampotts/plyr\n// ==========================================================================\n\ndocument.addEventListener('DOMContentLoaded', () => {\n if (window.shr) {\n window.shr.setup({\n count: {\n classname: 'button__count',\n },\n });\n }\n\n // Setup tab focus\n const tabClassName = 'tab-focus';\n\n // Remove class on blur\n document.addEventListener('focusout', event => {\n event.target.classList.remove(tabClassName);\n });\n\n // Add classname to tabbed elements\n document.addEventListener('keydown', event => {\n if (event.keyCode !== 9) {\n return;\n }\n\n // Delay the adding of classname until the focus has changed\n // This event fires before the focusin event\n window.setTimeout(() => {\n document.activeElement.classList.add(tabClassName);\n }, 0);\n });\n\n // Setup the player\n const player = new Plyr('#player', {\n debug: true,\n title: 'View From A Blue Moon',\n // iconUrl: '../dist/plyr.svg',\n keyboard: {\n global: true,\n },\n tooltips: {\n controls: true,\n },\n captions: {\n active: true,\n },\n keys: {\n google: 'AIzaSyDrNwtN3nLH_8rjCmu5Wq3ZCm4MNAVdc0c',\n },\n ads: {\n enabled: true,\n },\n });\n\n // Expose for testing\n window.player = player;\n\n // Setup type toggle\n const buttons = document.querySelectorAll('[data-source]');\n const types = {\n video: 'video',\n audio: 'audio',\n youtube: 'youtube',\n vimeo: 'vimeo',\n };\n let currentType = window.location.hash.replace('#', '');\n const historySupport = window.history && window.history.pushState;\n\n // Toggle class on an element\n function toggleClass(element, className, state) {\n if (element) {\n element.classList[state ? 'add' : 'remove'](className);\n }\n }\n\n // Set a new source\n function newSource(type, init) {\n // Bail if new type isn't known, it's the current type, or current type is empty (video is default) and new type is video\n if (!(type in types) || (!init && type === currentType) || (!currentType.length && type === types.video)) {\n return;\n }\n\n switch (type) {\n case types.video:\n player.source = {\n type: 'video',\n title: 'View From A Blue Moon',\n sources: [{\n src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4',\n type: 'video/mp4',\n }],\n poster: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg',\n tracks: [\n {\n kind: 'captions',\n label: 'English',\n srclang: 'en',\n src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt',\n default: true,\n },\n {\n kind: 'captions',\n label: 'French',\n srclang: 'fr',\n src: 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt',\n },\n ],\n };\n\n break;\n\n case types.audio:\n player.source = {\n type: 'audio',\n title: 'Kishi Bashi – “It All Began With A Burst”',\n sources: [\n {\n src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3',\n type: 'audio/mp3',\n },\n {\n src: 'https://cdn.plyr.io/static/demo/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg',\n type: 'audio/ogg',\n },\n ],\n };\n\n break;\n\n case types.youtube:\n player.source = {\n type: 'video',\n title: 'View From A Blue Moon',\n sources: [{\n src: 'https://youtube.com/watch?v=bTqVqk7FSmY',\n provider: 'youtube',\n }],\n };\n\n break;\n\n case types.vimeo:\n player.source = {\n type: 'video',\n sources: [{\n src: 'https://vimeo.com/76979871',\n provider: 'vimeo',\n }],\n };\n\n break;\n\n default:\n break;\n }\n\n // Set the current type for next time\n currentType = type;\n\n // Remove active classes\n Array.from(buttons).forEach(button => toggleClass(button.parentElement, 'active', false));\n\n // Set active on parent\n toggleClass(document.querySelector(`[data-source=\"${type}\"]`), 'active', true);\n\n // Show cite\n Array.from(document.querySelectorAll('.plyr__cite')).forEach(cite => {\n cite.setAttribute('hidden', '');\n });\n document.querySelector(`.plyr__cite--${type}`).removeAttribute('hidden');\n }\n\n // Bind to each button\n Array.from(buttons).forEach(button => {\n button.addEventListener('click', () => {\n const type = button.getAttribute('data-source');\n\n newSource(type);\n\n if (historySupport) {\n window.history.pushState({ type }, '', `#${type}`);\n }\n });\n });\n\n // List for backwards/forwards\n window.addEventListener('popstate', event => {\n if (event.state && 'type' in event.state) {\n newSource(event.state.type);\n }\n });\n\n // On load\n if (historySupport) {\n const video = !currentType.length;\n\n // If there's no current type set, assume video\n if (video) {\n currentType = types.video;\n }\n\n // Replace current history state\n if (currentType in types) {\n window.history.replaceState(\n {\n type: currentType,\n },\n '',\n video ? '' : `#${currentType}`,\n );\n }\n\n // If it's not video, load the source\n if (currentType !== types.video) {\n newSource(currentType, true);\n }\n }\n});\n\n// Google analytics\n// For demo site (https://plyr.io) only\n/* eslint-disable */\nif (window.location.host === 'plyr.io') {\n (function(i, s, o, g, r, a, m) {\n i.GoogleAnalyticsObject = r;\n i[r] =\n i[r] ||\n function() {\n (i[r].q = i[r].q || []).push(arguments);\n };\n i[r].l = 1 * new Date();\n a = s.createElement(o);\n m = s.getElementsByTagName(o)[0];\n a.async = 1;\n a.src = g;\n m.parentNode.insertBefore(a, m);\n })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');\n window.ga('create', 'UA-40881672-11', 'auto');\n window.ga('send', 'pageview');\n}\n/* eslint-enable */\n"]} \ No newline at end of file diff --git a/demo/index.local.html b/demo/index.local.html deleted file mode 100644 index ad5f047a..00000000 --- a/demo/index.local.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - Plyr - A simple, customizable HTML5 Video, Audio, YouTube and Vimeo player - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-

Plyr

-

A simple, accessible and customisable media player for - , - , - and - -

- - - - -
- -
- - - -
-
- - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/demo/src/js/demo.js b/demo/src/js/demo.js index d608ec18..a8603c0d 100644 --- a/demo/src/js/demo.js +++ b/demo/src/js/demo.js @@ -35,7 +35,7 @@ document.addEventListener('DOMContentLoaded', () => { }); // Setup the player - const player = new window.Plyr('#player', { + const player = new Plyr('#player', { debug: true, title: 'View From A Blue Moon', // iconUrl: '../dist/plyr.svg', diff --git a/dist/plyr.js b/dist/plyr.js index 0f7fb557..8f59cd57 100644 --- a/dist/plyr.js +++ b/dist/plyr.js @@ -1,3 +1,3 @@ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define("Plyr",t):e.Plyr=t()}(this,function(){"use strict";var e,t,i={html5:"html5",youtube:"youtube",vimeo:"vimeo"},n={audio:"audio",video:"video"},s={enabled:!0,title:"",debug:!1,autoplay:!1,autopause:!0,seekTime:10,volume:1,muted:!1,duration:null,displayDuration:!0,invertTime:!0,toggleInvert:!0,ratio:"16:9",clickToPlay:!0,hideControls:!0,showPosterOnEnd:!1,disableContextMenu:!0,loadSprite:!0,iconPrefix:"plyr",iconUrl:"https://cdn.plyr.io/3.0.0-beta.11/plyr.svg",blankVideo:"https://cdn.plyr.io/static/blank.mp4",quality:{default:"default",options:["hd2160","hd1440","hd1080","hd720","large","medium","small","tiny","default"]},loop:{active:!1},speed:{selected:1,options:[.5,.75,1,1.25,1.5,1.75,2]},keyboard:{focused:!0,global:!1},tooltips:{controls:!1,seek:!0},captions:{active:!1,language:window.navigator.language.split("-")[0]},fullscreen:{enabled:!0,fallback:!0},storage:{enabled:!0,key:"plyr"},controls:["play-large","play","progress","current-time","mute","volume","captions","settings","pip","airplay","fullscreen"],settings:["captions","quality","speed"],i18n:{restart:"Restart",rewind:"Rewind {seektime} secs",play:"Play",pause:"Pause",forward:"Forward {seektime} secs",seek:"Seek",played:"Played",buffered:"Buffered",currentTime:"Current time",duration:"Duration",volume:"Volume",mute:"Mute",unmute:"Unmute",enableCaptions:"Enable captions",disableCaptions:"Disable captions",enterFullscreen:"Enter fullscreen",exitFullscreen:"Exit fullscreen",frameTitle:"Player for {title}",captions:"Captions",settings:"Settings",speed:"Speed",quality:"Quality",loop:"Loop",start:"Start",end:"End",all:"All",reset:"Reset",none:"None",disabled:"Disabled",advertisment:"Ad"},urls:{vimeo:{api:"https://player.vimeo.com/api/player.js"},youtube:{api:"https://www.youtube.com/iframe_api"},googleIMA:{api:"https://imasdk.googleapis.com/js/sdkloader/ima3.js"}},listeners:{seek:null,play:null,pause:null,restart:null,rewind:null,forward:null,mute:null,volume:null,captions:null,fullscreen:null,pip:null,airplay:null,speed:null,quality:null,loop:null,language:null},events:["ended","progress","stalled","playing","waiting","canplay","canplaythrough","loadstart","loadeddata","loadedmetadata","timeupdate","volumechange","play","pause","error","seeking","seeked","emptied","ratechange","cuechange","enterfullscreen","exitfullscreen","captionsenabled","captionsdisabled","languagechange","controlshidden","controlsshown","ready","statechange","qualitychange","qualityrequested","adsloaded","adscontentpause","adsconentresume","adstarted","adsmidpoint","adscomplete","adsallcomplete","adsimpression","adsclick"],selectors:{editable:"input, textarea, select, [contenteditable]",container:".plyr",controls:{container:null,wrapper:".plyr__controls"},labels:"[data-plyr]",buttons:{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"]',pip:'[data-plyr="pip"]',airplay:'[data-plyr="airplay"]',settings:'[data-plyr="settings"]',loop:'[data-plyr="loop"]'},inputs:{seek:'[data-plyr="seek"]',volume:'[data-plyr="volume"]',speed:'[data-plyr="speed"]',language:'[data-plyr="language"]',quality:'[data-plyr="quality"]'},display:{currentTime:".plyr__time--current",duration:".plyr__time--duration",buffer:".plyr__progress--buffer",played:".plyr__progress--played",loop:".plyr__progress--loop",volume:".plyr__volume--display"},progress:".plyr__progress",captions:".plyr__captions",menu:{quality:".js-plyr__menu__list--quality"}},classNames:{video:"plyr__video-wrapper",embed:"plyr__video-embed",ads:"plyr__ads",control:"plyr__control",type:"plyr--{0}",provider:"plyr--{0}",stopped:"plyr--stopped",playing:"plyr--playing",loading:"plyr--loading",error:"plyr--has-error",hover:"plyr--hover",tooltip:"plyr__tooltip",cues:"plyr__cues",hidden:"plyr__sr-only",hideControls:"plyr--hide-controls",isIos:"plyr--is-ios",isTouch:"plyr--is-touch",uiSupported:"plyr--full-ui",noTransition:"plyr--no-transition",menu:{value:"plyr__menu__value",badge:"plyr__badge",open:"plyr--menu-open"},captions:{enabled:"plyr--captions-enabled",active:"plyr--captions-active"},fullscreen:{enabled:"plyr--fullscreen-enabled",fallback:"plyr--fullscreen-fallback"},pip:{supported:"plyr--pip-supported",active:"plyr--pip-active"},airplay:{supported:"plyr--airplay-supported",active:"plyr--airplay-active"},tabFocus:"plyr__tab-focus"},keys:{google:null},ads:{enabled:!1}},a=(function(){function e(e){this.value=e}function t(t){var i,n;function s(i,n){try{var o=t[i](n),l=o.value;l instanceof e?Promise.resolve(l.value).then(function(e){s("next",e)},function(e){s("throw",e)}):a(o.done?"return":"normal",o.value)}catch(e){a("throw",e)}}function a(e,t){switch(e){case"return":i.resolve({value:t,done:!0});break;case"throw":i.reject(t);break;default:i.resolve({value:t,done:!1})}(i=i.next)?s(i.key,i.arg):n=null}this._invoke=function(e,t){return new Promise(function(a,o){var l={key:e,arg:t,resolve:a,reject:o,next:null};n?n=n.next=l:(i=n=l,s(e,t))})},"function"!=typeof t.return&&(this.return=void 0)}"function"==typeof Symbol&&Symbol.asyncIterator&&(t.prototype[Symbol.asyncIterator]=function(){return this}),t.prototype.next=function(e){return this._invoke("next",e)},t.prototype.throw=function(e){return this._invoke("throw",e)},t.prototype.return=function(e){return this._invoke("return",e)}}(),function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}),o=function(){function e(e,t){for(var i=0;i0?t.cloneNode(!0):t,s=e.parentNode,a=e.nextSibling;n.appendChild(e),a?s.insertBefore(n,a):s.appendChild(n)})},createElement:function(e,t,i){var n=document.createElement(e);return c.is.object(t)&&c.setAttributes(n,t),c.is.string(i)&&(n.textContent=i),n},insertAfter:function(e,t){t.parentNode.insertBefore(e,t.nextSibling)},insertElement:function(e,t,i,n){t.appendChild(c.createElement(e,i,n))},removeElement:function(e){return c.is.element(e)&&c.is.element(e.parentNode)?(e.parentNode.removeChild(e),e):null},emptyElement:function(e){for(var t=e.childNodes.length;t>0;)e.removeChild(e.lastChild),t-=1},replaceElement:function(e,t){return c.is.element(t)&&c.is.element(t.parentNode)&&c.is.element(e)?(t.parentNode.replaceChild(e,t),e):null},setAttributes:function(e,t){c.is.element(e)&&!c.is.empty(t)&&Object.keys(t).forEach(function(i){e.setAttribute(i,t[i])})},getAttributesFromSelector:function(e,t){if(!c.is.string(e)||c.is.empty(e))return{};var i={},n=t;return e.split(",").forEach(function(e){var t=e.trim(),s=t.replace(".",""),a=t.replace(/[[\]]/g,"").split("="),o=a[0],l=a.length>1?a[1].replace(/["']/g,""):"";switch(t.charAt(0)){case".":c.is.object(n)&&c.is.string(n.class)&&(n.class+=" "+s),i.class=s;break;case"#":i.id=t.replace("#","");break;case"[":i[o]=l}}),i},toggleClass:function(e,t,i){if(c.is.element(e)){var n=e.classList.contains(t);return e.classList[i?"add":"remove"](t),i&&!n||!i&&n}return null},hasClass:function(e,t){return c.is.element(e)&&e.classList.contains(t)},toggleHidden:function(e,t){c.is.element(e)&&(t?e.setAttribute("hidden",""):e.removeAttribute("hidden"))},matches:function(e,t){var i={Element:Element};var n=i.matches||i.webkitMatchesSelector||i.mozMatchesSelector||i.msMatchesSelector||function(){return Array.from(document.querySelectorAll(t)).includes(this)};return n.call(e,t)},getElements:function(e){return this.elements.container.querySelectorAll(e)},getElement:function(e){return this.elements.container.querySelector(e)},findElements:function(){try{return this.elements.controls=c.getElement.call(this,this.config.selectors.controls.wrapper),this.elements.buttons={play:c.getElements.call(this,this.config.selectors.buttons.play),pause:c.getElement.call(this,this.config.selectors.buttons.pause),restart:c.getElement.call(this,this.config.selectors.buttons.restart),rewind:c.getElement.call(this,this.config.selectors.buttons.rewind),forward:c.getElement.call(this,this.config.selectors.buttons.forward),mute:c.getElement.call(this,this.config.selectors.buttons.mute),pip:c.getElement.call(this,this.config.selectors.buttons.pip),airplay:c.getElement.call(this,this.config.selectors.buttons.airplay),settings:c.getElement.call(this,this.config.selectors.buttons.settings),captions:c.getElement.call(this,this.config.selectors.buttons.captions),fullscreen:c.getElement.call(this,this.config.selectors.buttons.fullscreen)},this.elements.progress=c.getElement.call(this,this.config.selectors.progress),this.elements.inputs={seek:c.getElement.call(this,this.config.selectors.inputs.seek),volume:c.getElement.call(this,this.config.selectors.inputs.volume)},this.elements.display={buffer:c.getElement.call(this,this.config.selectors.display.buffer),duration:c.getElement.call(this,this.config.selectors.display.duration),currentTime:c.getElement.call(this,this.config.selectors.display.currentTime)},c.is.element(this.elements.progress)&&(this.elements.display.seekTooltip=this.elements.progress.querySelector("."+this.config.classNames.tooltip)),!0}catch(e){return this.debug.warn("It looks like there is a problem with your custom controls HTML",e),this.toggleNativeControls(!0),!1}},getFocusElement:function(){var e=document.activeElement;return e=e&&e!==document.body?document.querySelector(":focus"):null},trapFocus:function(){var e=this,t=c.getElements.call(this,"button:not(:disabled), input:not(:disabled), [tabindex]"),i=t[0],n=t[t.length-1];c.on(this.elements.container,"keydown",function(t){if("Tab"===t.key&&9===t.keyCode&&e.fullscreen.active){var s=c.getFocusElement();s!==n||t.shiftKey?s===i&&t.shiftKey&&(n.focus(),t.preventDefault()):(i.focus(),t.preventDefault())}},!1)},toggleListener:function(e,t,i,n,s,a){if(!c.is.nullOrUndefined(e))if(c.is.nodeList(e))Array.from(e).forEach(function(e){e instanceof Node&&c.toggleListener.call(null,e,t,i,n,s,a)});else{var o=t.split(" "),l=!!c.is.boolean(a)&&a;u.passiveListeners&&(l={passive:!c.is.boolean(s)||s,capture:!!c.is.boolean(a)&&a}),o.forEach(function(t){e[n?"addEventListener":"removeEventListener"](t,i,l)})}},on:function(e,t,i,n,s){c.toggleListener(e,t,i,!0,n,s)},off:function(e,t,i,n,s){c.toggleListener(e,t,i,!1,n,s)},dispatchEvent:function(e,t,i,n){if(e&&t){var s=new CustomEvent(t,{bubbles:!!c.is.boolean(i)&&i,detail:Object.assign({},n,{plyr:c.is.plyr(this)?this:null})});e.dispatchEvent(s)}},toggleState:function(e,t){if(c.is.element(e)){var i="true"===e.getAttribute("aria-pressed"),n=c.is.boolean(t)?t:!i;e.setAttribute("aria-pressed",n)}},getPercentage:function(e,t){return 0===e||0===t||Number.isNaN(e)||Number.isNaN(t)?0:(e/t*100).toFixed(2)},getHours:function(e){return parseInt(e/60/60%60,10)},getMinutes:function(e){return parseInt(e/60%60,10)},getSeconds:function(e){return parseInt(e%60,10)},formatTime:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(!c.is.number(e))return this.formatTime(null,t,i);var n=function(e){return("0"+e).slice(-2)},s=this.getHours(e),a=this.getMinutes(e),o=this.getSeconds(e);return t||s>0?s+=":":s="",(i?"-":"")+s+n(a)+":"+n(o)},extend:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length,i=Array(t>1?t-1:0),n=1;n0&&void 0!==arguments[0]&&arguments[0];a(this,e),this.enabled=window.console&&t,this.enabled&&this.log("Debugging enabled")}return o(e,[{key:"log",get:function(){return this.enabled?Function.prototype.bind.call(console.log,console):d}},{key:"warn",get:function(){return this.enabled?Function.prototype.bind.call(console.warn,console):d}},{key:"error",get:function(){return this.enabled?Function.prototype.bind.call(console.error,console):d}}]),e}(),p=function(){function e(t){a(this,e),this.enabled=t.config.storage.enabled,this.key=t.config.storage.key}return o(e,[{key:"get",value:function(t){var i=window.localStorage.getItem(this.key);if(!e.supported||c.is.empty(i))return null;var n=JSON.parse(i);return c.is.string(t)&&t.length?n[t]:n}},{key:"set",value:function(t){if(e.supported&&this.enabled&&c.is.object(t)){var i=this.get();c.is.empty(i)&&(i={}),c.extend(i,t),window.localStorage.setItem(this.key,JSON.stringify(i))}}}],[{key:"supported",get:function(){if(!("localStorage"in window))return!1;try{return window.localStorage.setItem("___test","___test"),window.localStorage.removeItem("___test"),!0}catch(e){return!1}}}]),e}(),m=function(){function e(t){var i=this;a(this,e),this.player=t,this.enabled=t.config.ads.enabled,this.playing=!1,this.initialized=!1,this.blocked=!1,this.enabled=c.is.url(t.config.ads.tag),this.enabled&&(c.is.object(window.google)?this.ready():c.loadScript(t.config.urls.googleIMA.api,function(){i.ready()},function(){i.blocked=!0,i.player.debug.log("Ads error: Google IMA SDK failed to load")}))}return o(e,[{key:"ready",value:function(){var e=this;this.elements={container:null,displayContainer:null},this.manager=null,this.loader=null,this.cuePoints=null,this.events={},this.safetyTimer=null,this.countdownTimer=null,this.listeners(),this.startSafetyTimer(12e3,"ready()"),this.loaderPromise=new Promise(function(t){e.on("ADS_LOADER_LOADED",function(){return t()})}),this.managerPromise=new Promise(function(t){e.on("ADS_MANAGER_LOADED",function(){return t()})}),this.managerPromise.then(function(){e.clearSafetyTimer("onAdsManagerLoaded()")}),this.setupIMA()}},{key:"setupIMA",value:function(){this.elements.container=c.createElement("div",{class:this.player.config.classNames.ads,hidden:""}),this.player.elements.container.appendChild(this.elements.container),google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED),google.ima.settings.setLocale(this.player.config.ads.language),this.elements.displayContainer=new google.ima.AdDisplayContainer(this.elements.container),this.requestAds()}},{key:"requestAds",value:function(){var e=this,t=this.player.elements.container;try{this.loader=new google.ima.AdsLoader(this.elements.displayContainer),this.loader.addEventListener(google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,function(t){return e.onAdsManagerLoaded(t)},!1),this.loader.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,function(t){return e.onAdError(t)},!1);var i=new google.ima.AdsRequest;i.adTagUrl="https://go.aniview.com/api/adserver6/vast/?"+c.buildUrlParams({AV_PUBLISHERID:"58c25bb0073ef448b1087ad6",AV_CHANNELID:"5a0458dc28a06145e4519d21",AV_URL:"127.0.0.1:3000",cb:1,AV_WIDTH:640,AV_HEIGHT:480}),i.linearAdSlotWidth=t.offsetWidth,i.linearAdSlotHeight=t.offsetHeight,i.nonLinearAdSlotWidth=t.offsetWidth,i.nonLinearAdSlotHeight=t.offsetHeight,i.forceNonLinearFullSlot=!1,this.loader.requestAds(i),this.handleEventListeners("ADS_LOADER_LOADED")}catch(e){this.onAdError(e)}}},{key:"pollCountdown",value:function(){var e=this;if(!(arguments.length>0&&void 0!==arguments[0]&&arguments[0]))return window.clearInterval(this.countdownTimer),void this.elements.container.removeAttribute("data-badge-text");this.countdownTimer=window.setInterval(function(){var t=c.formatTime(e.manager.getRemainingTime()),i=e.player.config.i18n.advertisment+" - "+t;e.elements.container.setAttribute("data-badge-text",i)},100)}},{key:"onAdsManagerLoaded",value:function(e){var t=this,i=new google.ima.AdsRenderingSettings;i.restoreCustomPlaybackStateOnAdBreakComplete=!0,i.enablePreloading=!0,this.manager=e.getAdsManager(this.player,i),this.cuePoints=this.manager.getCuePoints(),this.cuePoints.forEach(function(e){if(0!==e&&-1!==e){var i=t.player.elements.progress;if(i){var n=100/t.player.duration*e,s=c.createElement("span",{class:t.player.config.classNames.cues});s.style.left=n.toString()+"%",i.appendChild(s)}}}),this.manager.setVolume(this.player.volume),this.manager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,function(e){return t.onAdError(e)}),Object.keys(google.ima.AdEvent.Type).forEach(function(e){t.manager.addEventListener(google.ima.AdEvent.Type[e],function(e){return t.onAdEvent(e)})}),this.handleEventListeners("ADS_MANAGER_LOADED")}},{key:"onAdEvent",value:function(e){var t=this,i=this.player.elements.container,n=e.getAd(),s=function(e){c.dispatchEvent.call(t.player,t.player.media,"ads"+e)};switch(e.type){case google.ima.AdEvent.Type.LOADED:this.handleEventListeners("LOADED"),s("loaded"),this.pollCountdown(!0),n.isLinear()||(n.width=i.offsetWidth,n.height=i.offsetHeight);break;case google.ima.AdEvent.Type.ALL_ADS_COMPLETED:this.handleEventListeners("ALL_ADS_COMPLETED"),s("allcomplete"),this.loadAds();break;case google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED:this.handleEventListeners("CONTENT_PAUSE_REQUESTED"),s("contentpause"),this.pauseContent();break;case google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED:this.handleEventListeners("CONTENT_RESUME_REQUESTED"),s("contentresume"),this.pollCountdown(),this.resumeContent();break;case google.ima.AdEvent.Type.STARTED:s("started");break;case google.ima.AdEvent.Type.MIDPOINT:s("midpoint");break;case google.ima.AdEvent.Type.COMPLETE:s("complete");break;case google.ima.AdEvent.Type.IMPRESSION:s("impression");break;case google.ima.AdEvent.Type.CLICK:s("click")}}},{key:"onAdError",value:function(e){this.cancel(),this.player.debug.log("Ads error",e)}},{key:"listeners",value:function(){var e=this,t=this.player.elements.container,i=void 0;this.player.on("ended",function(){e.loader.contentComplete()}),this.player.on("seeking",function(){return i=e.player.currentTime}),this.player.on("seeked",function(){var t=e.player.currentTime;e.cuePoints.forEach(function(n,s){i0)&&(i?(e.decreaseVolume(.02),n=-1):(e.increaseVolume(.02),n=1)),(t.deltaY>0||t.deltaX<0)&&(i?(e.increaseVolume(.02),n=1):(e.decreaseVolume(.02),n=-1)),(1===n&&e.media.volume<1||-1===n&&e.media.volume>0)&&t.preventDefault()})},!1)}},b={addStyleHook:function(){c.toggleClass(this.elements.container,this.config.selectors.container.replace(".",""),!0),c.toggleClass(this.elements.container,this.config.classNames.uiSupported,this.supported.ui)},toggleNativeControls:function(){arguments.length>0&&void 0!==arguments[0]&&arguments[0]&&this.isHTML5?this.media.setAttribute("controls",""):this.media.removeAttribute("controls")},build:function(){if(v.media.call(this),!this.supported.ui)return this.debug.warn("Basic support only for "+this.provider+" "+this.type),c.removeElement.call(this,"controls"),c.removeElement.call(this,"buttons.play"),void b.toggleNativeControls.call(this,!0);c.is.element(this.elements.controls)||(w.inject.call(this),v.controls.call(this)),c.is.element(this.elements.controls)&&(b.toggleNativeControls.call(this),f.setup.call(this),E.setup.call(this),this.volume=null,this.muted=null,this.speed=null,this.loop=null,this.options.quality=[],b.timeUpdate.call(this),b.checkPlaying.call(this),this.ready=!0,c.dispatchEvent.call(this,this.media,"ready"),b.setTitle.call(this))},setTitle:function(){var e=this.config.i18n.play;if(c.is.string(this.config.title)&&!c.is.empty(this.config.title)&&(e+=", "+this.config.title,this.elements.container.setAttribute("aria-label",this.config.title)),c.is.nodeList(this.elements.buttons.play)&&Array.from(this.elements.buttons.play).forEach(function(t){t.setAttribute("aria-label",e)}),this.isEmbed){var t=c.getElement.call(this,"iframe");if(!c.is.element(t))return;var i=c.is.empty(this.config.title)?"video":this.config.title;t.setAttribute("title",this.config.i18n.frameTitle.replace("{title}",i))}},checkPlaying:function(){var e=this;c.toggleClass(this.elements.container,this.config.classNames.playing,this.playing),c.toggleClass(this.elements.container,this.config.classNames.stopped,this.paused),c.is.nodeList(this.elements.buttons.play)&&Array.from(this.elements.buttons.play).forEach(function(t){return c.toggleState(t,e.playing)}),this.toggleControls(!this.playing)},checkLoading:function(e){var t=this;this.loading=["stalled","waiting"].includes(e.type),clearTimeout(this.timers.loading),this.timers.loading=setTimeout(function(){c.toggleClass(t.elements.container,t.config.classNames.loading,t.loading),t.toggleControls(t.loading)},this.loading?250:0)},checkFailed:function(){var e=this;this.failed=3===this.media.networkState,this.failed&&(c.toggleClass(this.elements.container,this.config.classNames.loading,!1),c.toggleClass(this.elements.container,this.config.classNames.error,!0)),clearTimeout(this.timers.failed),this.timers.loading=setTimeout(function(){c.toggleClass(e.elements.container,e.config.classNames.loading,e.loading),e.toggleControls(e.loading)},this.loading?250:0)},updateVolume:function(){this.supported.ui&&(c.is.element(this.elements.inputs.volume)&&b.setRange.call(this,this.elements.inputs.volume,this.muted?0:this.volume),c.is.element(this.elements.buttons.mute)&&c.toggleState(this.elements.buttons.mute,this.muted||0===this.volume))},setRange:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;c.is.element(e)&&(e.value=t,w.updateRangeFill.call(this,e))},setProgress:function(e,t){var i=c.is.number(t)?t:0,n=c.is.element(e)?e:this.elements.display.buffer;if(c.is.element(n)){n.value=i;var s=n.getElementsByTagName("span")[0];c.is.element(s)&&(s.childNodes[0].nodeValue=i)}},updateProgress:function(e){var t=this;if(this.supported.ui&&c.is.event(e)){var i,n=0;if(e)switch(e.type){case"timeupdate":case"seeking":n=c.getPercentage(this.currentTime,this.duration),"timeupdate"===e.type&&b.setRange.call(this,this.elements.inputs.seek,n);break;case"playing":case"progress":n=(i=t.media.buffered)&&i.length?c.getPercentage(i.end(0),t.duration):c.is.number(i)?100*i:0,b.setProgress.call(this,this.elements.display.buffer,n)}}},updateTimeDisplay:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(c.is.element(e)&&c.is.number(t)){var n=c.getHours(this.duration)>0;e.textContent=c.formatTime(t,n,i)}},timeUpdate:function(e){var t=!c.is.element(this.elements.display.duration)&&this.config.invertTime;b.updateTimeDisplay.call(this,this.elements.display.currentTime,t?this.duration-this.currentTime:this.currentTime,t),e&&"timeupdate"===e.type&&this.media.seeking||b.updateProgress.call(this,e)},durationUpdate:function(){if(this.supported.ui){var e=c.is.element(this.elements.display.duration);!e&&this.config.displayDuration&&this.paused&&b.updateTimeDisplay.call(this,this.elements.display.currentTime,this.duration),e&&b.updateTimeDisplay.call(this,this.elements.display.duration,this.duration),w.updateSeekTooltip.call(this)}}},k=c.getBrowser(),w={updateRangeFill:function(e){if(k.isWebkit){var t=c.is.event(e)?e.target:e;c.is.element(t)&&"range"===t.getAttribute("type")&&t.style.setProperty("--value",t.value/t.max*100+"%")}},getIconUrl:function(){return{url:this.config.iconUrl,absolute:0===this.config.iconUrl.indexOf("http")||k.isIE&&!window.svg4everybody}},createIcon:function(e,t){var i=w.getIconUrl.call(this),n=(i.absolute?"":i.url)+"#"+this.config.iconPrefix,s=document.createElementNS("http://www.w3.org/2000/svg","svg");c.setAttributes(s,c.extend(t,{role:"presentation"}));var a=document.createElementNS("http://www.w3.org/2000/svg","use"),o=n+"-"+e;return"href"in a?a.setAttributeNS("http://www.w3.org/1999/xlink","href",o):a.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",o),s.appendChild(a),s},createLabel:function(e,t){var i=this.config.i18n[e],n=Object.assign({},t);switch(e){case"pip":i="PIP";break;case"airplay":i="AirPlay"}return"class"in n?n.class+=" "+this.config.classNames.hidden:n.class=this.config.classNames.hidden,c.createElement("span",n,i)},createBadge:function(e){if(c.is.empty(e))return null;var t=c.createElement("span",{class:this.config.classNames.menu.value});return t.appendChild(c.createElement("span",{class:this.config.classNames.menu.badge},e)),t},createButton:function(e,t){var i=c.createElement("button"),n=Object.assign({},t),s=e,a=!1,o=void 0,l=void 0,r=void 0,u=void 0;switch("type"in n||(n.type="button"),"class"in n?n.class.includes(this.config.classNames.control)&&(n.class+=" "+this.config.classNames.control):n.class=this.config.classNames.control,s){case"play":a=!0,o="play",r="pause",l="play",u="pause";break;case"mute":a=!0,o="mute",r="unmute",l="volume",u="muted";break;case"captions":a=!0,o="enableCaptions",r="disableCaptions",l="captions-off",u="captions-on";break;case"fullscreen":a=!0,o="enterFullscreen",r="exitFullscreen",l="enter-fullscreen",u="exit-fullscreen";break;case"play-large":n.class+=" "+this.config.classNames.control+"--overlaid",s="play",o="play",l="play";break;default:o=s,l=s}return a?(i.appendChild(w.createIcon.call(this,u,{class:"icon--pressed"})),i.appendChild(w.createIcon.call(this,l,{class:"icon--not-pressed"})),i.appendChild(w.createLabel.call(this,r,{class:"label--pressed"})),i.appendChild(w.createLabel.call(this,o,{class:"label--not-pressed"})),n["aria-pressed"]=!1,n["aria-label"]=this.config.i18n[o]):(i.appendChild(w.createIcon.call(this,l)),i.appendChild(w.createLabel.call(this,o))),c.extend(n,c.getAttributesFromSelector(this.config.selectors.buttons[s],n)),c.setAttributes(i,n),this.elements.buttons[s]=i,i},createRange:function(e,t){var i=c.createElement("label",{for:t.id,class:this.config.classNames.hidden},this.config.i18n[e]),n=c.createElement("input",c.extend(c.getAttributesFromSelector(this.config.selectors.inputs[e]),{type:"range",min:0,max:100,step:.01,value:0,autocomplete:"off"},t));return this.elements.inputs[e]=n,w.updateRangeFill.call(this,n),{label:i,input:n}},createProgress:function(e,t){var i=c.createElement("progress",c.extend(c.getAttributesFromSelector(this.config.selectors.display[e]),{min:0,max:100,value:0},t));if("volume"!==e){i.appendChild(c.createElement("span",null,"0"));var n="";switch(e){case"played":n=this.config.i18n.played;break;case"buffer":n=this.config.i18n.buffered}i.textContent="% "+n.toLowerCase()}return this.elements.display[e]=i,i},createTime:function(e){var t=c.createElement("div",{class:"plyr__time"});return t.appendChild(c.createElement("span",{class:this.config.classNames.hidden},this.config.i18n[e])),t.appendChild(c.createElement("span",c.getAttributesFromSelector(this.config.selectors.display[e]),"00:00")),this.elements.display[e]=t,t},createMenuItem:function(e,t,i,n){var s=arguments.length>4&&void 0!==arguments[4]?arguments[4]:null,a=arguments.length>5&&void 0!==arguments[5]&&arguments[5],o=c.createElement("li"),l=c.createElement("label",{class:this.config.classNames.control}),r=c.createElement("input",c.extend(c.getAttributesFromSelector(this.config.selectors.inputs[i]),{type:"radio",name:"plyr-"+i,value:e,checked:a,class:"plyr__sr-only"})),u=c.createElement("span",{"aria-hidden":!0});l.appendChild(r),l.appendChild(u),l.insertAdjacentHTML("beforeend",n),c.is.element(s)&&l.appendChild(s),o.appendChild(l),t.appendChild(o)},updateSeekTooltip:function(e){if(this.config.tooltips.seek&&c.is.element(this.elements.inputs.seek)&&c.is.element(this.elements.display.seekTooltip)&&0!==this.duration){var t=0,i=this.elements.inputs.seek.getBoundingClientRect(),n=this.config.classNames.tooltip+"--visible";if(c.is.event(e))t=100/i.width*(e.pageX-i.left);else{if(!c.hasClass(this.elements.display.seekTooltip,n))return;t=parseFloat(this.elements.display.seekTooltip.style.left,10)}t<0?t=0:t>100&&(t=100),b.updateTimeDisplay.call(this,this.elements.display.seekTooltip,this.duration/100*t),this.elements.display.seekTooltip.style.left=t+"%",c.is.event(e)&&["mouseenter","mouseleave"].includes(e.type)&&c.toggleClass(this.elements.display.seekTooltip,n,"mouseenter"===e.type)}},toggleTab:function(e,t){var i=this.elements.settings.tabs[e],n=this.elements.settings.panes[e];c.toggleHidden(i,!t),c.toggleHidden(n,!t)},setQualityMenu:function(e){var t=this,i=this.elements.settings.panes.quality.querySelector("ul");c.is.array(e)?this.options.quality=e.filter(function(e){return t.config.quality.options.includes(e)}):this.options.quality=this.config.quality.options;var n=!c.is.empty(this.options.quality)&&this.isYouTube;if(w.toggleTab.call(this,"quality",n),n){c.emptyElement(i);this.options.quality.forEach(function(e){return w.createMenuItem.call(t,e,i,"quality",w.getLabel.call(t,"quality",e),function(e){var i="";switch(e){case"hd2160":i="4K";break;case"hd1440":i="WQHD";break;case"hd1080":case"hd720":i="HD"}return i.length?w.createBadge.call(t,i):null}(e))}),w.updateSetting.call(this,"quality",i)}},getLabel:function(e,t){switch(e){case"speed":return 1===t?"Normal":t+"×";case"quality":switch(t){case"hd2160":return"2160P";case"hd1440":return"1440P";case"hd1080":return"1080P";case"hd720":return"720P";case"large":return"480P";case"medium":return"360P";case"small":return"240P";case"tiny":return"Tiny";case"default":return"Auto";default:return t}case"captions":return w.getLanguage.call(this);default:return null}},updateSetting:function(e,t){var i=this.elements.settings.panes[e],n=null,s=t;switch(e){case"captions":n=this.captions.active?this.captions.language:"";break;default:if(n=this[e],c.is.empty(n)&&(n=this.config[e].default),!this.options[e].includes(n))return void this.debug.warn("Unsupported value of '"+n+"' for "+e);if(!this.config[e].options.includes(n))return void this.debug.warn("Disabled value of '"+n+"' for "+e)}(c.is.element(s)||(s=i&&i.querySelector("ul")),c.is.empty(n))||(this.elements.settings.tabs[e].querySelector("."+this.config.classNames.menu.value).innerHTML=w.getLabel.call(this,e,n));var a=s&&s.querySelector('input[value="'+n+'"]');c.is.element(a)&&(a.checked=!0)},getLanguage:function(){if(!this.supported.ui)return null;if(!u.textTracks||!E.getTracks.call(this).length)return this.config.i18n.none;if(this.captions.active){var e=E.getCurrentTrack.call(this);if(c.is.track(e))return e.label}return this.config.i18n.disabled},setCaptionsMenu:function(){var e=this,t=this.elements.settings.panes.captions.querySelector("ul"),i=E.getTracks.call(this).length;if(w.toggleTab.call(this,"captions",i),c.emptyElement(t),i){var n=E.getTracks.call(this).map(function(e){return{language:e.language,label:c.is.empty(e.label)?e.language.toUpperCase():e.label}});n.unshift({language:"",label:this.config.i18n.none}),n.forEach(function(i){w.createMenuItem.call(e,i.language,t,"language",i.label||i.language,w.createBadge.call(e,i.language.toUpperCase()),i.language.toLowerCase()===e.captions.language.toLowerCase())}),w.updateSetting.call(this,"captions",t)}},setSpeedMenu:function(){var e=this;c.is.object(this.options.speed)&&Object.keys(this.options.speed).length||(this.options.speed=[.5,.75,1,1.25,1.5,1.75,2]),this.options.speed=this.options.speed.filter(function(t){return e.config.speed.options.includes(t)});var t=!c.is.empty(this.options.speed);if(w.toggleTab.call(this,"speed",t),t){var i=this.elements.settings.panes.speed.querySelector("ul");c.toggleHidden(this.elements.settings.tabs.speed,!1),c.toggleHidden(this.elements.settings.panes.speed,!1),c.emptyElement(i),this.options.speed.forEach(function(t){return w.createMenuItem.call(e,t,i,"speed",w.getLabel.call(e,"speed",t))}),w.updateSetting.call(this,"speed",i)}},toggleMenu:function(e){var t=this.elements.settings.form,i=this.elements.buttons.settings,n=c.is.boolean(e)?e:c.is.element(t)&&"true"===t.getAttribute("aria-hidden");if(c.is.event(e)){var s=c.is.element(t)&&t.contains(e.target),a=e.target===this.elements.buttons.settings;if(s||!s&&!a&&n)return;a&&e.stopPropagation()}c.is.element(i)&&i.setAttribute("aria-expanded",n),c.is.element(t)&&(t.setAttribute("aria-hidden",!n),c.toggleClass(this.elements.container,this.config.classNames.menu.open,n),n?t.removeAttribute("tabindex"):t.setAttribute("tabindex",-1))},getTabSize:function(e){var t=e.cloneNode(!0);t.style.position="absolute",t.style.opacity=0,t.setAttribute("aria-hidden",!1),Array.from(t.querySelectorAll("input[name]")).forEach(function(e){var t=e.getAttribute("name");e.setAttribute("name",t+"-clone")}),e.parentNode.appendChild(t);var i=t.scrollWidth,n=t.scrollHeight;return c.removeElement(t),{width:i,height:n}},showTab:function(e){var t=this.elements.settings.menu,i=e.target,n="false"===i.getAttribute("aria-expanded"),s=document.getElementById(i.getAttribute("aria-controls"));if(c.is.element(s)&&"tabpanel"===s.getAttribute("role")){var a=t.querySelector('[role="tabpanel"][aria-hidden="false"]'),o=a.parentNode;if(Array.from(t.querySelectorAll('[aria-controls="'+a.getAttribute("id")+'"]')).forEach(function(e){e.setAttribute("aria-expanded",!1)}),u.transitions&&!u.reducedMotion){o.style.width=a.scrollWidth+"px",o.style.height=a.scrollHeight+"px";var l=w.getTabSize.call(this,s);c.on(o,c.transitionEndEvent,function e(t){t.target===o&&["width","height"].includes(t.propertyName)&&(o.style.width="",o.style.height="",c.off(o,c.transitionEndEvent,e))}),o.style.width=l.width+"px",o.style.height=l.height+"px"}a.setAttribute("aria-hidden",!0),a.setAttribute("tabindex",-1),s.setAttribute("aria-hidden",!n),i.setAttribute("aria-expanded",n),s.removeAttribute("tabindex"),s.querySelectorAll("button:not(:disabled), input:not(:disabled), [tabindex]")[0].focus()}},create:function(e){var t=this;if(c.is.empty(this.config.controls))return null;var i=c.createElement("div",c.getAttributesFromSelector(this.config.selectors.controls.wrapper));if(this.config.controls.includes("restart")&&i.appendChild(w.createButton.call(this,"restart")),this.config.controls.includes("rewind")&&i.appendChild(w.createButton.call(this,"rewind")),this.config.controls.includes("play")&&i.appendChild(w.createButton.call(this,"play")),this.config.controls.includes("fast-forward")&&i.appendChild(w.createButton.call(this,"fast-forward")),this.config.controls.includes("progress")){var n=c.createElement("div",c.getAttributesFromSelector(this.config.selectors.progress)),s=w.createRange.call(this,"seek",{id:"plyr-seek-"+e.id});if(n.appendChild(s.label),n.appendChild(s.input),n.appendChild(w.createProgress.call(this,"buffer")),this.config.tooltips.seek){var a=c.createElement("span",{role:"tooltip",class:this.config.classNames.tooltip},"00:00");n.appendChild(a),this.elements.display.seekTooltip=a}this.elements.progress=n,i.appendChild(this.elements.progress)}if(this.config.controls.includes("current-time")&&i.appendChild(w.createTime.call(this,"currentTime")),this.config.controls.includes("duration")&&i.appendChild(w.createTime.call(this,"duration")),this.config.controls.includes("mute")&&i.appendChild(w.createButton.call(this,"mute")),this.config.controls.includes("volume")){var o=c.createElement("div",{class:"plyr__volume"}),l={max:1,step:.05,value:this.config.volume},r=w.createRange.call(this,"volume",c.extend(l,{id:"plyr-volume-"+e.id}));o.appendChild(r.label),o.appendChild(r.input),this.elements.volume=o,i.appendChild(o)}if(this.config.controls.includes("captions")&&i.appendChild(w.createButton.call(this,"captions")),this.config.controls.includes("settings")&&!c.is.empty(this.config.settings)){var d=c.createElement("div",{class:"plyr__menu"});d.appendChild(w.createButton.call(this,"settings",{id:"plyr-settings-toggle-"+e.id,"aria-haspopup":!0,"aria-controls":"plyr-settings-"+e.id,"aria-expanded":!1}));var h=c.createElement("form",{class:"plyr__menu__container",id:"plyr-settings-"+e.id,"aria-hidden":!0,"aria-labelled-by":"plyr-settings-toggle-"+e.id,role:"tablist",tabindex:-1}),p=c.createElement("div"),m=c.createElement("div",{id:"plyr-settings-"+e.id+"-home","aria-hidden":!1,"aria-labelled-by":"plyr-settings-toggle-"+e.id,role:"tabpanel"}),g=c.createElement("ul",{role:"tablist"});this.config.settings.forEach(function(i){var n=c.createElement("li",{role:"tab",hidden:""}),s=c.createElement("button",c.extend(c.getAttributesFromSelector(t.config.selectors.buttons.settings),{type:"button",class:t.config.classNames.control+" "+t.config.classNames.control+"--forward",id:"plyr-settings-"+e.id+"-"+i+"-tab","aria-haspopup":!0,"aria-controls":"plyr-settings-"+e.id+"-"+i,"aria-expanded":!1}),t.config.i18n[i]),a=c.createElement("span",{class:t.config.classNames.menu.value});a.innerHTML=e[i],s.appendChild(a),n.appendChild(s),g.appendChild(n),t.elements.settings.tabs[i]=n}),m.appendChild(g),p.appendChild(m),this.config.settings.forEach(function(i){var n=c.createElement("div",{id:"plyr-settings-"+e.id+"-"+i,"aria-hidden":!0,"aria-labelled-by":"plyr-settings-"+e.id+"-"+i+"-tab",role:"tabpanel",tabindex:-1,hidden:""}),s=c.createElement("button",{type:"button",class:t.config.classNames.control+" "+t.config.classNames.control+"--back","aria-haspopup":!0,"aria-controls":"plyr-settings-"+e.id+"-home","aria-expanded":!1},t.config.i18n[i]);n.appendChild(s);var a=c.createElement("ul");n.appendChild(a),p.appendChild(n),t.elements.settings.panes[i]=n}),h.appendChild(p),d.appendChild(h),i.appendChild(d),this.elements.settings.form=h,this.elements.settings.menu=d}return this.config.controls.includes("pip")&&u.pip&&i.appendChild(w.createButton.call(this,"pip")),this.config.controls.includes("airplay")&&u.airplay&&i.appendChild(w.createButton.call(this,"airplay")),this.config.controls.includes("fullscreen")&&i.appendChild(w.createButton.call(this,"fullscreen")),this.config.controls.includes("play-large")&&this.elements.container.appendChild(w.createButton.call(this,"play-large")),this.elements.controls=i,this.config.controls.includes("settings")&&this.config.settings.includes("speed")&&w.setSpeedMenu.call(this),i},inject:function(){var e=this;if(this.config.loadSprite){var t=w.getIconUrl.call(this);t.absolute&&c.loadSprite(t.url,"sprite-plyr")}this.id=Math.floor(1e4*Math.random());var i=null;i=c.is.string(this.config.controls)?this.config.controls:c.is.function(this.config.controls)?this.config.controls({id:this.id,seektime:this.config.seekTime,title:this.config.title}):w.create.call(this,{id:this.id,seektime:this.config.seekTime,speed:this.speed,quality:this.quality,captions:w.getLanguage.call(this)});var n=void 0;if(c.is.string(this.config.selectors.controls.container)&&(n=document.querySelector(this.config.selectors.controls.container)),c.is.element(n)||(n=this.elements.container),c.is.element(i)?n.appendChild(i):n.insertAdjacentHTML("beforeend",i),c.is.element(this.elements.controls)&&c.findElements.call(this),window.navigator.userAgent.includes("Edge")&&c.repaint(n),this.config.tooltips.controls){var s=c.getElements.call(this,[this.config.selectors.controls.wrapper," ",this.config.selectors.labels," .",this.config.classNames.hidden].join(""));Array.from(s).forEach(function(t){c.toggleClass(t,e.config.classNames.hidden,!1),c.toggleClass(t,e.config.classNames.tooltip,!0),t.setAttribute("role","tooltip")})}}},E={setup:function(){if(this.supported.ui){var e=this.storage.get("language");if(c.is.empty(e)||(this.captions.language=e),c.is.empty(this.captions.language)&&(this.captions.language=this.config.captions.language.toLowerCase()),!c.is.boolean(this.captions.active)){var t=this.storage.get("captions");c.is.boolean(t)?this.captions.active=t:this.captions.active=this.config.captions.active}!this.isVideo||this.isYouTube||this.isHTML5&&!u.textTracks?this.config.controls.includes("settings")&&this.config.settings.includes("captions")&&w.setCaptionsMenu.call(this):(c.is.element(this.elements.captions)||(this.elements.captions=c.createElement("div",c.getAttributesFromSelector(this.config.selectors.captions)),c.insertAfter(this.elements.captions,this.elements.wrapper)),c.toggleClass(this.elements.container,this.config.classNames.captions.enabled,!c.is.empty(E.getTracks.call(this))),c.is.empty(E.getTracks.call(this))||(E.setLanguage.call(this),E.show.call(this),this.config.controls.includes("settings")&&this.config.settings.includes("captions")&&w.setCaptionsMenu.call(this)))}},setLanguage:function(){var e=this;if(this.isHTML5&&this.isVideo){E.getTracks.call(this).forEach(function(t){c.on(t,"cuechange",function(t){return E.setCue.call(e,t)}),t.mode="hidden"});var t=E.getCurrentTrack.call(this);c.is.track(t)&&Array.from(t.activeCues||[]).length&&E.setCue.call(this,t)}else this.isVimeo&&this.captions.active&&this.embed.enableTextTrack(this.language)},getTracks:function(){return c.is.nullOrUndefined(this.media)?[]:Array.from(this.media.textTracks||[]).filter(function(e){return["captions","subtitles"].includes(e.kind)})},getCurrentTrack:function(){var e=this;return E.getTracks.call(this).find(function(t){return t.language.toLowerCase()===e.language})},setCue:function(e){var t=c.is.event(e)?e.target:e,i=t.activeCues[0];t===E.getCurrentTrack.call(this)&&(c.is.cue(i)?E.setText.call(this,i.getCueAsHTML()):E.setText.call(this,null),c.dispatchEvent.call(this,this.media,"cuechange"))},setText:function(e){if(this.supported.ui)if(c.is.element(this.elements.captions)){var t=c.createElement("span");c.emptyElement(this.elements.captions);var i=c.is.nullOrUndefined(e)?"":e;c.is.string(i)?t.textContent=i.trim():t.appendChild(i),this.elements.captions.appendChild(t)}else this.debug.warn("No captions element to render to")},show:function(){if(c.is.element(this.elements.buttons.captions)){var e=this.storage.get("captions");c.is.boolean(e)?this.captions.active=e:e=this.config.captions.active,e&&(c.toggleClass(this.elements.container,this.config.classNames.captions.active,!0),c.toggleState(this.elements.buttons.captions,!0))}}},T={setup:function(){var e=this;c.toggleClass(this.elements.wrapper,this.config.classNames.embed,!0),T.setAspectRatio.call(this),c.is.object(window.YT)&&c.is.function(window.YT.Player)?T.ready.call(this):(c.loadScript(this.config.urls.youtube.api),window.onYouTubeReadyCallbacks=window.onYouTubeReadyCallbacks||[],window.onYouTubeReadyCallbacks.push(function(){T.ready.call(e)}),window.onYouTubeIframeAPIReady=function(){window.onYouTubeReadyCallbacks.forEach(function(e){e()})})},getTitle:function(e){var t=this;if(c.is.function(this.embed.getVideoData)){var i=this.embed.getVideoData().title;if(c.is.empty(i))return this.config.title=i,void b.setTitle.call(this)}var n=this.config.keys.google;if(c.is.string(n)&&!c.is.empty(n)){var s="https://www.googleapis.com/youtube/v3/videos?id="+e+"&key="+n+"&fields=items(snippet(title))&part=snippet";c.fetch(s).then(function(e){c.is.object(e)&&(t.config.title=e.items[0].snippet.title,b.setTitle.call(t))}).catch(function(){})}},setAspectRatio:function(){var e=this.config.ratio.split(":");this.elements.wrapper.style.paddingBottom=100/e[0]*e[1]+"%"},ready:function(){var e=this,t=e.media.getAttribute("id");if(c.is.empty(t)||!t.startsWith("youtube-")){var i=c.parseYouTubeId(e.media.getAttribute("src")),n=c.generateId(e.provider),s=c.createElement("div",{id:n});e.media=c.replaceElement(s,e.media),e.embed=new window.YT.Player(n,{videoId:i,playerVars:{autoplay:e.config.autoplay?1:0,controls:e.supported.ui?0:1,rel:0,showinfo:0,iv_load_policy:3,modestbranding:1,disablekb:1,playsinline:1,widget_referrer:window?window.location.href:null,cc_load_policy:e.captions.active?1:0,cc_lang_pref:e.config.captions.language},events:{onError:function(t){if(!c.is.object(e.media.error)){var i={code:t.data};switch(t.data){case 2:i.message="The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.";break;case 5:i.message="The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.";break;case 100:i.message="The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.";break;case 101:case 150:i.message="The owner of the requested video does not allow it to be played in embedded players.";break;default:i.message="An unknown error occured"}e.media.error=i,c.dispatchEvent.call(e,e.media,"error")}},onPlaybackQualityChange:function(t){var i=t.target;e.media.quality=i.getPlaybackQuality(),c.dispatchEvent.call(e,e.media,"qualitychange")},onPlaybackRateChange:function(t){var i=t.target;e.media.playbackRate=i.getPlaybackRate(),c.dispatchEvent.call(e,e.media,"ratechange")},onReady:function(t){var n=t.target;T.getTitle.call(e,i),e.media.play=function(){n.playVideo(),e.media.paused=!1},e.media.pause=function(){n.pauseVideo(),e.media.paused=!0},e.media.stop=function(){n.stopVideo(),e.media.paused=!0},e.media.duration=n.getDuration(),e.media.paused=!0,e.media.currentTime=0,Object.defineProperty(e.media,"currentTime",{get:function(){return Number(n.getCurrentTime())},set:function(t){e.media.seeking=!0,c.dispatchEvent.call(e,e.media,"seeking"),n.seekTo(t)}}),Object.defineProperty(e.media,"playbackRate",{get:function(){return n.getPlaybackRate()},set:function(e){n.setPlaybackRate(e)}}),Object.defineProperty(e.media,"quality",{get:function(){return n.getPlaybackQuality()},set:function(t){c.dispatchEvent.call(e,e.media,"qualityrequested",!1,{quality:t}),n.setPlaybackQuality(t)}});var s=e.config.volume;Object.defineProperty(e.media,"volume",{get:function(){return s},set:function(t){s=t,n.setVolume(100*s),c.dispatchEvent.call(e,e.media,"volumechange")}});var a=e.config.muted;Object.defineProperty(e.media,"muted",{get:function(){return a},set:function(t){var i=c.is.boolean(t)?t:a;a=i,n[i?"mute":"unMute"](),c.dispatchEvent.call(e,e.media,"volumechange")}}),Object.defineProperty(e.media,"currentSrc",{get:function(){return n.getVideoUrl()}}),Object.defineProperty(e.media,"ended",{get:function(){return e.currentTime===e.duration}}),e.options.speed=n.getAvailablePlaybackRates(),e.supported.ui&&e.media.setAttribute("tabindex",-1),c.dispatchEvent.call(e,e.media,"timeupdate"),c.dispatchEvent.call(e,e.media,"durationchange"),window.clearInterval(e.timers.buffering),e.timers.buffering=window.setInterval(function(){e.media.buffered=n.getVideoLoadedFraction(),(null===e.media.lastBuffered||e.media.lastBuffered is missing");if(this.type=n.video,g=d.getAttribute("src"),this.provider=c.getProviderByUrl(g),f=c.getUrlParams(g),!c.is.empty(f)){var y=["1","true"];y.includes(f.autoplay)&&(this.config.autoplay=!0),y.includes(f.playsinline)&&(this.config.inline=!0),y.includes(f.loop)&&(this.config.loop.active=!0)}if(c.is.empty(this.provider)||!Object.keys(i).includes(this.provider))return void this.debug.error("Setup failed: Invalid provider");this.elements.container=this.media,this.media=d,this.elements.container.className="";break;case"video":case"audio":this.type=r,this.provider=i.html5,this.media.hasAttribute("crossorigin")&&(this.config.crossorigin=!0),this.media.hasAttribute("autoplay")&&(this.config.autoplay=!0),this.media.hasAttribute("playsinline")&&(this.config.inline=!0),this.media.hasAttribute("muted")&&(this.config.muted=!0),this.media.hasAttribute("loop")&&(this.config.loop.active=!0);break;default:return void this.debug.error("Setup failed: unsupported type")}this.storage=new p(this),this.supported=u.check(this.type,this.provider,this.config.inline),this.supported.api?(this.media.plyr=this,c.is.element(this.elements.container)||(this.elements.container=c.createElement("div"),c.wrap(this.media,this.elements.container)),this.elements.container.setAttribute("tabindex",0),v.global.call(this),b.addStyleHook.call(this),S.setup.call(this),this.config.debug&&c.on(this.elements.container,this.config.events.join(" "),function(e){l.debug.log("event: "+e.type)}),(this.isHTML5||this.isEmbed&&!this.supported.ui)&&b.build.call(this),this.ads=new m(this)):this.debug.error("Setup failed: no support")}else this.debug.error("Setup failed: no support");else this.debug.error("Setup failed: disabled by config");else this.debug.error("Setup failed: no suitable element passed")}return o(e,[{key:"play",value:function(){return!this.ads.enabled||this.ads.initialized||this.ads.blocked?this.media.play():(this.ads.play(),null)}},{key:"pause",value:function(){this.playing&&this.media.pause()}},{key:"togglePlay",value:function(e){(c.is.boolean(e)?e:!this.playing)?this.play():this.pause()}},{key:"stop",value:function(){this.restart(),this.pause()}},{key:"restart",value:function(){this.currentTime=0}},{key:"rewind",value:function(e){this.currentTime=this.currentTime-(c.is.number(e)?e:this.config.seekTime)}},{key:"forward",value:function(e){this.currentTime=this.currentTime+(c.is.number(e)?e:this.config.seekTime)}},{key:"increaseVolume",value:function(e){var t=this.media.muted?0:this.volume;this.volume=t+(c.is.number(e)?e:1)}},{key:"decreaseVolume",value:function(e){var t=this.media.muted?0:this.volume;this.volume=t-(c.is.number(e)?e:1)}},{key:"toggleCaptions",value:function(e){if(this.supported.ui&&c.is.element(this.elements.buttons.captions)){var t=c.is.boolean(e)?e:-1===this.elements.container.className.indexOf(this.config.classNames.captions.active);this.captions.active!==t&&(this.captions.active=t,c.toggleState(this.elements.buttons.captions,this.captions.active),c.toggleClass(this.elements.container,this.config.classNames.captions.active,this.captions.active),c.dispatchEvent.call(this,this.media,this.captions.active?"captionsenabled":"captionsdisabled"))}}},{key:"toggleFullscreen",value:function(e){if(!this.isAudio){if(f.enabled){if(!c.is.event(e)||e.type!==f.eventType)return void(this.fullscreen.active?f.cancelFullScreen():f.requestFullScreen(this.elements.container));this.fullscreen.active=f.isFullScreen(this.elements.container)}else this.fullscreen.active=!this.fullscreen.active,c.toggleClass(this.elements.container,this.config.classNames.fullscreen.fallback,this.fullscreen.active),this.fullscreen.active?P={x:window.pageXOffset||0,y:window.pageYOffset||0}:window.scrollTo(P.x,P.y),document.body.style.overflow=this.fullscreen.active?"hidden":"";c.is.element(this.elements.buttons.fullscreen)&&c.toggleState(this.elements.buttons.fullscreen,this.fullscreen.active),c.dispatchEvent.call(this,this.media,this.fullscreen.active?"enterfullscreen":"exitfullscreen")}}},{key:"airplay",value:function(){u.airplay&&this.media.webkitShowPlaybackTargetPicker()}},{key:"toggleControls",value:function(e){var t=this;if(c.is.element(this.elements.controls)&&this.supported.ui&&!this.isAudio){var i=0,n=e,s=!1;if(c.is.boolean(e)||(c.is.event(e)?(s="enterfullscreen"===e.type,n=["mouseenter","mousemove","touchstart","touchmove","focusin"].includes(e.type),["mousemove","touchmove","touchend"].includes(e.type)&&(i=2e3),"focusin"===e.type&&(i=3e3,c.toggleClass(this.elements.controls,this.config.classNames.noTransition,!0))):n=c.hasClass(this.elements.container,this.config.classNames.hideControls)),window.clearTimeout(this.timers.controls),n||this.paused||this.loading){if(c.toggleClass(this.elements.container,this.config.classNames.hideControls,!1)&&c.dispatchEvent.call(this,this.media,"controlsshown"),this.paused||this.loading)return;u.touch&&(i=3e3)}n&&!this.playing||(this.timers.controls=window.setTimeout(function(){(!t.elements.controls.pressed&&!t.elements.controls.hover||s)&&(c.hasClass(t.elements.container,t.config.classNames.hideControls)||c.toggleClass(t.elements.controls,t.config.classNames.noTransition,!1),c.toggleClass(t.elements.container,t.config.classNames.hideControls,!0)&&(c.dispatchEvent.call(t,t.media,"controlshidden"),t.config.controls.includes("settings")&&!c.is.empty(t.config.settings)&&w.toggleMenu.call(t,!1)))},i))}}},{key:"on",value:function(e,t){c.on(this.elements.container,e,t)}},{key:"off",value:function(e,t){c.off(this.elements.container,e,t)}},{key:"destroy",value:function(e){var t=this,i=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=function(){document.body.style.overflow="",t.embed=null,i?(Object.keys(t.elements).length&&(t.elements.buttons&&t.elements.buttons.play&&Array.from(t.elements.buttons.play).forEach(function(e){return c.removeElement(e)}),c.removeElement(t.elements.captions),c.removeElement(t.elements.controls),c.removeElement(t.elements.wrapper),t.elements.buttons.play=null,t.elements.captions=null,t.elements.controls=null,t.elements.wrapper=null),c.is.function(e)&&e()):(c.replaceElement(t.elements.original,t.elements.container),c.dispatchEvent.call(t,t.elements.original,"destroyed",!0),c.is.function(e)&&e.call(t.elements.original),t.elements=null)};switch(this.provider+":"+this.type){case"html5:video":case"html5:audio":b.toggleNativeControls.call(this,!0),n();break;case"youtube:video":window.clearInterval(this.timers.buffering),window.clearInterval(this.timers.playing),null!==this.embed&&this.embed.destroy(),n();break;case"vimeo:video":null!==this.embed&&this.embed.unload().then(n),window.setTimeout(n,200)}}},{key:"supports",value:function(e){return u.mime.call(this,e)}},{key:"isHTML5",get:function(){return this.provider===i.html5}},{key:"isEmbed",get:function(){return this.isYouTube||this.isVimeo}},{key:"isYouTube",get:function(){return this.provider===i.youtube}},{key:"isVimeo",get:function(){return this.provider===i.vimeo}},{key:"isVideo",get:function(){return this.type===n.video}},{key:"isAudio",get:function(){return this.type===n.audio}},{key:"paused",get:function(){return this.media.paused}},{key:"playing",get:function(){return!this.paused&&!this.ended&&(!this.isHTML5||this.media.readyState>2)}},{key:"ended",get:function(){return this.media.ended}},{key:"currentTime",set:function(e){var t=0;c.is.number(e)&&(t=e),t<0?t=0:t>this.duration&&(t=this.duration),this.media.currentTime=t.toFixed(4),this.debug.log("Seeking to "+this.currentTime+" seconds")},get:function(){return Number(this.media.currentTime)}},{key:"seeking",get:function(){return this.media.seeking}},{key:"duration",get:function(){var e=parseInt(this.config.duration,10),t=Number(this.media.duration);return Number.isNaN(e)?t:e}},{key:"volume",set:function(e){var t=e;c.is.string(t)&&(t=Number(t)),c.is.number(t)||(t=this.storage.get("volume")),c.is.number(t)||(t=this.config.volume),t>1&&(t=1),t<0&&(t=0),this.config.volume=t,this.media.volume=t,this.muted&&t>0&&(this.muted=!1)},get:function(){return this.media.volume}},{key:"muted",set:function(e){var t=e;c.is.boolean(t)||(t=this.storage.get("muted")),c.is.boolean(t)||(t=this.config.muted),this.config.muted=t,this.media.muted=t},get:function(){return this.media.muted}},{key:"hasAudio",get:function(){return!this.isHTML5||(!!this.isAudio||(this.media.mozHasAudio||Boolean(this.media.webkitAudioDecodedByteCount)||Boolean(this.media.audioTracks&&this.media.audioTracks.length)))}},{key:"speed",set:function(e){var t=null;c.is.number(e)&&(t=e),c.is.number(t)||(t=this.storage.get("speed")),c.is.number(t)||(t=this.config.speed.selected),t<.1&&(t=.1),t>2&&(t=2),this.config.speed.options.includes(t)?(this.config.speed.selected=t,this.media.playbackRate=t):this.debug.warn("Unsupported speed ("+t+")")},get:function(){return this.media.playbackRate}},{key:"quality",set:function(e){var t=null;c.is.string(e)&&(t=e),c.is.string(t)||(t=this.storage.get("quality")),c.is.string(t)||(t=this.config.quality.selected),this.options.quality.includes(t)?(this.config.quality.selected=t,this.media.quality=t):this.debug.warn("Unsupported quality option ("+t+")")},get:function(){return this.media.quality}},{key:"loop",set:function(e){var t=c.is.boolean(e)?e:this.config.loop.active;this.config.loop.active=t,this.media.loop=t},get:function(){return this.media.loop}},{key:"source",set:function(e){N.change.call(this,e)},get:function(){return this.media.currentSrc}},{key:"poster",set:function(e){this.isHTML5&&this.isVideo?c.is.string(e)&&this.media.setAttribute("poster",e):this.debug.warn("Poster can only be set on HTML5 video")},get:function(){return this.isHTML5&&this.isVideo?this.media.getAttribute("poster"):null}},{key:"autoplay",set:function(e){var t=c.is.boolean(e)?e:this.config.autoplay;this.config.autoplay=t},get:function(){return this.config.autoplay}},{key:"language",set:function(e){if(c.is.string(e)&&(this.toggleCaptions(!c.is.empty(e)),!c.is.empty(e))){var t=e.toLowerCase();this.language!==t&&(this.captions.language=t,E.setText.call(this,null),E.setLanguage.call(this),c.dispatchEvent.call(this,this.media,"languagechange"))}},get:function(){return this.captions.language}},{key:"pip",set:function(e){var t="picture-in-picture",i="inline";if(u.pip){var n=c.is.boolean(e)?e:this.pip===i;this.media.webkitSetPresentationMode(n?t:i)}},get:function(){return u.pip?this.media.webkitPresentationMode:null}}],[{key:"supported",value:function(e,t,i){return u.check(e,t,i)}},{key:"loadSprite",value:function(e,t){return c.loadSprite(e,t)}}]),e}()}); +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define("Plyr",t):e.Plyr=t()}(this,function(){"use strict";var e,t,i={html5:"html5",youtube:"youtube",vimeo:"vimeo"},n={audio:"audio",video:"video"},s={enabled:!0,title:"",debug:!1,autoplay:!1,autopause:!0,seekTime:10,volume:1,muted:!1,duration:null,displayDuration:!0,invertTime:!0,toggleInvert:!0,ratio:"16:9",clickToPlay:!0,hideControls:!0,showPosterOnEnd:!1,disableContextMenu:!0,loadSprite:!0,iconPrefix:"plyr",iconUrl:"https://cdn.plyr.io/3.0.0-beta.11/plyr.svg",blankVideo:"https://cdn.plyr.io/static/blank.mp4",quality:{default:"default",options:["hd2160","hd1440","hd1080","hd720","large","medium","small","tiny","default"]},loop:{active:!1},speed:{selected:1,options:[.5,.75,1,1.25,1.5,1.75,2]},keyboard:{focused:!0,global:!1},tooltips:{controls:!1,seek:!0},captions:{active:!1,language:window.navigator.language.split("-")[0]},fullscreen:{enabled:!0,fallback:!0},storage:{enabled:!0,key:"plyr"},controls:["play-large","play","progress","current-time","mute","volume","captions","settings","pip","airplay","fullscreen"],settings:["captions","quality","speed"],i18n:{restart:"Restart",rewind:"Rewind {seektime} secs",play:"Play",pause:"Pause",forward:"Forward {seektime} secs",seek:"Seek",played:"Played",buffered:"Buffered",currentTime:"Current time",duration:"Duration",volume:"Volume",mute:"Mute",unmute:"Unmute",enableCaptions:"Enable captions",disableCaptions:"Disable captions",enterFullscreen:"Enter fullscreen",exitFullscreen:"Exit fullscreen",frameTitle:"Player for {title}",captions:"Captions",settings:"Settings",speed:"Speed",quality:"Quality",loop:"Loop",start:"Start",end:"End",all:"All",reset:"Reset",none:"None",disabled:"Disabled",advertisment:"Ad"},urls:{vimeo:{api:"https://player.vimeo.com/api/player.js"},youtube:{api:"https://www.youtube.com/iframe_api"},googleIMA:{api:"https://imasdk.googleapis.com/js/sdkloader/ima3.js"}},listeners:{seek:null,play:null,pause:null,restart:null,rewind:null,forward:null,mute:null,volume:null,captions:null,fullscreen:null,pip:null,airplay:null,speed:null,quality:null,loop:null,language:null},events:["ended","progress","stalled","playing","waiting","canplay","canplaythrough","loadstart","loadeddata","loadedmetadata","timeupdate","volumechange","play","pause","error","seeking","seeked","emptied","ratechange","cuechange","enterfullscreen","exitfullscreen","captionsenabled","captionsdisabled","languagechange","controlshidden","controlsshown","ready","statechange","qualitychange","qualityrequested","adsloaded","adscontentpause","adsconentresume","adstarted","adsmidpoint","adscomplete","adsallcomplete","adsimpression","adsclick"],selectors:{editable:"input, textarea, select, [contenteditable]",container:".plyr",controls:{container:null,wrapper:".plyr__controls"},labels:"[data-plyr]",buttons:{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"]',pip:'[data-plyr="pip"]',airplay:'[data-plyr="airplay"]',settings:'[data-plyr="settings"]',loop:'[data-plyr="loop"]'},inputs:{seek:'[data-plyr="seek"]',volume:'[data-plyr="volume"]',speed:'[data-plyr="speed"]',language:'[data-plyr="language"]',quality:'[data-plyr="quality"]'},display:{currentTime:".plyr__time--current",duration:".plyr__time--duration",buffer:".plyr__progress--buffer",played:".plyr__progress--played",loop:".plyr__progress--loop",volume:".plyr__volume--display"},progress:".plyr__progress",captions:".plyr__captions",menu:{quality:".js-plyr__menu__list--quality"}},classNames:{video:"plyr__video-wrapper",embed:"plyr__video-embed",ads:"plyr__ads",control:"plyr__control",type:"plyr--{0}",provider:"plyr--{0}",stopped:"plyr--stopped",playing:"plyr--playing",loading:"plyr--loading",error:"plyr--has-error",hover:"plyr--hover",tooltip:"plyr__tooltip",cues:"plyr__cues",hidden:"plyr__sr-only",hideControls:"plyr--hide-controls",isIos:"plyr--is-ios",isTouch:"plyr--is-touch",uiSupported:"plyr--full-ui",noTransition:"plyr--no-transition",menu:{value:"plyr__menu__value",badge:"plyr__badge",open:"plyr--menu-open"},captions:{enabled:"plyr--captions-enabled",active:"plyr--captions-active"},fullscreen:{enabled:"plyr--fullscreen-enabled",fallback:"plyr--fullscreen-fallback"},pip:{supported:"plyr--pip-supported",active:"plyr--pip-active"},airplay:{supported:"plyr--airplay-supported",active:"plyr--airplay-active"},tabFocus:"plyr__tab-focus"},attributes:{embed:{provider:"data-plyr-provider",id:"data-plyr-embed-id"}},keys:{google:null},ads:{enabled:!1}},a=(function(){function e(e){this.value=e}function t(t){var i,n;function s(i,n){try{var o=t[i](n),l=o.value;l instanceof e?Promise.resolve(l.value).then(function(e){s("next",e)},function(e){s("throw",e)}):a(o.done?"return":"normal",o.value)}catch(e){a("throw",e)}}function a(e,t){switch(e){case"return":i.resolve({value:t,done:!0});break;case"throw":i.reject(t);break;default:i.resolve({value:t,done:!1})}(i=i.next)?s(i.key,i.arg):n=null}this._invoke=function(e,t){return new Promise(function(a,o){var l={key:e,arg:t,resolve:a,reject:o,next:null};n?n=n.next=l:(i=n=l,s(e,t))})},"function"!=typeof t.return&&(this.return=void 0)}"function"==typeof Symbol&&Symbol.asyncIterator&&(t.prototype[Symbol.asyncIterator]=function(){return this}),t.prototype.next=function(e){return this._invoke("next",e)},t.prototype.throw=function(e){return this._invoke("throw",e)},t.prototype.return=function(e){return this._invoke("return",e)}}(),function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}),o=function(){function e(e,t){for(var i=0;i0?t.cloneNode(!0):t,s=e.parentNode,a=e.nextSibling;n.appendChild(e),a?s.insertBefore(n,a):s.appendChild(n)})},createElement:function(e,t,i){var n=document.createElement(e);return c.is.object(t)&&c.setAttributes(n,t),c.is.string(i)&&(n.textContent=i),n},insertAfter:function(e,t){t.parentNode.insertBefore(e,t.nextSibling)},insertElement:function(e,t,i,n){t.appendChild(c.createElement(e,i,n))},removeElement:function(e){return c.is.element(e)&&c.is.element(e.parentNode)?(e.parentNode.removeChild(e),e):null},emptyElement:function(e){for(var t=e.childNodes.length;t>0;)e.removeChild(e.lastChild),t-=1},replaceElement:function(e,t){return c.is.element(t)&&c.is.element(t.parentNode)&&c.is.element(e)?(t.parentNode.replaceChild(e,t),e):null},setAttributes:function(e,t){c.is.element(e)&&!c.is.empty(t)&&Object.keys(t).forEach(function(i){e.setAttribute(i,t[i])})},getAttributesFromSelector:function(e,t){if(!c.is.string(e)||c.is.empty(e))return{};var i={},n=t;return e.split(",").forEach(function(e){var t=e.trim(),s=t.replace(".",""),a=t.replace(/[[\]]/g,"").split("="),o=a[0],l=a.length>1?a[1].replace(/["']/g,""):"";switch(t.charAt(0)){case".":c.is.object(n)&&c.is.string(n.class)&&(n.class+=" "+s),i.class=s;break;case"#":i.id=t.replace("#","");break;case"[":i[o]=l}}),i},toggleClass:function(e,t,i){if(c.is.element(e)){var n=e.classList.contains(t);return e.classList[i?"add":"remove"](t),i&&!n||!i&&n}return null},hasClass:function(e,t){return c.is.element(e)&&e.classList.contains(t)},toggleHidden:function(e,t){c.is.element(e)&&(t?e.setAttribute("hidden",""):e.removeAttribute("hidden"))},matches:function(e,t){var i={Element:Element};var n=i.matches||i.webkitMatchesSelector||i.mozMatchesSelector||i.msMatchesSelector||function(){return Array.from(document.querySelectorAll(t)).includes(this)};return n.call(e,t)},getElements:function(e){return this.elements.container.querySelectorAll(e)},getElement:function(e){return this.elements.container.querySelector(e)},findElements:function(){try{return this.elements.controls=c.getElement.call(this,this.config.selectors.controls.wrapper),this.elements.buttons={play:c.getElements.call(this,this.config.selectors.buttons.play),pause:c.getElement.call(this,this.config.selectors.buttons.pause),restart:c.getElement.call(this,this.config.selectors.buttons.restart),rewind:c.getElement.call(this,this.config.selectors.buttons.rewind),forward:c.getElement.call(this,this.config.selectors.buttons.forward),mute:c.getElement.call(this,this.config.selectors.buttons.mute),pip:c.getElement.call(this,this.config.selectors.buttons.pip),airplay:c.getElement.call(this,this.config.selectors.buttons.airplay),settings:c.getElement.call(this,this.config.selectors.buttons.settings),captions:c.getElement.call(this,this.config.selectors.buttons.captions),fullscreen:c.getElement.call(this,this.config.selectors.buttons.fullscreen)},this.elements.progress=c.getElement.call(this,this.config.selectors.progress),this.elements.inputs={seek:c.getElement.call(this,this.config.selectors.inputs.seek),volume:c.getElement.call(this,this.config.selectors.inputs.volume)},this.elements.display={buffer:c.getElement.call(this,this.config.selectors.display.buffer),duration:c.getElement.call(this,this.config.selectors.display.duration),currentTime:c.getElement.call(this,this.config.selectors.display.currentTime)},c.is.element(this.elements.progress)&&(this.elements.display.seekTooltip=this.elements.progress.querySelector("."+this.config.classNames.tooltip)),!0}catch(e){return this.debug.warn("It looks like there is a problem with your custom controls HTML",e),this.toggleNativeControls(!0),!1}},getFocusElement:function(){var e=document.activeElement;return e=e&&e!==document.body?document.querySelector(":focus"):null},trapFocus:function(){var e=this,t=c.getElements.call(this,"button:not(:disabled), input:not(:disabled), [tabindex]"),i=t[0],n=t[t.length-1];c.on(this.elements.container,"keydown",function(t){if("Tab"===t.key&&9===t.keyCode&&e.fullscreen.active){var s=c.getFocusElement();s!==n||t.shiftKey?s===i&&t.shiftKey&&(n.focus(),t.preventDefault()):(i.focus(),t.preventDefault())}},!1)},toggleListener:function(e,t,i,n,s,a){if(!c.is.nullOrUndefined(e))if(c.is.nodeList(e))Array.from(e).forEach(function(e){e instanceof Node&&c.toggleListener.call(null,e,t,i,n,s,a)});else{var o=t.split(" "),l=!!c.is.boolean(a)&&a;u.passiveListeners&&(l={passive:!c.is.boolean(s)||s,capture:!!c.is.boolean(a)&&a}),o.forEach(function(t){e[n?"addEventListener":"removeEventListener"](t,i,l)})}},on:function(e,t,i,n,s){c.toggleListener(e,t,i,!0,n,s)},off:function(e,t,i,n,s){c.toggleListener(e,t,i,!1,n,s)},dispatchEvent:function(e,t,i,n){if(e&&t){var s=new CustomEvent(t,{bubbles:!!c.is.boolean(i)&&i,detail:Object.assign({},n,{plyr:c.is.plyr(this)?this:null})});e.dispatchEvent(s)}},toggleState:function(e,t){if(c.is.element(e)){var i="true"===e.getAttribute("aria-pressed"),n=c.is.boolean(t)?t:!i;e.setAttribute("aria-pressed",n)}},getPercentage:function(e,t){return 0===e||0===t||Number.isNaN(e)||Number.isNaN(t)?0:(e/t*100).toFixed(2)},getHours:function(e){return parseInt(e/60/60%60,10)},getMinutes:function(e){return parseInt(e/60%60,10)},getSeconds:function(e){return parseInt(e%60,10)},formatTime:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(!c.is.number(e))return this.formatTime(null,t,i);var n=function(e){return("0"+e).slice(-2)},s=this.getHours(e),a=this.getMinutes(e),o=this.getSeconds(e);return t||s>0?s+=":":s="",(i?"-":"")+s+n(a)+":"+n(o)},extend:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length,i=Array(t>1?t-1:0),n=1;n0&&void 0!==arguments[0]&&arguments[0];a(this,e),this.enabled=window.console&&t,this.enabled&&this.log("Debugging enabled")}return o(e,[{key:"log",get:function(){return this.enabled?Function.prototype.bind.call(console.log,console):d}},{key:"warn",get:function(){return this.enabled?Function.prototype.bind.call(console.warn,console):d}},{key:"error",get:function(){return this.enabled?Function.prototype.bind.call(console.error,console):d}}]),e}(),p=function(){function e(t){a(this,e),this.enabled=t.config.storage.enabled,this.key=t.config.storage.key}return o(e,[{key:"get",value:function(t){var i=window.localStorage.getItem(this.key);if(!e.supported||c.is.empty(i))return null;var n=JSON.parse(i);return c.is.string(t)&&t.length?n[t]:n}},{key:"set",value:function(t){if(e.supported&&this.enabled&&c.is.object(t)){var i=this.get();c.is.empty(i)&&(i={}),c.extend(i,t),window.localStorage.setItem(this.key,JSON.stringify(i))}}}],[{key:"supported",get:function(){if(!("localStorage"in window))return!1;try{return window.localStorage.setItem("___test","___test"),window.localStorage.removeItem("___test"),!0}catch(e){return!1}}}]),e}(),m=function(){function e(t){var i=this;a(this,e),this.player=t,this.enabled=t.config.ads.enabled,this.playing=!1,this.initialized=!1,this.blocked=!1,this.enabled=c.is.url(t.config.ads.tag),this.enabled&&(c.is.object(window.google)?this.ready():c.loadScript(t.config.urls.googleIMA.api,function(){i.ready()},function(){i.blocked=!0,i.player.debug.log("Ads error: Google IMA SDK failed to load")}))}return o(e,[{key:"ready",value:function(){var e=this;this.elements={container:null,displayContainer:null},this.manager=null,this.loader=null,this.cuePoints=null,this.events={},this.safetyTimer=null,this.countdownTimer=null,this.listeners(),this.startSafetyTimer(12e3,"ready()"),this.loaderPromise=new Promise(function(t){e.on("ADS_LOADER_LOADED",function(){return t()})}),this.managerPromise=new Promise(function(t){e.on("ADS_MANAGER_LOADED",function(){return t()})}),this.managerPromise.then(function(){e.clearSafetyTimer("onAdsManagerLoaded()")}),this.setupIMA()}},{key:"setupIMA",value:function(){this.elements.container=c.createElement("div",{class:this.player.config.classNames.ads,hidden:""}),this.player.elements.container.appendChild(this.elements.container),google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED),google.ima.settings.setLocale(this.player.config.ads.language),this.elements.displayContainer=new google.ima.AdDisplayContainer(this.elements.container),this.requestAds()}},{key:"requestAds",value:function(){var e=this,t=this.player.elements.container;try{this.loader=new google.ima.AdsLoader(this.elements.displayContainer),this.loader.addEventListener(google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,function(t){return e.onAdsManagerLoaded(t)},!1),this.loader.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,function(t){return e.onAdError(t)},!1);var i=new google.ima.AdsRequest;i.adTagUrl="https://go.aniview.com/api/adserver6/vast/?"+c.buildUrlParams({AV_PUBLISHERID:"58c25bb0073ef448b1087ad6",AV_CHANNELID:"5a0458dc28a06145e4519d21",AV_URL:"127.0.0.1:3000",cb:1,AV_WIDTH:640,AV_HEIGHT:480}),i.linearAdSlotWidth=t.offsetWidth,i.linearAdSlotHeight=t.offsetHeight,i.nonLinearAdSlotWidth=t.offsetWidth,i.nonLinearAdSlotHeight=t.offsetHeight,i.forceNonLinearFullSlot=!1,this.loader.requestAds(i),this.handleEventListeners("ADS_LOADER_LOADED")}catch(e){this.onAdError(e)}}},{key:"pollCountdown",value:function(){var e=this;if(!(arguments.length>0&&void 0!==arguments[0]&&arguments[0]))return window.clearInterval(this.countdownTimer),void this.elements.container.removeAttribute("data-badge-text");this.countdownTimer=window.setInterval(function(){var t=c.formatTime(e.manager.getRemainingTime()),i=e.player.config.i18n.advertisment+" - "+t;e.elements.container.setAttribute("data-badge-text",i)},100)}},{key:"onAdsManagerLoaded",value:function(e){var t=this,i=new google.ima.AdsRenderingSettings;i.restoreCustomPlaybackStateOnAdBreakComplete=!0,i.enablePreloading=!0,this.manager=e.getAdsManager(this.player,i),this.cuePoints=this.manager.getCuePoints(),this.cuePoints.forEach(function(e){if(0!==e&&-1!==e){var i=t.player.elements.progress;if(i){var n=100/t.player.duration*e,s=c.createElement("span",{class:t.player.config.classNames.cues});s.style.left=n.toString()+"%",i.appendChild(s)}}}),this.manager.setVolume(this.player.volume),this.manager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR,function(e){return t.onAdError(e)}),Object.keys(google.ima.AdEvent.Type).forEach(function(e){t.manager.addEventListener(google.ima.AdEvent.Type[e],function(e){return t.onAdEvent(e)})}),this.handleEventListeners("ADS_MANAGER_LOADED")}},{key:"onAdEvent",value:function(e){var t=this,i=this.player.elements.container,n=e.getAd(),s=function(e){c.dispatchEvent.call(t.player,t.player.media,"ads"+e)};switch(e.type){case google.ima.AdEvent.Type.LOADED:this.handleEventListeners("LOADED"),s("loaded"),this.pollCountdown(!0),n.isLinear()||(n.width=i.offsetWidth,n.height=i.offsetHeight);break;case google.ima.AdEvent.Type.ALL_ADS_COMPLETED:this.handleEventListeners("ALL_ADS_COMPLETED"),s("allcomplete"),this.loadAds();break;case google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED:this.handleEventListeners("CONTENT_PAUSE_REQUESTED"),s("contentpause"),this.pauseContent();break;case google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED:this.handleEventListeners("CONTENT_RESUME_REQUESTED"),s("contentresume"),this.pollCountdown(),this.resumeContent();break;case google.ima.AdEvent.Type.STARTED:s("started");break;case google.ima.AdEvent.Type.MIDPOINT:s("midpoint");break;case google.ima.AdEvent.Type.COMPLETE:s("complete");break;case google.ima.AdEvent.Type.IMPRESSION:s("impression");break;case google.ima.AdEvent.Type.CLICK:s("click")}}},{key:"onAdError",value:function(e){this.cancel(),this.player.debug.log("Ads error",e)}},{key:"listeners",value:function(){var e=this,t=this.player.elements.container,i=void 0;this.player.on("ended",function(){e.loader.contentComplete()}),this.player.on("seeking",function(){return i=e.player.currentTime}),this.player.on("seeked",function(){var t=e.player.currentTime;e.cuePoints.forEach(function(n,s){i0)&&(i?(e.decreaseVolume(.02),n=-1):(e.increaseVolume(.02),n=1)),(t.deltaY>0||t.deltaX<0)&&(i?(e.increaseVolume(.02),n=1):(e.decreaseVolume(.02),n=-1)),(1===n&&e.media.volume<1||-1===n&&e.media.volume>0)&&t.preventDefault()})},!1)}},b={addStyleHook:function(){c.toggleClass(this.elements.container,this.config.selectors.container.replace(".",""),!0),c.toggleClass(this.elements.container,this.config.classNames.uiSupported,this.supported.ui)},toggleNativeControls:function(){arguments.length>0&&void 0!==arguments[0]&&arguments[0]&&this.isHTML5?this.media.setAttribute("controls",""):this.media.removeAttribute("controls")},build:function(){if(v.media.call(this),!this.supported.ui)return this.debug.warn("Basic support only for "+this.provider+" "+this.type),c.removeElement.call(this,"controls"),c.removeElement.call(this,"buttons.play"),void b.toggleNativeControls.call(this,!0);c.is.element(this.elements.controls)||(w.inject.call(this),v.controls.call(this)),c.is.element(this.elements.controls)&&(b.toggleNativeControls.call(this),f.setup.call(this),E.setup.call(this),this.volume=null,this.muted=null,this.speed=null,this.loop=null,this.options.quality=[],b.timeUpdate.call(this),b.checkPlaying.call(this),this.ready=!0,c.dispatchEvent.call(this,this.media,"ready"),b.setTitle.call(this))},setTitle:function(){var e=this.config.i18n.play;if(c.is.string(this.config.title)&&!c.is.empty(this.config.title)&&(e+=", "+this.config.title,this.elements.container.setAttribute("aria-label",this.config.title)),c.is.nodeList(this.elements.buttons.play)&&Array.from(this.elements.buttons.play).forEach(function(t){t.setAttribute("aria-label",e)}),this.isEmbed){var t=c.getElement.call(this,"iframe");if(!c.is.element(t))return;var i=c.is.empty(this.config.title)?"video":this.config.title;t.setAttribute("title",this.config.i18n.frameTitle.replace("{title}",i))}},checkPlaying:function(){var e=this;c.toggleClass(this.elements.container,this.config.classNames.playing,this.playing),c.toggleClass(this.elements.container,this.config.classNames.stopped,this.paused),c.is.nodeList(this.elements.buttons.play)&&Array.from(this.elements.buttons.play).forEach(function(t){return c.toggleState(t,e.playing)}),this.toggleControls(!this.playing)},checkLoading:function(e){var t=this;this.loading=["stalled","waiting"].includes(e.type),clearTimeout(this.timers.loading),this.timers.loading=setTimeout(function(){c.toggleClass(t.elements.container,t.config.classNames.loading,t.loading),t.toggleControls(t.loading)},this.loading?250:0)},checkFailed:function(){var e=this;this.failed=3===this.media.networkState,this.failed&&(c.toggleClass(this.elements.container,this.config.classNames.loading,!1),c.toggleClass(this.elements.container,this.config.classNames.error,!0)),clearTimeout(this.timers.failed),this.timers.loading=setTimeout(function(){c.toggleClass(e.elements.container,e.config.classNames.loading,e.loading),e.toggleControls(e.loading)},this.loading?250:0)},updateVolume:function(){this.supported.ui&&(c.is.element(this.elements.inputs.volume)&&b.setRange.call(this,this.elements.inputs.volume,this.muted?0:this.volume),c.is.element(this.elements.buttons.mute)&&c.toggleState(this.elements.buttons.mute,this.muted||0===this.volume))},setRange:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;c.is.element(e)&&(e.value=t,w.updateRangeFill.call(this,e))},setProgress:function(e,t){var i=c.is.number(t)?t:0,n=c.is.element(e)?e:this.elements.display.buffer;if(c.is.element(n)){n.value=i;var s=n.getElementsByTagName("span")[0];c.is.element(s)&&(s.childNodes[0].nodeValue=i)}},updateProgress:function(e){var t=this;if(this.supported.ui&&c.is.event(e)){var i,n=0;if(e)switch(e.type){case"timeupdate":case"seeking":n=c.getPercentage(this.currentTime,this.duration),"timeupdate"===e.type&&b.setRange.call(this,this.elements.inputs.seek,n);break;case"playing":case"progress":n=(i=t.media.buffered)&&i.length?c.getPercentage(i.end(0),t.duration):c.is.number(i)?100*i:0,b.setProgress.call(this,this.elements.display.buffer,n)}}},updateTimeDisplay:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if(c.is.element(e)&&c.is.number(t)){var n=c.getHours(this.duration)>0;e.textContent=c.formatTime(t,n,i)}},timeUpdate:function(e){var t=!c.is.element(this.elements.display.duration)&&this.config.invertTime;b.updateTimeDisplay.call(this,this.elements.display.currentTime,t?this.duration-this.currentTime:this.currentTime,t),e&&"timeupdate"===e.type&&this.media.seeking||b.updateProgress.call(this,e)},durationUpdate:function(){if(this.supported.ui){var e=c.is.element(this.elements.display.duration);!e&&this.config.displayDuration&&this.paused&&b.updateTimeDisplay.call(this,this.elements.display.currentTime,this.duration),e&&b.updateTimeDisplay.call(this,this.elements.display.duration,this.duration),w.updateSeekTooltip.call(this)}}},k=c.getBrowser(),w={updateRangeFill:function(e){if(k.isWebkit){var t=c.is.event(e)?e.target:e;c.is.element(t)&&"range"===t.getAttribute("type")&&t.style.setProperty("--value",t.value/t.max*100+"%")}},getIconUrl:function(){return{url:this.config.iconUrl,absolute:0===this.config.iconUrl.indexOf("http")||k.isIE&&!window.svg4everybody}},createIcon:function(e,t){var i=w.getIconUrl.call(this),n=(i.absolute?"":i.url)+"#"+this.config.iconPrefix,s=document.createElementNS("http://www.w3.org/2000/svg","svg");c.setAttributes(s,c.extend(t,{role:"presentation"}));var a=document.createElementNS("http://www.w3.org/2000/svg","use"),o=n+"-"+e;return"href"in a?a.setAttributeNS("http://www.w3.org/1999/xlink","href",o):a.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",o),s.appendChild(a),s},createLabel:function(e,t){var i=this.config.i18n[e],n=Object.assign({},t);switch(e){case"pip":i="PIP";break;case"airplay":i="AirPlay"}return"class"in n?n.class+=" "+this.config.classNames.hidden:n.class=this.config.classNames.hidden,c.createElement("span",n,i)},createBadge:function(e){if(c.is.empty(e))return null;var t=c.createElement("span",{class:this.config.classNames.menu.value});return t.appendChild(c.createElement("span",{class:this.config.classNames.menu.badge},e)),t},createButton:function(e,t){var i=c.createElement("button"),n=Object.assign({},t),s=e,a=!1,o=void 0,l=void 0,r=void 0,u=void 0;switch("type"in n||(n.type="button"),"class"in n?n.class.includes(this.config.classNames.control)&&(n.class+=" "+this.config.classNames.control):n.class=this.config.classNames.control,s){case"play":a=!0,o="play",r="pause",l="play",u="pause";break;case"mute":a=!0,o="mute",r="unmute",l="volume",u="muted";break;case"captions":a=!0,o="enableCaptions",r="disableCaptions",l="captions-off",u="captions-on";break;case"fullscreen":a=!0,o="enterFullscreen",r="exitFullscreen",l="enter-fullscreen",u="exit-fullscreen";break;case"play-large":n.class+=" "+this.config.classNames.control+"--overlaid",s="play",o="play",l="play";break;default:o=s,l=s}return a?(i.appendChild(w.createIcon.call(this,u,{class:"icon--pressed"})),i.appendChild(w.createIcon.call(this,l,{class:"icon--not-pressed"})),i.appendChild(w.createLabel.call(this,r,{class:"label--pressed"})),i.appendChild(w.createLabel.call(this,o,{class:"label--not-pressed"})),n["aria-pressed"]=!1,n["aria-label"]=this.config.i18n[o]):(i.appendChild(w.createIcon.call(this,l)),i.appendChild(w.createLabel.call(this,o))),c.extend(n,c.getAttributesFromSelector(this.config.selectors.buttons[s],n)),c.setAttributes(i,n),this.elements.buttons[s]=i,i},createRange:function(e,t){var i=c.createElement("label",{for:t.id,class:this.config.classNames.hidden},this.config.i18n[e]),n=c.createElement("input",c.extend(c.getAttributesFromSelector(this.config.selectors.inputs[e]),{type:"range",min:0,max:100,step:.01,value:0,autocomplete:"off"},t));return this.elements.inputs[e]=n,w.updateRangeFill.call(this,n),{label:i,input:n}},createProgress:function(e,t){var i=c.createElement("progress",c.extend(c.getAttributesFromSelector(this.config.selectors.display[e]),{min:0,max:100,value:0},t));if("volume"!==e){i.appendChild(c.createElement("span",null,"0"));var n="";switch(e){case"played":n=this.config.i18n.played;break;case"buffer":n=this.config.i18n.buffered}i.textContent="% "+n.toLowerCase()}return this.elements.display[e]=i,i},createTime:function(e){var t=c.createElement("div",{class:"plyr__time"});return t.appendChild(c.createElement("span",{class:this.config.classNames.hidden},this.config.i18n[e])),t.appendChild(c.createElement("span",c.getAttributesFromSelector(this.config.selectors.display[e]),"00:00")),this.elements.display[e]=t,t},createMenuItem:function(e,t,i,n){var s=arguments.length>4&&void 0!==arguments[4]?arguments[4]:null,a=arguments.length>5&&void 0!==arguments[5]&&arguments[5],o=c.createElement("li"),l=c.createElement("label",{class:this.config.classNames.control}),r=c.createElement("input",c.extend(c.getAttributesFromSelector(this.config.selectors.inputs[i]),{type:"radio",name:"plyr-"+i,value:e,checked:a,class:"plyr__sr-only"})),u=c.createElement("span",{"aria-hidden":!0});l.appendChild(r),l.appendChild(u),l.insertAdjacentHTML("beforeend",n),c.is.element(s)&&l.appendChild(s),o.appendChild(l),t.appendChild(o)},updateSeekTooltip:function(e){if(this.config.tooltips.seek&&c.is.element(this.elements.inputs.seek)&&c.is.element(this.elements.display.seekTooltip)&&0!==this.duration){var t=0,i=this.elements.inputs.seek.getBoundingClientRect(),n=this.config.classNames.tooltip+"--visible";if(c.is.event(e))t=100/i.width*(e.pageX-i.left);else{if(!c.hasClass(this.elements.display.seekTooltip,n))return;t=parseFloat(this.elements.display.seekTooltip.style.left,10)}t<0?t=0:t>100&&(t=100),b.updateTimeDisplay.call(this,this.elements.display.seekTooltip,this.duration/100*t),this.elements.display.seekTooltip.style.left=t+"%",c.is.event(e)&&["mouseenter","mouseleave"].includes(e.type)&&c.toggleClass(this.elements.display.seekTooltip,n,"mouseenter"===e.type)}},toggleTab:function(e,t){var i=this.elements.settings.tabs[e],n=this.elements.settings.panes[e];c.toggleHidden(i,!t),c.toggleHidden(n,!t)},setQualityMenu:function(e){var t=this,i=this.elements.settings.panes.quality.querySelector("ul");c.is.array(e)?this.options.quality=e.filter(function(e){return t.config.quality.options.includes(e)}):this.options.quality=this.config.quality.options;var n=!c.is.empty(this.options.quality)&&this.isYouTube;if(w.toggleTab.call(this,"quality",n),n){c.emptyElement(i);this.options.quality.forEach(function(e){return w.createMenuItem.call(t,e,i,"quality",w.getLabel.call(t,"quality",e),function(e){var i="";switch(e){case"hd2160":i="4K";break;case"hd1440":i="WQHD";break;case"hd1080":case"hd720":i="HD"}return i.length?w.createBadge.call(t,i):null}(e))}),w.updateSetting.call(this,"quality",i)}},getLabel:function(e,t){switch(e){case"speed":return 1===t?"Normal":t+"×";case"quality":switch(t){case"hd2160":return"2160P";case"hd1440":return"1440P";case"hd1080":return"1080P";case"hd720":return"720P";case"large":return"480P";case"medium":return"360P";case"small":return"240P";case"tiny":return"Tiny";case"default":return"Auto";default:return t}case"captions":return w.getLanguage.call(this);default:return null}},updateSetting:function(e,t){var i=this.elements.settings.panes[e],n=null,s=t;switch(e){case"captions":n=this.captions.active?this.captions.language:"";break;default:if(n=this[e],c.is.empty(n)&&(n=this.config[e].default),!this.options[e].includes(n))return void this.debug.warn("Unsupported value of '"+n+"' for "+e);if(!this.config[e].options.includes(n))return void this.debug.warn("Disabled value of '"+n+"' for "+e)}(c.is.element(s)||(s=i&&i.querySelector("ul")),c.is.empty(n))||(this.elements.settings.tabs[e].querySelector("."+this.config.classNames.menu.value).innerHTML=w.getLabel.call(this,e,n));var a=s&&s.querySelector('input[value="'+n+'"]');c.is.element(a)&&(a.checked=!0)},getLanguage:function(){if(!this.supported.ui)return null;if(!u.textTracks||!E.getTracks.call(this).length)return this.config.i18n.none;if(this.captions.active){var e=E.getCurrentTrack.call(this);if(c.is.track(e))return e.label}return this.config.i18n.disabled},setCaptionsMenu:function(){var e=this,t=this.elements.settings.panes.captions.querySelector("ul"),i=E.getTracks.call(this).length;if(w.toggleTab.call(this,"captions",i),c.emptyElement(t),i){var n=E.getTracks.call(this).map(function(e){return{language:e.language,label:c.is.empty(e.label)?e.language.toUpperCase():e.label}});n.unshift({language:"",label:this.config.i18n.none}),n.forEach(function(i){w.createMenuItem.call(e,i.language,t,"language",i.label||i.language,w.createBadge.call(e,i.language.toUpperCase()),i.language.toLowerCase()===e.captions.language.toLowerCase())}),w.updateSetting.call(this,"captions",t)}},setSpeedMenu:function(){var e=this;c.is.object(this.options.speed)&&Object.keys(this.options.speed).length||(this.options.speed=[.5,.75,1,1.25,1.5,1.75,2]),this.options.speed=this.options.speed.filter(function(t){return e.config.speed.options.includes(t)});var t=!c.is.empty(this.options.speed);if(w.toggleTab.call(this,"speed",t),t){var i=this.elements.settings.panes.speed.querySelector("ul");c.toggleHidden(this.elements.settings.tabs.speed,!1),c.toggleHidden(this.elements.settings.panes.speed,!1),c.emptyElement(i),this.options.speed.forEach(function(t){return w.createMenuItem.call(e,t,i,"speed",w.getLabel.call(e,"speed",t))}),w.updateSetting.call(this,"speed",i)}},toggleMenu:function(e){var t=this.elements.settings.form,i=this.elements.buttons.settings,n=c.is.boolean(e)?e:c.is.element(t)&&"true"===t.getAttribute("aria-hidden");if(c.is.event(e)){var s=c.is.element(t)&&t.contains(e.target),a=e.target===this.elements.buttons.settings;if(s||!s&&!a&&n)return;a&&e.stopPropagation()}c.is.element(i)&&i.setAttribute("aria-expanded",n),c.is.element(t)&&(t.setAttribute("aria-hidden",!n),c.toggleClass(this.elements.container,this.config.classNames.menu.open,n),n?t.removeAttribute("tabindex"):t.setAttribute("tabindex",-1))},getTabSize:function(e){var t=e.cloneNode(!0);t.style.position="absolute",t.style.opacity=0,t.setAttribute("aria-hidden",!1),Array.from(t.querySelectorAll("input[name]")).forEach(function(e){var t=e.getAttribute("name");e.setAttribute("name",t+"-clone")}),e.parentNode.appendChild(t);var i=t.scrollWidth,n=t.scrollHeight;return c.removeElement(t),{width:i,height:n}},showTab:function(e){var t=this.elements.settings.menu,i=e.target,n="false"===i.getAttribute("aria-expanded"),s=document.getElementById(i.getAttribute("aria-controls"));if(c.is.element(s)&&"tabpanel"===s.getAttribute("role")){var a=t.querySelector('[role="tabpanel"][aria-hidden="false"]'),o=a.parentNode;if(Array.from(t.querySelectorAll('[aria-controls="'+a.getAttribute("id")+'"]')).forEach(function(e){e.setAttribute("aria-expanded",!1)}),u.transitions&&!u.reducedMotion){o.style.width=a.scrollWidth+"px",o.style.height=a.scrollHeight+"px";var l=w.getTabSize.call(this,s);c.on(o,c.transitionEndEvent,function e(t){t.target===o&&["width","height"].includes(t.propertyName)&&(o.style.width="",o.style.height="",c.off(o,c.transitionEndEvent,e))}),o.style.width=l.width+"px",o.style.height=l.height+"px"}a.setAttribute("aria-hidden",!0),a.setAttribute("tabindex",-1),s.setAttribute("aria-hidden",!n),i.setAttribute("aria-expanded",n),s.removeAttribute("tabindex"),s.querySelectorAll("button:not(:disabled), input:not(:disabled), [tabindex]")[0].focus()}},create:function(e){var t=this;if(c.is.empty(this.config.controls))return null;var i=c.createElement("div",c.getAttributesFromSelector(this.config.selectors.controls.wrapper));if(this.config.controls.includes("restart")&&i.appendChild(w.createButton.call(this,"restart")),this.config.controls.includes("rewind")&&i.appendChild(w.createButton.call(this,"rewind")),this.config.controls.includes("play")&&i.appendChild(w.createButton.call(this,"play")),this.config.controls.includes("fast-forward")&&i.appendChild(w.createButton.call(this,"fast-forward")),this.config.controls.includes("progress")){var n=c.createElement("div",c.getAttributesFromSelector(this.config.selectors.progress)),s=w.createRange.call(this,"seek",{id:"plyr-seek-"+e.id});if(n.appendChild(s.label),n.appendChild(s.input),n.appendChild(w.createProgress.call(this,"buffer")),this.config.tooltips.seek){var a=c.createElement("span",{role:"tooltip",class:this.config.classNames.tooltip},"00:00");n.appendChild(a),this.elements.display.seekTooltip=a}this.elements.progress=n,i.appendChild(this.elements.progress)}if(this.config.controls.includes("current-time")&&i.appendChild(w.createTime.call(this,"currentTime")),this.config.controls.includes("duration")&&i.appendChild(w.createTime.call(this,"duration")),this.config.controls.includes("mute")&&i.appendChild(w.createButton.call(this,"mute")),this.config.controls.includes("volume")){var o=c.createElement("div",{class:"plyr__volume"}),l={max:1,step:.05,value:this.config.volume},r=w.createRange.call(this,"volume",c.extend(l,{id:"plyr-volume-"+e.id}));o.appendChild(r.label),o.appendChild(r.input),this.elements.volume=o,i.appendChild(o)}if(this.config.controls.includes("captions")&&i.appendChild(w.createButton.call(this,"captions")),this.config.controls.includes("settings")&&!c.is.empty(this.config.settings)){var d=c.createElement("div",{class:"plyr__menu"});d.appendChild(w.createButton.call(this,"settings",{id:"plyr-settings-toggle-"+e.id,"aria-haspopup":!0,"aria-controls":"plyr-settings-"+e.id,"aria-expanded":!1}));var h=c.createElement("form",{class:"plyr__menu__container",id:"plyr-settings-"+e.id,"aria-hidden":!0,"aria-labelled-by":"plyr-settings-toggle-"+e.id,role:"tablist",tabindex:-1}),p=c.createElement("div"),m=c.createElement("div",{id:"plyr-settings-"+e.id+"-home","aria-hidden":!1,"aria-labelled-by":"plyr-settings-toggle-"+e.id,role:"tabpanel"}),g=c.createElement("ul",{role:"tablist"});this.config.settings.forEach(function(i){var n=c.createElement("li",{role:"tab",hidden:""}),s=c.createElement("button",c.extend(c.getAttributesFromSelector(t.config.selectors.buttons.settings),{type:"button",class:t.config.classNames.control+" "+t.config.classNames.control+"--forward",id:"plyr-settings-"+e.id+"-"+i+"-tab","aria-haspopup":!0,"aria-controls":"plyr-settings-"+e.id+"-"+i,"aria-expanded":!1}),t.config.i18n[i]),a=c.createElement("span",{class:t.config.classNames.menu.value});a.innerHTML=e[i],s.appendChild(a),n.appendChild(s),g.appendChild(n),t.elements.settings.tabs[i]=n}),m.appendChild(g),p.appendChild(m),this.config.settings.forEach(function(i){var n=c.createElement("div",{id:"plyr-settings-"+e.id+"-"+i,"aria-hidden":!0,"aria-labelled-by":"plyr-settings-"+e.id+"-"+i+"-tab",role:"tabpanel",tabindex:-1,hidden:""}),s=c.createElement("button",{type:"button",class:t.config.classNames.control+" "+t.config.classNames.control+"--back","aria-haspopup":!0,"aria-controls":"plyr-settings-"+e.id+"-home","aria-expanded":!1},t.config.i18n[i]);n.appendChild(s);var a=c.createElement("ul");n.appendChild(a),p.appendChild(n),t.elements.settings.panes[i]=n}),h.appendChild(p),d.appendChild(h),i.appendChild(d),this.elements.settings.form=h,this.elements.settings.menu=d}return this.config.controls.includes("pip")&&u.pip&&i.appendChild(w.createButton.call(this,"pip")),this.config.controls.includes("airplay")&&u.airplay&&i.appendChild(w.createButton.call(this,"airplay")),this.config.controls.includes("fullscreen")&&i.appendChild(w.createButton.call(this,"fullscreen")),this.config.controls.includes("play-large")&&this.elements.container.appendChild(w.createButton.call(this,"play-large")),this.elements.controls=i,this.config.controls.includes("settings")&&this.config.settings.includes("speed")&&w.setSpeedMenu.call(this),i},inject:function(){var e=this;if(this.config.loadSprite){var t=w.getIconUrl.call(this);t.absolute&&c.loadSprite(t.url,"sprite-plyr")}this.id=Math.floor(1e4*Math.random());var i=null;i=c.is.string(this.config.controls)?this.config.controls:c.is.function(this.config.controls)?this.config.controls({id:this.id,seektime:this.config.seekTime,title:this.config.title}):w.create.call(this,{id:this.id,seektime:this.config.seekTime,speed:this.speed,quality:this.quality,captions:w.getLanguage.call(this)});var n=void 0;if(c.is.string(this.config.selectors.controls.container)&&(n=document.querySelector(this.config.selectors.controls.container)),c.is.element(n)||(n=this.elements.container),c.is.element(i)?n.appendChild(i):n.insertAdjacentHTML("beforeend",i),c.is.element(this.elements.controls)&&c.findElements.call(this),window.navigator.userAgent.includes("Edge")&&c.repaint(n),this.config.tooltips.controls){var s=c.getElements.call(this,[this.config.selectors.controls.wrapper," ",this.config.selectors.labels," .",this.config.classNames.hidden].join(""));Array.from(s).forEach(function(t){c.toggleClass(t,e.config.classNames.hidden,!1),c.toggleClass(t,e.config.classNames.tooltip,!0),t.setAttribute("role","tooltip")})}}},E={setup:function(){if(this.supported.ui){var e=this.storage.get("language");if(c.is.empty(e)||(this.captions.language=e),c.is.empty(this.captions.language)&&(this.captions.language=this.config.captions.language.toLowerCase()),!c.is.boolean(this.captions.active)){var t=this.storage.get("captions");c.is.boolean(t)?this.captions.active=t:this.captions.active=this.config.captions.active}!this.isVideo||this.isYouTube||this.isHTML5&&!u.textTracks?this.config.controls.includes("settings")&&this.config.settings.includes("captions")&&w.setCaptionsMenu.call(this):(c.is.element(this.elements.captions)||(this.elements.captions=c.createElement("div",c.getAttributesFromSelector(this.config.selectors.captions)),c.insertAfter(this.elements.captions,this.elements.wrapper)),c.toggleClass(this.elements.container,this.config.classNames.captions.enabled,!c.is.empty(E.getTracks.call(this))),c.is.empty(E.getTracks.call(this))||(E.setLanguage.call(this),E.show.call(this),this.config.controls.includes("settings")&&this.config.settings.includes("captions")&&w.setCaptionsMenu.call(this)))}},setLanguage:function(){var e=this;if(this.isHTML5&&this.isVideo){E.getTracks.call(this).forEach(function(t){c.on(t,"cuechange",function(t){return E.setCue.call(e,t)}),t.mode="hidden"});var t=E.getCurrentTrack.call(this);c.is.track(t)&&Array.from(t.activeCues||[]).length&&E.setCue.call(this,t)}else this.isVimeo&&this.captions.active&&this.embed.enableTextTrack(this.language)},getTracks:function(){return c.is.nullOrUndefined(this.media)?[]:Array.from(this.media.textTracks||[]).filter(function(e){return["captions","subtitles"].includes(e.kind)})},getCurrentTrack:function(){var e=this;return E.getTracks.call(this).find(function(t){return t.language.toLowerCase()===e.language})},setCue:function(e){var t=c.is.event(e)?e.target:e,i=t.activeCues[0];t===E.getCurrentTrack.call(this)&&(c.is.cue(i)?E.setText.call(this,i.getCueAsHTML()):E.setText.call(this,null),c.dispatchEvent.call(this,this.media,"cuechange"))},setText:function(e){if(this.supported.ui)if(c.is.element(this.elements.captions)){var t=c.createElement("span");c.emptyElement(this.elements.captions);var i=c.is.nullOrUndefined(e)?"":e;c.is.string(i)?t.textContent=i.trim():t.appendChild(i),this.elements.captions.appendChild(t)}else this.debug.warn("No captions element to render to")},show:function(){if(c.is.element(this.elements.buttons.captions)){var e=this.storage.get("captions");c.is.boolean(e)?this.captions.active=e:e=this.config.captions.active,e&&(c.toggleClass(this.elements.container,this.config.classNames.captions.active,!0),c.toggleState(this.elements.buttons.captions,!0))}}},T={setup:function(){var e=this;c.toggleClass(this.elements.wrapper,this.config.classNames.embed,!0),T.setAspectRatio.call(this),c.is.object(window.YT)&&c.is.function(window.YT.Player)?T.ready.call(this):(c.loadScript(this.config.urls.youtube.api),window.onYouTubeReadyCallbacks=window.onYouTubeReadyCallbacks||[],window.onYouTubeReadyCallbacks.push(function(){T.ready.call(e)}),window.onYouTubeIframeAPIReady=function(){window.onYouTubeReadyCallbacks.forEach(function(e){e()})})},getTitle:function(e){var t=this;if(c.is.function(this.embed.getVideoData)){var i=this.embed.getVideoData().title;if(c.is.empty(i))return this.config.title=i,void b.setTitle.call(this)}var n=this.config.keys.google;if(c.is.string(n)&&!c.is.empty(n)){var s="https://www.googleapis.com/youtube/v3/videos?id="+e+"&key="+n+"&fields=items(snippet(title))&part=snippet";c.fetch(s).then(function(e){c.is.object(e)&&(t.config.title=e.items[0].snippet.title,b.setTitle.call(t))}).catch(function(){})}},setAspectRatio:function(){var e=this.config.ratio.split(":");this.elements.wrapper.style.paddingBottom=100/e[0]*e[1]+"%"},ready:function(){var e=this,t=e.media.getAttribute("id");if(c.is.empty(t)||!t.startsWith("youtube-")){var i=e.media.getAttribute("src");c.is.empty(i)&&(i=e.media.getAttribute(this.config.attributes.embed.id));var n=c.parseYouTubeId(i),s=c.generateId(e.provider),a=c.createElement("div",{id:s});e.media=c.replaceElement(a,e.media),e.embed=new window.YT.Player(s,{videoId:n,playerVars:{autoplay:e.config.autoplay?1:0,controls:e.supported.ui?0:1,rel:0,showinfo:0,iv_load_policy:3,modestbranding:1,disablekb:1,playsinline:1,widget_referrer:window?window.location.href:null,cc_load_policy:e.captions.active?1:0,cc_lang_pref:e.config.captions.language},events:{onError:function(t){if(!c.is.object(e.media.error)){var i={code:t.data};switch(t.data){case 2:i.message="The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.";break;case 5:i.message="The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.";break;case 100:i.message="The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.";break;case 101:case 150:i.message="The owner of the requested video does not allow it to be played in embedded players.";break;default:i.message="An unknown error occured"}e.media.error=i,c.dispatchEvent.call(e,e.media,"error")}},onPlaybackQualityChange:function(t){var i=t.target;e.media.quality=i.getPlaybackQuality(),c.dispatchEvent.call(e,e.media,"qualitychange")},onPlaybackRateChange:function(t){var i=t.target;e.media.playbackRate=i.getPlaybackRate(),c.dispatchEvent.call(e,e.media,"ratechange")},onReady:function(t){var i=t.target;T.getTitle.call(e,n),e.media.play=function(){i.playVideo(),e.media.paused=!1},e.media.pause=function(){i.pauseVideo(),e.media.paused=!0},e.media.stop=function(){i.stopVideo(),e.media.paused=!0},e.media.duration=i.getDuration(),e.media.paused=!0,e.media.currentTime=0,Object.defineProperty(e.media,"currentTime",{get:function(){return Number(i.getCurrentTime())},set:function(t){e.media.seeking=!0,c.dispatchEvent.call(e,e.media,"seeking"),i.seekTo(t)}}),Object.defineProperty(e.media,"playbackRate",{get:function(){return i.getPlaybackRate()},set:function(e){i.setPlaybackRate(e)}}),Object.defineProperty(e.media,"quality",{get:function(){return i.getPlaybackQuality()},set:function(t){c.dispatchEvent.call(e,e.media,"qualityrequested",!1,{quality:t}),i.setPlaybackQuality(t)}});var s=e.config.volume;Object.defineProperty(e.media,"volume",{get:function(){return s},set:function(t){s=t,i.setVolume(100*s),c.dispatchEvent.call(e,e.media,"volumechange")}});var a=e.config.muted;Object.defineProperty(e.media,"muted",{get:function(){return a},set:function(t){var n=c.is.boolean(t)?t:a;a=n,i[n?"mute":"unMute"](),c.dispatchEvent.call(e,e.media,"volumechange")}}),Object.defineProperty(e.media,"currentSrc",{get:function(){return i.getVideoUrl()}}),Object.defineProperty(e.media,"ended",{get:function(){return e.currentTime===e.duration}}),e.options.speed=i.getAvailablePlaybackRates(),e.supported.ui&&e.media.setAttribute("tabindex",-1),c.dispatchEvent.call(e,e.media,"timeupdate"),c.dispatchEvent.call(e,e.media,"durationchange"),window.clearInterval(e.timers.buffering),e.timers.buffering=window.setInterval(function(){e.media.buffered=i.getVideoLoadedFraction(),(null===e.media.lastBuffered||e.media.lastBuffered1&&void 0!==arguments[1]&&arguments[1],n=function(){document.body.style.overflow="",t.embed=null,i?(Object.keys(t.elements).length&&(t.elements.buttons&&t.elements.buttons.play&&Array.from(t.elements.buttons.play).forEach(function(e){return c.removeElement(e)}),c.removeElement(t.elements.captions),c.removeElement(t.elements.controls),c.removeElement(t.elements.wrapper),t.elements.buttons.play=null,t.elements.captions=null,t.elements.controls=null,t.elements.wrapper=null),c.is.function(e)&&e()):(c.replaceElement(t.elements.original,t.elements.container),c.dispatchEvent.call(t,t.elements.original,"destroyed",!0),c.is.function(e)&&e.call(t.elements.original),t.elements=null)};switch(this.provider+":"+this.type){case"html5:video":case"html5:audio":b.toggleNativeControls.call(this,!0),n();break;case"youtube:video":window.clearInterval(this.timers.buffering),window.clearInterval(this.timers.playing),null!==this.embed&&this.embed.destroy(),n();break;case"vimeo:video":null!==this.embed&&this.embed.unload().then(n),window.setTimeout(n,200)}}},{key:"supports",value:function(e){return u.mime.call(this,e)}},{key:"isHTML5",get:function(){return this.provider===i.html5}},{key:"isEmbed",get:function(){return this.isYouTube||this.isVimeo}},{key:"isYouTube",get:function(){return this.provider===i.youtube}},{key:"isVimeo",get:function(){return this.provider===i.vimeo}},{key:"isVideo",get:function(){return this.type===n.video}},{key:"isAudio",get:function(){return this.type===n.audio}},{key:"paused",get:function(){return this.media.paused}},{key:"playing",get:function(){return!this.paused&&!this.ended&&(!this.isHTML5||this.media.readyState>2)}},{key:"ended",get:function(){return this.media.ended}},{key:"currentTime",set:function(e){var t=0;c.is.number(e)&&(t=e),t<0?t=0:t>this.duration&&(t=this.duration),this.media.currentTime=t.toFixed(4),this.debug.log("Seeking to "+this.currentTime+" seconds")},get:function(){return Number(this.media.currentTime)}},{key:"seeking",get:function(){return this.media.seeking}},{key:"duration",get:function(){var e=parseInt(this.config.duration,10),t=Number(this.media.duration);return Number.isNaN(e)?t:e}},{key:"volume",set:function(e){var t=e;c.is.string(t)&&(t=Number(t)),c.is.number(t)||(t=this.storage.get("volume")),c.is.number(t)||(t=this.config.volume),t>1&&(t=1),t<0&&(t=0),this.config.volume=t,this.media.volume=t,this.muted&&t>0&&(this.muted=!1)},get:function(){return this.media.volume}},{key:"muted",set:function(e){var t=e;c.is.boolean(t)||(t=this.storage.get("muted")),c.is.boolean(t)||(t=this.config.muted),this.config.muted=t,this.media.muted=t},get:function(){return this.media.muted}},{key:"hasAudio",get:function(){return!this.isHTML5||(!!this.isAudio||(this.media.mozHasAudio||Boolean(this.media.webkitAudioDecodedByteCount)||Boolean(this.media.audioTracks&&this.media.audioTracks.length)))}},{key:"speed",set:function(e){var t=null;c.is.number(e)&&(t=e),c.is.number(t)||(t=this.storage.get("speed")),c.is.number(t)||(t=this.config.speed.selected),t<.1&&(t=.1),t>2&&(t=2),this.config.speed.options.includes(t)?(this.config.speed.selected=t,this.media.playbackRate=t):this.debug.warn("Unsupported speed ("+t+")")},get:function(){return this.media.playbackRate}},{key:"quality",set:function(e){var t=null;c.is.string(e)&&(t=e),c.is.string(t)||(t=this.storage.get("quality")),c.is.string(t)||(t=this.config.quality.selected),this.options.quality.includes(t)?(this.config.quality.selected=t,this.media.quality=t):this.debug.warn("Unsupported quality option ("+t+")")},get:function(){return this.media.quality}},{key:"loop",set:function(e){var t=c.is.boolean(e)?e:this.config.loop.active;this.config.loop.active=t,this.media.loop=t},get:function(){return this.media.loop}},{key:"source",set:function(e){N.change.call(this,e)},get:function(){return this.media.currentSrc}},{key:"poster",set:function(e){this.isHTML5&&this.isVideo?c.is.string(e)&&this.media.setAttribute("poster",e):this.debug.warn("Poster can only be set on HTML5 video")},get:function(){return this.isHTML5&&this.isVideo?this.media.getAttribute("poster"):null}},{key:"autoplay",set:function(e){var t=c.is.boolean(e)?e:this.config.autoplay;this.config.autoplay=t},get:function(){return this.config.autoplay}},{key:"language",set:function(e){if(c.is.string(e)&&(this.toggleCaptions(!c.is.empty(e)),!c.is.empty(e))){var t=e.toLowerCase();this.language!==t&&(this.captions.language=t,E.setText.call(this,null),E.setLanguage.call(this),c.dispatchEvent.call(this,this.media,"languagechange"))}},get:function(){return this.captions.language}},{key:"pip",set:function(e){var t="picture-in-picture",i="inline";if(u.pip){var n=c.is.boolean(e)?e:this.pip===i;this.media.webkitSetPresentationMode(n?t:i)}},get:function(){return u.pip?this.media.webkitPresentationMode:null}}],[{key:"supported",value:function(e,t,i){return u.check(e,t,i)}},{key:"loadSprite",value:function(e,t){return c.loadSprite(e,t)}}]),e}()}); //# sourceMappingURL=plyr.js.map diff --git a/dist/plyr.js.map b/dist/plyr.js.map index 6743574c..20b7e8d8 100644 --- a/dist/plyr.js.map +++ b/dist/plyr.js.map @@ -1 +1 @@ -{"version":3,"sources":["src/js/types.js","src/js/support.js","src/js/fullscreen.js","src/js/defaults.js","src/js/utils.js","src/js/console.js","src/js/storage.js","src/js/plugins/ads.js","src/js/listeners.js","src/js/ui.js","src/js/controls.js","src/js/captions.js","src/js/plugins/youtube.js","src/js/plugins/vimeo.js","src/js/media.js","src/js/source.js","src/js/plyr.js"],"names":["range","value","providers","types","defaults","window","navigator","language","split","utils","input","this","instanceof","Plyr","getConstructor","Object","Number","isNaN","String","Boolean","Function","nullOrUndefined","Array","isArray","WeakMap","NodeList","Element","Text","Event","TextTrackCue","VTTCue","TextTrack","string","kind","test","array","nodeList","length","object","keys","constructor","document","documentMode","documentElement","style","userAgent","platform","url","Promise","resolve","reject","request","XMLHttpRequest","addEventListener","JSON","parse","responseText","e","Error","statusText","open","send","callback","error","current","querySelector","callbacks","push","element","createElement","errors","is","function","forEach","cb","call","event","err","src","first","getElementsByTagName","parentNode","insertBefore","id","hasId","querySelectorAll","container","toggleHidden","setAttribute","support","storage","cached","localStorage","getItem","data","content","fetch","then","empty","result","setItem","stringify","catch","updateSprite","innerHTML","body","childNodes","prefix","Math","floor","random","self","top","elements","wrapper","targets","from","reverse","index","child","cloneNode","parent","sibling","nextSibling","appendChild","type","attributes","text","setAttributes","textContent","target","removeChild","lastChild","newChild","oldChild","replaceChild","key","sel","existingAttributes","existing","selector","s","trim","className","replace","parts","charAt","class","toggle","contains","classList","removeAttribute","prototype","matches","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","includes","controls","getElement","config","selectors","buttons","getElements","play","pause","restart","rewind","forward","mute","pip","airplay","settings","captions","fullscreen","progress","inputs","seek","volume","display","buffer","duration","currentTime","seekTooltip","classNames","tooltip","debug","warn","toggleNativeControls","focused","activeElement","focusable","last","on","keyCode","_this","active","getFocusElement","shiftKey","focus","preventDefault","passive","capture","Node","toggleListener","events","options","boolean","passiveListeners","bubbles","detail","CustomEvent","assign","plyr","dispatchEvent","pressed","getAttribute","state","max","toFixed","parseInt","time","displayHours","inverted","number","formatTime","format","slice","hours","getHours","mins","getMinutes","secs","getSeconds","sources","source","shift","extend","youtube","vimeo","match","RegExp","$2","parser","href","search","startsWith","parseUrl","indexOf","reduce","params","hash","val","decodeURIComponent","map","encodeURIComponent","join","fragment","createDocumentFragment","firstChild","innerText","width","height","ratio","getRatio","w","h","find","undefined","setTimeout","offsetHeight","provider","inline","api","ui","browser","getBrowser","playsInline","isIPhone","video","rangeInput","audio","webkitSetPresentationMode","WebKitPlaybackTargetAvailabilityEvent","media","isHTML5","canPlayType","isVideo","isAudio","supported","defineProperty","transitionEndEvent","matchMedia","noop","Console","enabled","console","log","bind","Storage","player","store","json","get","removeItem","Ads","ads","playing","initialized","blocked","tag","google","ready","loadScript","urls","googleIMA","manager","loader","cuePoints","safetyTimer","countdownTimer","listeners","startSafetyTimer","loaderPromise","managerPromise","clearSafetyTimer","setupIMA","ima","setVpaidMode","ImaSdkSettings","VpaidMode","ENABLED","setLocale","displayContainer","AdDisplayContainer","requestAds","AdsLoader","AdsManagerLoadedEvent","Type","ADS_MANAGER_LOADED","_this3","onAdsManagerLoaded","AdErrorEvent","AD_ERROR","onAdError","AdsRequest","adTagUrl","base","buildUrlParams","linearAdSlotWidth","offsetWidth","linearAdSlotHeight","nonLinearAdSlotWidth","nonLinearAdSlotHeight","forceNonLinearFullSlot","handleEventListeners","clearInterval","setInterval","_this4","getRemainingTime","label","i18n","advertisment","adsManagerLoadedEvent","AdsRenderingSettings","restoreCustomPlaybackStateOnAdBreakComplete","enablePreloading","getAdsManager","getCuePoints","cuePoint","seekElement","_this5","cuePercentage","cue","cues","left","toString","setVolume","AdEvent","onAdEvent","ad","getAd","_this6","LOADED","pollCountdown","isLinear","ALL_ADS_COMPLETED","loadAds","CONTENT_PAUSE_REQUESTED","pauseContent","CONTENT_RESUME_REQUESTED","resumeContent","STARTED","MIDPOINT","COMPLETE","IMPRESSION","CLICK","cancel","contentComplete","_this7","seekedTime","discardAdBreak","splice","resize","ViewMode","NORMAL","initialize","_this8","init","start","adError","_this9","destroy","cancelFullScreen","some","pre","msExitFullscreen","msFullscreenEnabled","fullscreenEnabled","webkitFullscreenEnabled","mozFullScreenEnabled","fullscreenElement","mozFullScreenElement","requestFullScreen","nativeSupport","fallback","inFrame","toggleClass","toggleState","trapFocus","handleKey","code","which","getKeyCode","repeat","altKey","ctrlKey","metaKey","editable","stopPropagation","togglePlay","increaseVolume","decreaseVolume","muted","toggleFullscreen","toggleCaptions","loop","keyboard","global","tabFocus","hideControls","toggleControls","eventType","timeUpdate","durationUpdate","_this2","hasAudio","showPosterOnEnd","load","updateProgress","updateVolume","checkPlaying","checkLoading","clickToPlay","touch","paused","ended","disableContextMenu","set","updateSetting","speed","quality","concat","inputEvent","isIE","proxy","handlerKey","defaultHandler","customHandler","defaultPrevented","toggleMenu","form","parseFloat","showTab","toggleInvert","invertTime","isWebkit","updateRangeFill","updateSeekTooltip","hover","webkitDirectionInvertedFromDevice","direction","deltaY","deltaX","uiSupported","removeElement","inject","setup","setTitle","title","isEmbed","iframe","frameTitle","stopped","button","loading","timers","failed","networkState","setRange","nodeValue","buffered","getPercentage","end","setProgress","invert","updateTimeDisplay","seeking","hasDuration","displayDuration","setProperty","iconUrl","svg4everybody","getIconUrl","iconPath","absolute","iconPrefix","icon","createElementNS","use","path","setAttributeNS","attr","hidden","badge","menu","buttonType","labelPressed","iconPressed","control","createIcon","createLabel","getAttributesFromSelector","suffix","played","toLowerCase","list","checked","item","radio","faux","aria-hidden","insertAdjacentHTML","tooltips","percent","clientRect","getBoundingClientRect","visible","pageX","hasClass","setting","tab","tabs","pane","panes","filter","isYouTube","toggleTab","emptyElement","createMenuItem","getLabel","createBadge","getBadge","getLanguage","default","textTracks","getTracks","none","currentTrack","getCurrentTrack","track","disabled","hasTracks","tracks","toUpperCase","unshift","show","isMenuItem","isButton","clone","position","opacity","name","scrollWidth","scrollHeight","getElementById","transitions","reducedMotion","size","getTabSize","restore","propertyName","off","createButton","createRange","createProgress","createTime","inner","home","back","setSpeedMenu","loadSprite","seekTime","create","findElements","repaint","labels","stored","setCaptionsMenu","insertAfter","setLanguage","setCue","mode","activeCues","isVimeo","embed","enableTextTrack","setText","getCueAsHTML","caption","setAspectRatio","YT","Player","onYouTubeReadyCallbacks","onYouTubeIframeAPIReady","videoId","getVideoData","items","snippet","paddingBottom","currentId","parseYouTubeId","generateId","replaceElement","autoplay","location","message","instance","getPlaybackQuality","playbackRate","getPlaybackRate","getTitle","playVideo","pauseVideo","stop","stopVideo","getDuration","getCurrentTime","seekTo","setPlaybackRate","setPlaybackQuality","getVideoUrl","getAvailablePlaybackRates","buffering","getVideoLoadedFraction","lastBuffered","build","setQualityMenu","getAvailableQualityLevels","Vimeo","padding","offset","transform","parseVimeoId","setCurrentTime","selected","setLoop","currentSrc","all","getVideoWidth","getVideoHeight","getAspectRatio","dimensions","setAutopause","autopause","getVideoTitle","getTextTracks","stripHTML","seconds","isIos","isTouch","wrap","blankVideo","insertElement","attribute","cancelRequests","html5","check","crossorigin","poster","addStyleHook","insertElements","scrollPosition","jQuery","original","tagName","getProviderByUrl","getUrlParams","truthy","playsinline","hasAttribute","step","isFullScreen","pageXOffset","pageYOffset","scrollTo","x","y","overflow","webkitShowPlaybackTargetPicker","delay","isEnterFullscreen","noTransition","clearTimeout","soft","done","unload","mime","readyState","targetTime","fauxDuration","realDuration","mozHasAudio","webkitAudioDecodedByteCount","audioTracks","change","states","webkitPresentationMode"],"mappings":"uLAIA,IC2IcA,ECvINC,EFJKC,SACF,gBACE,gBACF,SAGEC,SACF,cACA,SGRLC,YAEO,QAGF,UAGA,YAGG,aAGC,WAGD,UAGF,SACD,WAGG,sBAIO,cAGL,gBAGE,QAGP,oBAGM,gBAGC,mBAGG,sBAGG,cAGR,aACA,eACH,wDAGG,wDAIC,mBAEL,SACA,SACA,SACA,QACA,QACA,SACA,QACA,OACA,0BAMI,mBAOE,WAEN,GACA,IACA,EACA,KACA,IACA,KACA,uBAMK,UACD,uBAKE,QACJ,qBAKE,WACEC,OAAOC,UAAUC,SAASC,MAAM,KAAK,yBAKtC,YACC,qBAKD,MACJ,kBAKL,aACA,OACA,WACA,eACA,OACA,SACA,WACA,WACA,MACA,UACA,wBAGA,WACA,UACA,uBAKS,iBACD,8BACF,aACC,gBACE,+BACH,cACE,kBACE,uBACG,wBACH,kBACF,cACF,cACE,wBACQ,kCACC,mCACA,kCACD,6BACJ,8BACF,oBACA,iBACH,gBACE,eACH,aACC,YACF,UACA,YACE,aACD,gBACI,wBACI,uBAML,uDAGA,qDAGA,uEAMH,UACA,WACC,aACE,YACD,aACC,UACH,YACE,cACE,gBACE,SACP,aACI,WACF,aACE,UACH,cACI,sBAQV,WACA,UACA,UACA,UACA,UACA,iBACA,YACA,aACA,iBACA,aACA,eACA,OACA,QACA,QACA,UACA,SACA,UACA,aACA,8BAIA,iBACA,kBACA,mBACA,iBACA,iBACA,gBACA,sBAIA,gBACA,+BAIA,kBACA,kBACA,YACA,cACA,cACA,iBACA,gBACA,gCAMU,uDACC,4BAEI,aACF,0BAEL,4BAEE,2BACC,8BACE,+BACD,+BACC,kCACH,8BACI,oCACE,+BACP,4BACI,iCACC,8BACJ,mCAGA,4BACE,6BACD,+BACG,iCACD,8CAGI,gCACH,+BACF,iCACA,+BACF,+BACE,mCAEF,2BACA,gCAEG,oDAMN,4BACA,wBACF,oBACI,qBACH,qBACI,oBACD,wBACA,wBACA,sBACF,wBACA,sBACE,qBACH,oBACE,6BACM,4BACP,uBACE,6BACI,6BACC,k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","file":"plyr.js","sourcesContent":["// ==========================================================================\n// Plyr supported types and providers\n// ==========================================================================\n\nexport const providers = {\n html5: 'html5',\n youtube: 'youtube',\n vimeo: 'vimeo',\n};\n\nexport const types = {\n audio: 'audio',\n video: 'video',\n};\n\nexport default { providers, types };\n","// ==========================================================================\n// Plyr support checks\n// ==========================================================================\n\nimport utils from './utils';\n\n// Check for feature support\nconst support = {\n // Basic support\n audio: 'canPlayType' in document.createElement('audio'),\n video: 'canPlayType' in document.createElement('video'),\n\n // Check for support\n // Basic functionality vs full UI\n check(type, provider, inline) {\n let api = false;\n let ui = false;\n const browser = utils.getBrowser();\n const playsInline = browser.isIPhone && inline && support.inline;\n\n switch (`${provider}:${type}`) {\n case 'html5:video':\n api = support.video;\n ui = api && support.rangeInput && (!browser.isIPhone || playsInline);\n break;\n\n case 'html5:audio':\n api = support.audio;\n ui = api && support.rangeInput;\n break;\n\n case 'youtube:video':\n api = true;\n ui = support.rangeInput && (!browser.isIPhone || playsInline);\n break;\n\n case 'vimeo:video':\n api = true;\n ui = support.rangeInput && !browser.isIPhone;\n break;\n\n default:\n api = support.audio && support.video;\n ui = api && support.rangeInput;\n }\n\n return {\n api,\n ui,\n };\n },\n\n // Picture-in-picture support\n // Safari only currently\n pip: (() => {\n const browser = utils.getBrowser();\n return !browser.isIPhone && utils.is.function(utils.createElement('video').webkitSetPresentationMode);\n })(),\n\n // Airplay support\n // Safari only currently\n airplay: utils.is.function(window.WebKitPlaybackTargetAvailabilityEvent),\n\n // Inline playback support\n // https://webkit.org/blog/6784/new-video-policies-for-ios/\n inline: 'playsInline' in document.createElement('video'),\n\n // Check for mime type support against a player instance\n // Credits: http://diveintohtml5.info/everything.html\n // Related: http://www.leanbackplayer.com/test/h5mt.html\n mime(type) {\n const { media } = this;\n\n try {\n // Bail if no checking function\n if (!this.isHTML5 || !utils.is.function(media.canPlayType)) {\n return false;\n }\n\n // Type specific checks\n if (this.isVideo) {\n switch (type) {\n case 'video/webm':\n return media.canPlayType('video/webm; codecs=\"vp8, vorbis\"').replace(/no/, '');\n\n case 'video/mp4':\n return media.canPlayType('video/mp4; codecs=\"avc1.42E01E, mp4a.40.2\"').replace(/no/, '');\n\n case 'video/ogg':\n return media.canPlayType('video/ogg; codecs=\"theora\"').replace(/no/, '');\n\n default:\n return false;\n }\n } else if (this.isAudio) {\n switch (type) {\n case 'audio/mpeg':\n return media.canPlayType('audio/mpeg;').replace(/no/, '');\n\n case 'audio/ogg':\n return media.canPlayType('audio/ogg; codecs=\"vorbis\"').replace(/no/, '');\n\n case 'audio/wav':\n return media.canPlayType('audio/wav; codecs=\"1\"').replace(/no/, '');\n\n default:\n return false;\n }\n }\n } catch (e) {\n return false;\n }\n\n // If we got this far, we're stuffed\n return false;\n },\n\n // Check for textTracks support\n textTracks: 'textTracks' in document.createElement('video'),\n\n // Check for passive event listener support\n // https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md\n // https://www.youtube.com/watch?v=NPM6172J22g\n passiveListeners: (() => {\n // Test via a getter in the options object to see if the passive property is accessed\n let supported = false;\n try {\n const options = Object.defineProperty({}, 'passive', {\n get() {\n supported = true;\n return null;\n },\n });\n window.addEventListener('test', null, options);\n } catch (e) {\n // Do nothing\n }\n\n return supported;\n })(),\n\n // Sliders\n rangeInput: (() => {\n const range = document.createElement('input');\n range.type = 'range';\n return range.type === 'range';\n })(),\n\n // Touch\n // Remember a device can be moust + touch enabled\n touch: 'ontouchstart' in document.documentElement,\n\n // Detect transitions support\n transitions: utils.transitionEndEvent !== false,\n\n // Reduced motion iOS & MacOS setting\n // https://webkit.org/blog/7551/responsive-design-for-motion/\n reducedMotion: 'matchMedia' in window && window.matchMedia('(prefers-reduced-motion)').matches,\n};\n\nexport default support;\n","// ==========================================================================\n// Plyr fullscreen API\n// ==========================================================================\n\nimport utils from './utils';\n\n// Determine the prefix\nconst prefix = (() => {\n let value = false;\n\n if (utils.is.function(document.cancelFullScreen)) {\n value = '';\n } else {\n // Check for fullscreen support by vendor prefix\n [\n 'webkit',\n 'o',\n 'moz',\n 'ms',\n 'khtml',\n ].some(pre => {\n if (utils.is.function(document[`${pre}CancelFullScreen`])) {\n value = pre;\n return true;\n } else if (utils.is.function(document.msExitFullscreen) && document.msFullscreenEnabled) {\n // Special case for MS (when isn't it?)\n value = 'ms';\n return true;\n }\n\n return false;\n });\n }\n\n return value;\n})();\n\n// Fullscreen API\nconst fullscreen = {\n // Get the prefix\n prefix,\n\n // Check if we can use it\n enabled: document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled,\n\n // Yet again Microsoft awesomeness,\n // Sometimes the prefix is 'ms', sometimes 'MS' to keep you on your toes\n eventType: prefix === 'ms' ? 'MSFullscreenChange' : `${prefix}fullscreenchange`,\n\n // Is an element fullscreen\n isFullScreen(element) {\n if (!fullscreen.enabled) {\n return false;\n }\n\n const target = utils.is.nullOrUndefined(element) ? document.body : element;\n\n switch (prefix) {\n case '':\n return document.fullscreenElement === target;\n\n case 'moz':\n return document.mozFullScreenElement === target;\n\n default:\n return document[`${prefix}FullscreenElement`] === target;\n }\n },\n\n // Make an element fullscreen\n requestFullScreen(element) {\n if (!fullscreen.enabled) {\n return false;\n }\n\n const target = utils.is.nullOrUndefined(element) ? document.body : element;\n\n return !prefix.length ? target.requestFullScreen() : target[prefix + (prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')]();\n },\n\n // Bail from fullscreen\n cancelFullScreen() {\n if (!fullscreen.enabled) {\n return false;\n }\n\n return !prefix.length ? document.cancelFullScreen() : document[prefix + (prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen')]();\n },\n\n // Get the current element\n element() {\n if (!fullscreen.enabled) {\n return null;\n }\n\n return !prefix.length ? document.fullscreenElement : document[`${prefix}FullscreenElement`];\n },\n\n // Setup fullscreen\n setup() {\n if (!this.supported.ui || this.isAudio || !this.config.fullscreen.enabled) {\n return;\n }\n\n // Check for native support\n const nativeSupport = fullscreen.enabled;\n\n if (nativeSupport || (this.config.fullscreen.fallback && !utils.inFrame())) {\n this.debug.log(`${nativeSupport ? 'Native' : 'Fallback'} fullscreen enabled`);\n\n // Add styling hook to show button\n utils.toggleClass(this.elements.container, this.config.classNames.fullscreen.enabled, true);\n } else {\n this.debug.log('Fullscreen not supported and fallback disabled');\n }\n\n // Toggle state\n if (this.elements.buttons && this.elements.buttons.fullscreen) {\n utils.toggleState(this.elements.buttons.fullscreen, false);\n }\n\n // Trap focus in container\n utils.trapFocus.call(this);\n },\n};\n\nexport default fullscreen;\n","// ==========================================================================\n// Plyr default config\n// ==========================================================================\n\nconst defaults = {\n // Disable\n enabled: true,\n\n // Custom media title\n title: '',\n\n // Logging to console\n debug: false,\n\n // Auto play (if supported)\n autoplay: false,\n\n // Only allow one media playing at once (vimeo only)\n autopause: true,\n\n // Default time to skip when rewind/fast forward\n seekTime: 10,\n\n // Default volume\n volume: 1,\n muted: false,\n\n // Pass a custom duration\n duration: null,\n\n // Display the media duration on load in the current time position\n // If you have opted to display both duration and currentTime, this is ignored\n displayDuration: true,\n\n // Invert the current time to be a countdown\n invertTime: true,\n\n // Clicking the currentTime inverts it's value to show time left rather than elapsed\n toggleInvert: true,\n\n // Aspect ratio (for embeds)\n ratio: '16:9',\n\n // Click video container to play/pause\n clickToPlay: true,\n\n // Auto hide the controls\n hideControls: true,\n\n // Revert to poster on finish (HTML5 - will cause reload)\n showPosterOnEnd: false,\n\n // Disable the standard context menu\n disableContextMenu: true,\n\n // Sprite (for icons)\n loadSprite: true,\n iconPrefix: 'plyr',\n iconUrl: 'https://cdn.plyr.io/3.0.0-beta.11/plyr.svg',\n\n // Blank video (used to prevent errors on source change)\n blankVideo: 'https://cdn.plyr.io/static/blank.mp4',\n\n // Quality default\n quality: {\n default: 'default',\n options: [\n 'hd2160',\n 'hd1440',\n 'hd1080',\n 'hd720',\n 'large',\n 'medium',\n 'small',\n 'tiny',\n 'default',\n ],\n },\n\n // Set loops\n loop: {\n active: false,\n // start: null,\n // end: null,\n },\n\n // Speed default and options to display\n speed: {\n selected: 1,\n options: [\n 0.5,\n 0.75,\n 1,\n 1.25,\n 1.5,\n 1.75,\n 2,\n ],\n },\n\n // Keyboard shortcut settings\n keyboard: {\n focused: true,\n global: false,\n },\n\n // Display tooltips\n tooltips: {\n controls: false,\n seek: true,\n },\n\n // Captions settings\n captions: {\n active: false,\n language: window.navigator.language.split('-')[0],\n },\n\n // Fullscreen settings\n fullscreen: {\n enabled: true, // Allow fullscreen?\n fallback: true, // Fallback for vintage browsers\n },\n\n // Local storage\n storage: {\n enabled: true,\n key: 'plyr',\n },\n\n // Default controls\n controls: [\n 'play-large',\n 'play',\n 'progress',\n 'current-time',\n 'mute',\n 'volume',\n 'captions',\n 'settings',\n 'pip',\n 'airplay',\n 'fullscreen',\n ],\n settings: [\n 'captions',\n 'quality',\n 'speed',\n ],\n\n // Localisation\n i18n: {\n restart: 'Restart',\n rewind: 'Rewind {seektime} secs',\n play: 'Play',\n pause: 'Pause',\n forward: 'Forward {seektime} secs',\n seek: 'Seek',\n played: 'Played',\n buffered: 'Buffered',\n currentTime: 'Current time',\n duration: 'Duration',\n volume: 'Volume',\n mute: 'Mute',\n unmute: 'Unmute',\n enableCaptions: 'Enable captions',\n disableCaptions: 'Disable captions',\n enterFullscreen: 'Enter fullscreen',\n exitFullscreen: 'Exit fullscreen',\n frameTitle: 'Player for {title}',\n captions: 'Captions',\n settings: 'Settings',\n speed: 'Speed',\n quality: 'Quality',\n loop: 'Loop',\n start: 'Start',\n end: 'End',\n all: 'All',\n reset: 'Reset',\n none: 'None',\n disabled: 'Disabled',\n advertisment: 'Ad',\n },\n\n // URLs\n urls: {\n vimeo: {\n api: 'https://player.vimeo.com/api/player.js',\n },\n youtube: {\n api: 'https://www.youtube.com/iframe_api',\n },\n googleIMA: {\n api: 'https://imasdk.googleapis.com/js/sdkloader/ima3.js',\n },\n },\n\n // Custom control listeners\n listeners: {\n seek: null,\n play: null,\n pause: null,\n restart: null,\n rewind: null,\n forward: null,\n mute: null,\n volume: null,\n captions: null,\n fullscreen: null,\n pip: null,\n airplay: null,\n speed: null,\n quality: null,\n loop: null,\n language: null,\n },\n\n // Events to watch and bubble\n events: [\n // Events to watch on HTML5 media elements and bubble\n // https://developer.mozilla.org/en/docs/Web/Guide/Events/Media_events\n 'ended',\n 'progress',\n 'stalled',\n 'playing',\n 'waiting',\n 'canplay',\n 'canplaythrough',\n 'loadstart',\n 'loadeddata',\n 'loadedmetadata',\n 'timeupdate',\n 'volumechange',\n 'play',\n 'pause',\n 'error',\n 'seeking',\n 'seeked',\n 'emptied',\n 'ratechange',\n 'cuechange',\n\n // Custom events\n 'enterfullscreen',\n 'exitfullscreen',\n 'captionsenabled',\n 'captionsdisabled',\n 'languagechange',\n 'controlshidden',\n 'controlsshown',\n 'ready',\n\n // YouTube\n 'statechange',\n 'qualitychange',\n 'qualityrequested',\n\n // Ads\n 'adsloaded',\n 'adscontentpause',\n 'adsconentresume',\n 'adstarted',\n 'adsmidpoint',\n 'adscomplete',\n 'adsallcomplete',\n 'adsimpression',\n 'adsclick',\n ],\n\n // Selectors\n // Change these to match your template if using custom HTML\n selectors: {\n editable: 'input, textarea, select, [contenteditable]',\n container: '.plyr',\n controls: {\n container: null,\n wrapper: '.plyr__controls',\n },\n labels: '[data-plyr]',\n buttons: {\n play: '[data-plyr=\"play\"]',\n pause: '[data-plyr=\"pause\"]',\n restart: '[data-plyr=\"restart\"]',\n rewind: '[data-plyr=\"rewind\"]',\n forward: '[data-plyr=\"fast-forward\"]',\n mute: '[data-plyr=\"mute\"]',\n captions: '[data-plyr=\"captions\"]',\n fullscreen: '[data-plyr=\"fullscreen\"]',\n pip: '[data-plyr=\"pip\"]',\n airplay: '[data-plyr=\"airplay\"]',\n settings: '[data-plyr=\"settings\"]',\n loop: '[data-plyr=\"loop\"]',\n },\n inputs: {\n seek: '[data-plyr=\"seek\"]',\n volume: '[data-plyr=\"volume\"]',\n speed: '[data-plyr=\"speed\"]',\n language: '[data-plyr=\"language\"]',\n quality: '[data-plyr=\"quality\"]',\n },\n display: {\n currentTime: '.plyr__time--current',\n duration: '.plyr__time--duration',\n buffer: '.plyr__progress--buffer',\n played: '.plyr__progress--played',\n loop: '.plyr__progress--loop',\n volume: '.plyr__volume--display',\n },\n progress: '.plyr__progress',\n captions: '.plyr__captions',\n menu: {\n quality: '.js-plyr__menu__list--quality',\n },\n },\n\n // Class hooks added to the player in different states\n classNames: {\n video: 'plyr__video-wrapper',\n embed: 'plyr__video-embed',\n ads: 'plyr__ads',\n control: 'plyr__control',\n type: 'plyr--{0}',\n provider: 'plyr--{0}',\n stopped: 'plyr--stopped',\n playing: 'plyr--playing',\n loading: 'plyr--loading',\n error: 'plyr--has-error',\n hover: 'plyr--hover',\n tooltip: 'plyr__tooltip',\n cues: 'plyr__cues',\n hidden: 'plyr__sr-only',\n hideControls: 'plyr--hide-controls',\n isIos: 'plyr--is-ios',\n isTouch: 'plyr--is-touch',\n uiSupported: 'plyr--full-ui',\n noTransition: 'plyr--no-transition',\n menu: {\n value: 'plyr__menu__value',\n badge: 'plyr__badge',\n open: 'plyr--menu-open',\n },\n captions: {\n enabled: 'plyr--captions-enabled',\n active: 'plyr--captions-active',\n },\n fullscreen: {\n enabled: 'plyr--fullscreen-enabled',\n fallback: 'plyr--fullscreen-fallback',\n },\n pip: {\n supported: 'plyr--pip-supported',\n active: 'plyr--pip-active',\n },\n airplay: {\n supported: 'plyr--airplay-supported',\n active: 'plyr--airplay-active',\n },\n tabFocus: 'plyr__tab-focus',\n },\n\n // API keys\n keys: {\n google: null,\n },\n\n // Advertisements plugin\n // Tag is not required as publisher is determined by vi.ai using the domain\n ads: {\n enabled: false,\n },\n};\n\nexport default defaults;\n","// ==========================================================================\n// Plyr utils\n// ==========================================================================\n\nimport support from './support';\nimport { providers } from './types';\n\nconst utils = {\n // Check variable types\n is: {\n plyr(input) {\n return this.instanceof(input, window.Plyr);\n },\n object(input) {\n return this.getConstructor(input) === Object;\n },\n number(input) {\n return this.getConstructor(input) === Number && !Number.isNaN(input);\n },\n string(input) {\n return this.getConstructor(input) === String;\n },\n boolean(input) {\n return this.getConstructor(input) === Boolean;\n },\n function(input) {\n return this.getConstructor(input) === Function;\n },\n array(input) {\n return !this.nullOrUndefined(input) && Array.isArray(input);\n },\n weakMap(input) {\n return this.instanceof(input, window.WeakMap);\n },\n nodeList(input) {\n return this.instanceof(input, window.NodeList);\n },\n element(input) {\n return this.instanceof(input, window.Element);\n },\n textNode(input) {\n return this.getConstructor(input) === Text;\n },\n event(input) {\n return this.instanceof(input, window.Event);\n },\n cue(input) {\n return this.instanceof(input, window.TextTrackCue) || this.instanceof(input, window.VTTCue);\n },\n track(input) {\n return this.instanceof(input, TextTrack) || (!this.nullOrUndefined(input) && this.string(input.kind));\n },\n url(input) {\n return !this.nullOrUndefined(input) && /(ftp|http|https):\\/\\/(\\w+:{0,1}\\w*@)?(\\S+)(:[0-9]+)?(\\/|\\/([\\w#!:.?+=&%@!\\-/]))?/.test(input);\n },\n nullOrUndefined(input) {\n return input === null || typeof input === 'undefined';\n },\n empty(input) {\n return (\n this.nullOrUndefined(input) ||\n ((this.string(input) || this.array(input) || this.nodeList(input)) && !input.length) ||\n (this.object(input) && !Object.keys(input).length)\n );\n },\n instanceof(input, constructor) {\n return Boolean(input && constructor && input instanceof constructor);\n },\n getConstructor(input) {\n return !this.nullOrUndefined(input) ? input.constructor : null;\n },\n },\n\n // Unfortunately, due to mixed support, UA sniffing is required\n getBrowser() {\n return {\n isIE: /* @cc_on!@ */ false || !!document.documentMode,\n isWebkit: 'WebkitAppearance' in document.documentElement.style && !/Edge/.test(navigator.userAgent),\n isIPhone: /(iPhone|iPod)/gi.test(navigator.platform),\n isIos: /(iPad|iPhone|iPod)/gi.test(navigator.platform),\n };\n },\n\n // Fetch wrapper\n // Using XHR to avoid issues with older browsers\n fetch(url) {\n return new Promise((resolve, reject) => {\n try {\n const request = new XMLHttpRequest();\n\n // Check for CORS support\n if (!('withCredentials' in request)) {\n return;\n }\n\n request.addEventListener('load', () => {\n try {\n resolve(JSON.parse(request.responseText));\n } catch(e) {\n resolve(request.responseText);\n }\n });\n\n request.addEventListener('error', () => {\n throw new Error(request.statusText);\n });\n\n request.open('GET', url, true);\n request.send();\n } catch (e) {\n reject(e);\n }\n });\n },\n\n // Load an external script\n loadScript(url, callback, error) {\n const current = document.querySelector(`script[src=\"${url}\"]`);\n\n // Check script is not already referenced, if so wait for load\n if (current !== null) {\n current.callbacks = current.callbacks || [];\n current.callbacks.push(callback);\n return;\n }\n\n // Build the element\n const element = document.createElement('script');\n\n // Callback queue\n element.callbacks = element.callbacks || [];\n element.callbacks.push(callback);\n\n // Error queue\n element.errors = element.errors || [];\n element.errors.push(error);\n\n // Bind callback\n if (utils.is.function(callback)) {\n element.addEventListener(\n 'load',\n event => {\n element.callbacks.forEach(cb => cb.call(null, event));\n element.callbacks = null;\n },\n false,\n );\n }\n\n // Bind error handling\n element.addEventListener(\n 'error',\n event => {\n element.errors.forEach(err => err.call(null, event));\n element.errors = null;\n },\n false,\n );\n\n // Set the URL after binding callback\n element.src = url;\n\n // Inject\n const first = document.getElementsByTagName('script')[0];\n first.parentNode.insertBefore(element, first);\n },\n\n // Load an external SVG sprite\n loadSprite(url, id) {\n if (!utils.is.string(url)) {\n return;\n }\n\n const prefix = 'cache-';\n const hasId = utils.is.string(id);\n let isCached = false;\n\n function updateSprite(data) {\n // Inject content\n this.innerHTML = data;\n\n // Inject the SVG to the body\n document.body.insertBefore(this, document.body.childNodes[0]);\n }\n\n // Only load once\n if (!hasId || !document.querySelectorAll(`#${id}`).length) {\n // Create container\n const container = document.createElement('div');\n utils.toggleHidden(container, true);\n\n if (hasId) {\n container.setAttribute('id', id);\n }\n\n // Check in cache\n if (support.storage) {\n const cached = window.localStorage.getItem(prefix + id);\n isCached = cached !== null;\n\n if (isCached) {\n const data = JSON.parse(cached);\n updateSprite.call(container, data.content);\n return;\n }\n }\n\n // Get the sprite\n utils\n .fetch(url)\n .then(result => {\n if (utils.is.empty(result)) {\n return;\n }\n\n if (support.storage) {\n window.localStorage.setItem(\n prefix + id,\n JSON.stringify({\n content: result,\n }),\n );\n }\n\n updateSprite.call(container, result);\n })\n .catch(() => {});\n }\n },\n\n // Generate a random ID\n generateId(prefix) {\n return `${prefix}-${Math.floor(Math.random() * 10000)}`;\n },\n\n // Determine if we're in an iframe\n inFrame() {\n try {\n return window.self !== window.top;\n } catch (e) {\n return true;\n }\n },\n\n // Wrap an element\n wrap(elements, wrapper) {\n // Convert `elements` to an array, if necessary.\n const targets = elements.length ? elements : [elements];\n\n // Loops backwards to prevent having to clone the wrapper on the\n // first element (see `child` below).\n Array.from(targets)\n .reverse()\n .forEach((element, index) => {\n const child = index > 0 ? wrapper.cloneNode(true) : wrapper;\n\n // Cache the current parent and sibling.\n const parent = element.parentNode;\n const sibling = element.nextSibling;\n\n // Wrap the element (is automatically removed from its current\n // parent).\n child.appendChild(element);\n\n // If the element had a sibling, insert the wrapper before\n // the sibling to maintain the HTML structure; otherwise, just\n // append it to the parent.\n if (sibling) {\n parent.insertBefore(child, sibling);\n } else {\n parent.appendChild(child);\n }\n });\n },\n\n // Create a DocumentFragment\n createElement(type, attributes, text) {\n // Create a new \n const element = document.createElement(type);\n\n // Set all passed attributes\n if (utils.is.object(attributes)) {\n utils.setAttributes(element, attributes);\n }\n\n // Add text node\n if (utils.is.string(text)) {\n element.textContent = text;\n }\n\n // Return built element\n return element;\n },\n\n // Inaert an element after another\n insertAfter(element, target) {\n target.parentNode.insertBefore(element, target.nextSibling);\n },\n\n // Insert a DocumentFragment\n insertElement(type, parent, attributes, text) {\n // Inject the new \n parent.appendChild(utils.createElement(type, attributes, text));\n },\n\n // Remove an element\n removeElement(element) {\n if (!utils.is.element(element) || !utils.is.element(element.parentNode)) {\n return null;\n }\n\n element.parentNode.removeChild(element);\n\n return element;\n },\n\n // Remove all child elements\n emptyElement(element) {\n let { length } = element.childNodes;\n\n while (length > 0) {\n element.removeChild(element.lastChild);\n length -= 1;\n }\n },\n\n // Replace element\n replaceElement(newChild, oldChild) {\n if (!utils.is.element(oldChild) || !utils.is.element(oldChild.parentNode) || !utils.is.element(newChild)) {\n return null;\n }\n\n oldChild.parentNode.replaceChild(newChild, oldChild);\n\n return newChild;\n },\n\n // Set attributes\n setAttributes(element, attributes) {\n if (!utils.is.element(element) || utils.is.empty(attributes)) {\n return;\n }\n\n Object.keys(attributes).forEach(key => {\n element.setAttribute(key, attributes[key]);\n });\n },\n\n // Get an attribute object from a string selector\n getAttributesFromSelector(sel, existingAttributes) {\n // For example:\n // '.test' to { class: 'test' }\n // '#test' to { id: 'test' }\n // '[data-test=\"test\"]' to { 'data-test': 'test' }\n\n if (!utils.is.string(sel) || utils.is.empty(sel)) {\n return {};\n }\n\n const attributes = {};\n const existing = existingAttributes;\n\n sel.split(',').forEach(s => {\n // Remove whitespace\n const selector = s.trim();\n const className = selector.replace('.', '');\n const stripped = selector.replace(/[[\\]]/g, '');\n\n // Get the parts and value\n const parts = stripped.split('=');\n const key = parts[0];\n const value = parts.length > 1 ? parts[1].replace(/[\"']/g, '') : '';\n\n // Get the first character\n const start = selector.charAt(0);\n\n switch (start) {\n case '.':\n // Add to existing classname\n if (utils.is.object(existing) && utils.is.string(existing.class)) {\n existing.class += ` ${className}`;\n }\n\n attributes.class = className;\n break;\n\n case '#':\n // ID selector\n attributes.id = selector.replace('#', '');\n break;\n\n case '[':\n // Attribute selector\n attributes[key] = value;\n\n break;\n\n default:\n break;\n }\n });\n\n return attributes;\n },\n\n // Toggle class on an element\n toggleClass(element, className, toggle) {\n if (utils.is.element(element)) {\n const contains = element.classList.contains(className);\n\n element.classList[toggle ? 'add' : 'remove'](className);\n\n return (toggle && !contains) || (!toggle && contains);\n }\n\n return null;\n },\n\n // Has class name\n hasClass(element, className) {\n return utils.is.element(element) && element.classList.contains(className);\n },\n\n // Toggle hidden attribute on an element\n toggleHidden(element, toggle) {\n if (!utils.is.element(element)) {\n return;\n }\n\n if (toggle) {\n element.setAttribute('hidden', '');\n } else {\n element.removeAttribute('hidden');\n }\n },\n\n // Element matches selector\n matches(element, selector) {\n const prototype = { Element };\n\n function match() {\n return Array.from(document.querySelectorAll(selector)).includes(this);\n }\n\n const matches = prototype.matches || prototype.webkitMatchesSelector || prototype.mozMatchesSelector || prototype.msMatchesSelector || match;\n\n return matches.call(element, selector);\n },\n\n // Find all elements\n getElements(selector) {\n return this.elements.container.querySelectorAll(selector);\n },\n\n // Find a single element\n getElement(selector) {\n return this.elements.container.querySelector(selector);\n },\n\n // Find the UI controls and store references in custom controls\n // TODO: Allow settings menus with custom controls\n findElements() {\n try {\n this.elements.controls = utils.getElement.call(this, this.config.selectors.controls.wrapper);\n\n // Buttons\n this.elements.buttons = {\n play: utils.getElements.call(this, this.config.selectors.buttons.play),\n pause: utils.getElement.call(this, this.config.selectors.buttons.pause),\n restart: utils.getElement.call(this, this.config.selectors.buttons.restart),\n rewind: utils.getElement.call(this, this.config.selectors.buttons.rewind),\n forward: utils.getElement.call(this, this.config.selectors.buttons.forward),\n mute: utils.getElement.call(this, this.config.selectors.buttons.mute),\n pip: utils.getElement.call(this, this.config.selectors.buttons.pip),\n airplay: utils.getElement.call(this, this.config.selectors.buttons.airplay),\n settings: utils.getElement.call(this, this.config.selectors.buttons.settings),\n captions: utils.getElement.call(this, this.config.selectors.buttons.captions),\n fullscreen: utils.getElement.call(this, this.config.selectors.buttons.fullscreen),\n };\n\n // Progress\n this.elements.progress = utils.getElement.call(this, this.config.selectors.progress);\n\n // Inputs\n this.elements.inputs = {\n seek: utils.getElement.call(this, this.config.selectors.inputs.seek),\n volume: utils.getElement.call(this, this.config.selectors.inputs.volume),\n };\n\n // Display\n this.elements.display = {\n buffer: utils.getElement.call(this, this.config.selectors.display.buffer),\n duration: utils.getElement.call(this, this.config.selectors.display.duration),\n currentTime: utils.getElement.call(this, this.config.selectors.display.currentTime),\n };\n\n // Seek tooltip\n if (utils.is.element(this.elements.progress)) {\n this.elements.display.seekTooltip = this.elements.progress.querySelector(`.${this.config.classNames.tooltip}`);\n }\n\n return true;\n } catch (error) {\n // Log it\n this.debug.warn('It looks like there is a problem with your custom controls HTML', error);\n\n // Restore native video controls\n this.toggleNativeControls(true);\n\n return false;\n }\n },\n\n // Get the focused element\n getFocusElement() {\n let focused = document.activeElement;\n\n if (!focused || focused === document.body) {\n focused = null;\n } else {\n focused = document.querySelector(':focus');\n }\n\n return focused;\n },\n\n // Trap focus inside container\n trapFocus() {\n const focusable = utils.getElements.call(this, 'button:not(:disabled), input:not(:disabled), [tabindex]');\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n utils.on(\n this.elements.container,\n 'keydown',\n event => {\n // Bail if not tab key or not fullscreen\n if (event.key !== 'Tab' || event.keyCode !== 9 || !this.fullscreen.active) {\n return;\n }\n\n // Get the current focused element\n const focused = utils.getFocusElement();\n\n if (focused === last && !event.shiftKey) {\n // Move focus to first element that can be tabbed if Shift isn't used\n first.focus();\n event.preventDefault();\n } else if (focused === first && event.shiftKey) {\n // Move focus to last element that can be tabbed if Shift is used\n last.focus();\n event.preventDefault();\n }\n },\n false,\n );\n },\n\n // Toggle event listener\n toggleListener(elements, event, callback, toggle, passive, capture) {\n // Bail if no elements\n if (utils.is.nullOrUndefined(elements)) {\n return;\n }\n\n // If a nodelist is passed, call itself on each node\n if (utils.is.nodeList(elements)) {\n // Create listener for each node\n Array.from(elements).forEach(element => {\n if (element instanceof Node) {\n utils.toggleListener.call(null, element, event, callback, toggle, passive, capture);\n }\n });\n\n return;\n }\n\n // Allow multiple events\n const events = event.split(' ');\n\n // Build options\n // Default to just capture boolean\n let options = utils.is.boolean(capture) ? capture : false;\n\n // If passive events listeners are supported\n if (support.passiveListeners) {\n options = {\n // Whether the listener can be passive (i.e. default never prevented)\n passive: utils.is.boolean(passive) ? passive : true,\n // Whether the listener is a capturing listener or not\n capture: utils.is.boolean(capture) ? capture : false,\n };\n }\n\n // If a single node is passed, bind the event listener\n events.forEach(type => {\n elements[toggle ? 'addEventListener' : 'removeEventListener'](type, callback, options);\n });\n },\n\n // Bind event handler\n on(element, events, callback, passive, capture) {\n utils.toggleListener(element, events, callback, true, passive, capture);\n },\n\n // Unbind event handler\n off(element, events, callback, passive, capture) {\n utils.toggleListener(element, events, callback, false, passive, capture);\n },\n\n // Trigger event\n dispatchEvent(element, type, bubbles, detail) {\n // Bail if no element\n if (!element || !type) {\n return;\n }\n\n // Create and dispatch the event\n const event = new CustomEvent(type, {\n bubbles: utils.is.boolean(bubbles) ? bubbles : false,\n detail: Object.assign({}, detail, {\n plyr: utils.is.plyr(this) ? this : null,\n }),\n });\n\n // Dispatch the event\n element.dispatchEvent(event);\n },\n\n // Toggle aria-pressed state on a toggle button\n // http://www.ssbbartgroup.com/blog/how-not-to-misuse-aria-states-properties-and-roles\n toggleState(element, input) {\n // Bail if no target\n if (!utils.is.element(element)) {\n return;\n }\n\n // Get state\n const pressed = element.getAttribute('aria-pressed') === 'true';\n const state = utils.is.boolean(input) ? input : !pressed;\n\n // Set the attribute on target\n element.setAttribute('aria-pressed', state);\n },\n\n // Get percentage\n getPercentage(current, max) {\n if (current === 0 || max === 0 || Number.isNaN(current) || Number.isNaN(max)) {\n return 0;\n }\n return (current / max * 100).toFixed(2);\n },\n\n // Time helpers\n getHours(value) {\n return parseInt((value / 60 / 60) % 60, 10);\n },\n getMinutes(value) {\n return parseInt((value / 60) % 60, 10);\n },\n getSeconds(value) {\n return parseInt(value % 60, 10);\n },\n\n // Format time to UI friendly string\n formatTime(time = 0, displayHours = false, inverted = false) {\n // Bail if the value isn't a number\n if (!utils.is.number(time)) {\n return this.formatTime(null, displayHours, inverted);\n }\n\n // Format time component to add leading zero\n const format = value => `0${value}`.slice(-2);\n\n // Breakdown to hours, mins, secs\n let hours = this.getHours(time);\n const mins = this.getMinutes(time);\n const secs = this.getSeconds(time);\n\n // Do we need to display hours?\n if (displayHours || hours > 0) {\n hours = `${hours}:`;\n } else {\n hours = '';\n }\n\n // Render\n return `${inverted ? '-' : ''}${hours}${format(mins)}:${format(secs)}`;\n },\n\n // Deep extend destination object with N more objects\n extend(target = {}, ...sources) {\n if (!sources.length) {\n return target;\n }\n\n const source = sources.shift();\n\n if (!utils.is.object(source)) {\n return target;\n }\n\n Object.keys(source).forEach(key => {\n if (utils.is.object(source[key])) {\n if (!Object.keys(target).includes(key)) {\n Object.assign(target, { [key]: {} });\n }\n\n utils.extend(target[key], source[key]);\n } else {\n Object.assign(target, { [key]: source[key] });\n }\n });\n\n return utils.extend(target, ...sources);\n },\n\n // Get the provider for a given URL\n getProviderByUrl(url) {\n // YouTube\n if (/^(https?:\\/\\/)?(www\\.)?(youtube\\.com|youtu\\.?be)\\/.+$/.test(url)) {\n return providers.youtube;\n }\n\n // Vimeo\n if (/^https?:\\/\\/player.vimeo.com\\/video\\/\\d{8,}(?=\\b|\\/)/.test(url)) {\n return providers.vimeo;\n }\n\n return null;\n },\n\n // Parse YouTube ID from URL\n parseYouTubeId(url) {\n if (utils.is.empty(url)) {\n return null;\n }\n\n const regex = /^.*(youtu.be\\/|v\\/|u\\/\\w\\/|embed\\/|watch\\?v=|&v=)([^#&?]*).*/;\n return url.match(regex) ? RegExp.$2 : url;\n },\n\n // Parse Vimeo ID from URL\n parseVimeoId(url) {\n if (utils.is.empty(url)) {\n return null;\n }\n\n if (utils.is.number(Number(url))) {\n return url;\n }\n\n const regex = /^.*(vimeo.com\\/|video\\/)(\\d+).*/;\n return url.match(regex) ? RegExp.$2 : url;\n },\n\n // Convert a URL to a location object\n parseUrl(url) {\n const parser = document.createElement('a');\n parser.href = url;\n return parser;\n },\n\n // Get URL query parameters\n getUrlParams(input) {\n let search = input;\n\n // Parse URL if needed\n if (input.startsWith('http://') || input.startsWith('https://')) {\n ({ search } = this.parseUrl(input));\n }\n\n if (this.is.empty(search)) {\n return null;\n }\n\n const hashes = search.slice(search.indexOf('?') + 1).split('&');\n\n return hashes.reduce((params, hash) => {\n const [\n key,\n val,\n ] = hash.split('=');\n\n return Object.assign(params, { [key]: decodeURIComponent(val) });\n }, {});\n },\n\n // Convert object to URL parameters\n buildUrlParams(input) {\n if (!utils.is.object(input)) {\n return '';\n }\n\n return Object.keys(input)\n .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(input[key])}`)\n .join('&');\n },\n\n // Remove HTML from a string\n stripHTML(source) {\n const fragment = document.createDocumentFragment();\n const element = document.createElement('div');\n fragment.appendChild(element);\n element.innerHTML = source;\n return fragment.firstChild.innerText;\n },\n\n // Get aspect ratio for dimensions\n getAspectRatio(width, height) {\n const getRatio = (w, h) => (h === 0 ? w : getRatio(h, w % h));\n const ratio = getRatio(width, height);\n return `${width / ratio}:${height / ratio}`;\n },\n\n // Get the transition end event\n get transitionEndEvent() {\n const element = document.createElement('span');\n\n const events = {\n WebkitTransition: 'webkitTransitionEnd',\n MozTransition: 'transitionend',\n OTransition: 'oTransitionEnd otransitionend',\n transition: 'transitionend',\n };\n\n const type = Object.keys(events).find(event => element.style[event] !== undefined);\n\n return utils.is.string(type) ? events[type] : false;\n },\n\n // Force repaint of element\n repaint(element) {\n window.setTimeout(() => {\n utils.toggleHidden(element, true);\n element.offsetHeight; // eslint-disable-line\n utils.toggleHidden(element, false);\n }, 0);\n },\n};\n\nexport default utils;\n","// ==========================================================================\n// Console wrapper\n// ==========================================================================\n\nconst noop = () => {};\n\nexport default class Console {\n constructor(enabled = false) {\n this.enabled = window.console && enabled;\n\n if (this.enabled) {\n this.log('Debugging enabled');\n }\n }\n\n get log() {\n // eslint-disable-next-line no-console\n return this.enabled ? Function.prototype.bind.call(console.log, console) : noop;\n }\n get warn() {\n // eslint-disable-next-line no-console\n return this.enabled ? Function.prototype.bind.call(console.warn, console) : noop;\n }\n get error() {\n // eslint-disable-next-line no-console\n return this.enabled ? Function.prototype.bind.call(console.error, console) : noop;\n }\n}\n","// ==========================================================================\n// Plyr storage\n// ==========================================================================\n\nimport utils from './utils';\n\nclass Storage {\n constructor(player) {\n this.enabled = player.config.storage.enabled;\n this.key = player.config.storage.key;\n }\n\n // Check for actual support (see if we can use it)\n static get supported() {\n if (!('localStorage' in window)) {\n return false;\n }\n\n const test = '___test';\n\n // Try to use it (it might be disabled, e.g. user is in private mode)\n // see: https://github.com/sampotts/plyr/issues/131\n try {\n window.localStorage.setItem(test, test);\n window.localStorage.removeItem(test);\n return true;\n } catch (e) {\n return false;\n }\n }\n\n get(key) {\n const store = window.localStorage.getItem(this.key);\n\n if (!Storage.supported || utils.is.empty(store)) {\n return null;\n }\n\n const json = JSON.parse(store);\n\n return utils.is.string(key) && key.length ? json[key] : json;\n }\n\n set(object) {\n // Bail if we don't have localStorage support or it's disabled\n if (!Storage.supported || !this.enabled) {\n return;\n }\n\n // Can only store objectst\n if (!utils.is.object(object)) {\n return;\n }\n\n // Get current storage\n let storage = this.get();\n\n // Default to empty object\n if (utils.is.empty(storage)) {\n storage = {};\n }\n\n // Update the working copy of the values\n utils.extend(storage, object);\n\n // Update storage\n window.localStorage.setItem(this.key, JSON.stringify(storage));\n }\n}\n\nexport default Storage;\n","// ==========================================================================\n// Advertisement plugin using Google IMA HTML5 SDK\n// Create an account with our ad partner, vi here:\n// https://www.vi.ai/publisher-video-monetization/\n// ==========================================================================\n\n/* global google */\n\nimport utils from '../utils';\n\n// Build the default tag URL\nconst getTagUrl = () => {\n const params = {\n AV_PUBLISHERID: '58c25bb0073ef448b1087ad6',\n AV_CHANNELID: '5a0458dc28a06145e4519d21',\n AV_URL: '127.0.0.1:3000',\n cb: 1,\n AV_WIDTH: 640,\n AV_HEIGHT: 480,\n };\n\n const base = 'https://go.aniview.com/api/adserver6/vast/';\n\n return `${base}?${utils.buildUrlParams(params)}`;\n};\n\nclass Ads {\n /**\n * Ads constructor.\n * @param {object} player\n * @return {Ads}\n */\n constructor(player) {\n this.player = player;\n this.enabled = player.config.ads.enabled;\n this.playing = false;\n this.initialized = false;\n this.blocked = false;\n this.enabled = utils.is.url(player.config.ads.tag);\n\n // Check if a tag URL is provided.\n if (!this.enabled) {\n return;\n }\n\n // Check if the Google IMA3 SDK is loaded or load it ourselves\n if (!utils.is.object(window.google)) {\n utils.loadScript(\n player.config.urls.googleIMA.api,\n () => {\n this.ready();\n },\n () => {\n // Script failed to load or is blocked\n this.blocked = true;\n this.player.debug.log('Ads error: Google IMA SDK failed to load');\n },\n );\n } else {\n this.ready();\n }\n }\n\n /**\n * Get the ads instance ready.\n */\n ready() {\n this.elements = {\n container: null,\n displayContainer: null,\n };\n this.manager = null;\n this.loader = null;\n this.cuePoints = null;\n this.events = {};\n this.safetyTimer = null;\n this.countdownTimer = null;\n\n // Set listeners on the Plyr instance\n this.listeners();\n\n // Start ticking our safety timer. If the whole advertisement\n // thing doesn't resolve within our set time; we bail\n this.startSafetyTimer(12000, 'ready()');\n\n // Setup a simple promise to resolve if the IMA loader is ready\n this.loaderPromise = new Promise(resolve => {\n this.on('ADS_LOADER_LOADED', () => resolve());\n });\n\n // Setup a promise to resolve if the IMA manager is ready\n this.managerPromise = new Promise(resolve => {\n this.on('ADS_MANAGER_LOADED', () => resolve());\n });\n\n // Clear the safety timer\n this.managerPromise.then(() => {\n this.clearSafetyTimer('onAdsManagerLoaded()');\n });\n\n // Setup the IMA SDK\n this.setupIMA();\n }\n\n /**\n * In order for the SDK to display ads for our video, we need to tell it where to put them,\n * so here we define our ad container. This div is set up to render on top of the video player.\n * Using the code below, we tell the SDK to render ads within that div. We also provide a\n * handle to the content video player - the SDK will poll the current time of our player to\n * properly place mid-rolls. After we create the ad display container, we initialize it. On\n * mobile devices, this initialization is done as the result of a user action.\n */\n setupIMA() {\n // Create the container for our advertisements\n this.elements.container = utils.createElement('div', {\n class: this.player.config.classNames.ads,\n hidden: '',\n });\n this.player.elements.container.appendChild(this.elements.container);\n\n // So we can run VPAID2\n google.ima.settings.setVpaidMode(google.ima.ImaSdkSettings.VpaidMode.ENABLED);\n\n // Set language\n google.ima.settings.setLocale(this.player.config.ads.language);\n\n // We assume the adContainer is the video container of the plyr element\n // that will house the ads\n this.elements.displayContainer = new google.ima.AdDisplayContainer(this.elements.container);\n\n // Request video ads to be pre-loaded\n this.requestAds();\n }\n\n /**\n * Request advertisements\n */\n requestAds() {\n const { container } = this.player.elements;\n\n try {\n // Create ads loader\n this.loader = new google.ima.AdsLoader(this.elements.displayContainer);\n\n // Listen and respond to ads loaded and error events\n this.loader.addEventListener(google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, event => this.onAdsManagerLoaded(event), false);\n this.loader.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, error => this.onAdError(error), false);\n\n // Request video ads\n const request = new google.ima.AdsRequest();\n request.adTagUrl = getTagUrl();\n\n // Specify the linear and nonlinear slot sizes. This helps the SDK\n // to select the correct creative if multiple are returned\n request.linearAdSlotWidth = container.offsetWidth;\n request.linearAdSlotHeight = container.offsetHeight;\n request.nonLinearAdSlotWidth = container.offsetWidth;\n request.nonLinearAdSlotHeight = container.offsetHeight;\n\n // We only overlay ads as we only support video.\n request.forceNonLinearFullSlot = false;\n\n this.loader.requestAds(request);\n\n this.handleEventListeners('ADS_LOADER_LOADED');\n } catch (e) {\n this.onAdError(e);\n }\n }\n\n /**\n * Update the ad countdown\n * @param {boolean} start\n */\n pollCountdown(start = false) {\n if (!start) {\n window.clearInterval(this.countdownTimer);\n this.elements.container.removeAttribute('data-badge-text');\n return;\n }\n\n const update = () => {\n const time = utils.formatTime(this.manager.getRemainingTime());\n const label = `${this.player.config.i18n.advertisment} - ${time}`;\n this.elements.container.setAttribute('data-badge-text', label);\n };\n\n this.countdownTimer = window.setInterval(update, 100);\n }\n\n /**\n * This method is called whenever the ads are ready inside the AdDisplayContainer\n * @param {Event} adsManagerLoadedEvent\n */\n onAdsManagerLoaded(adsManagerLoadedEvent) {\n // Get the ads manager\n const settings = new google.ima.AdsRenderingSettings();\n\n // Tell the SDK to save and restore content video state on our behalf\n settings.restoreCustomPlaybackStateOnAdBreakComplete = true;\n settings.enablePreloading = true;\n\n // The SDK is polling currentTime on the contentPlayback. And needs a duration\n // so it can determine when to start the mid- and post-roll\n this.manager = adsManagerLoadedEvent.getAdsManager(this.player, settings);\n\n // Get the cue points for any mid-rolls by filtering out the pre- and post-roll\n this.cuePoints = this.manager.getCuePoints();\n\n // Add advertisement cue's within the time line if available\n this.cuePoints.forEach(cuePoint => {\n if (cuePoint !== 0 && cuePoint !== -1) {\n const seekElement = this.player.elements.progress;\n\n if (seekElement) {\n const cuePercentage = 100 / this.player.duration * cuePoint;\n const cue = utils.createElement('span', {\n class: this.player.config.classNames.cues,\n });\n\n cue.style.left = `${cuePercentage.toString()}%`;\n seekElement.appendChild(cue);\n }\n }\n });\n\n // Get skippable state\n // TODO: Skip button\n // this.manager.getAdSkippableState();\n\n // Set volume to match player\n this.manager.setVolume(this.player.volume);\n\n // Add listeners to the required events\n // Advertisement error events\n this.manager.addEventListener(google.ima.AdErrorEvent.Type.AD_ERROR, error => this.onAdError(error));\n\n // Advertisement regular events\n Object.keys(google.ima.AdEvent.Type).forEach(type => {\n this.manager.addEventListener(google.ima.AdEvent.Type[type], event => this.onAdEvent(event));\n });\n\n // Resolve our adsManager\n this.handleEventListeners('ADS_MANAGER_LOADED');\n }\n\n /**\n * This is where all the event handling takes place. Retrieve the ad from the event. Some\n * events (e.g. ALL_ADS_COMPLETED) don't have the ad object associated\n * https://developers.google.com/interactive-media-ads/docs/sdks/html5/v3/apis#ima.AdEvent.Type\n * @param {Event} event\n */\n onAdEvent(event) {\n const { container } = this.player.elements;\n\n // Retrieve the ad from the event. Some events (e.g. ALL_ADS_COMPLETED)\n // don't have ad object associated\n const ad = event.getAd();\n\n // Proxy event\n const dispatchEvent = type => {\n utils.dispatchEvent.call(this.player, this.player.media, `ads${type}`);\n };\n\n switch (event.type) {\n case google.ima.AdEvent.Type.LOADED:\n // This is the first event sent for an ad - it is possible to determine whether the\n // ad is a video ad or an overlay\n this.handleEventListeners('LOADED');\n\n // Bubble event\n dispatchEvent('loaded');\n\n // Start countdown\n this.pollCountdown(true);\n\n if (!ad.isLinear()) {\n // Position AdDisplayContainer correctly for overlay\n ad.width = container.offsetWidth;\n ad.height = container.offsetHeight;\n }\n\n // console.info('Ad type: ' + event.getAd().getAdPodInfo().getPodIndex());\n // console.info('Ad time: ' + event.getAd().getAdPodInfo().getTimeOffset());\n break;\n\n case google.ima.AdEvent.Type.ALL_ADS_COMPLETED:\n // All ads for the current videos are done. We can now request new advertisements\n // in case the video is re-played\n this.handleEventListeners('ALL_ADS_COMPLETED');\n\n // Fire event\n dispatchEvent('allcomplete');\n\n // TODO: Example for what happens when a next video in a playlist would be loaded.\n // So here we load a new video when all ads are done.\n // Then we load new ads within a new adsManager. When the video\n // Is started - after - the ads are loaded, then we get ads.\n // You can also easily test cancelling and reloading by running\n // player.ads.cancel() and player.ads.play from the console I guess.\n // this.player.source = {\n // type: 'video',\n // title: 'View From A Blue Moon',\n // sources: [{\n // src:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.mp4', type:\n // 'video/mp4', }], poster:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.jpg', tracks:\n // [ { kind: 'captions', label: 'English', srclang: 'en', src:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.en.vtt',\n // default: true, }, { kind: 'captions', label: 'French', srclang: 'fr', src:\n // 'https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-HD.fr.vtt', }, ],\n // };\n\n // TODO: So there is still this thing where a video should only be allowed to start\n // playing when the IMA SDK is ready or has failed\n\n this.loadAds();\n break;\n\n case google.ima.AdEvent.Type.CONTENT_PAUSE_REQUESTED:\n // This event indicates the ad has started - the video player can adjust the UI,\n // for example display a pause button and remaining time. Fired when content should\n // be paused. This usually happens right before an ad is about to cover the content\n this.handleEventListeners('CONTENT_PAUSE_REQUESTED');\n\n dispatchEvent('contentpause');\n\n this.pauseContent();\n\n break;\n\n case google.ima.AdEvent.Type.CONTENT_RESUME_REQUESTED:\n // This event indicates the ad has finished - the video player can perform\n // appropriate UI actions, such as removing the timer for remaining time detection.\n // Fired when content should be resumed. This usually happens when an ad finishes\n // or collapses\n this.handleEventListeners('CONTENT_RESUME_REQUESTED');\n\n dispatchEvent('contentresume');\n\n this.pollCountdown();\n\n this.resumeContent();\n\n break;\n\n case google.ima.AdEvent.Type.STARTED:\n dispatchEvent('started');\n break;\n\n case google.ima.AdEvent.Type.MIDPOINT:\n dispatchEvent('midpoint');\n break;\n\n case google.ima.AdEvent.Type.COMPLETE:\n dispatchEvent('complete');\n break;\n\n case google.ima.AdEvent.Type.IMPRESSION:\n dispatchEvent('impression');\n break;\n\n case google.ima.AdEvent.Type.CLICK:\n dispatchEvent('click');\n break;\n\n default:\n break;\n }\n }\n\n /**\n * Any ad error handling comes through here\n * @param {Event} event\n */\n onAdError(event) {\n this.cancel();\n this.player.debug.log('Ads error', event);\n }\n\n /**\n * Setup hooks for Plyr and window events. This ensures\n * the mid- and post-roll launch at the correct time. And\n * resize the advertisement when the player resizes\n */\n listeners() {\n const { container } = this.player.elements;\n let time;\n\n // Add listeners to the required events\n this.player.on('ended', () => {\n this.loader.contentComplete();\n });\n\n this.player.on('seeking', () => {\n time = this.player.currentTime;\n return time;\n });\n\n this.player.on('seeked', () => {\n const seekedTime = this.player.currentTime;\n\n this.cuePoints.forEach((cuePoint, index) => {\n if (time < cuePoint && cuePoint < seekedTime) {\n this.manager.discardAdBreak();\n this.cuePoints.splice(index, 1);\n }\n });\n });\n\n // Listen to the resizing of the window. And resize ad accordingly\n // TODO: eventually implement ResizeObserver\n window.addEventListener('resize', () => {\n this.manager.resize(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);\n });\n }\n\n /**\n * Initialize the adsManager and start playing advertisements\n */\n play() {\n const { container } = this.player.elements;\n\n if (!this.managerPromise) {\n return;\n }\n\n // Play the requested advertisement whenever the adsManager is ready\n this.managerPromise.then(() => {\n // Initialize the container. Must be done via a user action on mobile devices\n this.elements.displayContainer.initialize();\n\n try {\n if (!this.initialized) {\n // Initialize the ads manager. Ad rules playlist will start at this time\n this.manager.init(container.offsetWidth, container.offsetHeight, google.ima.ViewMode.NORMAL);\n\n // Call play to start showing the ad. Single video and overlay ads will\n // start at this time; the call will be ignored for ad rules\n this.manager.start();\n }\n\n this.initialized = true;\n } catch (adError) {\n // An error may be thrown if there was a problem with the\n // VAST response\n this.onAdError(adError);\n }\n });\n }\n\n /**\n * Resume our video.\n */\n resumeContent() {\n // Hide our ad container\n utils.toggleHidden(this.elements.container, true);\n\n // Ad is stopped\n this.playing = false;\n\n // Play our video\n if (this.player.currentTime < this.player.duration) {\n this.player.play();\n }\n }\n\n /**\n * Pause our video\n */\n pauseContent() {\n // Show our ad container.\n utils.toggleHidden(this.elements.container, false);\n\n // Ad is playing.\n this.playing = true;\n\n // Pause our video.\n this.player.pause();\n }\n\n /**\n * Destroy the adsManager so we can grab new ads after this. If we don't then we're not\n * allowed to call new ads based on google policies, as they interpret this as an accidental\n * video requests. https://developers.google.com/interactive-\n * media-ads/docs/sdks/android/faq#8\n */\n cancel() {\n // Pause our video\n if (this.initialized) {\n this.resumeContent();\n }\n\n // Tell our instance that we're done for now\n this.handleEventListeners('ERROR');\n\n // Re-create our adsManager\n this.loadAds();\n }\n\n /**\n * Re-create our adsManager\n */\n loadAds() {\n // Tell our adsManager to go bye bye\n this.managerPromise.then(() => {\n // Destroy our adsManager\n if (this.manager) {\n this.manager.destroy();\n }\n\n // Re-set our adsManager promises\n this.managerPromise = new Promise(resolve => {\n this.on('ADS_MANAGER_LOADED', () => resolve());\n this.player.debug.log(this.manager);\n });\n\n // Now request some new advertisements\n this.requestAds();\n });\n }\n\n /**\n * Handles callbacks after an ad event was invoked\n * @param {string} event - Event type\n */\n handleEventListeners(event) {\n if (utils.is.function(this.events[event])) {\n this.events[event].call(this);\n }\n }\n\n /**\n * Add event listeners\n * @param {string} event - Event type\n * @param {function} callback - Callback for when event occurs\n * @return {Ads}\n */\n on(event, callback) {\n this.events[event] = callback;\n return this;\n }\n\n /**\n * Setup a safety timer for when the ad network doesn't respond for whatever reason.\n * The advertisement has 12 seconds to get its things together. We stop this timer when the\n * advertisement is playing, or when a user action is required to start, then we clear the\n * timer on ad ready\n * @param {number} time\n * @param {string} from\n */\n startSafetyTimer(time, from) {\n this.player.debug.log(`Safety timer invoked from: ${from}`);\n\n this.safetyTimer = window.setTimeout(() => {\n this.cancel();\n this.clearSafetyTimer('startSafetyTimer()');\n }, time);\n }\n\n /**\n * Clear our safety timer(s)\n * @param {string} from\n */\n clearSafetyTimer(from) {\n if (!utils.is.nullOrUndefined(this.safetyTimer)) {\n this.player.debug.log(`Safety timer cleared from: ${from}`);\n\n clearTimeout(this.safetyTimer);\n this.safetyTimer = null;\n }\n }\n}\n\nexport default Ads;\n","// ==========================================================================\n// Plyr Event Listeners\n// ==========================================================================\n\nimport support from './support';\nimport utils from './utils';\nimport controls from './controls';\nimport fullscreen from './fullscreen';\nimport ui from './ui';\n\n// Sniff out the browser\nconst browser = utils.getBrowser();\n\nconst listeners = {\n // Global listeners\n global() {\n let last = null;\n\n // Get the key code for an event\n const getKeyCode = event => (event.keyCode ? event.keyCode : event.which);\n\n // Handle key press\n const handleKey = event => {\n const code = getKeyCode(event);\n const pressed = event.type === 'keydown';\n const repeat = pressed && code === last;\n\n // Bail if a modifier key is set\n if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {\n return;\n }\n\n // If the event is bubbled from the media element\n // Firefox doesn't get the keycode for whatever reason\n if (!utils.is.number(code)) {\n return;\n }\n\n // Seek by the number keys\n const seekByKey = () => {\n // Divide the max duration into 10th's and times by the number value\n this.currentTime = this.duration / 10 * (code - 48);\n };\n\n // Handle the key on keydown\n // Reset on keyup\n if (pressed) {\n // Which keycodes should we prevent default\n const preventDefault = [\n 48,\n 49,\n 50,\n 51,\n 52,\n 53,\n 54,\n 56,\n 57,\n 32,\n 75,\n 38,\n 40,\n 77,\n 39,\n 37,\n 70,\n 67,\n 73,\n 76,\n 79,\n ];\n\n // Check focused element\n // and if the focused element is not editable (e.g. text input)\n // and any that accept key input http://webaim.org/techniques/keyboard/\n const focused = utils.getFocusElement();\n if (utils.is.element(focused) && utils.matches(focused, this.config.selectors.editable)) {\n return;\n }\n\n // If the code is found prevent default (e.g. prevent scrolling for arrows)\n if (preventDefault.includes(code)) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n switch (code) {\n case 48:\n case 49:\n case 50:\n case 51:\n case 52:\n case 53:\n case 54:\n case 55:\n case 56:\n case 57:\n // 0-9\n if (!repeat) {\n seekByKey();\n }\n break;\n\n case 32:\n case 75:\n // Space and K key\n if (!repeat) {\n this.togglePlay();\n }\n break;\n\n case 38:\n // Arrow up\n this.increaseVolume(0.1);\n break;\n\n case 40:\n // Arrow down\n this.decreaseVolume(0.1);\n break;\n\n case 77:\n // M key\n if (!repeat) {\n this.muted = !this.muted;\n }\n break;\n\n case 39:\n // Arrow forward\n this.forward();\n break;\n\n case 37:\n // Arrow back\n this.rewind();\n break;\n\n case 70:\n // F key\n this.toggleFullscreen();\n break;\n\n case 67:\n // C key\n if (!repeat) {\n this.toggleCaptions();\n }\n break;\n\n case 76:\n // L key\n this.loop = !this.loop;\n break;\n\n /* case 73:\n this.setLoop('start');\n break;\n\n case 76:\n this.setLoop();\n break;\n\n case 79:\n this.setLoop('end');\n break; */\n\n default:\n break;\n }\n\n // Escape is handle natively when in full screen\n // So we only need to worry about non native\n if (!fullscreen.enabled && this.fullscreen.active && code === 27) {\n this.toggleFullscreen();\n }\n\n // Store last code for next cycle\n last = code;\n } else {\n last = null;\n }\n };\n\n // Keyboard shortcuts\n if (this.config.keyboard.global) {\n utils.on(window, 'keydown keyup', handleKey, false);\n } else if (this.config.keyboard.focused) {\n utils.on(this.elements.container, 'keydown keyup', handleKey, false);\n }\n\n // Detect tab focus\n // Remove class on blur/focusout\n utils.on(this.elements.container, 'focusout', event => {\n utils.toggleClass(event.target, this.config.classNames.tabFocus, false);\n });\n\n // Add classname to tabbed elements\n utils.on(this.elements.container, 'keydown', event => {\n if (event.keyCode !== 9) {\n return;\n }\n\n // Delay the adding of classname until the focus has changed\n // This event fires before the focusin event\n window.setTimeout(() => {\n utils.toggleClass(utils.getFocusElement(), this.config.classNames.tabFocus, true);\n }, 0);\n });\n\n // Toggle controls visibility based on mouse movement\n if (this.config.hideControls) {\n // Toggle controls on mouse events and entering fullscreen\n utils.on(this.elements.container, 'mouseenter mouseleave mousemove touchstart touchend touchmove enterfullscreen exitfullscreen', event => {\n this.toggleControls(event);\n });\n }\n\n // Handle user exiting fullscreen by escaping etc\n if (fullscreen.enabled) {\n utils.on(document, fullscreen.eventType, event => {\n this.toggleFullscreen(event);\n });\n\n // Fullscreen toggle on double click\n utils.on(this.elements.container, 'dblclick', event => {\n this.toggleFullscreen(event);\n });\n }\n },\n\n // Listen for media events\n media() {\n // Time change on media\n utils.on(this.media, 'timeupdate seeking', event => ui.timeUpdate.call(this, event));\n\n // Display duration\n utils.on(this.media, 'durationchange loadedmetadata', event => ui.durationUpdate.call(this, event));\n\n // Check for audio tracks on load\n // We can't use `loadedmetadata` as it doesn't seem to have audio tracks at that point\n utils.on(this.media, 'loadeddata', () => {\n utils.toggleHidden(this.elements.volume, !this.hasAudio);\n utils.toggleHidden(this.elements.buttons.mute, !this.hasAudio);\n });\n\n // Handle the media finishing\n utils.on(this.media, 'ended', () => {\n // Show poster on end\n if (this.isHTML5 && this.isVideo && this.config.showPosterOnEnd) {\n // Restart\n this.restart();\n\n // Re-load media\n this.media.load();\n }\n });\n\n // Check for buffer progress\n utils.on(this.media, 'progress playing', event => ui.updateProgress.call(this, event));\n\n // Handle native mute\n utils.on(this.media, 'volumechange', event => ui.updateVolume.call(this, event));\n\n // Handle native play/pause\n utils.on(this.media, 'playing play pause ended', event => ui.checkPlaying.call(this, event));\n\n // Loading\n utils.on(this.media, 'stalled waiting canplay seeked playing', event => ui.checkLoading.call(this, event));\n\n // Check if media failed to load\n // utils.on(this.media, 'play', event => ui.checkFailed.call(this, event));\n\n // Click video\n if (this.supported.ui && this.config.clickToPlay && !this.isAudio) {\n // Re-fetch the wrapper\n const wrapper = utils.getElement.call(this, `.${this.config.classNames.video}`);\n\n // Bail if there's no wrapper (this should never happen)\n if (!utils.is.element(wrapper)) {\n return;\n }\n\n // On click play, pause ore restart\n utils.on(wrapper, 'click', () => {\n // Touch devices will just show controls (if we're hiding controls)\n if (this.config.hideControls && support.touch && !this.paused) {\n return;\n }\n\n if (this.paused) {\n this.play();\n } else if (this.ended) {\n this.restart();\n this.play();\n } else {\n this.pause();\n }\n });\n }\n\n // Disable right click\n if (this.supported.ui && this.config.disableContextMenu) {\n utils.on(\n this.media,\n 'contextmenu',\n event => {\n event.preventDefault();\n },\n false\n );\n }\n\n // Volume change\n utils.on(this.media, 'volumechange', () => {\n // Save to storage\n this.storage.set({ volume: this.volume, muted: this.muted });\n });\n\n // Speed change\n utils.on(this.media, 'ratechange', () => {\n // Update UI\n controls.updateSetting.call(this, 'speed');\n\n // Save to storage\n this.storage.set({ speed: this.speed });\n });\n\n // Quality change\n utils.on(this.media, 'qualitychange', () => {\n // Update UI\n controls.updateSetting.call(this, 'quality');\n\n // Save to storage\n this.storage.set({ quality: this.quality });\n });\n\n // Caption language change\n utils.on(this.media, 'languagechange', () => {\n // Update UI\n controls.updateSetting.call(this, 'captions');\n\n // Save to storage\n this.storage.set({ language: this.language });\n });\n\n // Captions toggle\n utils.on(this.media, 'captionsenabled captionsdisabled', () => {\n // Update UI\n controls.updateSetting.call(this, 'captions');\n\n // Save to storage\n this.storage.set({ captions: this.captions.active });\n });\n\n // Proxy events to container\n // Bubble up key events for Edge\n utils.on(this.media, this.config.events.concat([\n 'keyup',\n 'keydown',\n ]).join(' '), event => {\n let detail = {};\n\n // Get error details from media\n if (event.type === 'error') {\n detail = this.media.error;\n }\n\n utils.dispatchEvent.call(this, this.elements.container, event.type, true, detail);\n });\n },\n\n // Listen for control events\n controls() {\n // IE doesn't support input event, so we fallback to change\n const inputEvent = browser.isIE ? 'change' : 'input';\n\n // Trigger custom and default handlers\n const proxy = (event, handlerKey, defaultHandler) => {\n const customHandler = this.config.listeners[handlerKey];\n\n // Execute custom handler\n if (utils.is.function(customHandler)) {\n customHandler.call(this, event);\n }\n\n // Only call default handler if not prevented in custom handler\n if (!event.defaultPrevented && utils.is.function(defaultHandler)) {\n defaultHandler.call(this, event);\n }\n };\n\n // Play/pause toggle\n utils.on(this.elements.buttons.play, 'click', event =>\n proxy(event, 'play', () => {\n this.togglePlay();\n })\n );\n\n // Pause\n utils.on(this.elements.buttons.restart, 'click', event =>\n proxy(event, 'restart', () => {\n this.restart();\n })\n );\n\n // Rewind\n utils.on(this.elements.buttons.rewind, 'click', event =>\n proxy(event, 'rewind', () => {\n this.rewind();\n })\n );\n\n // Rewind\n utils.on(this.elements.buttons.forward, 'click', event =>\n proxy(event, 'forward', () => {\n this.forward();\n })\n );\n\n // Mute toggle\n utils.on(this.elements.buttons.mute, 'click', event =>\n proxy(event, 'mute', () => {\n this.muted = !this.muted;\n })\n );\n\n // Captions toggle\n utils.on(this.elements.buttons.captions, 'click', event =>\n proxy(event, 'captions', () => {\n this.toggleCaptions();\n })\n );\n\n // Fullscreen toggle\n utils.on(this.elements.buttons.fullscreen, 'click', event =>\n proxy(event, 'fullscreen', () => {\n this.toggleFullscreen();\n })\n );\n\n // Picture-in-Picture\n utils.on(this.elements.buttons.pip, 'click', event =>\n proxy(event, 'pip', () => {\n this.pip = 'toggle';\n })\n );\n\n // Airplay\n utils.on(this.elements.buttons.airplay, 'click', event =>\n proxy(event, 'airplay', () => {\n this.airplay();\n })\n );\n\n // Settings menu\n utils.on(this.elements.buttons.settings, 'click', event => {\n controls.toggleMenu.call(this, event);\n });\n\n // Click anywhere closes menu\n utils.on(document.documentElement, 'click', event => {\n controls.toggleMenu.call(this, event);\n });\n\n // Settings menu\n utils.on(this.elements.settings.form, 'click', event => {\n event.stopPropagation();\n\n // Settings menu items - use event delegation as items are added/removed\n if (utils.matches(event.target, this.config.selectors.inputs.language)) {\n proxy(event, 'language', () => {\n this.language = event.target.value;\n });\n } else if (utils.matches(event.target, this.config.selectors.inputs.quality)) {\n proxy(event, 'quality', () => {\n this.quality = event.target.value;\n });\n } else if (utils.matches(event.target, this.config.selectors.inputs.speed)) {\n proxy(event, 'speed', () => {\n this.speed = parseFloat(event.target.value);\n });\n } else {\n controls.showTab.call(this, event);\n }\n });\n\n // Seek\n utils.on(this.elements.inputs.seek, inputEvent, event =>\n proxy(event, 'seek', () => {\n this.currentTime = event.target.value / event.target.max * this.duration;\n })\n );\n\n // Current time invert\n // Only if one time element is used for both currentTime and duration\n if (this.config.toggleInvert && !utils.is.element(this.elements.display.duration)) {\n utils.on(this.elements.display.currentTime, 'click', () => {\n // Do nothing if we're at the start\n if (this.currentTime === 0) {\n return;\n }\n\n this.config.invertTime = !this.config.invertTime;\n ui.timeUpdate.call(this);\n });\n }\n\n // Volume\n utils.on(this.elements.inputs.volume, inputEvent, event =>\n proxy(event, 'volume', () => {\n this.volume = event.target.value;\n })\n );\n\n // Polyfill for lower fill in for webkit\n if (browser.isWebkit) {\n utils.on(utils.getElements.call(this, 'input[type=\"range\"]'), 'input', event => {\n controls.updateRangeFill.call(this, event.target);\n });\n }\n\n // Seek tooltip\n utils.on(this.elements.progress, 'mouseenter mouseleave mousemove', event => controls.updateSeekTooltip.call(this, event));\n\n // Toggle controls visibility based on mouse movement\n if (this.config.hideControls) {\n // Watch for cursor over controls so they don't hide when trying to interact\n utils.on(this.elements.controls, 'mouseenter mouseleave', event => {\n this.elements.controls.hover = event.type === 'mouseenter';\n });\n\n // Watch for cursor over controls so they don't hide when trying to interact\n utils.on(this.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => {\n this.elements.controls.pressed = [\n 'mousedown',\n 'touchstart',\n ].includes(event.type);\n });\n\n // Focus in/out on controls\n utils.on(this.elements.controls, 'focusin focusout', event => {\n this.toggleControls(event);\n });\n }\n\n // Mouse wheel for volume\n utils.on(\n this.elements.inputs.volume,\n 'wheel',\n event =>\n proxy(event, 'volume', () => {\n // Detect \"natural\" scroll - suppored on OS X Safari only\n // Other browsers on OS X will be inverted until support improves\n const inverted = event.webkitDirectionInvertedFromDevice;\n const step = 1 / 50;\n let direction = 0;\n\n // Scroll down (or up on natural) to decrease\n if (event.deltaY < 0 || event.deltaX > 0) {\n if (inverted) {\n this.decreaseVolume(step);\n direction = -1;\n } else {\n this.increaseVolume(step);\n direction = 1;\n }\n }\n\n // Scroll up (or down on natural) to increase\n if (event.deltaY > 0 || event.deltaX < 0) {\n if (inverted) {\n this.increaseVolume(step);\n direction = 1;\n } else {\n this.decreaseVolume(step);\n direction = -1;\n }\n }\n\n // Don't break page scrolling at max and min\n if ((direction === 1 && this.media.volume < 1) || (direction === -1 && this.media.volume > 0)) {\n event.preventDefault();\n }\n }),\n false\n );\n },\n};\n\nexport default listeners;\n","// ==========================================================================\n// Plyr UI\n// ==========================================================================\n\nimport utils from './utils';\nimport captions from './captions';\nimport controls from './controls';\nimport fullscreen from './fullscreen';\nimport listeners from './listeners';\n\nconst ui = {\n addStyleHook() {\n utils.toggleClass(this.elements.container, this.config.selectors.container.replace('.', ''), true);\n utils.toggleClass(this.elements.container, this.config.classNames.uiSupported, this.supported.ui);\n },\n\n // Toggle native HTML5 media controls\n toggleNativeControls(toggle = false) {\n if (toggle && this.isHTML5) {\n this.media.setAttribute('controls', '');\n } else {\n this.media.removeAttribute('controls');\n }\n },\n\n // Setup the UI\n build() {\n // Re-attach media element listeners\n // TODO: Use event bubbling\n listeners.media.call(this);\n\n // Don't setup interface if no support\n if (!this.supported.ui) {\n this.debug.warn(`Basic support only for ${this.provider} ${this.type}`);\n\n // Remove controls\n utils.removeElement.call(this, 'controls');\n\n // Remove large play\n utils.removeElement.call(this, 'buttons.play');\n\n // Restore native controls\n ui.toggleNativeControls.call(this, true);\n\n // Bail\n return;\n }\n\n // Inject custom controls if not present\n if (!utils.is.element(this.elements.controls)) {\n // Inject custom controls\n controls.inject.call(this);\n\n // Re-attach control listeners\n listeners.controls.call(this);\n }\n\n // If there's no controls, bail\n if (!utils.is.element(this.elements.controls)) {\n return;\n }\n\n // Remove native controls\n ui.toggleNativeControls.call(this);\n\n // Setup fullscreen\n fullscreen.setup.call(this);\n\n // Captions\n captions.setup.call(this);\n\n // Reset volume\n this.volume = null;\n\n // Reset mute state\n this.muted = null;\n\n // Reset speed\n this.speed = null;\n\n // Reset loop state\n this.loop = null;\n\n // Reset quality options\n this.options.quality = [];\n\n // Reset time display\n ui.timeUpdate.call(this);\n\n // Update the UI\n ui.checkPlaying.call(this);\n\n // Ready for API calls\n this.ready = true;\n\n // Ready event at end of execution stack\n utils.dispatchEvent.call(this, this.media, 'ready');\n\n // Set the title\n ui.setTitle.call(this);\n },\n\n // Setup aria attribute for play and iframe title\n setTitle() {\n // Find the current text\n let label = this.config.i18n.play;\n\n // If there's a media title set, use that for the label\n if (utils.is.string(this.config.title) && !utils.is.empty(this.config.title)) {\n label += `, ${this.config.title}`;\n\n // Set container label\n this.elements.container.setAttribute('aria-label', this.config.title);\n }\n\n // If there's a play button, set label\n if (utils.is.nodeList(this.elements.buttons.play)) {\n Array.from(this.elements.buttons.play).forEach(button => {\n button.setAttribute('aria-label', label);\n });\n }\n\n // Set iframe title\n // https://github.com/sampotts/plyr/issues/124\n if (this.isEmbed) {\n const iframe = utils.getElement.call(this, 'iframe');\n\n if (!utils.is.element(iframe)) {\n return;\n }\n\n // Default to media type\n const title = !utils.is.empty(this.config.title) ? this.config.title : 'video';\n\n iframe.setAttribute('title', this.config.i18n.frameTitle.replace('{title}', title));\n }\n },\n\n // Check playing state\n checkPlaying() {\n // Class hooks\n utils.toggleClass(this.elements.container, this.config.classNames.playing, this.playing);\n utils.toggleClass(this.elements.container, this.config.classNames.stopped, this.paused);\n\n // Set aria state\n if (utils.is.nodeList(this.elements.buttons.play)) {\n Array.from(this.elements.buttons.play).forEach(button => utils.toggleState(button, this.playing));\n }\n\n // Toggle controls\n this.toggleControls(!this.playing);\n },\n\n // Check if media is loading\n checkLoading(event) {\n this.loading = [\n 'stalled',\n 'waiting',\n ].includes(event.type);\n\n // Clear timer\n clearTimeout(this.timers.loading);\n\n // Timer to prevent flicker when seeking\n this.timers.loading = setTimeout(() => {\n // Toggle container class hook\n utils.toggleClass(this.elements.container, this.config.classNames.loading, this.loading);\n\n // Show controls if loading, hide if done\n this.toggleControls(this.loading);\n }, this.loading ? 250 : 0);\n },\n\n // Check if media failed to load\n checkFailed() {\n // https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/networkState\n this.failed = this.media.networkState === 3;\n\n if (this.failed) {\n utils.toggleClass(this.elements.container, this.config.classNames.loading, false);\n utils.toggleClass(this.elements.container, this.config.classNames.error, true);\n }\n\n // Clear timer\n clearTimeout(this.timers.failed);\n\n // Timer to prevent flicker when seeking\n this.timers.loading = setTimeout(() => {\n // Toggle container class hook\n utils.toggleClass(this.elements.container, this.config.classNames.loading, this.loading);\n\n // Show controls if loading, hide if done\n this.toggleControls(this.loading);\n }, this.loading ? 250 : 0);\n },\n\n // Update volume UI and storage\n updateVolume() {\n if (!this.supported.ui) {\n return;\n }\n\n // Update range\n if (utils.is.element(this.elements.inputs.volume)) {\n ui.setRange.call(this, this.elements.inputs.volume, this.muted ? 0 : this.volume);\n }\n\n // Update mute state\n if (utils.is.element(this.elements.buttons.mute)) {\n utils.toggleState(this.elements.buttons.mute, this.muted || this.volume === 0);\n }\n },\n\n // Update seek value and lower fill\n setRange(target, value = 0) {\n if (!utils.is.element(target)) {\n return;\n }\n\n // eslint-disable-next-line\n target.value = value;\n\n // Webkit range fill\n controls.updateRangeFill.call(this, target);\n },\n\n // Set value\n setProgress(target, input) {\n const value = utils.is.number(input) ? input : 0;\n const progress = utils.is.element(target) ? target : this.elements.display.buffer;\n\n // Update value and label\n if (utils.is.element(progress)) {\n progress.value = value;\n\n // Update text label inside\n const label = progress.getElementsByTagName('span')[0];\n if (utils.is.element(label)) {\n label.childNodes[0].nodeValue = value;\n }\n }\n },\n\n // Update elements\n updateProgress(event) {\n if (!this.supported.ui || !utils.is.event(event)) {\n return;\n }\n\n let value = 0;\n\n if (event) {\n switch (event.type) {\n // Video playing\n case 'timeupdate':\n case 'seeking':\n value = utils.getPercentage(this.currentTime, this.duration);\n\n // Set seek range value only if it's a 'natural' time event\n if (event.type === 'timeupdate') {\n ui.setRange.call(this, this.elements.inputs.seek, value);\n }\n\n break;\n\n // Check buffer status\n case 'playing':\n case 'progress':\n value = (() => {\n const { buffered } = this.media;\n\n if (buffered && buffered.length) {\n // HTML5\n return utils.getPercentage(buffered.end(0), this.duration);\n } else if (utils.is.number(buffered)) {\n // YouTube returns between 0 and 1\n return buffered * 100;\n }\n\n return 0;\n })();\n\n ui.setProgress.call(this, this.elements.display.buffer, value);\n\n break;\n\n default:\n break;\n }\n }\n },\n\n // Update the displayed time\n updateTimeDisplay(target = null, time = 0, inverted = false) {\n // Bail if there's no element to display or the value isn't a number\n if (!utils.is.element(target) || !utils.is.number(time)) {\n return;\n }\n\n // Always display hours if duration is over an hour\n const displayHours = utils.getHours(this.duration) > 0;\n\n // eslint-disable-next-line no-param-reassign\n target.textContent = utils.formatTime(time, displayHours, inverted);\n },\n\n // Handle time change event\n timeUpdate(event) {\n // Only invert if only one time element is displayed and used for both duration and currentTime\n const invert = !utils.is.element(this.elements.display.duration) && this.config.invertTime;\n\n // Duration\n ui.updateTimeDisplay.call(this, this.elements.display.currentTime, invert ? this.duration - this.currentTime : this.currentTime, invert);\n\n // Ignore updates while seeking\n if (event && event.type === 'timeupdate' && this.media.seeking) {\n return;\n }\n\n // Playing progress\n ui.updateProgress.call(this, event);\n },\n\n // Show the duration on metadataloaded\n durationUpdate() {\n if (!this.supported.ui) {\n return;\n }\n\n // If there's a spot to display duration\n const hasDuration = utils.is.element(this.elements.display.duration);\n\n // If there's only one time display, display duration there\n if (!hasDuration && this.config.displayDuration && this.paused) {\n ui.updateTimeDisplay.call(this, this.elements.display.currentTime, this.duration);\n }\n\n // If there's a duration element, update content\n if (hasDuration) {\n ui.updateTimeDisplay.call(this, this.elements.display.duration, this.duration);\n }\n\n // Update the tooltip (if visible)\n controls.updateSeekTooltip.call(this);\n },\n};\n\nexport default ui;\n","// ==========================================================================\n// Plyr controls\n// ==========================================================================\n\nimport support from './support';\nimport utils from './utils';\nimport ui from './ui';\nimport captions from './captions';\n\n// Sniff out the browser\nconst browser = utils.getBrowser();\n\nconst controls = {\n // Webkit polyfill for lower fill range\n updateRangeFill(target) {\n // WebKit only\n if (!browser.isWebkit) {\n return;\n }\n\n // Get range from event if event passed\n const range = utils.is.event(target) ? target.target : target;\n\n // Needs to be a valid \n if (!utils.is.element(range) || range.getAttribute('type') !== 'range') {\n return;\n }\n\n // Set CSS custom property\n range.style.setProperty('--value', `${range.value / range.max * 100}%`);\n },\n\n // Get icon URL\n getIconUrl() {\n return {\n url: this.config.iconUrl,\n absolute: this.config.iconUrl.indexOf('http') === 0 || (browser.isIE && !window.svg4everybody),\n };\n },\n\n // Create icon\n createIcon(type, attributes) {\n const namespace = 'http://www.w3.org/2000/svg';\n const iconUrl = controls.getIconUrl.call(this);\n const iconPath = `${!iconUrl.absolute ? iconUrl.url : ''}#${this.config.iconPrefix}`;\n\n // Create \n const icon = document.createElementNS(namespace, 'svg');\n utils.setAttributes(\n icon,\n utils.extend(attributes, {\n role: 'presentation',\n })\n );\n\n // Create the to reference sprite\n const use = document.createElementNS(namespace, 'use');\n const path = `${iconPath}-${type}`;\n\n // Set `href` attributes\n // https://github.com/sampotts/plyr/issues/460\n // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href\n if ('href' in use) {\n use.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);\n } else {\n use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', path);\n }\n\n // Add to \n icon.appendChild(use);\n\n return icon;\n },\n\n // Create hidden text label\n createLabel(type, attr) {\n let text = this.config.i18n[type];\n const attributes = Object.assign({}, attr);\n\n switch (type) {\n case 'pip':\n text = 'PIP';\n break;\n\n case 'airplay':\n text = 'AirPlay';\n break;\n\n default:\n break;\n }\n\n if ('class' in attributes) {\n attributes.class += ` ${this.config.classNames.hidden}`;\n } else {\n attributes.class = this.config.classNames.hidden;\n }\n\n return utils.createElement('span', attributes, text);\n },\n\n // Create a badge\n createBadge(text) {\n if (utils.is.empty(text)) {\n return null;\n }\n\n const badge = utils.createElement('span', {\n class: this.config.classNames.menu.value,\n });\n\n badge.appendChild(\n utils.createElement(\n 'span',\n {\n class: this.config.classNames.menu.badge,\n },\n text\n )\n );\n\n return badge;\n },\n\n // Create a
due to YouTube API issues\n const videoId = utils.parseYouTubeId(player.media.getAttribute('src'));\n const id = utils.generateId(player.provider);\n const container = utils.createElement('div', { id });\n player.media = utils.replaceElement(container, player.media);\n\n // Setup instance\n // https://developers.google.com/youtube/iframe_api_reference\n player.embed = new window.YT.Player(id, {\n videoId,\n playerVars: {\n autoplay: player.config.autoplay ? 1 : 0, // Autoplay\n controls: player.supported.ui ? 0 : 1, // Only show controls if not fully supported\n rel: 0, // No related vids\n showinfo: 0, // Hide info\n iv_load_policy: 3, // Hide annotations\n modestbranding: 1, // Hide logos as much as possible (they still show one in the corner when paused)\n disablekb: 1, // Disable keyboard as we handle it\n playsinline: 1, // Allow iOS inline playback\n\n // Tracking for stats\n // origin: window ? `${window.location.protocol}//${window.location.host}` : null,\n widget_referrer: window ? window.location.href : null,\n\n // Captions are flaky on YouTube\n cc_load_policy: player.captions.active ? 1 : 0,\n cc_lang_pref: player.config.captions.language,\n },\n events: {\n onError(event) {\n // If we've already fired an error, don't do it again\n // YouTube fires onError twice\n if (utils.is.object(player.media.error)) {\n return;\n }\n\n const detail = {\n code: event.data,\n };\n\n // Messages copied from https://developers.google.com/youtube/iframe_api_reference#onError\n switch (event.data) {\n case 2:\n detail.message =\n 'The request contains an invalid parameter value. For example, this error occurs if you specify a video ID that does not have 11 characters, or if the video ID contains invalid characters, such as exclamation points or asterisks.';\n break;\n\n case 5:\n detail.message =\n 'The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.';\n break;\n\n case 100:\n detail.message =\n 'The video requested was not found. This error occurs when a video has been removed (for any reason) or has been marked as private.';\n break;\n\n case 101:\n case 150:\n detail.message = 'The owner of the requested video does not allow it to be played in embedded players.';\n break;\n\n default:\n detail.message = 'An unknown error occured';\n break;\n }\n\n player.media.error = detail;\n\n utils.dispatchEvent.call(player, player.media, 'error');\n },\n onPlaybackQualityChange(event) {\n // Get the instance\n const instance = event.target;\n\n // Get current quality\n player.media.quality = instance.getPlaybackQuality();\n\n utils.dispatchEvent.call(player, player.media, 'qualitychange');\n },\n onPlaybackRateChange(event) {\n // Get the instance\n const instance = event.target;\n\n // Get current speed\n player.media.playbackRate = instance.getPlaybackRate();\n\n utils.dispatchEvent.call(player, player.media, 'ratechange');\n },\n onReady(event) {\n // Get the instance\n const instance = event.target;\n\n // Get the title\n youtube.getTitle.call(player, videoId);\n\n // Create a faux HTML5 API using the YouTube API\n player.media.play = () => {\n instance.playVideo();\n player.media.paused = false;\n };\n\n player.media.pause = () => {\n instance.pauseVideo();\n player.media.paused = true;\n };\n\n player.media.stop = () => {\n instance.stopVideo();\n player.media.paused = true;\n };\n\n player.media.duration = instance.getDuration();\n player.media.paused = true;\n\n // Seeking\n player.media.currentTime = 0;\n Object.defineProperty(player.media, 'currentTime', {\n get() {\n return Number(instance.getCurrentTime());\n },\n set(time) {\n // Set seeking flag\n player.media.seeking = true;\n\n // Trigger seeking\n utils.dispatchEvent.call(player, player.media, 'seeking');\n\n // Seek after events sent\n instance.seekTo(time);\n },\n });\n\n // Playback speed\n Object.defineProperty(player.media, 'playbackRate', {\n get() {\n return instance.getPlaybackRate();\n },\n set(input) {\n instance.setPlaybackRate(input);\n },\n });\n\n // Quality\n Object.defineProperty(player.media, 'quality', {\n get() {\n return instance.getPlaybackQuality();\n },\n set(input) {\n // Trigger request event\n utils.dispatchEvent.call(player, player.media, 'qualityrequested', false, {\n quality: input,\n });\n\n instance.setPlaybackQuality(input);\n },\n });\n\n // Volume\n let { volume } = player.config;\n Object.defineProperty(player.media, 'volume', {\n get() {\n return volume;\n },\n set(input) {\n volume = input;\n instance.setVolume(volume * 100);\n utils.dispatchEvent.call(player, player.media, 'volumechange');\n },\n });\n\n // Muted\n let { muted } = player.config;\n Object.defineProperty(player.media, 'muted', {\n get() {\n return muted;\n },\n set(input) {\n const toggle = utils.is.boolean(input) ? input : muted;\n muted = toggle;\n instance[toggle ? 'mute' : 'unMute']();\n utils.dispatchEvent.call(player, player.media, 'volumechange');\n },\n });\n\n // Source\n Object.defineProperty(player.media, 'currentSrc', {\n get() {\n return instance.getVideoUrl();\n },\n });\n\n // Ended\n Object.defineProperty(player.media, 'ended', {\n get() {\n return player.currentTime === player.duration;\n },\n });\n\n // Get available speeds\n player.options.speed = instance.getAvailablePlaybackRates();\n\n // Set the tabindex to avoid focus entering iframe\n if (player.supported.ui) {\n player.media.setAttribute('tabindex', -1);\n }\n\n utils.dispatchEvent.call(player, player.media, 'timeupdate');\n utils.dispatchEvent.call(player, player.media, 'durationchange');\n\n // Reset timer\n window.clearInterval(player.timers.buffering);\n\n // Setup buffering\n player.timers.buffering = window.setInterval(() => {\n // Get loaded % from YouTube\n player.media.buffered = instance.getVideoLoadedFraction();\n\n // Trigger progress only when we actually buffer something\n if (player.media.lastBuffered === null || player.media.lastBuffered < player.media.buffered) {\n utils.dispatchEvent.call(player, player.media, 'progress');\n }\n\n // Set last buffer point\n player.media.lastBuffered = player.media.buffered;\n\n // Bail if we're at 100%\n if (player.media.buffered === 1) {\n window.clearInterval(player.timers.buffering);\n\n // Trigger event\n utils.dispatchEvent.call(player, player.media, 'canplaythrough');\n }\n }, 200);\n\n // Rebuild UI\n window.setTimeout(() => ui.build.call(player), 50);\n },\n onStateChange(event) {\n // Get the instance\n const instance = event.target;\n\n // Reset timer\n window.clearInterval(player.timers.playing);\n\n // Handle events\n // -1 Unstarted\n // 0 Ended\n // 1 Playing\n // 2 Paused\n // 3 Buffering\n // 5 Video cued\n switch (event.data) {\n case 0:\n player.media.paused = true;\n\n // YouTube doesn't support loop for a single video, so mimick it.\n if (player.media.loop) {\n // YouTube needs a call to `stopVideo` before playing again\n instance.stopVideo();\n instance.playVideo();\n } else {\n utils.dispatchEvent.call(player, player.media, 'ended');\n }\n\n break;\n\n case 1:\n // If we were seeking, fire seeked event\n if (player.media.seeking) {\n utils.dispatchEvent.call(player, player.media, 'seeked');\n }\n player.media.seeking = false;\n\n // Only fire play if paused before\n if (player.media.paused) {\n utils.dispatchEvent.call(player, player.media, 'play');\n }\n player.media.paused = false;\n\n utils.dispatchEvent.call(player, player.media, 'playing');\n\n // Poll to get playback progress\n player.timers.playing = window.setInterval(() => {\n utils.dispatchEvent.call(player, player.media, 'timeupdate');\n }, 50);\n\n // Check duration again due to YouTube bug\n // https://github.com/sampotts/plyr/issues/374\n // https://code.google.com/p/gdata-issues/issues/detail?id=8690\n if (player.media.duration !== instance.getDuration()) {\n player.media.duration = instance.getDuration();\n utils.dispatchEvent.call(player, player.media, 'durationchange');\n }\n\n // Get quality\n controls.setQualityMenu.call(player, instance.getAvailableQualityLevels());\n\n break;\n\n case 2:\n player.media.paused = true;\n\n utils.dispatchEvent.call(player, player.media, 'pause');\n\n break;\n\n default:\n break;\n }\n\n utils.dispatchEvent.call(player, player.elements.container, 'statechange', false, {\n code: event.data,\n });\n },\n },\n });\n },\n};\n\nexport default youtube;\n","// ==========================================================================\n// Vimeo plugin\n// ==========================================================================\n\nimport utils from './../utils';\nimport captions from './../captions';\nimport ui from './../ui';\n\nconst vimeo = {\n setup() {\n // Add embed class for responsive\n utils.toggleClass(this.elements.wrapper, this.config.classNames.embed, true);\n\n // Set intial ratio\n vimeo.setAspectRatio.call(this);\n\n // Load the API if not already\n if (!utils.is.object(window.Vimeo)) {\n utils.loadScript(this.config.urls.vimeo.api, () => {\n vimeo.ready.call(this);\n });\n } else {\n vimeo.ready.call(this);\n }\n },\n\n // Set aspect ratio\n // For Vimeo we have an extra 300% height
to hide the standard controls and UI\n setAspectRatio(input) {\n const ratio = utils.is.string(input) ? input.split(':') : this.config.ratio.split(':');\n const padding = 100 / ratio[0] * ratio[1];\n const height = 200;\n const offset = (height - padding) / (height / 50);\n this.elements.wrapper.style.paddingBottom = `${padding}%`;\n this.media.style.transform = `translateY(-${offset}%)`;\n },\n\n // API Ready\n ready() {\n const player = this;\n\n // Get Vimeo params for the iframe\n const options = {\n loop: player.config.loop.active,\n autoplay: player.autoplay,\n byline: false,\n portrait: false,\n title: false,\n speed: true,\n transparent: 0,\n gesture: 'media',\n };\n const params = utils.buildUrlParams(options);\n const id = utils.parseVimeoId(player.media.getAttribute('src'));\n\n // Build an iframe\n const iframe = utils.createElement('iframe');\n const src = `https://player.vimeo.com/video/${id}?${params}`;\n iframe.setAttribute('src', src);\n iframe.setAttribute('allowfullscreen', '');\n iframe.setAttribute('allowtransparency', '');\n iframe.setAttribute('allow', 'autoplay');\n\n // Inject the package\n const wrapper = utils.createElement('div');\n wrapper.appendChild(iframe);\n player.media = utils.replaceElement(wrapper, player.media);\n\n // Setup instance\n // https://github.com/vimeo/player.js\n player.embed = new window.Vimeo.Player(iframe);\n\n player.media.paused = true;\n player.media.currentTime = 0;\n\n // Create a faux HTML5 API using the Vimeo API\n player.media.play = () => {\n player.embed.play().then(() => {\n player.media.paused = false;\n });\n };\n\n player.media.pause = () => {\n player.embed.pause().then(() => {\n player.media.paused = true;\n });\n };\n\n player.media.stop = () => {\n player.embed.stop().then(() => {\n player.media.paused = true;\n player.currentTime = 0;\n });\n };\n\n // Seeking\n let { currentTime } = player.media;\n Object.defineProperty(player.media, 'currentTime', {\n get() {\n return currentTime;\n },\n set(time) {\n // Get current paused state\n // Vimeo will automatically play on seek\n const { paused } = player.media;\n\n // Set seeking flag\n player.media.seeking = true;\n\n // Trigger seeking\n utils.dispatchEvent.call(player, player.media, 'seeking');\n\n // Seek after events\n player.embed.setCurrentTime(time);\n\n // Restore pause state\n if (paused) {\n player.pause();\n }\n },\n });\n\n // Playback speed\n let speed = player.config.speed.selected;\n Object.defineProperty(player.media, 'playbackRate', {\n get() {\n return speed;\n },\n set(input) {\n player.embed.setPlaybackRate(input).then(() => {\n speed = input;\n utils.dispatchEvent.call(player, player.media, 'ratechange');\n });\n },\n });\n\n // Volume\n let { volume } = player.config;\n Object.defineProperty(player.media, 'volume', {\n get() {\n return volume;\n },\n set(input) {\n player.embed.setVolume(input).then(() => {\n volume = input;\n utils.dispatchEvent.call(player, player.media, 'volumechange');\n });\n },\n });\n\n // Muted\n let { muted } = player.config;\n Object.defineProperty(player.media, 'muted', {\n get() {\n return muted;\n },\n set(input) {\n const toggle = utils.is.boolean(input) ? input : false;\n\n player.embed.setVolume(toggle ? 0 : player.config.volume).then(() => {\n muted = toggle;\n utils.dispatchEvent.call(player, player.media, 'volumechange');\n });\n },\n });\n\n // Loop\n let { loop } = player.config;\n Object.defineProperty(player.media, 'loop', {\n get() {\n return loop;\n },\n set(input) {\n const toggle = utils.is.boolean(input) ? input : player.config.loop.active;\n\n player.embed.setLoop(toggle).then(() => {\n loop = toggle;\n });\n },\n });\n\n // Source\n let currentSrc;\n player.embed.getVideoUrl().then(value => {\n currentSrc = value;\n });\n Object.defineProperty(player.media, 'currentSrc', {\n get() {\n return currentSrc;\n },\n });\n\n // Ended\n Object.defineProperty(player.media, 'ended', {\n get() {\n return player.currentTime === player.duration;\n },\n });\n\n // Set aspect ratio based on video size\n Promise.all([\n player.embed.getVideoWidth(),\n player.embed.getVideoHeight(),\n ]).then(dimensions => {\n const ratio = utils.getAspectRatio(dimensions[0], dimensions[1]);\n vimeo.setAspectRatio.call(this, ratio);\n });\n\n // Set autopause\n player.embed.setAutopause(player.config.autopause).then(state => {\n player.config.autopause = state;\n });\n\n // Get title\n player.embed.getVideoTitle().then(title => {\n player.config.title = title;\n ui.setTitle.call(this);\n });\n\n // Get current time\n player.embed.getCurrentTime().then(value => {\n currentTime = value;\n utils.dispatchEvent.call(player, player.media, 'timeupdate');\n });\n\n // Get duration\n player.embed.getDuration().then(value => {\n player.media.duration = value;\n utils.dispatchEvent.call(player, player.media, 'durationchange');\n });\n\n // Get captions\n player.embed.getTextTracks().then(tracks => {\n player.media.textTracks = tracks;\n captions.setup.call(player);\n });\n\n player.embed.on('cuechange', data => {\n let cue = null;\n\n if (data.cues.length) {\n cue = utils.stripHTML(data.cues[0].text);\n }\n\n captions.setText.call(player, cue);\n });\n\n player.embed.on('loaded', () => {\n if (utils.is.element(player.embed.element) && player.supported.ui) {\n const frame = player.embed.element;\n\n // Fix keyboard focus issues\n // https://github.com/sampotts/plyr/issues/317\n frame.setAttribute('tabindex', -1);\n }\n });\n\n player.embed.on('play', () => {\n // Only fire play if paused before\n if (player.media.paused) {\n utils.dispatchEvent.call(player, player.media, 'play');\n }\n player.media.paused = false;\n utils.dispatchEvent.call(player, player.media, 'playing');\n });\n\n player.embed.on('pause', () => {\n player.media.paused = true;\n utils.dispatchEvent.call(player, player.media, 'pause');\n });\n\n player.embed.on('timeupdate', data => {\n player.media.seeking = false;\n currentTime = data.seconds;\n utils.dispatchEvent.call(player, player.media, 'timeupdate');\n });\n\n player.embed.on('progress', data => {\n player.media.buffered = data.percent;\n utils.dispatchEvent.call(player, player.media, 'progress');\n\n // Check all loaded\n if (parseInt(data.percent, 10) === 1) {\n utils.dispatchEvent.call(player, player.media, 'canplaythrough');\n }\n });\n\n player.embed.on('seeked', () => {\n player.media.seeking = false;\n utils.dispatchEvent.call(player, player.media, 'seeked');\n utils.dispatchEvent.call(player, player.media, 'play');\n });\n\n player.embed.on('ended', () => {\n player.media.paused = true;\n utils.dispatchEvent.call(player, player.media, 'ended');\n });\n\n player.embed.on('error', detail => {\n player.media.error = detail;\n utils.dispatchEvent.call(player, player.media, 'error');\n });\n\n // Rebuild UI\n window.setTimeout(() => ui.build.call(player), 0);\n },\n};\n\nexport default vimeo;\n","// ==========================================================================\n// Plyr Media\n// ==========================================================================\n\nimport support from './support';\nimport utils from './utils';\nimport youtube from './plugins/youtube';\nimport vimeo from './plugins/vimeo';\nimport ui from './ui';\n\n// Sniff out the browser\nconst browser = utils.getBrowser();\n\nconst media = {\n // Setup media\n setup() {\n // If there's no media, bail\n if (!this.media) {\n this.debug.warn('No media element found!');\n return;\n }\n\n // Add type class\n utils.toggleClass(this.elements.container, this.config.classNames.type.replace('{0}', this.type), true);\n\n // Add provider class\n utils.toggleClass(this.elements.container, this.config.classNames.provider.replace('{0}', this.provider), true);\n\n // Add video class for embeds\n // This will require changes if audio embeds are added\n if (this.isEmbed) {\n utils.toggleClass(this.elements.container, this.config.classNames.type.replace('{0}', 'video'), true);\n }\n\n if (this.supported.ui) {\n // Check for picture-in-picture support\n utils.toggleClass(this.elements.container, this.config.classNames.pip.supported, support.pip && this.isHTML5 && this.isVideo);\n\n // Check for airplay support\n utils.toggleClass(this.elements.container, this.config.classNames.airplay.supported, support.airplay && this.isHTML5);\n\n // If there's no autoplay attribute, assume the video is stopped and add state class\n utils.toggleClass(this.elements.container, this.config.classNames.stopped, this.config.autoplay);\n\n // Add iOS class\n utils.toggleClass(this.elements.container, this.config.classNames.isIos, browser.isIos);\n\n // Add touch class\n utils.toggleClass(this.elements.container, this.config.classNames.isTouch, support.touch);\n }\n\n // Inject the player wrapper\n if (this.isVideo) {\n // Create the wrapper div\n this.elements.wrapper = utils.createElement('div', {\n class: this.config.classNames.video,\n });\n\n // Wrap the video in a container\n utils.wrap(this.media, this.elements.wrapper);\n }\n\n if (this.isEmbed) {\n switch (this.provider) {\n case 'youtube':\n youtube.setup.call(this);\n break;\n\n case 'vimeo':\n vimeo.setup.call(this);\n break;\n\n default:\n break;\n }\n } else if (this.isHTML5) {\n ui.setTitle.call(this);\n }\n },\n\n // Cancel current network requests\n // See https://github.com/sampotts/plyr/issues/174\n cancelRequests() {\n if (!this.isHTML5) {\n return;\n }\n\n // Remove child sources\n Array.from(this.media.querySelectorAll('source')).forEach(utils.removeElement);\n\n // Set blank video src attribute\n // This is to prevent a MEDIA_ERR_SRC_NOT_SUPPORTED error\n // Info: http://stackoverflow.com/questions/32231579/how-to-properly-dispose-of-an-html5-video-and-close-socket-or-connection\n this.media.setAttribute('src', this.config.blankVideo);\n\n // Load the new empty source\n // This will cancel existing requests\n // See https://github.com/sampotts/plyr/issues/174\n this.media.load();\n\n // Debugging\n this.debug.log('Cancelled network requests');\n },\n};\n\nexport default media;\n","// ==========================================================================\n// Plyr source update\n// ==========================================================================\n\nimport { providers } from './types';\nimport utils from './utils';\nimport media from './media';\nimport ui from './ui';\nimport support from './support';\n\nconst source = {\n // Add elements to HTML5 media (source, tracks, etc)\n insertElements(type, attributes) {\n if (utils.is.string(attributes)) {\n utils.insertElement(type, this.media, {\n src: attributes,\n });\n } else if (utils.is.array(attributes)) {\n attributes.forEach(attribute => {\n utils.insertElement(type, this.media, attribute);\n });\n }\n },\n\n // Update source\n // Sources are not checked for support so be careful\n change(input) {\n if (!utils.is.object(input) || !('sources' in input) || !input.sources.length) {\n this.debug.warn('Invalid source format');\n return;\n }\n\n // Cancel current network requests\n media.cancelRequests.call(this);\n\n // Destroy instance and re-setup\n this.destroy.call(\n this,\n () => {\n // TODO: Reset menus here\n\n // Remove elements\n utils.removeElement(this.media);\n this.media = null;\n\n // Reset class name\n if (utils.is.element(this.elements.container)) {\n this.elements.container.removeAttribute('class');\n }\n\n // Set the type and provider\n this.type = input.type;\n this.provider = !utils.is.empty(input.sources[0].provider) ? input.sources[0].provider : providers.html5;\n\n // Check for support\n this.supported = support.check(this.type, this.provider, this.config.inline);\n\n // Create new markup\n switch (`${this.provider}:${this.type}`) {\n case 'html5:video':\n this.media = utils.createElement('video');\n break;\n\n case 'html5:audio':\n this.media = utils.createElement('audio');\n break;\n\n case 'youtube:video':\n case 'vimeo:video':\n this.media = utils.createElement('div', {\n src: input.sources[0].src,\n });\n break;\n\n default:\n break;\n }\n\n // Inject the new element\n this.elements.container.appendChild(this.media);\n\n // Autoplay the new source?\n if (utils.is.boolean(input.autoplay)) {\n this.config.autoplay = input.autoplay;\n }\n\n // Set attributes for audio and video\n if (this.isHTML5) {\n if (this.config.crossorigin) {\n this.media.setAttribute('crossorigin', '');\n }\n if (this.config.autoplay) {\n this.media.setAttribute('autoplay', '');\n }\n if ('poster' in input) {\n this.media.setAttribute('poster', input.poster);\n }\n if (this.config.loop.active) {\n this.media.setAttribute('loop', '');\n }\n if (this.config.muted) {\n this.media.setAttribute('muted', '');\n }\n if (this.config.inline) {\n this.media.setAttribute('playsinline', '');\n }\n }\n\n // Restore class hook\n ui.addStyleHook.call(this);\n\n // Set new sources for html5\n if (this.isHTML5) {\n source.insertElements.call(this, 'source', input.sources);\n }\n\n // Set video title\n this.config.title = input.title;\n\n // Set up from scratch\n media.setup.call(this);\n\n // HTML5 stuff\n if (this.isHTML5) {\n // Setup captions\n if ('tracks' in input) {\n source.insertElements.call(this, 'track', input.tracks);\n }\n\n // Load HTML5 sources\n this.media.load();\n }\n\n // If HTML5 or embed but not fully supported, setupInterface and call ready now\n if (this.isHTML5 || (this.isEmbed && !this.supported.ui)) {\n // Setup interface\n ui.build.call(this);\n }\n },\n true,\n );\n },\n};\n\nexport default source;\n","// ==========================================================================\n// Plyr\n// plyr.js v3.0.0-beta.11\n// https://github.com/sampotts/plyr\n// License: The MIT License (MIT)\n// ==========================================================================\n\nimport { providers, types } from './types';\nimport defaults from './defaults';\nimport support from './support';\nimport utils from './utils';\n\nimport Console from './console';\nimport Storage from './storage';\nimport Ads from './plugins/ads';\n\nimport captions from './captions';\nimport controls from './controls';\nimport fullscreen from './fullscreen';\nimport listeners from './listeners';\nimport media from './media';\nimport source from './source';\nimport ui from './ui';\n\n// Private properties\n// TODO: Use a WeakMap for private globals\n// const globals = new WeakMap();\n\n// Globals\nlet scrollPosition = {\n x: 0,\n y: 0,\n};\n\n// Plyr instance\nclass Plyr {\n constructor(target, options) {\n this.timers = {};\n\n // State\n this.ready = false;\n this.loading = false;\n this.failed = false;\n\n // Set the media element\n this.media = target;\n\n // String selector passed\n if (utils.is.string(this.media)) {\n this.media = document.querySelectorAll(this.media);\n }\n\n // jQuery, NodeList or Array passed, use first element\n if ((window.jQuery && this.media instanceof jQuery) || utils.is.nodeList(this.media) || utils.is.array(this.media)) {\n // eslint-disable-next-line\n this.media = this.media[0];\n }\n\n // Set config\n this.config = utils.extend(\n {},\n defaults,\n options,\n (() => {\n try {\n return JSON.parse(this.media.getAttribute('data-plyr-config'));\n } catch (e) {\n return {};\n }\n })(),\n );\n\n // Elements cache\n this.elements = {\n container: null,\n buttons: {},\n display: {},\n progress: {},\n inputs: {},\n settings: {\n menu: null,\n panes: {},\n tabs: {},\n },\n captions: null,\n };\n\n // Captions\n this.captions = {\n active: null,\n currentTrack: null,\n };\n\n // Fullscreen\n this.fullscreen = {\n active: false,\n };\n\n // Options\n this.options = {\n speed: [],\n quality: [],\n };\n\n // Debugging\n // TODO: move to globals\n this.debug = new Console(this.config.debug);\n\n // Log config options and support\n this.debug.log('Config', this.config);\n this.debug.log('Support', support);\n\n // We need an element to setup\n if (utils.is.nullOrUndefined(this.media) || !utils.is.element(this.media)) {\n this.debug.error('Setup failed: no suitable element passed');\n return;\n }\n\n // Bail if the element is initialized\n if (this.media.plyr) {\n this.debug.warn('Target already setup');\n return;\n }\n\n // Bail if not enabled\n if (!this.config.enabled) {\n this.debug.error('Setup failed: disabled by config');\n return;\n }\n\n // Bail if disabled or no basic support\n // You may want to disable certain UAs etc\n if (!support.check().api) {\n this.debug.error('Setup failed: no support');\n return;\n }\n\n // Cache original element state for .destroy()\n this.elements.original = this.media.cloneNode(true);\n\n // Set media type based on tag or data attribute\n // Supported: video, audio, vimeo, youtube\n const type = this.media.tagName.toLowerCase();\n\n // Embed properties\n let iframe = null;\n let url = null;\n let params = null;\n\n // Different setup based on type\n switch (type) {\n case 'div':\n // Find the frame\n iframe = this.media.querySelector('iframe');\n\n //
``` +_Note_: The `plyr__video-embed` classname will make the player a responsive 16:9 (most common) iframe embed. When plyr itself kicks in, your custom `ratio` config option will be used. + +Or the `
` non progressively enhanced method: + +```html +
+``` + +_Note_: The `data-plyr-embed-id` can either be the video ID or URL for the media. + #### Vimeo embed +Much the same as YouTube above. + ```html
``` +Or the `
` non progressively enhanced method: + +```html +
+``` + ### JavaScript Include the `plyr.js` script before the closing `` tag and then call `plyr.setup()`. More info on `setup()` can be found under @@ -125,6 +145,8 @@ If you want to use our CDN (provided by [Fastly](https://www.fastly.com/)) for t ``` +_Note_: Be sure to read the [polyfills](#polyfills) section below about browser compatibility + ### CSS Include the `plyr.css` stylsheet into your `` @@ -570,22 +592,25 @@ Fullscreen in Plyr is supported by all browsers that [currently support it](http ## Browser support -Plyr supports the last 2 versions of most _modern_ browsers. IE11 is also supported. +Plyr supports the last 2 versions of most _modern_ browsers. -| Browser | Supported | -| ------------- | -------------- | -| Safari | ✔ | -| Mobile Safari | ✔¹ | -| Firefox | ✔ | -| Chrome | ✔ | -| Opera | ✔ | -| Edge | ✔ | -| IE10+ | ✔² | -| IE9 | API only³ | +| Browser | Supported | +| ------------- | --------- | +| Safari | ✔ | +| Mobile Safari | ✔¹ | +| Firefox | ✔ | +| Chrome | ✔ | +| Opera | ✔ | +| Edge | ✔ | +| IE11 | ✔ | +| IE10 | ✔² | -1. Mobile Safari on the iPhone forces the native player for `