From 0ef87f93a6e93abbdcf4cc7d949ed6938ab79e11 Mon Sep 17 00:00:00 2001 From: Guru Prasad Srinivasa Date: Sun, 30 Oct 2016 00:49:09 -0400 Subject: [PATCH 1/5] Added logic to parse youtube video id This commit is targetted at solving issue#345 and adds functionality to parse youtube video IDs from various types of youtube video URLs. Other embed types like vimeo/soundcloud can be extended by following a similar structure as implemented in this commit. --- src/js/plyr.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/js/plyr.js b/src/js/plyr.js index dd14f767..4ebb060a 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -3259,6 +3259,19 @@ } } + // Taken from https://gist.github.com/takien/4077195 + function parseYoutubeVideoId(url) { + var videoId; + url = url.replace(/(>|<)/gi,'').split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/); + if(url[2] !== undefined) { + videoId = url[2].split(/[^0-9a-z_\-]/i); + videoId = videoId[0]; + } else { + videoId = url; + } + return videoId; + } + // Setup a player function _init() { // Bail if the element is initialized @@ -3287,6 +3300,12 @@ plyr.type = media.getAttribute('data-type'); plyr.embedId = media.getAttribute('data-video-id'); + switch(plyr.type) { + case 'youtube': + plyr.embedId = parseYoutubeVideoId(plyr.embedId); + break; + } + // Clean up media.removeAttribute('data-type'); media.removeAttribute('data-video-id'); From efe54fbba4b4b1134fef87f7e839fbd0ba46418a Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Wed, 2 Nov 2016 18:09:40 +1100 Subject: [PATCH 2/5] Added seek event fixes (fixes #409), Added support for URLs (fixes #345) --- demo/dist/demo.js | 2 +- demo/src/js/main.js | 2 +- dist/plyr.js | 4 +-- readme.md | 36 +++++++++++++++++------- src/js/plyr.js | 67 +++++++++++++++++++++++++++++---------------- 5 files changed, 74 insertions(+), 37 deletions(-) diff --git a/demo/dist/demo.js b/demo/dist/demo.js index 8c0e3080..3ecf85aa 100644 --- a/demo/dist/demo.js +++ b/demo/dist/demo.js @@ -1 +1 @@ -"document"in self&&("classList"in document.createElement("_")?!function(){"use strict";var e=document.createElement("_");if(e.classList.add("c1","c2"),!e.classList.contains("c2")){var t=function(e){var t=DOMTokenList.prototype[e];DOMTokenList.prototype[e]=function(e){var i,s=arguments.length;for(i=0;i=0;a--)e(o[a].parentElement,"active",!1);e(document.querySelector('[data-source="'+t+'"]').parentElement,"active",!0)}}var i=plyr.setup({debug:!0,title:"Video demo",iconUrl:"../dist/plyr.svg",tooltips:{controls:!0},captions:{defaultActive:!0}});plyr.loadSprite("dist/demo.svg");for(var s=i[0],o=document.querySelectorAll("[data-source]"),n={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},r=window.location.hash.replace("#",""),a=window.history&&window.history.pushState,c=o.length-1;c>=0;c--)o[c].addEventListener("click",function(){var e=this.getAttribute("data-source");t(e),a&&history.pushState({type:e},"","#"+e)});if(window.addEventListener("popstate",function(e){e.state&&"type"in e.state&&t(e.state.type)}),a){var l=!r.length;l&&(r=n.video),r in n&&history.replaceState({type:r},"",l?"":"#"+r),r!==n.video&&t(r,!0)}}(),document.domain.indexOf("plyr.io")>-1&&(!function(e,t,i,s,o,n,r){e.GoogleAnalyticsObject=o,e[o]=e[o]||function(){(e[o].q=e[o].q||[]).push(arguments)},e[o].l=1*new Date,n=t.createElement(i),r=t.getElementsByTagName(i)[0],n.async=1,n.src=s,r.parentNode.insertBefore(n,r)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),ga("create","UA-40881672-11","auto"),ga("send","pageview")); \ No newline at end of file +"document"in self&&("classList"in document.createElement("_")?!function(){"use strict";var e=document.createElement("_");if(e.classList.add("c1","c2"),!e.classList.contains("c2")){var t=function(e){var t=DOMTokenList.prototype[e];DOMTokenList.prototype[e]=function(e){var i,s=arguments.length;for(i=0;i=0;a--)e(o[a].parentElement,"active",!1);e(document.querySelector('[data-source="'+t+'"]').parentElement,"active",!0)}}var i=plyr.setup({debug:!0,title:"Video demo",iconUrl:"../dist/plyr.svg",tooltips:{controls:!0},captions:{defaultActive:!0}});plyr.loadSprite("dist/demo.svg");for(var s=i[0],o=document.querySelectorAll("[data-source]"),n={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},r=window.location.hash.replace("#",""),a=window.history&&window.history.pushState,c=o.length-1;c>=0;c--)o[c].addEventListener("click",function(){var e=this.getAttribute("data-source");t(e),a&&history.pushState({type:e},"","#"+e)});if(window.addEventListener("popstate",function(e){e.state&&"type"in e.state&&t(e.state.type)}),a){var l=!r.length;l&&(r=n.video),r in n&&history.replaceState({type:r},"",l?"":"#"+r),r!==n.video&&t(r,!0)}}(),document.domain.indexOf("plyr.io")>-1&&(!function(e,t,i,s,o,n,r){e.GoogleAnalyticsObject=o,e[o]=e[o]||function(){(e[o].q=e[o].q||[]).push(arguments)},e[o].l=1*new Date,n=t.createElement(i),r=t.getElementsByTagName(i)[0],n.async=1,n.src=s,r.parentNode.insertBefore(n,r)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),ga("create","UA-40881672-11","auto"),ga("send","pageview")); \ No newline at end of file diff --git a/demo/src/js/main.js b/demo/src/js/main.js index 3337df88..56f7d634 100644 --- a/demo/src/js/main.js +++ b/demo/src/js/main.js @@ -94,7 +94,7 @@ // Set a new source function newSource(type, init) { // Bail if new type isn't known, it's the current type, or current type is empty (video is default) and new type is video - if(!(type in types) || (!init && type == currentType) || (!currentType.length && type == types.video)) { + if(!(type in types) || (!init && type === currentType) || (!currentType.length && type === types.video)) { return; } diff --git a/dist/plyr.js b/dist/plyr.js index ae69ee52..d5446449 100644 --- a/dist/plyr.js +++ b/dist/plyr.js @@ -1,2 +1,2 @@ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=t(e,document):"function"==typeof define&&define.amd?define([],function(){return t(e,document)}):e.plyr=t(e,document)}("undefined"!=typeof window?window:this,function(e,t){"use strict";function n(){var e,n,r,a=navigator.userAgent,s=navigator.appName,o=""+parseFloat(navigator.appVersion),i=parseInt(navigator.appVersion,10),l=!1,u=!1,c=!1,d=!1;return navigator.appVersion.indexOf("Windows NT")!==-1&&navigator.appVersion.indexOf("rv:11")!==-1?(l=!0,s="IE",o="11"):(n=a.indexOf("MSIE"))!==-1?(l=!0,s="IE",o=a.substring(n+5)):(n=a.indexOf("Chrome"))!==-1?(c=!0,s="Chrome",o=a.substring(n+7)):(n=a.indexOf("Safari"))!==-1?(d=!0,s="Safari",o=a.substring(n+7),(n=a.indexOf("Version"))!==-1&&(o=a.substring(n+8))):(n=a.indexOf("Firefox"))!==-1?(u=!0,s="Firefox",o=a.substring(n+8)):(e=a.lastIndexOf(" ")+1)<(n=a.lastIndexOf("/"))&&(s=a.substring(e,n),o=a.substring(n+1),s.toLowerCase()===s.toUpperCase()&&(s=navigator.appName)),(r=o.indexOf(";"))!==-1&&(o=o.substring(0,r)),(r=o.indexOf(" "))!==-1&&(o=o.substring(0,r)),i=parseInt(""+o,10),isNaN(i)&&(o=""+parseFloat(navigator.appVersion),i=parseInt(navigator.appVersion,10)),{name:s,version:i,isIE:l,isFirefox:u,isChrome:c,isSafari:d,isIos:/(iPad|iPhone|iPod)/g.test(navigator.platform),isTouch:"ontouchstart"in t.documentElement}}function r(e,t){var n=e.media;if("video"===e.type)switch(t){case"video/webm":return!(!n.canPlayType||!n.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/no/,""));case"video/mp4":return!(!n.canPlayType||!n.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"').replace(/no/,""));case"video/ogg":return!(!n.canPlayType||!n.canPlayType('video/ogg; codecs="theora"').replace(/no/,""))}else if("audio"===e.type)switch(t){case"audio/mpeg":return!(!n.canPlayType||!n.canPlayType("audio/mpeg;").replace(/no/,""));case"audio/ogg":return!(!n.canPlayType||!n.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/,""));case"audio/wav":return!(!n.canPlayType||!n.canPlayType('audio/wav; codecs="1"').replace(/no/,""))}return!1}function a(e){if(!t.querySelectorAll('script[src="'+e+'"]').length){var n=t.createElement("script");n.src=e;var r=t.getElementsByTagName("script")[0];r.parentNode.insertBefore(n,r)}}function s(e,t){return Array.prototype.indexOf&&e.indexOf(t)!==-1}function o(e,t,n){return e.replace(new RegExp(t.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g,"\\$1"),"g"),n)}function i(e,t){e.length||(e=[e]);for(var n=e.length-1;n>=0;n--){var r=n>0?t.cloneNode(!0):t,a=e[n],s=a.parentNode,o=a.nextSibling;return r.appendChild(a),o?s.insertBefore(r,o):s.appendChild(r),r}}function l(e){e&&e.parentNode.removeChild(e)}function u(e,t){e.insertBefore(t,e.firstChild)}function c(e,t){for(var n in t)e.setAttribute(n,P.boolean(t[n])&&t[n]?"":t[n])}function d(e,n,r){var a=t.createElement(e);c(a,r),u(n,a)}function p(e){return e.replace(".","")}function m(e,t,n){if(e)if(e.classList)e.classList[n?"add":"remove"](t);else{var r=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=r+(n?" "+t:"")}}function f(e,t){return!!e&&(e.classList?e.classList.contains(t):new RegExp("(\\s|^)"+t+"(\\s|$)").test(e.className))}function y(e,n){var r=Element.prototype,a=r.matches||r.webkitMatchesSelector||r.mozMatchesSelector||r.msMatchesSelector||function(e){return[].indexOf.call(t.querySelectorAll(e),this)!==-1};return a.call(e,n)}function b(e,t,n,r,a){g(e,t,function(t){n&&n.apply(e,[t]),r.apply(e,[t])},a)}function v(e,t,n,r,a){var s=t.split(" ");if(P.boolean(a)||(a=!1),e instanceof NodeList)for(var o=0;o','',''+S.i18n.play+"",""),e.push('
'),s(S.controls,"restart")&&e.push('"),s(S.controls,"rewind")&&e.push('"),s(S.controls,"play")&&e.push('",'"),s(S.controls,"fast-forward")&&e.push('"),s(S.controls,"progress")&&(e.push('','','','','',"0% "+S.i18n.buffered,""),S.tooltips.seek&&e.push('00:00'),e.push("")),s(S.controls,"current-time")&&e.push('',''+S.i18n.currentTime+"",'00:00',""),s(S.controls,"duration")&&e.push('',''+S.i18n.duration+"",'00:00',""),s(S.controls,"mute")&&e.push('"),s(S.controls,"volume")&&e.push('','",'','',""),s(S.controls,"captions")&&e.push('"),s(S.controls,"fullscreen")&&e.push('"),e.push("
"),e.join("")}function V(){if(Ye.supported.full&&("audio"!==Ye.type||S.fullscreen.allowAudio)&&S.fullscreen.enabled){var e=A.supportsFullScreen;e||S.fullscreen.fallback&&!B()?(Ue((e?"Native":"Fallback")+" fullscreen enabled"),m(Ye.container,S.classes.fullscreen.enabled,!0)):Ue("Fullscreen not supported and fallback disabled"),Ye.buttons&&Ye.buttons.fullscreen&&k(Ye.buttons.fullscreen,!1),X()}}function q(){if("video"===Ye.type){Y(S.selectors.captions)||Ye.videoContainer.insertAdjacentHTML("afterbegin",'
'),Ye.usingTextTracks=!1,Ye.media.textTracks&&(Ye.usingTextTracks=!0);for(var e,t="",n=Ye.media.childNodes,r=0;r=10||Ye.browser.isFirefox&&Ye.browser.version>=31)&&(Ue("Detected browser with known TextTrack issues - using manual fallback"),Ye.usingTextTracks=!1),Ye.usingTextTracks){Ue("TextTracks supported");for(var o=0;o ");for(var r=0;rYe.captions.length-1){Ye.subcount=Ye.captions.length-1;break}Ye.media.currentTime.toFixed(1)>=n(Ye.captions[Ye.subcount][0])&&Ye.media.currentTime.toFixed(1)<=r(Ye.captions[Ye.subcount][0])?(Ye.currentCaption=Ye.captions[Ye.subcount][1],R(Ye.currentCaption)):R()}}function H(){if(Ye.buttons.captions){m(Ye.container,S.classes.captions.enabled,!0);var e=Ye.storage.captionsEnabled;P.boolean(e)||(e=S.captions.defaultActive),e&&(m(Ye.container,S.classes.captions.active,!0),k(Ye.buttons.captions,!0))}}function W(e){return Ye.container.querySelectorAll(e)}function Y(e){return W(e)[0]}function B(){try{return e.self!==e.top}catch(e){return!0}}function X(){function e(e){9===e.which&&Ye.isFullscreen&&(e.target!==r||e.shiftKey?e.target===n&&e.shiftKey&&(e.preventDefault(),r.focus()):(e.preventDefault(),n.focus()))}var t=W("input:not([disabled]), button:not([disabled])"),n=t[0],r=t[t.length-1];g(Ye.container,"keydown",e)}function U(e,t){if(P.string(t))d(e,Ye.media,{src:t});else if(t.constructor===Array)for(var n=t.length-1;n>=0;n--)d(e,Ye.media,t[n])}function J(){if(S.loadSprite){var e=L();e.absolute?(Ue("AJAX loading absolute SVG sprite"+(Ye.browser.isIE?" (due to IE)":"")),_(e.url,"sprite-plyr")):Ue("Sprite will be used as external resource directly")}var n=S.html;Ue("Injecting custom controls"),n||(n=j()),n=o(n,"{seektime}",S.seekTime),n=o(n,"{id}",Math.floor(1e4*Math.random()));var r;if(P.string(S.selectors.controls.container)&&(r=t.querySelector(S.selectors.controls.container)),P.htmlElement(r)||(r=Ye.container),r.insertAdjacentHTML("beforeend",n),S.tooltips.controls)for(var a=W([S.selectors.controls.wrapper," ",S.selectors.labels," .",S.classes.hidden].join("")),s=a.length-1;s>=0;s--){var i=a[s];m(i,S.classes.hidden,!1),m(i,S.classes.tooltip,!0)}}function z(){try{return Ye.controls=Y(S.selectors.controls.wrapper),Ye.buttons={},Ye.buttons.seek=Y(S.selectors.buttons.seek),Ye.buttons.play=W(S.selectors.buttons.play),Ye.buttons.pause=Y(S.selectors.buttons.pause),Ye.buttons.restart=Y(S.selectors.buttons.restart),Ye.buttons.rewind=Y(S.selectors.buttons.rewind),Ye.buttons.forward=Y(S.selectors.buttons.forward),Ye.buttons.fullscreen=Y(S.selectors.buttons.fullscreen),Ye.buttons.mute=Y(S.selectors.buttons.mute),Ye.buttons.captions=Y(S.selectors.buttons.captions),Ye.progress={},Ye.progress.container=Y(S.selectors.progress.container),Ye.progress.buffer={},Ye.progress.buffer.bar=Y(S.selectors.progress.buffer),Ye.progress.buffer.text=Ye.progress.buffer.bar&&Ye.progress.buffer.bar.getElementsByTagName("span")[0],Ye.progress.played=Y(S.selectors.progress.played),Ye.progress.tooltip=Ye.progress.container&&Ye.progress.container.querySelector("."+S.classes.tooltip),Ye.volume={},Ye.volume.input=Y(S.selectors.volume.input),Ye.volume.display=Y(S.selectors.volume.display),Ye.duration=Y(S.selectors.duration),Ye.currentTime=Y(S.selectors.currentTime),Ye.seekTime=W(S.selectors.seekTime),!0}catch(e){return Je("It looks like there is a problem with your controls HTML"),G(!0),!1}}function $(){m(Ye.container,S.selectors.container.replace(".",""),Ye.supported.full)}function G(e){e&&s(S.types.html5,Ye.type)?Ye.media.setAttribute("controls",""):Ye.media.removeAttribute("controls")}function K(e){var t=S.i18n.play;if(P.string(S.title)&&S.title.length&&(t+=", "+S.title,Ye.container.setAttribute("aria-label",S.title)),Ye.supported.full&&Ye.buttons.play)for(var n=Ye.buttons.play.length-1;n>=0;n--)Ye.buttons.play[n].setAttribute("aria-label",t);P.htmlElement(e)&&e.setAttribute("title",S.i18n.frameTitle.replace("{title}",S.title))}function Q(){var t=null;Ye.storage={},M.supported&&S.storage.enabled&&(e.localStorage.removeItem("plyr-volume"),t=e.localStorage.getItem(S.storage.key),t&&(/^\d+(\.\d+)?$/.test(t)?Z({volume:parseFloat(t)}):Ye.storage=JSON.parse(t)))}function Z(t){M.supported&&S.storage.enabled&&(x(Ye.storage,t),e.localStorage.setItem(S.storage.key,JSON.stringify(Ye.storage)))}function ee(){if(!Ye.media)return void Je("No media element found!");if(Ye.supported.full&&(m(Ye.container,S.classes.type.replace("{0}",Ye.type),!0),s(S.types.embed,Ye.type)&&m(Ye.container,S.classes.type.replace("{0}","video"),!0),m(Ye.container,S.classes.stopped,S.autoplay),m(Ye.ontainer,S.classes.isIos,Ye.browser.isIos),m(Ye.container,S.classes.isTouch,Ye.browser.isTouch),"video"===Ye.type)){var e=t.createElement("div");e.setAttribute("class",S.classes.videoWrapper),i(Ye.media,e),Ye.videoContainer=e}s(S.types.embed,Ye.type)&&te()}function te(){for(var n=t.createElement("div"),r=Ye.embedId,s=Ye.type+"-"+Math.floor(1e4*Math.random()),o=W('[id^="'+Ye.type+'-"]'),i=o.length-1;i>=0;i--)l(o[i]);if(m(Ye.media,S.classes.videoWrapper,!0),m(Ye.media,S.classes.embedWrapper,!0),"youtube"===Ye.type)Ye.media.appendChild(n),n.setAttribute("id",s),P.object(e.YT)?re(r,n):(a(S.urls.youtube.api),e.onYouTubeReadyCallbacks=e.onYouTubeReadyCallbacks||[],e.onYouTubeReadyCallbacks.push(function(){re(r,n)}),e.onYouTubeIframeAPIReady=function(){e.onYouTubeReadyCallbacks.forEach(function(e){e()})});else if("vimeo"===Ye.type)if(Ye.supported.full?Ye.media.appendChild(n):n=Ye.media,n.setAttribute("id",s),P.object(e.Vimeo))ae(r,n);else{a(S.urls.vimeo.api);var u=e.setInterval(function(){P.object(e.Vimeo)&&(e.clearInterval(u),ae(r,n))},50)}else if("soundcloud"===Ye.type){var d=t.createElement("iframe");d.loaded=!1,g(d,"load",function(){d.loaded=!0}),c(d,{src:"https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/"+r,id:s}),n.appendChild(d),Ye.media.appendChild(n),e.SC||a(S.urls.soundcloud.api);var p=e.setInterval(function(){e.SC&&d.loaded&&(e.clearInterval(p),se.call(d))},50)}}function ne(){Ye.supported.full&&(De(),He()),K(Y("iframe"))}function re(t,n){Ye.embed=new e.YT.Player(n.id,{videoId:t,playerVars:{autoplay:S.autoplay?1:0,controls:Ye.supported.full?0:1,rel:0,showinfo:0,iv_load_policy:3,cc_load_policy:S.captions.defaultActive?1:0,cc_lang_pref:"en",wmode:"transparent",modestbranding:1,disablekb:1,origin:"*"},events:{onError:function(e){C(Ye.container,"error",!0,{code:e.data,embed:e.target})},onReady:function(t){var n=t.target;Ye.media.play=function(){n.playVideo(),Ye.media.paused=!1},Ye.media.pause=function(){n.pauseVideo(),Ye.media.paused=!0},Ye.media.stop=function(){n.stopVideo(),Ye.media.paused=!0},Ye.media.duration=n.getDuration(),Ye.media.paused=!0,Ye.media.currentTime=0,Ye.media.muted=n.isMuted(),S.title=n.getVideoData().title,Ye.supported.full&&Ye.media.querySelector("iframe").setAttribute("tabindex","-1"),ne(),C(Ye.media,"timeupdate"),C(Ye.media,"durationchange"),e.clearInterval(Be.buffering),Be.buffering=e.setInterval(function(){Ye.media.buffered=n.getVideoLoadedFraction(),(null===Ye.media.lastBuffered||Ye.media.lastBufferedr&&(t=r),Ae(t);try{Ye.media.currentTime=t.toFixed(4)}catch(e){}if(s(S.types.embed,Ye.type)){switch(Ye.type){case"youtube":Ye.embed.seekTo(t);break;case"vimeo":Ye.embed.setCurrentTime(t.toFixed(0));break;case"soundcloud":Ye.embed.seekTo(1e3*t)}n&&ie(),C(Ye.media,"timeupdate"),Ye.media.seeking=!0}Ue("Seeking to "+Ye.media.currentTime+" seconds"),D(t)}function pe(){var e=parseInt(S.duration),t=0;return null===Ye.media.duration||isNaN(Ye.media.duration)||(t=Ye.media.duration),isNaN(e)?t:e}function me(){m(Ye.container,S.classes.playing,!Ye.media.paused),m(Ye.container,S.classes.stopped,Ye.media.paused),Ne(Ye.media.paused)}function fe(){I={x:e.pageXOffset||0,y:e.pageYOffset||0}}function ye(){e.scrollTo(I.x,I.y)}function be(e){var n=A.supportsFullScreen;if(n){if(!e||e.type!==A.fullScreenEventName)return A.isFullScreen(Ye.container)?A.cancelFullScreen():(fe(),A.requestFullScreen(Ye.container)),void(Ye.isFullscreen=A.isFullScreen(Ye.container));Ye.isFullscreen=A.isFullScreen(Ye.container)}else Ye.isFullscreen=!Ye.isFullscreen,t.body.style.overflow=Ye.isFullscreen?"hidden":"";m(Ye.container,S.classes.fullscreen.active,Ye.isFullscreen),X(Ye.isFullscreen),Ye.buttons&&Ye.buttons.fullscreen&&k(Ye.buttons.fullscreen,Ye.isFullscreen),C(Ye.container,Ye.isFullscreen?"enterfullscreen":"exitfullscreen",!0),!Ye.isFullscreen&&n&&ye()}function ve(e){if(P.boolean(e)||(e=!Ye.media.muted),k(Ye.buttons.mute,e),Ye.media.muted=e,0===Ye.media.volume&&ge(S.volume),s(S.types.embed,Ye.type)){switch(Ye.type){case"youtube":Ye.embed[Ye.media.muted?"mute":"unMute"]();break;case"vimeo":case"soundcloud":Ye.embed.setVolume(Ye.media.muted?0:parseFloat(S.volume/S.volumeMax))}C(Ye.media,"volumechange")}}function ge(e){var t=S.volumeMax,n=S.volumeMin;if(P.undefined(e)&&(e=Ye.storage.volume),(null===e||isNaN(e))&&(e=S.volume),e>t&&(e=t),e0&&ve()}function he(e){var t=Ye.media.muted?0:Ye.media.volume*S.volumeMax;P.number(e)||(e=S.volumeStep),ge(t+e)}function ke(e){var t=Ye.media.muted?0:Ye.media.volume*S.volumeMax;P.number(e)||(e=S.volumeStep),ge(t-e)}function we(){var e=Ye.media.muted?0:Ye.media.volume*S.volumeMax;Ye.supported.full&&(Ye.volume.input&&(Ye.volume.input.value=e),Ye.volume.display&&(Ye.volume.display.value=e)),Z({volume:e}),m(Ye.container,S.classes.muted,0===e),Ye.supported.full&&Ye.buttons.mute&&k(Ye.buttons.mute,0===e)}function xe(e){Ye.supported.full&&Ye.buttons.captions&&(P.boolean(e)||(e=Ye.container.className.indexOf(S.classes.captions.active)===-1),Ye.captionsEnabled=e,k(Ye.buttons.captions,Ye.captionsEnabled),m(Ye.container,S.classes.captions.active,Ye.captionsEnabled),C(Ye.container,Ye.captionsEnabled?"captionsenabled":"captionsdisabled",!0),Z({captionsEnabled:Ye.captionsEnabled}))}function Te(e){var t="waiting"===e.type;clearTimeout(Be.loading),Be.loading=setTimeout(function(){m(Ye.container,S.classes.loading,t),Ne(t)},t?250:0)}function Se(e){if(Ye.supported.full){var t=Ye.progress.played,n=0,r=pe();if(e)switch(e.type){case"timeupdate":case"seeking":if(Ye.controls.pressed)return;n=w(Ye.media.currentTime,r),"timeupdate"===e.type&&Ye.buttons.seek&&(Ye.buttons.seek.value=n);break;case"playing":case"progress":t=Ye.progress.buffer,n=function(){var e=Ye.media.buffered;return e&&e.length?w(e.end(0),r):P.number(e)?100*e:0}()}_e(t,n)}}function _e(e,t){if(Ye.supported.full){if(P.undefined(t)&&(t=0),P.undefined(e)){if(!Ye.progress||!Ye.progress.buffer)return;e=Ye.progress.buffer}P.htmlElement(e)?e.value=t:e&&(e.bar&&(e.bar.value=t),e.text&&(e.text.innerHTML=t))}}function Ee(e,t){if(t){isNaN(e)&&(e=0),Ye.secs=parseInt(e%60),Ye.mins=parseInt(e/60%60),Ye.hours=parseInt(e/60/60%60);var n=parseInt(pe()/60/60%60)>0;Ye.secs=("0"+Ye.secs).slice(-2),Ye.mins=("0"+Ye.mins).slice(-2),t.innerHTML=(n?Ye.hours+":":"")+Ye.mins+":"+Ye.secs}}function Ce(){if(Ye.supported.full){var e=pe()||0;!Ye.duration&&S.displayDuration&&Ye.media.paused&&Ee(e,Ye.currentTime),Ye.duration&&Ee(e,Ye.duration),Ie()}}function Fe(e){Ee(Ye.media.currentTime,Ye.currentTime),e&&"timeupdate"===e.type&&Ye.media.seeking||Se(e)}function Ae(e){P.number(e)||(e=0);var t=pe(),n=w(e,t);Ye.progress&&Ye.progress.played&&(Ye.progress.played.value=n),Ye.buttons&&Ye.buttons.seek&&(Ye.buttons.seek.value=n)}function Ie(e){var t=pe();if(S.tooltips.seek&&Ye.progress.container&&0!==t){var n=Ye.progress.container.getBoundingClientRect(),r=0,a=S.classes.tooltip+"--visible";if(e)r=100/n.width*(e.pageX-n.left);else{if(!f(Ye.progress.tooltip,a))return;r=Ye.progress.tooltip.style.left.replace("%","")}r<0?r=0:r>100&&(r=100),Ee(t/100*r,Ye.progress.tooltip),Ye.progress.tooltip.style.left=r+"%",e&&s(["mouseenter","mouseleave"],e.type)&&m(Ye.progress.tooltip,a,"mouseenter"===e.type)}}function Ne(t){if(S.hideControls&&"audio"!==Ye.type){var n=0,r=!1,a=t,o=f(Ye.container,S.classes.loading);if(P.boolean(t)||(t&&t.type?(r="enterfullscreen"===t.type,a=s(["mousemove","touchstart","mouseenter","focus"],t.type),s(["mousemove","touchmove"],t.type)&&(n=2e3),"focus"===t.type&&(n=3e3)):a=f(Ye.container,S.classes.hideControls)),e.clearTimeout(Be.hover),a||Ye.media.paused||o){if(m(Ye.container,S.classes.hideControls,!1),Ye.media.paused||o)return;Ye.browser.isTouch&&(n=3e3)}a&&Ye.media.paused||(Be.hover=e.setTimeout(function(){(!Ye.controls.pressed&&!Ye.controls.hover||r)&&m(Ye.container,S.classes.hideControls,!0)},n))}}function Pe(e){if(!P.undefined(e))return void Me(e);var t;switch(Ye.type){case"youtube":t=Ye.embed.getVideoUrl();break;case"vimeo":Ye.embed.getVideoUrl.then(function(e){t=e});break;case"soundcloud":Ye.embed.getCurrentSound(function(e){t=e.permalink_url});break;default:t=Ye.media.currentSrc}return t||""}function Me(e){function n(){if(Ye.embed=null,l(Ye.media),"video"===Ye.type&&Ye.videoContainer&&l(Ye.videoContainer),Ye.container&&Ye.container.removeAttribute("class"),"type"in e&&(Ye.type=e.type,"video"===Ye.type)){var n=e.sources[0];"type"in n&&s(S.types.embed,n.type)&&(Ye.type=n.type)}switch(Ye.supported=E(Ye.type),Ye.type){case"video":Ye.media=t.createElement("video");break;case"audio":Ye.media=t.createElement("audio");break;case"youtube":case"vimeo":case"soundcloud":Ye.media=t.createElement("div"),Ye.embedId=e.sources[0].src}u(Ye.container,Ye.media),P.boolean(e.autoplay)&&(S.autoplay=e.autoplay),s(S.types.html5,Ye.type)&&(S.crossorigin&&Ye.media.setAttribute("crossorigin",""),S.autoplay&&Ye.media.setAttribute("autoplay",""),"poster"in e&&Ye.media.setAttribute("poster",e.poster),S.loop&&Ye.media.setAttribute("loop","")),m(Ye.container,S.classes.fullscreen.active,Ye.isFullscreen),m(Ye.container,S.classes.captions.active,Ye.captionsEnabled),$(),s(S.types.html5,Ye.type)&&U("source",e.sources),ee(),s(S.types.html5,Ye.type)&&("tracks"in e&&U("track",e.tracks),Ye.media.load()),(s(S.types.html5,Ye.type)||s(S.types.embed,Ye.type)&&!Ye.supported.full)&&(De(),He()),S.title=e.title,K()}return P.object(e)&&"sources"in e&&e.sources.length?(m(Ye.container,S.classes.ready,!1),ie(),Ae(),_e(),Ve(),void qe(n,!1)):void Je("Invalid source format")}function Oe(e){"video"===Ye.type&&Ye.media.setAttribute("poster",e)}function Le(){function n(){var e=le(),t=Ye.buttons[e?"play":"pause"],n=Ye.buttons[e?"pause":"play"];if(n=n&&n.length>1?n[n.length-1]:n[0]){var r=f(t,S.classes.tabFocus);setTimeout(function(){n.focus(),r&&(m(t,S.classes.tabFocus,!1),m(n,S.classes.tabFocus,!0))},100)}}function r(){var e=t.activeElement;return e=e&&e!==t.body?t.querySelector(":focus"):null}function a(e){return e.keyCode?e.keyCode:e.which}function o(e){for(var t in Ye.buttons){var n=Ye.buttons[t];if(P.nodeList(n))for(var r=0;r0)&&(t?ke(n):he(n)),(e.deltaY>0||e.deltaX<0)&&(t?he(n):ke(n))})}function je(){if(g(Ye.media,"timeupdate seeking",Fe),g(Ye.media,"timeupdate",D),g(Ye.media,"durationchange loadedmetadata",Ce),g(Ye.media,"ended",function(){"video"===Ye.type&&S.showPosterOnEnd&&("video"===Ye.type&&R(),de(),Ye.media.load())}),g(Ye.media,"progress playing",Se),g(Ye.media,"volumechange",we),g(Ye.media,"play pause ended",me),g(Ye.media,"waiting canplay seeked",Te),S.clickToPlay&&"audio"!==Ye.type){var e=Y("."+S.classes.videoWrapper);if(!e)return;e.style.cursor="pointer",g(e,"click",function(){S.hideControls&&Ye.browser.isTouch&&!Ye.media.paused||(Ye.media.paused?oe():Ye.media.ended?(de(),oe()):ie())})}S.disableContextMenu&&g(Ye.media,"contextmenu",function(e){e.preventDefault()}),g(Ye.media,S.events.concat(["keyup","keydown"]).join(" "),function(e){C(Ye.container,e.type,!0)})}function Ve(){if(s(S.types.html5,Ye.type)){for(var e=Ye.media.querySelectorAll("source"),t=0;t=0;n--){var r=n>0?t.cloneNode(!0):t,a=e[n],s=a.parentNode,o=a.nextSibling;return r.appendChild(a),o?s.insertBefore(r,o):s.appendChild(r),r}}function l(e){e&&e.parentNode.removeChild(e)}function u(e,t){e.insertBefore(t,e.firstChild)}function c(e,t){for(var n in t)e.setAttribute(n,O.boolean(t[n])&&t[n]?"":t[n])}function d(e,n,r){var a=t.createElement(e);c(a,r),u(n,a)}function p(e){return e.replace(".","")}function m(e,t,n){if(e)if(e.classList)e.classList[n?"add":"remove"](t);else{var r=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=r+(n?" "+t:"")}}function f(e,t){return!!e&&(e.classList?e.classList.contains(t):new RegExp("(\\s|^)"+t+"(\\s|$)").test(e.className))}function y(e,n){var r=Element.prototype,a=r.matches||r.webkitMatchesSelector||r.mozMatchesSelector||r.msMatchesSelector||function(e){return[].indexOf.call(t.querySelectorAll(e),this)!==-1};return a.call(e,n)}function b(e,t,n,r,a){g(e,t,function(t){n&&n.apply(e,[t]),r.apply(e,[t])},a)}function v(e,t,n,r,a){var s=t.split(" ");if(O.boolean(a)||(a=!1),e instanceof NodeList)for(var o=0;o','',''+E.i18n.play+"",""),e.push('
'),s(E.controls,"restart")&&e.push('"),s(E.controls,"rewind")&&e.push('"),s(E.controls,"play")&&e.push('",'"),s(E.controls,"fast-forward")&&e.push('"),s(E.controls,"progress")&&(e.push('','','','','',"0% "+E.i18n.buffered,""),E.tooltips.seek&&e.push('00:00'),e.push("")),s(E.controls,"current-time")&&e.push('',''+E.i18n.currentTime+"",'00:00',""),s(E.controls,"duration")&&e.push('',''+E.i18n.duration+"",'00:00',""),s(E.controls,"mute")&&e.push('"),s(E.controls,"volume")&&e.push('','",'','',""),s(E.controls,"captions")&&e.push('"),s(E.controls,"fullscreen")&&e.push('"),e.push("
"),e.join("")}function q(){if(Xe.supported.full&&("audio"!==Xe.type||E.fullscreen.allowAudio)&&E.fullscreen.enabled){var e=N.supportsFullScreen;e||E.fullscreen.fallback&&!U()?(Je((e?"Native":"Fallback")+" fullscreen enabled"),m(Xe.container,E.classes.fullscreen.enabled,!0)):Je("Fullscreen not supported and fallback disabled"),Xe.buttons&&Xe.buttons.fullscreen&&k(Xe.buttons.fullscreen,!1),$()}}function D(){if("video"===Xe.type){X(E.selectors.captions)||Xe.videoContainer.insertAdjacentHTML("afterbegin",'
'),Xe.usingTextTracks=!1,Xe.media.textTracks&&(Xe.usingTextTracks=!0);for(var e,t="",n=Xe.media.childNodes,r=0;r=10||Xe.browser.isFirefox&&Xe.browser.version>=31)&&(Je("Detected browser with known TextTrack issues - using manual fallback"),Xe.usingTextTracks=!1),Xe.usingTextTracks){Je("TextTracks supported");for(var o=0;o ");for(var r=0;rXe.captions.length-1){Xe.subcount=Xe.captions.length-1;break}Xe.media.currentTime.toFixed(1)>=n(Xe.captions[Xe.subcount][0])&&Xe.media.currentTime.toFixed(1)<=r(Xe.captions[Xe.subcount][0])?(Xe.currentCaption=Xe.captions[Xe.subcount][1],H(Xe.currentCaption)):H()}}function Y(){if(Xe.buttons.captions){m(Xe.container,E.classes.captions.enabled,!0);var e=Xe.storage.captionsEnabled;O.boolean(e)||(e=E.captions.defaultActive),e&&(m(Xe.container,E.classes.captions.active,!0),k(Xe.buttons.captions,!0))}}function B(e){return Xe.container.querySelectorAll(e)}function X(e){return B(e)[0]}function U(){try{return e.self!==e.top}catch(e){return!0}}function $(){function e(e){9===e.which&&Xe.isFullscreen&&(e.target!==r||e.shiftKey?e.target===n&&e.shiftKey&&(e.preventDefault(),r.focus()):(e.preventDefault(),n.focus()))}var t=B("input:not([disabled]), button:not([disabled])"),n=t[0],r=t[t.length-1];g(Xe.container,"keydown",e)}function J(e,t){if(O.string(t))d(e,Xe.media,{src:t});else if(t.constructor===Array)for(var n=t.length-1;n>=0;n--)d(e,Xe.media,t[n])}function z(){if(E.loadSprite){var e=V();e.absolute?(Je("AJAX loading absolute SVG sprite"+(Xe.browser.isIE?" (due to IE)":"")),C(e.url,"sprite-plyr")):Je("Sprite will be used as external resource directly")}var n=E.html;Je("Injecting custom controls"),n||(n=R()),n=o(n,"{seektime}",E.seekTime),n=o(n,"{id}",Math.floor(1e4*Math.random()));var r;if(O.string(E.selectors.controls.container)&&(r=t.querySelector(E.selectors.controls.container)),O.htmlElement(r)||(r=Xe.container),r.insertAdjacentHTML("beforeend",n),E.tooltips.controls)for(var a=B([E.selectors.controls.wrapper," ",E.selectors.labels," .",E.classes.hidden].join("")),s=a.length-1;s>=0;s--){var i=a[s];m(i,E.classes.hidden,!1),m(i,E.classes.tooltip,!0)}}function G(){try{return Xe.controls=X(E.selectors.controls.wrapper),Xe.buttons={},Xe.buttons.seek=X(E.selectors.buttons.seek),Xe.buttons.play=B(E.selectors.buttons.play),Xe.buttons.pause=X(E.selectors.buttons.pause),Xe.buttons.restart=X(E.selectors.buttons.restart),Xe.buttons.rewind=X(E.selectors.buttons.rewind),Xe.buttons.forward=X(E.selectors.buttons.forward),Xe.buttons.fullscreen=X(E.selectors.buttons.fullscreen),Xe.buttons.mute=X(E.selectors.buttons.mute),Xe.buttons.captions=X(E.selectors.buttons.captions),Xe.progress={},Xe.progress.container=X(E.selectors.progress.container),Xe.progress.buffer={},Xe.progress.buffer.bar=X(E.selectors.progress.buffer),Xe.progress.buffer.text=Xe.progress.buffer.bar&&Xe.progress.buffer.bar.getElementsByTagName("span")[0],Xe.progress.played=X(E.selectors.progress.played),Xe.progress.tooltip=Xe.progress.container&&Xe.progress.container.querySelector("."+E.classes.tooltip),Xe.volume={},Xe.volume.input=X(E.selectors.volume.input),Xe.volume.display=X(E.selectors.volume.display),Xe.duration=X(E.selectors.duration),Xe.currentTime=X(E.selectors.currentTime),Xe.seekTime=B(E.selectors.seekTime),!0}catch(e){return ze("It looks like there is a problem with your controls HTML"),Q(!0),!1}}function K(){m(Xe.container,E.selectors.container.replace(".",""),Xe.supported.full)}function Q(e){e&&s(E.types.html5,Xe.type)?Xe.media.setAttribute("controls",""):Xe.media.removeAttribute("controls")}function Z(e){var t=E.i18n.play;if(O.string(E.title)&&E.title.length&&(t+=", "+E.title,Xe.container.setAttribute("aria-label",E.title)),Xe.supported.full&&Xe.buttons.play)for(var n=Xe.buttons.play.length-1;n>=0;n--)Xe.buttons.play[n].setAttribute("aria-label",t);O.htmlElement(e)&&e.setAttribute("title",E.i18n.frameTitle.replace("{title}",E.title))}function ee(){var t=null;Xe.storage={},L.supported&&E.storage.enabled&&(e.localStorage.removeItem("plyr-volume"),t=e.localStorage.getItem(E.storage.key),t&&(/^\d+(\.\d+)?$/.test(t)?te({volume:parseFloat(t)}):Xe.storage=JSON.parse(t)))}function te(t){L.supported&&E.storage.enabled&&(x(Xe.storage,t),e.localStorage.setItem(E.storage.key,JSON.stringify(Xe.storage)))}function ne(){if(!Xe.media)return void ze("No media element found!");if(Xe.supported.full&&(m(Xe.container,E.classes.type.replace("{0}",Xe.type),!0),s(E.types.embed,Xe.type)&&m(Xe.container,E.classes.type.replace("{0}","video"),!0),m(Xe.container,E.classes.stopped,E.autoplay),m(Xe.ontainer,E.classes.isIos,Xe.browser.isIos),m(Xe.container,E.classes.isTouch,Xe.browser.isTouch),"video"===Xe.type)){var e=t.createElement("div");e.setAttribute("class",E.classes.videoWrapper),i(Xe.media,e),Xe.videoContainer=e}s(E.types.embed,Xe.type)&&re()}function re(){var n,r=t.createElement("div"),s=Xe.type+"-"+Math.floor(1e4*Math.random());switch(Xe.type){case"youtube":n=T(Xe.embedId);break;case"vimeo":n=S(Xe.embedId);break;default:n=Xe.embedId}for(var o=B('[id^="'+Xe.type+'-"]'),i=o.length-1;i>=0;i--)l(o[i]);if(m(Xe.media,E.classes.videoWrapper,!0),m(Xe.media,E.classes.embedWrapper,!0),"youtube"===Xe.type)Xe.media.appendChild(r),r.setAttribute("id",s),O.object(e.YT)?se(n,r):(a(E.urls.youtube.api),e.onYouTubeReadyCallbacks=e.onYouTubeReadyCallbacks||[],e.onYouTubeReadyCallbacks.push(function(){se(n,r)}),e.onYouTubeIframeAPIReady=function(){e.onYouTubeReadyCallbacks.forEach(function(e){e()})});else if("vimeo"===Xe.type)if(Xe.supported.full?Xe.media.appendChild(r):r=Xe.media,r.setAttribute("id",s),O.object(e.Vimeo))oe(n,r);else{a(E.urls.vimeo.api);var u=e.setInterval(function(){O.object(e.Vimeo)&&(e.clearInterval(u),oe(n,r))},50)}else if("soundcloud"===Xe.type){var d=t.createElement("iframe");d.loaded=!1,g(d,"load",function(){d.loaded=!0}),c(d,{src:"https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/"+n,id:s}),r.appendChild(d),Xe.media.appendChild(r),e.SC||a(E.urls.soundcloud.api);var p=e.setInterval(function(){e.SC&&d.loaded&&(e.clearInterval(p),ie.call(d))},50)}}function ae(){Xe.supported.full&&(We(),Ye()),Z(X("iframe"))}function se(t,n){Xe.embed=new e.YT.Player(n.id,{videoId:t,playerVars:{autoplay:E.autoplay?1:0,controls:Xe.supported.full?0:1,rel:0,showinfo:0,iv_load_policy:3,cc_load_policy:E.captions.defaultActive?1:0,cc_lang_pref:"en",wmode:"transparent",modestbranding:1,disablekb:1,origin:"*"},events:{onError:function(e){A(Xe.container,"error",!0,{code:e.data,embed:e.target})},onReady:function(t){var n=t.target;Xe.media.play=function(){n.playVideo(),Xe.media.paused=!1},Xe.media.pause=function(){n.pauseVideo(),Xe.media.paused=!0},Xe.media.stop=function(){n.stopVideo(),Xe.media.paused=!0},Xe.media.duration=n.getDuration(),Xe.media.paused=!0,Xe.media.currentTime=0,Xe.media.muted=n.isMuted(),E.title=n.getVideoData().title,Xe.supported.full&&Xe.media.querySelector("iframe").setAttribute("tabindex","-1"),ae(),A(Xe.media,"timeupdate"),A(Xe.media,"durationchange"),e.clearInterval(Ue.buffering),Ue.buffering=e.setInterval(function(){Xe.media.buffered=n.getVideoLoadedFraction(),(null===Xe.media.lastBuffered||Xe.media.lastBufferedr&&(t=r),Ne(t);try{Xe.media.currentTime=t.toFixed(4)}catch(e){}if(s(E.types.embed,Xe.type)){switch(Xe.type){case"youtube":Xe.embed.seekTo(t);break;case"vimeo":Xe.embed.setCurrentTime(t.toFixed(0));break;case"soundcloud":Xe.embed.seekTo(1e3*t)}n&&ue(),A(Xe.media,"timeupdate"),Xe.media.seeking=!0,A(Xe.media,"seeking")}Je("Seeking to "+Xe.media.currentTime+" seconds"),W(t)}function fe(){var e=parseInt(E.duration),t=0;return null===Xe.media.duration||isNaN(Xe.media.duration)||(t=Xe.media.duration),isNaN(e)?t:e}function ye(){m(Xe.container,E.classes.playing,!Xe.media.paused),m(Xe.container,E.classes.stopped,Xe.media.paused),Me(Xe.media.paused)}function be(){P={x:e.pageXOffset||0,y:e.pageYOffset||0}}function ve(){e.scrollTo(P.x,P.y)}function ge(e){var n=N.supportsFullScreen;if(n){if(!e||e.type!==N.fullScreenEventName)return N.isFullScreen(Xe.container)?N.cancelFullScreen():(be(),N.requestFullScreen(Xe.container)),void(Xe.isFullscreen=N.isFullScreen(Xe.container));Xe.isFullscreen=N.isFullScreen(Xe.container)}else Xe.isFullscreen=!Xe.isFullscreen,t.body.style.overflow=Xe.isFullscreen?"hidden":"";m(Xe.container,E.classes.fullscreen.active,Xe.isFullscreen),$(Xe.isFullscreen),Xe.buttons&&Xe.buttons.fullscreen&&k(Xe.buttons.fullscreen,Xe.isFullscreen),A(Xe.container,Xe.isFullscreen?"enterfullscreen":"exitfullscreen",!0),!Xe.isFullscreen&&n&&ve()}function he(e){if(O.boolean(e)||(e=!Xe.media.muted),k(Xe.buttons.mute,e),Xe.media.muted=e,0===Xe.media.volume&&ke(E.volume),s(E.types.embed,Xe.type)){switch(Xe.type){case"youtube":Xe.embed[Xe.media.muted?"mute":"unMute"]();break;case"vimeo":case"soundcloud":Xe.embed.setVolume(Xe.media.muted?0:parseFloat(E.volume/E.volumeMax))}A(Xe.media,"volumechange")}}function ke(e){var t=E.volumeMax,n=E.volumeMin;if(O.undefined(e)&&(e=Xe.storage.volume),(null===e||isNaN(e))&&(e=E.volume),e>t&&(e=t),e0&&he()}function we(e){var t=Xe.media.muted?0:Xe.media.volume*E.volumeMax;O.number(e)||(e=E.volumeStep),ke(t+e)}function xe(e){var t=Xe.media.muted?0:Xe.media.volume*E.volumeMax;O.number(e)||(e=E.volumeStep),ke(t-e)}function Te(){var e=Xe.media.muted?0:Xe.media.volume*E.volumeMax;Xe.supported.full&&(Xe.volume.input&&(Xe.volume.input.value=e),Xe.volume.display&&(Xe.volume.display.value=e)),te({volume:e}),m(Xe.container,E.classes.muted,0===e),Xe.supported.full&&Xe.buttons.mute&&k(Xe.buttons.mute,0===e)}function Se(e){Xe.supported.full&&Xe.buttons.captions&&(O.boolean(e)||(e=Xe.container.className.indexOf(E.classes.captions.active)===-1),Xe.captionsEnabled=e,k(Xe.buttons.captions,Xe.captionsEnabled),m(Xe.container,E.classes.captions.active,Xe.captionsEnabled),A(Xe.container,Xe.captionsEnabled?"captionsenabled":"captionsdisabled",!0),te({captionsEnabled:Xe.captionsEnabled}))}function _e(e){var t="waiting"===e.type;clearTimeout(Ue.loading),Ue.loading=setTimeout(function(){m(Xe.container,E.classes.loading,t),Me(t)},t?250:0)}function Ee(e){if(Xe.supported.full){var t=Xe.progress.played,n=0,r=fe();if(e)switch(e.type){case"timeupdate":case"seeking":if(Xe.controls.pressed)return;n=w(Xe.media.currentTime,r),"timeupdate"===e.type&&Xe.buttons.seek&&(Xe.buttons.seek.value=n);break;case"playing":case"progress":t=Xe.progress.buffer,n=function(){var e=Xe.media.buffered;return e&&e.length?w(e.end(0),r):O.number(e)?100*e:0}()}Ce(t,n)}}function Ce(e,t){if(Xe.supported.full){if(O.undefined(t)&&(t=0),O.undefined(e)){if(!Xe.progress||!Xe.progress.buffer)return;e=Xe.progress.buffer}O.htmlElement(e)?e.value=t:e&&(e.bar&&(e.bar.value=t),e.text&&(e.text.innerHTML=t))}}function Fe(e,t){if(t){isNaN(e)&&(e=0),Xe.secs=parseInt(e%60),Xe.mins=parseInt(e/60%60),Xe.hours=parseInt(e/60/60%60);var n=parseInt(fe()/60/60%60)>0;Xe.secs=("0"+Xe.secs).slice(-2),Xe.mins=("0"+Xe.mins).slice(-2),t.innerHTML=(n?Xe.hours+":":"")+Xe.mins+":"+Xe.secs}}function Ae(){if(Xe.supported.full){var e=fe()||0;!Xe.duration&&E.displayDuration&&Xe.media.paused&&Fe(e,Xe.currentTime),Xe.duration&&Fe(e,Xe.duration),Pe()}}function Ie(e){Fe(Xe.media.currentTime,Xe.currentTime),e&&"timeupdate"===e.type&&Xe.media.seeking||Ee(e)}function Ne(e){O.number(e)||(e=0);var t=fe(),n=w(e,t);Xe.progress&&Xe.progress.played&&(Xe.progress.played.value=n),Xe.buttons&&Xe.buttons.seek&&(Xe.buttons.seek.value=n)}function Pe(e){var t=fe();if(E.tooltips.seek&&Xe.progress.container&&0!==t){var n=Xe.progress.container.getBoundingClientRect(),r=0,a=E.classes.tooltip+"--visible";if(e)r=100/n.width*(e.pageX-n.left);else{if(!f(Xe.progress.tooltip,a))return;r=Xe.progress.tooltip.style.left.replace("%","")}r<0?r=0:r>100&&(r=100),Fe(t/100*r,Xe.progress.tooltip),Xe.progress.tooltip.style.left=r+"%",e&&s(["mouseenter","mouseleave"],e.type)&&m(Xe.progress.tooltip,a,"mouseenter"===e.type)}}function Me(t){if(E.hideControls&&"audio"!==Xe.type){var n=0,r=!1,a=t,o=f(Xe.container,E.classes.loading);if(O.boolean(t)||(t&&t.type?(r="enterfullscreen"===t.type,a=s(["mousemove","touchstart","mouseenter","focus"],t.type),s(["mousemove","touchmove"],t.type)&&(n=2e3),"focus"===t.type&&(n=3e3)):a=f(Xe.container,E.classes.hideControls)),e.clearTimeout(Ue.hover),a||Xe.media.paused||o){if(m(Xe.container,E.classes.hideControls,!1),Xe.media.paused||o)return;Xe.browser.isTouch&&(n=3e3)}a&&Xe.media.paused||(Ue.hover=e.setTimeout(function(){(!Xe.controls.pressed&&!Xe.controls.hover||r)&&m(Xe.container,E.classes.hideControls,!0)},n))}}function Oe(e){if(!O.undefined(e))return void Le(e);var t;switch(Xe.type){case"youtube":t=Xe.embed.getVideoUrl();break;case"vimeo":Xe.embed.getVideoUrl.then(function(e){t=e});break;case"soundcloud":Xe.embed.getCurrentSound(function(e){t=e.permalink_url});break;default:t=Xe.media.currentSrc}return t||""}function Le(e){function n(){if(Xe.embed=null,l(Xe.media),"video"===Xe.type&&Xe.videoContainer&&l(Xe.videoContainer),Xe.container&&Xe.container.removeAttribute("class"),"type"in e&&(Xe.type=e.type,"video"===Xe.type)){var n=e.sources[0];"type"in n&&s(E.types.embed,n.type)&&(Xe.type=n.type)}switch(Xe.supported=F(Xe.type),Xe.type){case"video":Xe.media=t.createElement("video");break;case"audio":Xe.media=t.createElement("audio");break;case"youtube":case"vimeo":case"soundcloud":Xe.media=t.createElement("div"),Xe.embedId=e.sources[0].src}u(Xe.container,Xe.media),O.boolean(e.autoplay)&&(E.autoplay=e.autoplay),s(E.types.html5,Xe.type)&&(E.crossorigin&&Xe.media.setAttribute("crossorigin",""),E.autoplay&&Xe.media.setAttribute("autoplay",""),"poster"in e&&Xe.media.setAttribute("poster",e.poster),E.loop&&Xe.media.setAttribute("loop","")),m(Xe.container,E.classes.fullscreen.active,Xe.isFullscreen),m(Xe.container,E.classes.captions.active,Xe.captionsEnabled),K(),s(E.types.html5,Xe.type)&&J("source",e.sources),ne(),s(E.types.html5,Xe.type)&&("tracks"in e&&J("track",e.tracks),Xe.media.load()),(s(E.types.html5,Xe.type)||s(E.types.embed,Xe.type)&&!Xe.supported.full)&&(We(),Ye()),E.title=e.title,Z()}return O.object(e)&&"sources"in e&&e.sources.length?(m(Xe.container,E.classes.ready,!1),ue(),Ne(),Ce(),qe(),void De(n,!1)):void ze("Invalid source format")}function je(e){"video"===Xe.type&&Xe.media.setAttribute("poster",e)}function Ve(){function n(){var e=ce(),t=Xe.buttons[e?"play":"pause"],n=Xe.buttons[e?"pause":"play"];if(n=n&&n.length>1?n[n.length-1]:n[0]){var r=f(t,E.classes.tabFocus);setTimeout(function(){n.focus(),r&&(m(t,E.classes.tabFocus,!1),m(n,E.classes.tabFocus,!0))},100)}}function r(){var e=t.activeElement;return e=e&&e!==t.body?t.querySelector(":focus"):null}function a(e){return e.keyCode?e.keyCode:e.which}function o(e){for(var t in Xe.buttons){var n=Xe.buttons[t];if(O.nodeList(n))for(var r=0;r0)&&(t?xe(n):we(n)),(e.deltaY>0||e.deltaX<0)&&(t?we(n):xe(n))})}function Re(){if(g(Xe.media,"timeupdate seeking",Ie),g(Xe.media,"timeupdate",W),g(Xe.media,"durationchange loadedmetadata",Ae),g(Xe.media,"ended",function(){"video"===Xe.type&&E.showPosterOnEnd&&("video"===Xe.type&&H(),me(),Xe.media.load())}),g(Xe.media,"progress playing",Ee),g(Xe.media,"volumechange",Te),g(Xe.media,"play pause ended",ye),g(Xe.media,"waiting canplay seeked",_e),E.clickToPlay&&"audio"!==Xe.type){var e=X("."+E.classes.videoWrapper);if(!e)return;e.style.cursor="pointer",g(e,"click",function(){E.hideControls&&Xe.browser.isTouch&&!Xe.media.paused||(Xe.media.paused?le():Xe.media.ended?(me(),le()):ue())})}E.disableContextMenu&&g(Xe.media,"contextmenu",function(e){e.preventDefault()}),g(Xe.media,E.events.concat(["keyup","keydown"]).join(" "),function(e){A(Xe.container,e.type,!0)})}function qe(){if(s(E.types.html5,Xe.type)){for(var e=Xe.media.querySelectorAll("source"),t=0;t ``` +Note: `data-video-id` value can now be the ID or URL for the video. This attribute name will change in a future release to reflect this change. + #### Vimeo embed ```html
``` +Note: `data-video-id` value can now be the ID or URL for the video. This attribute name will change in a future release to reflect this change. ### JavaScript Include the `plyr.js` script before the closing `` tag and then call `plyr.setup()`. More info on `setup()` can be found under [initialising](#initialising). @@ -676,6 +688,8 @@ player.source({ }); ``` +Note: `src` can be the video ID or URL + Vimeo example ```javascript @@ -689,7 +703,9 @@ player.source({ }); ``` -Some more details on the object parameters +Note: `src` can be the video ID or URL + +More details on the object parameters @@ -713,7 +729,7 @@ Some more details on the object parameters - + @@ -776,7 +792,7 @@ These events also bubble up the DOM. The event target will be the container elem - + @@ -820,12 +836,12 @@ These events also bubble up the DOM. The event target will be the container elem - + - + diff --git a/src/js/plyr.js b/src/js/plyr.js index 4ebb060a..37500fe5 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -175,7 +175,7 @@ fullscreen: null }, // Events to watch on HTML5 media elements - events: ['ready', 'ended', 'progress', 'stalled', 'playing', 'waiting', 'canplay', 'canplaythrough', 'loadstart', 'loadeddata', 'loadedmetadata', 'timeupdate', 'volumechange', 'play', 'pause', 'error', 'seeking', 'emptied'], + events: ['ready', 'ended', 'progress', 'stalled', 'playing', 'waiting', 'canplay', 'canplaythrough', 'loadstart', 'loadeddata', 'loadedmetadata', 'timeupdate', 'volumechange', 'play', 'pause', 'error', 'seeking', 'seeked', 'emptied'], // Logging logPrefix: '[Plyr]' }; @@ -596,6 +596,18 @@ } }; + // Parse YouTube ID from url + function _parseYouTubeId(url) { + var regex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/; + return (url.match(regex)) ? RegExp.$2 : url; + } + + // Parse Vimeo ID from url + function _parseVimeoId(url) { + var regex = /^.*(vimeo.com\/|video\/)(\d+).*/; + return (url.match(regex)) ? RegExp.$2 : url; + } + // Fullscreen API function _fullscreen() { var fullscreen = { @@ -1505,9 +1517,23 @@ // Setup YouTube/Vimeo function _setupEmbed() { var container = document.createElement('div'), - mediaId = plyr.embedId, + mediaId, id = plyr.type + '-' + Math.floor(Math.random() * (10000)); + // Parse IDs from URLs if supplied + switch (plyr.type) { + case 'youtube': + mediaId = _parseYouTubeId(plyr.embedId); + break; + + case 'vimeo': + mediaId = _parseVimeoId(plyr.embedId); + break; + + default: + mediaId = plyr.embedId; + } + // Remove old containers var containers = _getElements('[id^="' + plyr.type + '-"]'); for (var i = containers.length - 1; i >= 0; i--) { @@ -1724,6 +1750,12 @@ case 1: plyr.media.paused = false; + + // If we were seeking, fire seeked event + if (plyr.media.seeking) { + _triggerEvent(plyr.media, 'seeked'); + } + plyr.media.seeking = false; _triggerEvent(plyr.media, 'play'); _triggerEvent(plyr.media, 'playing'); @@ -1848,6 +1880,12 @@ } }); + plyr.embed.on('seeked', function() { + plyr.media.seeking = false; + _triggerEvent(plyr.media, 'seeked'); + _triggerEvent(plyr.media, 'play'); + }); + plyr.embed.on('ended', function() { plyr.media.paused = true; _triggerEvent(plyr.media, 'ended'); @@ -2009,7 +2047,6 @@ // Embeds if (_inArray(config.types.embed, plyr.type)) { - // YouTube switch(plyr.type) { case 'youtube': plyr.embed.seekTo(targetTime); @@ -2029,11 +2066,14 @@ _pause(); } - // Trigger timeupdate for embeds + // Trigger timeupdate _triggerEvent(plyr.media, 'timeupdate'); // Set seeking flag plyr.media.seeking = true; + + // Trigger seeking + _triggerEvent(plyr.media, 'seeking'); } // Logging @@ -3259,19 +3299,6 @@ } } - // Taken from https://gist.github.com/takien/4077195 - function parseYoutubeVideoId(url) { - var videoId; - url = url.replace(/(>|<)/gi,'').split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/); - if(url[2] !== undefined) { - videoId = url[2].split(/[^0-9a-z_\-]/i); - videoId = videoId[0]; - } else { - videoId = url; - } - return videoId; - } - // Setup a player function _init() { // Bail if the element is initialized @@ -3300,12 +3327,6 @@ plyr.type = media.getAttribute('data-type'); plyr.embedId = media.getAttribute('data-video-id'); - switch(plyr.type) { - case 'youtube': - plyr.embedId = parseYoutubeVideoId(plyr.embedId); - break; - } - // Clean up media.removeAttribute('data-type'); media.removeAttribute('data-video-id'); From 94208dce76c48ea284232e067521511ca963c625 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Wed, 2 Nov 2016 18:14:06 +1100 Subject: [PATCH 3/5] v2.0.10 - Added seek event fixes for Vimeo and YouTube (fixes #409) - Added support for embed URLs rather than ID only (fixes #345) --- changelog.md | 4 ++++ package.json | 2 +- readme.md | 6 +++--- src/js/plyr.js | 4 ++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/changelog.md b/changelog.md index dbbf4d28..0be6dc90 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,9 @@ # Changelog +## v2.0.10 +- Added seek event fixes for Vimeo and YouTube (fixes #409) +- Added support for embed URLs rather than ID only (fixes #345) + ## v2.0.9 - Temporary patch for the YouTube API issues with `getDuration()` (relates to #374) diff --git a/package.json b/package.json index 13e704c0..50d5dce6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plyr", - "version": "2.0.9", + "version": "2.0.10", "description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player", "homepage": "http://plyr.io", "main": "src/js/plyr.js", diff --git a/readme.md b/readme.md index a9a4cd12..ee13d88d 100644 --- a/readme.md +++ b/readme.md @@ -134,7 +134,7 @@ Include the `plyr.js` script before the closing `` tag and then call `ply If you want to use our CDN for the JavaScript, you can use the following: ```html - + ``` ### CSS @@ -147,11 +147,11 @@ Include the `plyr.css` stylsheet into your `` If you want to use our CDN for the default CSS, you can use the following: ```html - + ``` ### SVG Sprite -The SVG sprite is loaded automatically from our CDN. To change this, see the [options](#Options) below. For reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/2.0.9/plyr.svg`. +The SVG sprite is loaded automatically from our CDN. To change this, see the [options](#Options) below. For reference, the CDN hosted SVG sprite can be found at `https://cdn.plyr.io/2.0.10/plyr.svg`. ## Advanced diff --git a/src/js/plyr.js b/src/js/plyr.js index 37500fe5..4c02b8fd 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -1,6 +1,6 @@ // ========================================================================== // Plyr -// plyr.js v2.0.9 +// plyr.js v2.0.10 // https://github.com/selz/plyr // License: The MIT License (MIT) // ========================================================================== @@ -43,7 +43,7 @@ displayDuration: true, loadSprite: true, iconPrefix: 'plyr', - iconUrl: 'https://cdn.plyr.io/2.0.9/plyr.svg', + iconUrl: 'https://cdn.plyr.io/2.0.10/plyr.svg', clickToPlay: true, hideControls: true, showPosterOnEnd: false, From 660ff0434dca22470fc9705bed4c59ec1e003219 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Wed, 2 Nov 2016 18:29:38 +1100 Subject: [PATCH 4/5] Cache bust --- demo/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/index.html b/demo/index.html index 0c9b83af..ed9faf65 100644 --- a/demo/index.html +++ b/demo/index.html @@ -51,7 +51,7 @@
-
sources ArrayThis is an array of sources. type is optional for YouTube and Vimeo when specifying an array. For YouTube and Vimeo media, only the video ID must be passed as the source as shown above. The keys of this object are mapped directly to HTML attributes so more can be added to the object if required.This is an array of sources. type is optional for YouTube and Vimeo when specifying an array. For YouTube and Vimeo media, the video ID or URL must be passed as the source as shown above. The keys of this object are mapped directly to HTML attributes so more can be added to the object if required.
poster
ended Sent when playback completes.Sent when playback completes. Note: with Vimeo this does not occur if `loop` is enabled.
error
seeked Sent when a seek operation completes.
seeking Sent when a seek operation begins.