aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bundles.json2
-rw-r--r--dist/plyr.css2
-rw-r--r--dist/plyr.js2
-rw-r--r--docs/dist/docs.css2
-rw-r--r--docs/dist/docs.js2
-rw-r--r--docs/dist/templates.js2
-rw-r--r--docs/src/js/docs.js10
-rw-r--r--docs/src/less/components/examples.less39
-rw-r--r--docs/src/less/components/type.less18
-rw-r--r--readme.md68
-rw-r--r--src/js/plyr.js869
-rw-r--r--src/less/plyr.less58
12 files changed, 579 insertions, 495 deletions
diff --git a/bundles.json b/bundles.json
index f96c12d2..1d92e632 100644
--- a/bundles.json
+++ b/bundles.json
@@ -16,9 +16,7 @@
},
"js": {
"docs.js": [
- "docs/src/js/lib/hogan-3.0.2.mustache.js",
"docs/src/js/lib/classlist.js",
- "docs/dist/templates.js",
"docs/src/js/docs.js"
]
}
diff --git a/dist/plyr.css b/dist/plyr.css
index ffe33461..de5a062e 100644
--- a/dist/plyr.css
+++ b/dist/plyr.css
@@ -1 +1 @@
-.player-captions,.player-controls,.player-controls .player-time{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}.player-controls button:focus,.player-progress-seek[type=range]:focus,.player-volume[type=range]:focus{outline:0}@-webkit-keyframes progress{to{background-position:40px 0}}@keyframes progress{to{background-position:40px 0}}.sr-only{position:absolute!important;clip:rect(1px,1px,1px,1px);padding:0!important;border:0!important;height:1px!important;width:1px!important;overflow:hidden}.player,.player-video-wrapper{position:relative}.player{max-width:100%;min-width:290px}.player,.player *,.player ::after,.player ::before{box-sizing:border-box}.player audio,.player video{width:100%;height:auto;vertical-align:middle}.player-video-embed{padding-bottom:56.25%;height:0;overflow:hidden;background:#000}.player-video-embed iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.player-video-embed>div{position:relative;padding-bottom:200%;-webkit-transform:translateY(-35.95%);transform:translateY(-35.95%)}.player-captions{display:none;position:absolute;bottom:0;left:0;width:100%;padding:20px 20px 30px;color:#fff;font-size:20px;text-align:center}.player-captions span{border-radius:2px;padding:3px 10px;background:rgba(0,0,0,.9)}.player-captions span:empty{display:none}@media (min-width:768px){.player-captions{font-size:24px}}.player.captions-active .player-captions{display:block}.player.fullscreen-active .player-captions{font-size:32px}.player-controls{zoom:1;position:relative;padding:10px;background:#fff;line-height:1;text-align:center;box-shadow:0 1px 1px rgba(52,63,74,.2)}.player-controls:after,.player-controls:before{content:"";display:table}.player-controls:after{clear:both}.player-controls-right{display:block;margin:10px auto 0}@media (min-width:560px){.player-controls-left{float:left}.player-controls-right{float:right;margin-top:0}}.player-controls button{display:inline-block;vertical-align:middle;margin:0 2px;padding:5px 10px;overflow:hidden;border:0;background:0 0;border-radius:3px;cursor:pointer;color:#6B7D86;transition:background .3s ease,color .3s ease,opacity .3s ease}.player-controls button svg{width:18px;height:18px;display:block;fill:currentColor;transition:fill .3s ease}.player-controls button.tab-focus,.player-controls button:hover{background:#3498DB;color:#fff}.player-controls .icon-captions-on,.player-controls .icon-exit-fullscreen,.player-controls .icon-muted{display:none}.player-controls .player-time{display:inline-block;vertical-align:middle;margin-left:10px;color:#6B7D86;font-weight:600;font-size:14px}.player-controls .player-time+.player-time{display:none}@media (min-width:560px){.player-controls .player-time+.player-time{display:inline-block}}.player-controls .player-time+.player-time::before{content:'\2044';margin-right:10px}.player-tooltip{position:absolute;z-index:2;bottom:100%;margin-bottom:10px;padding:10px 15px;opacity:0;background:#fff;border:1px solid #D6DADD;border-radius:3px;color:#6B7D86;font-size:14px;line-height:1.5;font-weight:600;-webkit-transform:translate(-50%,30px) scale(0);transform:translate(-50%,30px) scale(0);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;transition:-webkit-transform .2s .1s ease,opacity .2s .1s ease;transition:transform .2s .1s ease,opacity .2s .1s ease}.player-tooltip::after{content:'';position:absolute;z-index:1;top:100%;left:50%;display:block;width:10px;height:10px;background:#fff;-webkit-transform:translate(-50%,-50%) rotate(45deg) translateY(1px);transform:translate(-50%,-50%) rotate(45deg) translateY(1px);border:1px solid #D6DADD;border-width:0 1px 1px 0}.player button.tab-focus:focus .player-tooltip,.player button:hover .player-tooltip{opacity:1;-webkit-transform:translate(-50%,0) scale(1);transform:translate(-50%,0) scale(1)}.player button:hover .player-tooltip{z-index:3}.player-progress{position:absolute;bottom:100%;left:0;right:0;width:100%;height:10px;background:rgba(86,93,100,.2)}.player-progress-buffer[value],.player-progress-played[value],.player-progress-seek[type=range]{position:absolute;left:0;top:0;width:100%;height:10px;margin:0;padding:0;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;border:none;background:0 0}.player-progress-buffer[value]::-webkit-progress-bar,.player-progress-played[value]::-webkit-progress-bar{background:0 0}.player-progress-buffer[value]::-webkit-progress-value,.player-progress-played[value]::-webkit-progress-value{background:currentColor}.player-progress-buffer[value]::-moz-progress-bar,.player-progress-played[value]::-moz-progress-bar{background:currentColor}.player-progress-played[value]{z-index:2;color:#3498DB}.player-progress-buffer[value]{color:rgba(86,93,100,.25)}.player-progress-seek[type=range]{z-index:4;cursor:pointer;outline:0}.player-progress-seek[type=range]::-webkit-slider-runnable-track{background:0 0;border:0}.player-progress-seek[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background:0 0;border:0;width:20px;height:10px}.player-progress-seek[type=range]::-moz-range-track{background:0 0;border:0}.player-progress-seek[type=range]::-moz-range-thumb{-moz-appearance:none;background:0 0;border:0;width:20px;height:10px}.player-progress-seek[type=range]::-ms-track{color:transparent;background:0 0;border:0}.player-progress-seek[type=range]::-ms-fill-lower,.player-progress-seek[type=range]::-ms-fill-upper{background:0 0;border:0}.player-progress-seek[type=range]::-ms-thumb{background:0 0;border:0;width:20px;height:10px}.player-progress-seek[type=range]::-moz-focus-outer{border:0}.player.loading .player-progress-buffer{-webkit-animation:progress 1s linear infinite;animation:progress 1s linear infinite;background-size:40px 40px;background-repeat:repeat-x;background-color:rgba(86,93,100,.25);background-image:linear-gradient(-45deg,rgba(0,0,0,.15) 25%,transparent 25%,transparent 50%,rgba(0,0,0,.15) 50%,rgba(0,0,0,.15) 75%,transparent 75%,transparent);color:transparent}.player-controls [data-player=pause],.player.playing .player-controls [data-player=play]{display:none}.player.playing .player-controls [data-player=pause]{display:inline-block}.player-volume[type=range]{display:inline-block;vertical-align:middle;-webkit-appearance:none;-moz-appearance:none;width:100px;margin:0 10px 0 0;padding:0;cursor:pointer;background:0 0;border:none}.player-volume[type=range]::-webkit-slider-runnable-track{height:6px;background:#e6e6e6;border:0;border-radius:3px}.player-volume[type=range]::-webkit-slider-thumb{-webkit-appearance:none;margin-top:-3px;height:12px;width:12px;background:#6B7D86;border:0;border-radius:6px;transition:background .3s ease;cursor:ew-resize}.player-volume[type=range]::-moz-range-track{height:6px;background:#e6e6e6;border:0;border-radius:3px}.player-volume[type=range]::-moz-range-thumb{height:12px;width:12px;background:#6B7D86;border:0;border-radius:6px;transition:background .3s ease;cursor:ew-resize}.player-volume[type=range]::-ms-track{height:6px;background:0 0;border-color:transparent;border-width:3px 0;color:transparent}.player-volume[type=range]::-ms-fill-lower,.player-volume[type=range]::-ms-fill-upper{height:6px;background:#e6e6e6;border:0;border-radius:3px}.player-volume[type=range]::-ms-thumb{height:12px;width:12px;background:#6B7D86;border:0;border-radius:6px;transition:background .3s ease;cursor:ew-resize}.player-volume[type=range]:focus::-webkit-slider-thumb{background:#3498DB}.player-volume[type=range]:focus::-moz-range-thumb{background:#3498DB}.player-volume[type=range]:focus::-ms-thumb{background:#3498DB}.player-audio.ios .player-controls-right,.player.ios .player-volume,.player.ios [data-player=mute]{display:none}.player-audio.ios .player-controls-left{float:none}.player-audio .player-controls{padding-top:20px}.player-audio .player-progress{bottom:auto;top:0;background:#D6DADD}.player-fullscreen,.player.fullscreen-active{position:fixed;top:0;left:0;right:0;bottom:0;height:100%;width:100%;z-index:10000000;background:#000}.player-fullscreen video,.player.fullscreen-active video{height:100%}.player-fullscreen .player-video-wrapper,.player.fullscreen-active .player-video-wrapper{height:100%;width:100%}.player-fullscreen .player-controls,.player.fullscreen-active .player-controls{position:absolute;bottom:0;left:0;right:0}.player-fullscreen.fullscreen-hide-controls.playing .player-controls,.player.fullscreen-active.fullscreen-hide-controls.playing .player-controls{-webkit-transform:translateY(100%) translateY(5px);transform:translateY(100%) translateY(5px);transition:-webkit-transform .3s .2s ease;transition:transform .3s .2s ease}.player-fullscreen.fullscreen-hide-controls.playing.player-hover .player-controls,.player.fullscreen-active.fullscreen-hide-controls.playing.player-hover .player-controls{-webkit-transform:translateY(0);transform:translateY(0)}.player-fullscreen.fullscreen-hide-controls.playing .player-captions,.player.fullscreen-active.fullscreen-hide-controls.playing .player-captions{bottom:5px;transition:bottom .3s .2s ease}.player-fullscreen .player-captions,.player-fullscreen.fullscreen-hide-controls.playing.player-hover .player-captions,.player.fullscreen-active .player-captions,.player.fullscreen-active.fullscreen-hide-controls.playing.player-hover .player-captions{top:auto;bottom:90px}@media (min-width:560px){.player-fullscreen .player-captions,.player-fullscreen.fullscreen-hide-controls.playing.player-hover .player-captions,.player.fullscreen-active .player-captions,.player.fullscreen-active.fullscreen-hide-controls.playing.player-hover .player-captions{bottom:60px}}.player.captions-active .player-controls .icon-captions-on,.player.fullscreen-active .icon-exit-fullscreen,.player.muted .player-controls .icon-muted{display:block}.player [data-player=captions],.player [data-player=fullscreen],.player.captions-active .player-controls .icon-captions-on+svg,.player.fullscreen-active .icon-exit-fullscreen+svg,.player.muted .player-controls .icon-muted+svg{display:none}.player.captions-enabled [data-player=captions],.player.fullscreen-enabled [data-player=fullscreen]{display:inline-block} \ No newline at end of file
+.plyr-captions,.plyr-controls,.plyr-controls .plyr-time{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}.plyr-controls button:focus,.plyr-progress-seek[type=range]:focus,.plyr-volume[type=range]:focus{outline:0}@-webkit-keyframes progress{to{background-position:40px 0}}@keyframes progress{to{background-position:40px 0}}.sr-only{position:absolute!important;clip:rect(1px,1px,1px,1px);padding:0!important;border:0!important;height:1px!important;width:1px!important;overflow:hidden}.plyr,.plyr-video-wrapper{position:relative}.plyr{max-width:100%;min-width:290px}.plyr,.plyr *,.plyr ::after,.plyr ::before{box-sizing:border-box}.plyr audio,.plyr video{width:100%;height:auto;vertical-align:middle}.plyr-video-embed{padding-bottom:56.25%;height:0;overflow:hidden;background:#000}.plyr-video-embed iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.plyr-video-embed>div{position:relative;padding-bottom:200%;-webkit-transform:translateY(-35.95%);transform:translateY(-35.95%)}.plyr-captions{display:none;position:absolute;bottom:0;left:0;width:100%;padding:20px 20px 30px;color:#fff;font-size:20px;text-align:center}.plyr-captions span{border-radius:2px;padding:3px 10px;background:rgba(0,0,0,.9)}.plyr-captions span:empty{display:none}@media (min-width:768px){.plyr-captions{font-size:24px}}.plyr.captions-active .plyr-captions{display:block}.plyr.fullscreen-active .plyr-captions{font-size:32px}.plyr-controls{zoom:1;position:relative;padding:10px;background:#fff;line-height:1;text-align:center;box-shadow:0 1px 1px rgba(52,63,74,.2)}.plyr-controls:after,.plyr-controls:before{content:"";display:table}.plyr-controls:after{clear:both}.plyr-controls-right{display:block;margin:10px auto 0}@media (min-width:560px){.plyr-controls-left{float:left}.plyr-controls-right{float:right;margin-top:0}}.plyr-controls button{display:inline-block;vertical-align:middle;margin:0 2px;padding:5px 10px;overflow:hidden;border:0;background:0 0;border-radius:3px;cursor:pointer;color:#6B7D86;transition:background .3s ease,color .3s ease,opacity .3s ease}.plyr-controls button svg{width:18px;height:18px;display:block;fill:currentColor;transition:fill .3s ease}.plyr-controls button.tab-focus,.plyr-controls button:hover{background:#3498DB;color:#fff}.plyr-controls .plyr-time,.plyr-tooltip{color:#6B7D86;font-size:14px;font-weight:600}.plyr-controls .icon-captions-on,.plyr-controls .icon-exit-fullscreen,.plyr-controls .icon-muted{display:none}.plyr-controls .plyr-time{display:inline-block;vertical-align:middle;margin-left:10px}.plyr-controls .plyr-time+.plyr-time{display:none}@media (min-width:560px){.plyr-controls .plyr-time+.plyr-time{display:inline-block}}.plyr-controls .plyr-time+.plyr-time::before{content:'\2044';margin-right:10px}.plyr-tooltip{position:absolute;z-index:2;bottom:100%;margin-bottom:10px;padding:10px 15px;opacity:0;background:#fff;border:1px solid #D6DADD;border-radius:3px;line-height:1.5;-webkit-transform:translate(-50%,30px) scale(0);transform:translate(-50%,30px) scale(0);-webkit-transform-origin:50% 100%;transform-origin:50% 100%;transition:-webkit-transform .2s .1s ease,opacity .2s .1s ease;transition:transform .2s .1s ease,opacity .2s .1s ease}.plyr-tooltip::after{content:'';position:absolute;z-index:1;top:100%;left:50%;display:block;width:10px;height:10px;background:#fff;-webkit-transform:translate(-50%,-50%) rotate(45deg) translateY(1px);transform:translate(-50%,-50%) rotate(45deg) translateY(1px);border:1px solid #D6DADD;border-width:0 1px 1px 0}.plyr button.tab-focus:focus .plyr-tooltip,.plyr button:hover .plyr-tooltip{opacity:1;-webkit-transform:translate(-50%,0) scale(1);transform:translate(-50%,0) scale(1)}.plyr button:hover .plyr-tooltip{z-index:3}.plyr-progress{position:absolute;bottom:100%;left:0;right:0;width:100%;height:10px;background:rgba(86,93,100,.2)}.plyr-progress-buffer[value],.plyr-progress-played[value],.plyr-progress-seek[type=range]{position:absolute;left:0;top:0;width:100%;height:10px;margin:0;padding:0;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;border:none;background:0 0}.plyr-progress-buffer[value]::-webkit-progress-bar,.plyr-progress-played[value]::-webkit-progress-bar{background:0 0}.plyr-progress-buffer[value]::-webkit-progress-value,.plyr-progress-played[value]::-webkit-progress-value{background:currentColor}.plyr-progress-buffer[value]::-moz-progress-bar,.plyr-progress-played[value]::-moz-progress-bar{background:currentColor}.plyr-progress-played[value]{z-index:2;color:#3498DB}.plyr-progress-buffer[value]{color:rgba(86,93,100,.25)}.plyr-progress-seek[type=range]{z-index:4;cursor:pointer;outline:0}.plyr-progress-seek[type=range]::-webkit-slider-runnable-track{background:0 0;border:0}.plyr-progress-seek[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background:0 0;border:0;width:20px;height:10px}.plyr-progress-seek[type=range]::-moz-range-track{background:0 0;border:0}.plyr-progress-seek[type=range]::-moz-range-thumb{-moz-appearance:none;background:0 0;border:0;width:20px;height:10px}.plyr-progress-seek[type=range]::-ms-track{color:transparent;background:0 0;border:0}.plyr-progress-seek[type=range]::-ms-fill-lower,.plyr-progress-seek[type=range]::-ms-fill-upper{background:0 0;border:0}.plyr-progress-seek[type=range]::-ms-thumb{background:0 0;border:0;width:20px;height:10px}.plyr-progress-seek[type=range]::-moz-focus-outer{border:0}.plyr.loading .plyr-progress-buffer{-webkit-animation:progress 1s linear infinite;animation:progress 1s linear infinite;background-size:40px 40px;background-repeat:repeat-x;background-color:rgba(86,93,100,.25);background-image:linear-gradient(-45deg,rgba(0,0,0,.15) 25%,transparent 25%,transparent 50%,rgba(0,0,0,.15) 50%,rgba(0,0,0,.15) 75%,transparent 75%,transparent);color:transparent}.plyr-controls [data-plyr=pause],.plyr.playing .plyr-controls [data-plyr=play]{display:none}.plyr.playing .plyr-controls [data-plyr=pause]{display:inline-block}.plyr-volume[type=range]{display:inline-block;vertical-align:middle;-webkit-appearance:none;-moz-appearance:none;width:100px;margin:0 10px 0 0;padding:0;cursor:pointer;background:0 0;border:none}.plyr-volume[type=range]::-webkit-slider-runnable-track{height:6px;background:#e6e6e6;border:0;border-radius:3px}.plyr-volume[type=range]::-webkit-slider-thumb{-webkit-appearance:none;margin-top:-3px;height:12px;width:12px;background:#6B7D86;border:0;border-radius:6px;transition:background .3s ease;cursor:ew-resize}.plyr-volume[type=range]::-moz-range-track{height:6px;background:#e6e6e6;border:0;border-radius:3px}.plyr-volume[type=range]::-moz-range-thumb{height:12px;width:12px;background:#6B7D86;border:0;border-radius:6px;transition:background .3s ease;cursor:ew-resize}.plyr-volume[type=range]::-ms-track{height:6px;background:0 0;border-color:transparent;border-width:3px 0;color:transparent}.plyr-volume[type=range]::-ms-fill-lower,.plyr-volume[type=range]::-ms-fill-upper{height:6px;background:#e6e6e6;border:0;border-radius:3px}.plyr-volume[type=range]::-ms-thumb{height:12px;width:12px;background:#6B7D86;border:0;border-radius:6px;transition:background .3s ease;cursor:ew-resize}.plyr-volume[type=range]:focus::-webkit-slider-thumb{background:#3498DB}.plyr-volume[type=range]:focus::-moz-range-thumb{background:#3498DB}.plyr-volume[type=range]:focus::-ms-thumb{background:#3498DB}.plyr-audio.ios .plyr-controls-right,.plyr.ios .plyr-volume,.plyr.ios [data-plyr=mute]{display:none}.plyr-audio.ios .plyr-controls-left{float:none}.plyr-audio .plyr-controls{padding-top:20px}.plyr-audio .plyr-progress{bottom:auto;top:0;background:#D6DADD}.plyr-fullscreen,.plyr.fullscreen-active{position:fixed;top:0;left:0;right:0;bottom:0;height:100%;width:100%;z-index:10000000;background:#000}.plyr-fullscreen video,.plyr.fullscreen-active video{height:100%}.plyr-fullscreen .plyr-video-wrapper,.plyr.fullscreen-active .plyr-video-wrapper{height:100%;width:100%}.plyr-fullscreen .plyr-controls,.plyr.fullscreen-active .plyr-controls{position:absolute;bottom:0;left:0;right:0}.plyr-fullscreen.fullscreen-hide-controls.playing .plyr-controls,.plyr.fullscreen-active.fullscreen-hide-controls.playing .plyr-controls{-webkit-transform:translateY(100%) translateY(5px);transform:translateY(100%) translateY(5px);transition:-webkit-transform .3s .2s ease;transition:transform .3s .2s ease}.plyr-fullscreen.fullscreen-hide-controls.playing.plyr-hover .plyr-controls,.plyr.fullscreen-active.fullscreen-hide-controls.playing.plyr-hover .plyr-controls{-webkit-transform:translateY(0);transform:translateY(0)}.plyr-fullscreen.fullscreen-hide-controls.playing .plyr-captions,.plyr.fullscreen-active.fullscreen-hide-controls.playing .plyr-captions{bottom:5px;transition:bottom .3s .2s ease}.plyr-fullscreen .plyr-captions,.plyr-fullscreen.fullscreen-hide-controls.playing.plyr-hover .plyr-captions,.plyr.fullscreen-active .plyr-captions,.plyr.fullscreen-active.fullscreen-hide-controls.playing.plyr-hover .plyr-captions{top:auto;bottom:90px}@media (min-width:560px){.plyr-fullscreen .plyr-captions,.plyr-fullscreen.fullscreen-hide-controls.playing.plyr-hover .plyr-captions,.plyr.fullscreen-active .plyr-captions,.plyr.fullscreen-active.fullscreen-hide-controls.playing.plyr-hover .plyr-captions{bottom:60px}}.plyr.captions-active .plyr-controls .icon-captions-on,.plyr.fullscreen-active .icon-exit-fullscreen,.plyr.muted .plyr-controls .icon-muted{display:block}.plyr [data-plyr=captions],.plyr [data-plyr=fullscreen],.plyr.captions-active .plyr-controls .icon-captions-on+svg,.plyr.fullscreen-active .icon-exit-fullscreen+svg,.plyr.muted .plyr-controls .icon-muted+svg{display:none}.plyr.captions-enabled [data-plyr=captions],.plyr.fullscreen-enabled [data-plyr=fullscreen]{display:inline-block} \ No newline at end of file
diff --git a/dist/plyr.js b/dist/plyr.js
index ecb63e34..3e79617e 100644
--- a/dist/plyr.js
+++ b/dist/plyr.js
@@ -1 +1 @@
-!function(e){"use strict";function t(){var e=['<div class="player-controls">','<div class="player-progress">','<label for="seek{id}" class="sr-only">Seek</label>','<input id="seek{id}" class="player-progress-seek" type="range" min="0" max="100" step="0.5" value="0" data-player="seek">','<progress class="player-progress-played" max="100" value="0">',"<span>0</span>% "+E.i18n.played,"</progress>",'<progress class="player-progress-buffer" max="100" value="0">',"<span>0</span>% "+E.i18n.buffered,"</progress>","</div>",'<span class="player-controls-left">'];return s(E.controls,"restart")&&e.push('<button type="button" data-player="restart">','<svg><use xlink:href="#'+E.iconPrefix+'-restart" /></svg>','<span class="sr-only">'+E.i18n.restart+"</span>","</button>"),s(E.controls,"rewind")&&e.push('<button type="button" data-player="rewind">','<svg><use xlink:href="#'+E.iconPrefix+'-rewind" /></svg>','<span class="sr-only">'+E.i18n.rewind+"</span>","</button>"),s(E.controls,"play")&&e.push('<button type="button" data-player="play">','<svg><use xlink:href="#'+E.iconPrefix+'-play" /></svg>','<span class="sr-only">'+E.i18n.play+"</span>","</button>",'<button type="button" data-player="pause">','<svg><use xlink:href="#'+E.iconPrefix+'-pause" /></svg>','<span class="sr-only">'+E.i18n.pause+"</span>","</button>"),s(E.controls,"fast-forward")&&e.push('<button type="button" data-player="fast-forward">','<svg><use xlink:href="#'+E.iconPrefix+'-fast-forward" /></svg>','<span class="sr-only">'+E.i18n.forward+"</span>","</button>"),s(E.controls,"current-time")&&e.push('<span class="player-time">','<span class="sr-only">'+E.i18n.currentTime+"</span>",'<span class="player-current-time">00:00</span>',"</span>"),s(E.controls,"duration")&&e.push('<span class="player-time">','<span class="sr-only">'+E.i18n.duration+"</span>",'<span class="player-duration">00:00</span>',"</span>"),e.push("</span>",'<span class="player-controls-right">'),s(E.controls,"mute")&&e.push('<button type="button" data-player="mute">','<svg class="icon-muted"><use xlink:href="#'+E.iconPrefix+'-muted" /></svg>','<svg><use xlink:href="#'+E.iconPrefix+'-volume" /></svg>','<span class="sr-only">'+E.i18n.toggleMute+"</span>","</button>"),s(E.controls,"volume")&&e.push('<label for="volume{id}" class="sr-only">'+E.i18n.volume+"</label>",'<input id="volume{id}" class="player-volume" type="range" min="0" max="10" value="5" data-player="volume">'),s(E.controls,"captions")&&e.push('<button type="button" data-player="captions">','<svg class="icon-captions-on"><use xlink:href="#'+E.iconPrefix+'-captions-on" /></svg>','<svg><use xlink:href="#'+E.iconPrefix+'-captions-off" /></svg>','<span class="sr-only">'+E.i18n.toggleCaptions+"</span>","</button>"),s(E.controls,"fullscreen")&&e.push('<button type="button" data-player="fullscreen">','<svg class="icon-exit-fullscreen"><use xlink:href="#'+E.iconPrefix+'-exit-fullscreen" /></svg>','<svg><use xlink:href="#'+E.iconPrefix+'-enter-fullscreen" /></svg>','<span class="sr-only">'+E.i18n.toggleFullscreen+"</span>","</button>"),e.push("</span>","</div>"),e.join("")}function n(e,t){E.debug&&window.console&&console[t?"error":"log"](e)}function a(){var e,t,n,a=navigator.userAgent,r=navigator.appName,o=""+parseFloat(navigator.appVersion),s=parseInt(navigator.appVersion,10);return-1!==navigator.appVersion.indexOf("Windows NT")&&-1!==navigator.appVersion.indexOf("rv:11")?(r="IE",o="11;"):-1!==(t=a.indexOf("MSIE"))?(r="IE",o=a.substring(t+5)):-1!==(t=a.indexOf("Chrome"))?(r="Chrome",o=a.substring(t+7)):-1!==(t=a.indexOf("Safari"))?(r="Safari",o=a.substring(t+7),-1!==(t=a.indexOf("Version"))&&(o=a.substring(t+8))):-1!==(t=a.indexOf("Firefox"))?(r="Firefox",o=a.substring(t+8)):(e=a.lastIndexOf(" ")+1)<(t=a.lastIndexOf("/"))&&(r=a.substring(e,t),o=a.substring(t+1),r.toLowerCase()==r.toUpperCase()&&(r=navigator.appName)),-1!==(n=o.indexOf(";"))&&(o=o.substring(0,n)),-1!==(n=o.indexOf(" "))&&(o=o.substring(0,n)),s=parseInt(""+o,10),isNaN(s)&&(o=""+parseFloat(navigator.appVersion),s=parseInt(navigator.appVersion,10)),{name:r,version:s,ios:/(iPad|iPhone|iPod)/g.test(navigator.platform)}}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 o(e){if(!document.querySelectorAll('script[src="'+e+'"]').length){var t=document.createElement("script");t.src=e;var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n)}}function s(e,t){return Array.prototype.indexOf&&-1!=e.indexOf(t)}function i(e,t,n){return e.replace(new RegExp(t.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g,"\\$1"),"g"),n)}function l(e,t){e.length||(e=[e]);for(var n=e.length-1;n>=0;n--){var a=n>0?t.cloneNode(!0):t,r=e[n],o=r.parentNode,s=r.nextSibling;a.appendChild(r),s?o.insertBefore(a,s):o.appendChild(a)}}function u(e){for(var t=e.parentNode;e.firstChild;)t.insertBefore(e.firstChild,e);t.removeChild(e)}function c(e){e.parentNode.removeChild(e)}function p(e,t){e.insertBefore(t,e.firstChild)}function d(e,t){for(var n in t)e.setAttribute(n,"boolean"==typeof t[n]&&t[n]?"":t[n])}function m(e,t,n){var a=document.createElement(e);d(a,n),p(t,a)}function f(e){return e.replace(".","")}function y(e,t,n){if(e)if(e.classList)e.classList[n?"add":"remove"](t);else{var a=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=a+(n?" "+t:"")}}function b(e,t,n,a){var r=t.split(" ");if(e instanceof NodeList)for(var o=0;o<e.length;o++)e[o]instanceof Node&&b(e[o],arguments[1],arguments[2],arguments[3]);else for(var s=0;s<r.length;s++)e[a?"addEventListener":"removeEventListener"](r[s],n,!1)}function v(e,t,n){e&&b(e,t,n,!0)}function g(e,t,n){e&&b(e,t,n,!1)}function h(e,t){var n=document.createEvent("MouseEvents");n.initEvent(t,!0,!0),e.dispatchEvent(n)}function w(e,t){return t="boolean"==typeof t?t:!e.getAttribute("aria-pressed"),e.setAttribute("aria-pressed",t),t}function k(e,t){return 0===e||0===t||isNaN(e)||isNaN(t)?0:(e/t*100).toFixed(2)}function T(e,t){for(var n in t)t[n]&&t[n].constructor&&t[n].constructor===Object?(e[n]=e[n]||{},T(e[n],t[n])):e[n]=t[n];return e}function x(){var e={supportsFullScreen:!1,isFullScreen:function(){return!1},requestFullScreen:function(){},cancelFullScreen:function(){},fullScreenEventName:"",element:null,prefix:""},t="webkit moz o ms khtml".split(" ");if("undefined"!=typeof document.cancelFullScreen)e.supportsFullScreen=!0;else for(var n=0,a=t.length;a>n;n++){if(e.prefix=t[n],"undefined"!=typeof document[e.prefix+"CancelFullScreen"]){e.supportsFullScreen=!0;break}if("undefined"!=typeof document.msExitFullscreen&&document.msFullscreenEnabled){e.prefix="ms",e.supportsFullScreen=!0;break}}return e.supportsFullScreen&&(e.fullScreenEventName="ms"==e.prefix?"MSFullscreenChange":e.prefix+"fullscreenchange",e.isFullScreen=function(e){switch("undefined"==typeof e&&(e=document.body),this.prefix){case"":return document.fullscreenElement==e;case"moz":return document.mozFullScreenElement==e;default:return document[this.prefix+"FullscreenElement"]==e}},e.requestFullScreen=function(e){return"undefined"==typeof e&&(e=document.body),""===this.prefix?e.requestFullScreen():e[this.prefix+("ms"==this.prefix?"RequestFullscreen":"RequestFullScreen")]()},e.cancelFullScreen=function(){return""===this.prefix?document.cancelFullScreen():document[this.prefix+("ms"==this.prefix?"ExitFullscreen":"CancelFullScreen")]()},e.element=function(){return""===this.prefix?document.fullscreenElement:document[this.prefix+"FullscreenElement"]}),e}function F(){var e={supported:function(){try{return"localStorage"in window&&null!==window.localStorage}catch(e){return!1}}()};return e}function C(T){function C(e){if(!he.usingTextTracks&&"video"===he.type&&he.supported.full&&(he.subcount=0,e="number"==typeof e?e:he.media.currentTime,he.captions[he.subcount])){for(;N(he.captions[he.subcount][0])<e.toFixed(1);)if(he.subcount++,he.subcount>he.captions.length-1){he.subcount=he.captions.length-1;break}if(he.media.currentTime.toFixed(1)>=P(he.captions[he.subcount][0])&&he.media.currentTime.toFixed(1)<=N(he.captions[he.subcount][0])){he.currentCaption=he.captions[he.subcount][1];var t=he.currentCaption.trim();he.captionsContainer.innerHTML!=t&&(he.captionsContainer.innerHTML="",he.captionsContainer.innerHTML=t)}else he.captionsContainer.innerHTML=""}}function A(){he.buttons.captions&&(y(he.container,E.classes.captions.enabled,!0),E.captions.defaultActive&&(y(he.container,E.classes.captions.active,!0),w(he.buttons.captions,!0)))}function P(e){var t=[];return t=e.split(" --> "),I(t[0])}function N(e){var t=[];return t=e.split(" --> "),I(t[1])}function I(e){if(null===e||void 0===e)return 0;var t,n=[],a=[];return n=e.split(","),a=n[0].split(":"),t=Math.floor(60*a[0]*60)+Math.floor(60*a[1])+Math.floor(a[2])}function M(e){return he.container.querySelectorAll(e)}function L(e){return M(e)[0]}function O(){try{return window.self!==window.top}catch(e){return!0}}function V(){var e=E.html;if(n("Injecting custom controls."),e||(e=t()),e=i(e,"{seektime}",E.seekTime),e=i(e,"{id}",Math.floor(1e4*Math.random())),he.container.insertAdjacentHTML("beforeend",e),E.tooltips)for(var a=M(E.selectors.labels),r=a.length-1;r>=0;r--){var o=a[r];y(o,E.classes.hidden,!1),y(o,E.classes.tooltip,!0)}}function q(){try{return he.controls=L(E.selectors.controls),he.buttons={},he.buttons.seek=L(E.selectors.buttons.seek),he.buttons.play=L(E.selectors.buttons.play),he.buttons.pause=L(E.selectors.buttons.pause),he.buttons.restart=L(E.selectors.buttons.restart),he.buttons.rewind=L(E.selectors.buttons.rewind),he.buttons.forward=L(E.selectors.buttons.forward),he.buttons.fullscreen=L(E.selectors.buttons.fullscreen),he.buttons.mute=L(E.selectors.buttons.mute),he.buttons.captions=L(E.selectors.buttons.captions),he.checkboxes=M('[type="checkbox"]'),he.progress={},he.progress.container=L(E.selectors.progress.container),he.progress.buffer={},he.progress.buffer.bar=L(E.selectors.progress.buffer),he.progress.buffer.text=he.progress.buffer.bar&&he.progress.buffer.bar.getElementsByTagName("span")[0],he.progress.played={},he.progress.played.bar=L(E.selectors.progress.played),he.progress.played.text=he.progress.played.bar&&he.progress.played.bar.getElementsByTagName("span")[0],he.volume=L(E.selectors.buttons.volume),he.duration=L(E.selectors.duration),he.currentTime=L(E.selectors.currentTime),he.seekTime=M(E.selectors.seekTime),!0}catch(e){return n("It looks like there's a problem with your controls html. Bailing.",!0),he.media.setAttribute("controls",""),!1}}function H(){if(he.buttons.play){var e=he.buttons.play.innerText||E.i18n.play;"undefined"!=typeof E.title&&E.title.length&&(e+=", "+E.title),he.buttons.play.setAttribute("aria-label",e)}}function j(){if(!he.media)return n("No audio or video element found!",!0),!1;if(he.supported.full&&(he.media.removeAttribute("controls"),y(he.container,E.classes.type.replace("{0}",he.type),!0),y(he.container,E.classes.stopped,E.autoplay),he.browser.ios&&y(he.container,"ios",!0),"video"===he.type)){var e=document.createElement("div");e.setAttribute("class",E.classes.videoWrapper),l(he.media,e),he.videoContainer=e}s(E.types.embed,he.type)?(D(he.embedId,he.type),he.embedId=null):E.autoplay&&$()}function D(e){for(var t=document.createElement("div"),n=he.type+"-"+Math.floor(1e4*Math.random()),a=M('[id^="'+he.type+'-"]'),r=a.length-1;r>=0;r--)c(a[r]);if(t.setAttribute("id",n),y(he.media,E.classes.videoWrapper,!0),y(he.media,E.classes.embedWrapper,!0),"youtube"===he.type)he.media.appendChild(t),"object"==typeof YT?R(e,t):(o("https://www.youtube.com/iframe_api"),window.onYouTubeIframeAPIReady=function(){R(e,t)});else if("vimeo"===he.type){var s=document.createElement("iframe");if(s.loaded=!1,v(s,"load",function(){s.loaded=!0}),d(s,{src:"https://player.vimeo.com/video/"+e+"?player_id="+n+"&api=1&badge=0&byline=0&portrait=0&title=0",id:n,webkitallowfullscreen:"",mozallowfullscreen:"",allowfullscreen:"",frameborder:0}),t.appendChild(s),he.media.appendChild(t),"function"==typeof Froogaloop)v(s,"load",_);else{o("https://rawgit.com/vimeo/player-api/master/javascript/froogaloop.js");var i=window.setInterval(function(){"$f"in window&&s.loaded&&(window.clearInterval(i),_.call(s))},50)}}}function B(){he.supported.full&&(he.container.querySelectorAll(E.selectors.controls).length||ve()),te(),ne()}function R(e,t){"timer"in he||(he.timer={}),he.embed=new YT.Player(t.id,{videoId:e,playerVars:{autoplay:E.autoplay?1:0,controls:he.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},events:{onReady:function(e){var t=e.target;he.media.play=function(){t.playVideo()},he.media.pause=function(){t.pauseVideo()},he.media.stop=function(){t.stopVideo()},he.media.duration=t.getDuration(),he.media.paused=!E.autoplay,he.media.currentTime=t.getCurrentTime(),he.media.muted=t.isMuted(),h(he.media,"timeupdate"),window.clearInterval(he.timer.buffering),he.timer.buffering=window.setInterval(function(){he.media.buffered=t.getVideoLoadedFraction(),h(he.media,"progress"),1===he.media.buffered&&window.clearInterval(he.timer.buffering)},200),B(),E.displayDuration&&ie()},onStateChange:function(e){var t=e.target;switch(window.clearInterval(he.timer.playing),e.data){case 0:he.media.paused=!0,h(he.media,"ended");break;case 1:he.media.paused=!1,h(he.media,"play"),he.timer.playing=window.setInterval(function(){he.media.currentTime=t.getCurrentTime(),h(he.media,"timeupdate")},200);break;case 2:he.media.paused=!0,h(he.media,"pause")}}}})}function _(){he.embed=$f(this),he.embed.addEvent("ready",function(){he.media.play=function(){he.embed.api("play")},he.media.pause=function(){he.embed.api("pause")},he.media.stop=function(){he.embed.api("stop")},he.media.paused=!E.autoplay,he.media.currentTime=0,B(),he.embed.api("getCurrentTime",function(e){he.media.currentTime=e,h(he.media,"timeupdate")}),he.embed.api("getDuration",function(e){he.media.duration=e,he.supported.full&&E.displayDuration&&ie()}),he.embed.addEvent("play",function(){console.log("play"),he.media.paused=!1,h(he.media,"play")}),he.embed.addEvent("pause",function(){console.log("pause"),he.media.paused=!0,h(he.media,"pause")}),he.embed.addEvent("playProgress",function(e){he.media.currentTime=e.seconds,h(he.media,"timeupdate")}),he.embed.addEvent("loadProgress",function(e){he.media.buffered=e.percent,h(he.media,"progress")}),he.embed.addEvent("finish",function(){he.media.paused=!0,h(he.media,"ended")})})}function W(){if("video"===he.type){L(E.selectors.captions)||he.videoContainer.insertAdjacentHTML("afterbegin",'<div class="'+f(E.selectors.captions)+'"><span></span></div>'),he.captionsContainer=L(E.selectors.captions).querySelector("span"),he.usingTextTracks=!1,he.media.textTracks&&(he.usingTextTracks=!0);for(var e,t="",a=he.media.childNodes,r=0;r<a.length;r++)"track"===a[r].nodeName.toLowerCase()&&(e=a[r].kind,("captions"===e||"subtitles"===e)&&(t=a[r].getAttribute("src")));if(he.captionExists=!0,""===t?(he.captionExists=!1,n("No caption track found.")):n("Caption track found; URI: "+t),he.captionExists){for(var o=he.media.textTracks,s=0;s<o.length;s++)o[s].mode="hidden";if(A(he),("IE"===he.browser.name&&he.browser.version>=10||"Firefox"===he.browser.name&&he.browser.version>=31||"Chrome"===he.browser.name&&he.browser.version>=43||"Safari"===he.browser.name&&he.browser.version>=7)&&(n("Detected unsupported browser for HTML5 captions. Using fallback."),he.usingTextTracks=!1),he.usingTextTracks){n("TextTracks supported.");for(var i=0;i<o.length;i++){var l=o[i];("captions"===l.kind||"subtitles"===l.kind)&&v(l,"cuechange",function(){he.captionsContainer.innerHTML="",this.activeCues[0]&&this.activeCues[0].hasOwnProperty("text")&&he.captionsContainer.appendChild(this.activeCues[0].getCueAsHTML().trim())})}}else if(n("TextTracks not supported so rendering captions manually."),he.currentCaption="",he.captions=[],""!==t){var u=new XMLHttpRequest;u.onreadystatechange=function(){if(4===u.readyState)if(200===u.status){var e,t=[],a=u.responseText;t=a.split("\n\n");for(var r=0;r<t.length;r++)e=t[r],he.captions[r]=[],he.captions[r]=e.split("\n");he.captions.shift(),n("Successfully loaded the caption file via AJAX.")}else n("There was a problem loading the caption file via AJAX.",!0)},u.open("get",t,!0),u.send()}if("Safari"===he.browser.name&&he.browser.version>=7){n("Safari 7+ detected; removing track from DOM."),o=he.media.getElementsByTagName("track");for(var c=0;c<o.length;c++)he.media.removeChild(o[c])}}else y(he.container,E.classes.captions.enabled)}}function z(){if("audio"!=he.type&&E.fullscreen.enabled){var e=S.supportsFullScreen;e||E.fullscreen.fallback&&!O()?(n((e?"Native":"Fallback")+" fullscreen enabled."),y(he.container,E.classes.fullscreen.enabled,!0)):n("Fullscreen not supported and fallback disabled."),w(he.buttons.fullscreen,!1),E.fullscreen.hideControls&&y(he.container,E.classes.fullscreen.hideControls,!0)}}function $(){he.media.play()}function U(){he.media.pause()}function X(e){e===!0?$():e===!1?U():he.media[he.media.paused?"play":"pause"]()}function Y(e){"number"!=typeof e&&(e=E.seekTime),G(he.media.currentTime-e)}function J(e){"number"!=typeof e&&(e=E.seekTime),G(he.media.currentTime+e)}function G(e){var t=0,a=he.media.paused;"number"==typeof e?t=e:"object"!=typeof e||"input"!==e.type&&"change"!==e.type||(t=e.target.value/e.target.max*he.media.duration),0>t?t=0:t>he.media.duration&&(t=he.media.duration);try{he.media.currentTime=t.toFixed(1)}catch(r){}"embed"in he&&("youtube"===he.type&&he.embed.seekTo(t),"vimeo"===he.type&&he.embed.api("seekTo",t),h(he.media,"timeupdate"),a&&U()),n("Seeking to "+he.media.currentTime+" seconds"),C(t)}function K(){y(he.container,E.classes.playing,!he.media.paused),y(he.container,E.classes.stopped,he.media.paused)}function Q(e){function t(){y(he.container,E.classes.hover,!0),window.clearTimeout(r),o||(r=window.setTimeout(function(){y(he.container,E.classes.hover,!1)},2e3))}function n(e){o="mouseenter"===e.type}var a=S.supportsFullScreen;e&&e.type===S.fullScreenEventName?he.isFullscreen=S.isFullScreen(he.container):a?(S.isFullScreen(he.container)?S.cancelFullScreen():S.requestFullScreen(he.container),he.isFullscreen=S.isFullScreen(he.container)):(he.isFullscreen=!he.isFullscreen,he.isFullscreen?(v(document,"keyup",Z),document.body.style.overflow="hidden"):(g(document,"keyup",Z),document.body.style.overflow="")),y(he.container,E.classes.fullscreen.active,he.isFullscreen),w(he.buttons.fullscreen,he.isFullscreen);var r,o=!1;E.fullscreen.hideControls&&(y(he.controls,E.classes.hover,!1),b(he.controls,"mouseenter mouseleave",n,he.isFullscreen),b(he.container,"mousemove",t,he.isFullscreen))}function Z(e){27===(e.which||e.charCode||e.keyCode)&&he.isFullscreen&&Q()}function ee(e){"boolean"!=typeof e&&(e=!he.media.muted),w(he.buttons.mute,e),he.media.muted=e,"youtube"===he.type&&(he.embed[he.media.muted?"mute":"unMute"](),h(he.media,"volumechange"))}function te(e){"undefined"==typeof e&&(e=E.storage.enabled&&F().supported?window.localStorage[E.storage.key]||E.volume:E.volume),e>10&&(e=10),0>e&&(e=0),he.media.volume=parseFloat(e/10),E.volume=e,"youtube"===he.type&&he.embed.setVolume(100*he.media.volume),"vimeo"===he.type&&he.embed.api("setVolume",he.media.volume),"embed"in he&&h(he.media,"volumechange"),he.media.muted&&e>0&&ee()}function ne(){var e=he.media.muted?0:10*he.media.volume;he.supported.full&&he.volume&&(he.volume.value=e),E.storage.enabled&&F().supported&&window.localStorage.setItem(E.storage.key,e),y(he.container,E.classes.muted,0===e),he.supported.full&&he.buttons.mute&&w(he.buttons.mute,0===e)}function ae(e){he.supported.full&&he.buttons.captions&&("boolean"!=typeof e&&(e=-1===he.container.className.indexOf(E.classes.captions.active)),w(he.buttons.captions,e),y(he.container,E.classes.captions.active,e))}function re(e){var t="waiting"===e.type;clearTimeout(he.loadingTimer),he.loadingTimer=setTimeout(function(){y(he.container,E.classes.loading,t)},t?250:0)}function oe(e){var t=he.progress.played.bar,n=he.progress.played.text,a=0;if(e)switch(e.type){case"timeupdate":case"seeking":a=k(he.media.currentTime,he.media.duration),"timeupdate"==e.type&&he.buttons.seek&&(he.buttons.seek.value=a);break;case"change":case"input":a=e.target.value;break;case"playing":case"progress":t=he.progress.buffer.bar,n=he.progress.buffer.text,a=function(){var e=he.media.buffered;return e&&e.length?k(e.end(0),he.media.duration):"number"==typeof e?100*e:0}()}t&&(t.value=a),n&&(n.innerHTML=a)}function se(e,t){if(t){isNaN(e)&&(e=0),he.secs=parseInt(e%60),he.mins=parseInt(e/60%60),he.hours=parseInt(e/60/60%60);var n=parseInt(he.media.duration/60/60%60)>0;he.secs=("0"+he.secs).slice(-2),he.mins=("0"+he.mins).slice(-2),t.innerHTML=(n?he.hours+":":"")+he.mins+":"+he.secs}}function ie(){var e=he.media.duration||0;!he.duration&&E.displayDuration&&he.media.paused&&se(e,he.currentTime),he.duration&&se(e,he.duration)}function le(e){se(he.media.currentTime,he.currentTime),oe(e)}function ue(e){m("source",he.media,e)}function ce(e){for(var t=e.length-1;t>=0;t--)m("track",he.media,e[t])}function pe(e){if("string"==typeof e)ue({src:e});else if(e.constructor===Array)for(var t=e.length-1;t>=0;t--)ue(e[t])}function de(e){if("undefined"!=typeof e){switch(U(),"youtube"===he.type?(he.embed.destroy(),window.clearInterval(he.timer.buffering),window.clearInterval(he.timer.playing)):"video"===he.type&&c(he.videoContainer),c(he.media),"type"in e&&e.type!==he.type&&(he.type=e.type),he.type){case"video":he.media=document.createElement("video");break;case"audio":he.media=document.createElement("audio");break;case"youtube":case"vimeo":he.media=document.createElement("div"),he.embedId=e.sources}p(he.container,he.media),s(E.types.html5,he.type)&&(E.crossorigin&&he.media.setAttribute("crossorigin",""),E.autoplay&&he.media.setAttribute("autoplay",""),"poster"in e&&he.media.setAttribute("poster",e.poster),E.loop&&he.media.setAttribute("loop","")),he.container.className=f(E.selectors.container),E.autoplay=e.autoplay||E.autoplay,s(E.types.embed,he.type)&&(he.embedId=e.sources),s(E.types.html5,he.type)&&pe(e.sources),j(),ge(),s(E.types.html5,he.type)&&(te(),ne(),he.supported.full&&(le(),K()),"tracks"in e&&(ce(e.tracks),W()),he.media.load(),E.autoplay&&$()),"title"in e&&(E.title=e.title,H())}}function me(e){"video"===he.type&&he.media.setAttribute("poster",e)}function fe(){function e(){var e=document.activeElement;e&&e!=document.body?document.querySelector&&(e=document.querySelector(":focus")):e=null;for(var t in he.buttons){var n=he.buttons[t];y(n,"tab-focus",n===e)}}var t="IE"==he.browser.name?"change":"input";v(window,"keyup",function(t){var n=t.keyCode?t.keyCode:t.which;9==n&&e()});for(var n in he.buttons){var a=he.buttons[n];v(a,"blur",function(){y(a,"tab-focus",!1)})}v(he.buttons.play,"click",function(){$(),setTimeout(function(){he.buttons.pause.focus()},100)}),v(he.buttons.pause,"click",function(){U(),setTimeout(function(){he.buttons.play.focus()},100)}),v(he.buttons.restart,"click",G),v(he.buttons.rewind,"click",Y),v(he.buttons.forward,"click",J),v(he.buttons.seek,t,G),v(he.volume,t,function(){te(this.value)}),v(he.buttons.mute,"click",ee),v(he.buttons.fullscreen,"click",Q),S.supportsFullScreen&&v(document,S.fullScreenEventName,Q),v(he.media,"timeupdate seeking",le),v(he.media,"timeupdate",C),v(he.media,"loadedmetadata",ie),v(he.buttons.captions,"click",ae),v(he.media,"ended",function(){"video"===he.type&&(he.captionsContainer.innerHTML=""),K()}),v(he.media,"progress playing",oe),v(he.media,"volumechange",ne),v(he.media,"play pause",K),v(he.media,"waiting canplay seeked",re),"video"===he.type&&E.click&&v(he.videoContainer,"click",function(){he.media.paused?h(he.buttons.play,"click"):he.media.ended?(G(),h(he.buttons.play,"click")):h(he.buttons.pause,"click")})}function ye(){if(!he.init)return null;if(he.container.setAttribute("class",f(E.selectors.container)),he.init=!1,c(L(E.selectors.controls)),"youtube"===he.type)return void he.embed.destroy();"video"===he.type&&(c(L(E.selectors.captions)),u(he.videoContainer)),he.media.setAttribute("controls","");var e=he.media.cloneNode(!0);he.media.parentNode.replaceChild(e,he.media)}function be(){if(he.init)return null;S=x(),he.browser=a(),he.media=he.container.querySelectorAll("audio, video, div")[0];var t=he.media.tagName.toLowerCase();if("div"===t?(he.type=he.media.getAttribute("data-type"),he.embedId=he.media.getAttribute("data-video-id"),he.media.removeAttribute("data-type"),he.media.removeAttribute("data-video-id")):(he.type=t,E.crossorigin=null!==he.media.getAttribute("crossorigin"),E.autoplay=E.autoplay||null!==he.media.getAttribute("autoplay"),E.loop=E.loop||null!==he.media.getAttribute("loop")),he.supported=e.supported(he.type),!he.supported.basic)return!1;if(n(he.browser.name+" "+he.browser.version),j(),"video"==he.type||"audio"==he.type){if(!he.supported.full)return void(he.init=!0);ve(),E.displayDuration&&ie(),H()}he.init=!0}function ve(){return V(),q()?(W(),ge(),te(),void ne()):!1}function ge(){z(),fe()}var he=this;return he.container=T,be(),he.init?{media:he.media,play:$,pause:U,restart:G,rewind:Y,forward:J,seek:G,source:de,poster:me,setVolume:te,togglePlay:X,toggleMute:ee,toggleCaptions:ae,toggleFullscreen:Q,isFullscreen:function(){return he.isFullscreen||!1},support:function(e){return r(he,e)},destroy:ye,restore:be}:{}}var S,E,A={enabled:!0,debug:!1,autoplay:!1,loop:!1,seekTime:10,volume:5,click:!0,tooltips:!1,displayDuration:!0,iconPrefix:"icon",selectors:{container:".player",controls:".player-controls",labels:"[data-player] .sr-only, label .sr-only",buttons:{seek:'[data-player="seek"]',play:'[data-player="play"]',pause:'[data-player="pause"]',restart:'[data-player="restart"]',rewind:'[data-player="rewind"]',forward:'[data-player="fast-forward"]',mute:'[data-player="mute"]',volume:'[data-player="volume"]',captions:'[data-player="captions"]',fullscreen:'[data-player="fullscreen"]'},progress:{container:".player-progress",buffer:".player-progress-buffer",played:".player-progress-played"},captions:".player-captions",currentTime:".player-current-time",duration:".player-duration"},classes:{videoWrapper:"player-video-wrapper",embedWrapper:"player-video-embed",type:"player-{0}",stopped:"stopped",playing:"playing",muted:"muted",loading:"loading",tooltip:"player-tooltip",hidden:"sr-only",hover:"player-hover",captions:{enabled:"captions-enabled",active:"captions-active"},fullscreen:{enabled:"fullscreen-enabled",active:"fullscreen-active",hideControls:"fullscreen-hide-controls"}},captions:{defaultActive:!1},fullscreen:{enabled:!0,fallback:!0,hideControls:!0},storage:{enabled:!0,key:"plyr_volume"},controls:["restart","rewind","play","fast-forward","current-time","duration","mute","volume","captions","fullscreen"],i18n:{restart:"Restart",rewind:"Rewind {seektime} secs",play:"Play",pause:"Pause",forward:"Forward {seektime} secs",played:"played",buffered:"buffered",currentTime:"Current time",duration:"Duration",volume:"Volume",toggleMute:"Toggle Mute",toggleCaptions:"Toggle Captions",toggleFullscreen:"Toggle Fullscreen"},types:{embed:["youtube","vimeo"],html5:["video","audio"]}};e.supported=function(e){var t,n,r=a(),o="IE"===r.name&&r.version<=9,s=/iPhone|iPod/i.test(navigator.userAgent),i=!!document.createElement("audio").canPlayType,l=!!document.createElement("video").canPlayType;switch(e){case"video":t=l,n=t&&!o&&!s;break;case"audio":t=i,n=t&&!o;break;case"vimeo":case"youtube":t=!0,n=!o&&!s;break;default:t=i&&l,n=t&&!o}return{basic:t,full:n}},e.setup=function(t){if(E=T(A,t),!E.enabled||!e.supported().basic)return!1;for(var n=document.querySelectorAll(E.selectors.container),a=[],r=n.length-1;r>=0;r--){var o=n[r];if("undefined"==typeof o.plyr){var s=new C(o);o.plyr=Object.keys(s).length?s:!1,"function"==typeof E.onSetup&&E.onSetup.apply(o.plyr)}a.push(o.plyr)}return a}}(this.plyr=this.plyr||{}); \ No newline at end of file
+!function(e){"use strict";function t(){var e=['<div class="plyr-controls">','<div class="plyr-progress">','<label for="seek{id}" class="sr-only">Seek</label>','<input id="seek{id}" class="plyr-progress-seek" type="range" min="0" max="100" step="0.5" value="0" data-plyr="seek">','<progress class="plyr-progress-played" max="100" value="0">',"<span>0</span>% "+E.i18n.played,"</progress>",'<progress class="plyr-progress-buffer" max="100" value="0">',"<span>0</span>% "+E.i18n.buffered,"</progress>","</div>",'<span class="plyr-controls-left">'];return s(E.controls,"restart")&&e.push('<button type="button" data-plyr="restart">','<svg><use xlink:href="#'+E.iconPrefix+'-restart" /></svg>','<span class="sr-only">'+E.i18n.restart+"</span>","</button>"),s(E.controls,"rewind")&&e.push('<button type="button" data-plyr="rewind">','<svg><use xlink:href="#'+E.iconPrefix+'-rewind" /></svg>','<span class="sr-only">'+E.i18n.rewind+"</span>","</button>"),s(E.controls,"play")&&e.push('<button type="button" data-plyr="play">','<svg><use xlink:href="#'+E.iconPrefix+'-play" /></svg>','<span class="sr-only">'+E.i18n.play+"</span>","</button>",'<button type="button" data-plyr="pause">','<svg><use xlink:href="#'+E.iconPrefix+'-pause" /></svg>','<span class="sr-only">'+E.i18n.pause+"</span>","</button>"),s(E.controls,"fast-forward")&&e.push('<button type="button" data-plyr="fast-forward">','<svg><use xlink:href="#'+E.iconPrefix+'-fast-forward" /></svg>','<span class="sr-only">'+E.i18n.forward+"</span>","</button>"),s(E.controls,"current-time")&&e.push('<span class="plyr-time">','<span class="sr-only">'+E.i18n.currentTime+"</span>",'<span class="plyr-current-time">00:00</span>',"</span>"),s(E.controls,"duration")&&e.push('<span class="plyr-time">','<span class="sr-only">'+E.i18n.duration+"</span>",'<span class="plyr-duration">00:00</span>',"</span>"),e.push("</span>",'<span class="plyr-controls-right">'),s(E.controls,"mute")&&e.push('<button type="button" data-plyr="mute">','<svg class="icon-muted"><use xlink:href="#'+E.iconPrefix+'-muted" /></svg>','<svg><use xlink:href="#'+E.iconPrefix+'-volume" /></svg>','<span class="sr-only">'+E.i18n.toggleMute+"</span>","</button>"),s(E.controls,"volume")&&e.push('<label for="volume{id}" class="sr-only">'+E.i18n.volume+"</label>",'<input id="volume{id}" class="plyr-volume" type="range" min="0" max="10" value="5" data-plyr="volume">'),s(E.controls,"captions")&&e.push('<button type="button" data-plyr="captions">','<svg class="icon-captions-on"><use xlink:href="#'+E.iconPrefix+'-captions-on" /></svg>','<svg><use xlink:href="#'+E.iconPrefix+'-captions-off" /></svg>','<span class="sr-only">'+E.i18n.toggleCaptions+"</span>","</button>"),s(E.controls,"fullscreen")&&e.push('<button type="button" data-plyr="fullscreen">','<svg class="icon-exit-fullscreen"><use xlink:href="#'+E.iconPrefix+'-exit-fullscreen" /></svg>','<svg><use xlink:href="#'+E.iconPrefix+'-enter-fullscreen" /></svg>','<span class="sr-only">'+E.i18n.toggleFullscreen+"</span>","</button>"),e.push("</span>","</div>"),e.join("")}function n(e,t){E.debug&&window.console&&console[t?"error":"log"](e)}function r(){var e,t,n,r=navigator.userAgent,a=navigator.appName,o=""+parseFloat(navigator.appVersion),s=parseInt(navigator.appVersion,10);return-1!==navigator.appVersion.indexOf("Windows NT")&&-1!==navigator.appVersion.indexOf("rv:11")?(a="IE",o="11;"):-1!==(t=r.indexOf("MSIE"))?(a="IE",o=r.substring(t+5)):-1!==(t=r.indexOf("Chrome"))?(a="Chrome",o=r.substring(t+7)):-1!==(t=r.indexOf("Safari"))?(a="Safari",o=r.substring(t+7),-1!==(t=r.indexOf("Version"))&&(o=r.substring(t+8))):-1!==(t=r.indexOf("Firefox"))?(a="Firefox",o=r.substring(t+8)):(e=r.lastIndexOf(" ")+1)<(t=r.lastIndexOf("/"))&&(a=r.substring(e,t),o=r.substring(t+1),a.toLowerCase()==a.toUpperCase()&&(a=navigator.appName)),-1!==(n=o.indexOf(";"))&&(o=o.substring(0,n)),-1!==(n=o.indexOf(" "))&&(o=o.substring(0,n)),s=parseInt(""+o,10),isNaN(s)&&(o=""+parseFloat(navigator.appVersion),s=parseInt(navigator.appVersion,10)),{name:a,version:s,ios:/(iPad|iPhone|iPod)/g.test(navigator.platform)}}function a(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 o(e){if(!document.querySelectorAll('script[src="'+e+'"]').length){var t=document.createElement("script");t.src=e;var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n)}}function s(e,t){return Array.prototype.indexOf&&-1!=e.indexOf(t)}function i(e,t,n){return e.replace(new RegExp(t.replace(/([.*+?\^=!:${}()|\[\]\/\\])/g,"\\$1"),"g"),n)}function l(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],o=a.parentNode,s=a.nextSibling;r.appendChild(a),s?o.insertBefore(r,s):o.appendChild(r)}}function u(e){for(var t=e.parentNode;e.firstChild;)t.insertBefore(e.firstChild,e);t.removeChild(e)}function c(e){e.parentNode.removeChild(e)}function p(e,t){e.insertBefore(t,e.firstChild)}function d(e,t){for(var n in t)e.setAttribute(n,"boolean"==typeof t[n]&&t[n]?"":t[n])}function m(e,t,n){var r=document.createElement(e);d(r,n),p(t,r)}function f(e){return e.replace(".","")}function y(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 b(e,t,n,r){var a=t.split(" ");if(e instanceof NodeList)for(var o=0;o<e.length;o++)e[o]instanceof Node&&b(e[o],arguments[1],arguments[2],arguments[3]);else for(var s=0;s<a.length;s++)e[r?"addEventListener":"removeEventListener"](a[s],n,!1)}function v(e,t,n){e&&b(e,t,n,!0)}function g(e,t,n){e&&b(e,t,n,!1)}function h(e,t){var n=document.createEvent("MouseEvents");n.initEvent(t,!0,!0),e.dispatchEvent(n)}function w(e,t){return t="boolean"==typeof t?t:!e.getAttribute("aria-pressed"),e.setAttribute("aria-pressed",t),t}function k(e,t){return 0===e||0===t||isNaN(e)||isNaN(t)?0:(e/t*100).toFixed(2)}function T(e,t){for(var n in t)t[n]&&t[n].constructor&&t[n].constructor===Object?(e[n]=e[n]||{},T(e[n],t[n])):e[n]=t[n];return e}function x(){var e={supportsFullScreen:!1,isFullScreen:function(){return!1},requestFullScreen:function(){},cancelFullScreen:function(){},fullScreenEventName:"",element:null,prefix:""},t="webkit moz o ms khtml".split(" ");if("undefined"!=typeof document.cancelFullScreen)e.supportsFullScreen=!0;else for(var n=0,r=t.length;r>n;n++){if(e.prefix=t[n],"undefined"!=typeof document[e.prefix+"CancelFullScreen"]){e.supportsFullScreen=!0;break}if("undefined"!=typeof document.msExitFullscreen&&document.msFullscreenEnabled){e.prefix="ms",e.supportsFullScreen=!0;break}}return e.supportsFullScreen&&(e.fullScreenEventName="ms"==e.prefix?"MSFullscreenChange":e.prefix+"fullscreenchange",e.isFullScreen=function(e){switch("undefined"==typeof e&&(e=document.body),this.prefix){case"":return document.fullscreenElement==e;case"moz":return document.mozFullScreenElement==e;default:return document[this.prefix+"FullscreenElement"]==e}},e.requestFullScreen=function(e){return"undefined"==typeof e&&(e=document.body),""===this.prefix?e.requestFullScreen():e[this.prefix+("ms"==this.prefix?"RequestFullscreen":"RequestFullScreen")]()},e.cancelFullScreen=function(){return""===this.prefix?document.cancelFullScreen():document[this.prefix+("ms"==this.prefix?"ExitFullscreen":"CancelFullScreen")]()},e.element=function(){return""===this.prefix?document.fullscreenElement:document[this.prefix+"FullscreenElement"]}),e}function F(){var e={supported:function(){try{return"localStorage"in window&&null!==window.localStorage}catch(e){return!1}}()};return e}function C(T){function C(e){if(!ve.usingTextTracks&&"video"===ve.type&&ve.supported.full&&(ve.subcount=0,e="number"==typeof e?e:ve.media.currentTime,ve.captions[ve.subcount])){for(;P(ve.captions[ve.subcount][0])<e.toFixed(1);)if(ve.subcount++,ve.subcount>ve.captions.length-1){ve.subcount=ve.captions.length-1;break}if(ve.media.currentTime.toFixed(1)>=N(ve.captions[ve.subcount][0])&&ve.media.currentTime.toFixed(1)<=P(ve.captions[ve.subcount][0])){ve.currentCaption=ve.captions[ve.subcount][1];var t=ve.currentCaption.trim();ve.captionsContainer.innerHTML!=t&&(ve.captionsContainer.innerHTML="",ve.captionsContainer.innerHTML=t)}else ve.captionsContainer.innerHTML=""}}function A(){ve.buttons.captions&&(y(ve.container,E.classes.captions.enabled,!0),E.captions.defaultActive&&(y(ve.container,E.classes.captions.active,!0),w(ve.buttons.captions,!0)))}function N(e){var t=[];return t=e.split(" --> "),I(t[0])}function P(e){var t=[];return t=e.split(" --> "),I(t[1])}function I(e){if(null===e||void 0===e)return 0;var t,n=[],r=[];return n=e.split(","),r=n[0].split(":"),t=Math.floor(60*r[0]*60)+Math.floor(60*r[1])+Math.floor(r[2])}function M(e){return ve.container.querySelectorAll(e)}function L(e){return M(e)[0]}function O(){try{return window.self!==window.top}catch(e){return!0}}function q(){var e=E.html;if(n("Injecting custom controls."),e||(e=t()),e=i(e,"{seektime}",E.seekTime),e=i(e,"{id}",Math.floor(1e4*Math.random())),ve.container.insertAdjacentHTML("beforeend",e),E.tooltips)for(var r=M(E.selectors.labels),a=r.length-1;a>=0;a--){var o=r[a];y(o,E.classes.hidden,!1),y(o,E.classes.tooltip,!0)}}function V(){try{return ve.controls=L(E.selectors.controls),ve.buttons={},ve.buttons.seek=L(E.selectors.buttons.seek),ve.buttons.play=L(E.selectors.buttons.play),ve.buttons.pause=L(E.selectors.buttons.pause),ve.buttons.restart=L(E.selectors.buttons.restart),ve.buttons.rewind=L(E.selectors.buttons.rewind),ve.buttons.forward=L(E.selectors.buttons.forward),ve.buttons.fullscreen=L(E.selectors.buttons.fullscreen),ve.buttons.mute=L(E.selectors.buttons.mute),ve.buttons.captions=L(E.selectors.buttons.captions),ve.checkboxes=M('[type="checkbox"]'),ve.progress={},ve.progress.container=L(E.selectors.progress.container),ve.progress.buffer={},ve.progress.buffer.bar=L(E.selectors.progress.buffer),ve.progress.buffer.text=ve.progress.buffer.bar&&ve.progress.buffer.bar.getElementsByTagName("span")[0],ve.progress.played={},ve.progress.played.bar=L(E.selectors.progress.played),ve.progress.played.text=ve.progress.played.bar&&ve.progress.played.bar.getElementsByTagName("span")[0],ve.volume=L(E.selectors.buttons.volume),ve.duration=L(E.selectors.duration),ve.currentTime=L(E.selectors.currentTime),ve.seekTime=M(E.selectors.seekTime),!0}catch(e){return n("It looks like there's a problem with your controls html. Bailing.",!0),ve.media.setAttribute("controls",""),!1}}function H(){if(ve.buttons.play){var e=ve.buttons.play.innerText||E.i18n.play;"undefined"!=typeof E.title&&E.title.length&&(e+=", "+E.title),ve.buttons.play.setAttribute("aria-label",e)}}function j(){if(!ve.media)return n("No audio or video element found!",!0),!1;if(ve.supported.full&&(ve.media.removeAttribute("controls"),y(ve.container,E.classes.type.replace("{0}",ve.type),!0),y(ve.container,E.classes.stopped,E.autoplay),ve.browser.ios&&y(ve.container,"ios",!0),"video"===ve.type)){var e=document.createElement("div");e.setAttribute("class",E.classes.videoWrapper),l(ve.media,e),ve.videoContainer=e}s(E.types.embed,ve.type)?(D(ve.embedId,ve.type),ve.embedId=null):E.autoplay&&$()}function D(e){for(var t=document.createElement("div"),n=ve.type+"-"+Math.floor(1e4*Math.random()),r=M('[id^="'+ve.type+'-"]'),a=r.length-1;a>=0;a--)c(r[a]);if(t.setAttribute("id",n),y(ve.media,E.classes.videoWrapper,!0),y(ve.media,E.classes.embedWrapper,!0),"youtube"===ve.type)ve.media.appendChild(t),"object"==typeof YT?R(e,t):(o(E.urls.youtube.api),window.onYouTubeIframeAPIReady=function(){R(e,t)});else if("vimeo"===ve.type){var s=document.createElement("iframe");if(s.loaded=!1,v(s,"load",function(){s.loaded=!0}),d(s,{src:"https://player.vimeo.com/video/"+e+"?player_id="+n+"&api=1&badge=0&byline=0&portrait=0&title=0",id:n,webkitallowfullscreen:"",mozallowfullscreen:"",allowfullscreen:"",frameborder:0}),t.appendChild(s),ve.media.appendChild(t),"function"==typeof Froogaloop)v(s,"load",_);else{o(E.urls.vimeo.api);var i=window.setInterval(function(){"$f"in window&&s.loaded&&(window.clearInterval(i),_.call(s))},50)}}}function B(){ve.supported.full&&(ve.container.querySelectorAll(E.selectors.controls).length||ye()),te(),ne()}function R(e,t){"timer"in ve||(ve.timer={}),ve.embed=new YT.Player(t.id,{videoId:e,playerVars:{autoplay:E.autoplay?1:0,controls:ve.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},events:{onReady:function(e){var t=e.target;ve.media.play=function(){t.playVideo()},ve.media.pause=function(){t.pauseVideo()},ve.media.stop=function(){t.stopVideo()},ve.media.duration=t.getDuration(),ve.media.paused=!E.autoplay,ve.media.currentTime=t.getCurrentTime(),ve.media.muted=t.isMuted(),h(ve.media,"timeupdate"),window.clearInterval(ve.timer.buffering),ve.timer.buffering=window.setInterval(function(){ve.media.buffered=t.getVideoLoadedFraction(),h(ve.media,"progress"),1===ve.media.buffered&&window.clearInterval(ve.timer.buffering)},200),B(),E.displayDuration&&ie()},onStateChange:function(e){var t=e.target;switch(window.clearInterval(ve.timer.playing),e.data){case 0:ve.media.paused=!0,h(ve.media,"ended");break;case 1:ve.media.paused=!1,h(ve.media,"play"),ve.timer.playing=window.setInterval(function(){ve.media.currentTime=t.getCurrentTime(),h(ve.media,"timeupdate")},200);break;case 2:ve.media.paused=!0,h(ve.media,"pause")}}}})}function _(){ve.embed=$f(this),ve.embed.addEvent("ready",function(){ve.media.play=function(){ve.embed.api("play")},ve.media.pause=function(){ve.embed.api("pause")},ve.media.stop=function(){ve.embed.api("stop")},ve.media.paused=!E.autoplay,ve.media.currentTime=0,B(),ve.embed.api("getCurrentTime",function(e){ve.media.currentTime=e,h(ve.media,"timeupdate")}),ve.embed.api("getDuration",function(e){ve.media.duration=e,ve.supported.full&&E.displayDuration&&ie()}),ve.embed.addEvent("play",function(){ve.media.paused=!1,h(ve.media,"play")}),ve.embed.addEvent("pause",function(){ve.media.paused=!0,h(ve.media,"pause")}),ve.embed.addEvent("playProgress",function(e){ve.media.currentTime=e.seconds,h(ve.media,"timeupdate")}),ve.embed.addEvent("loadProgress",function(e){ve.media.buffered=e.percent,h(ve.media,"progress")}),ve.embed.addEvent("finish",function(){ve.media.paused=!0,h(ve.media,"ended")})})}function W(){if("video"===ve.type){L(E.selectors.captions)||ve.videoContainer.insertAdjacentHTML("afterbegin",'<div class="'+f(E.selectors.captions)+'"><span></span></div>'),ve.captionsContainer=L(E.selectors.captions).querySelector("span"),ve.usingTextTracks=!1,ve.media.textTracks&&(ve.usingTextTracks=!0);for(var e,t="",r=ve.media.childNodes,a=0;a<r.length;a++)"track"===r[a].nodeName.toLowerCase()&&(e=r[a].kind,("captions"===e||"subtitles"===e)&&(t=r[a].getAttribute("src")));if(ve.captionExists=!0,""===t?(ve.captionExists=!1,n("No caption track found.")):n("Caption track found; URI: "+t),ve.captionExists){for(var o=ve.media.textTracks,s=0;s<o.length;s++)o[s].mode="hidden";if(A(ve),("IE"===ve.browser.name&&ve.browser.version>=10||"Firefox"===ve.browser.name&&ve.browser.version>=31||"Chrome"===ve.browser.name&&ve.browser.version>=43||"Safari"===ve.browser.name&&ve.browser.version>=7)&&(n("Detected unsupported browser for HTML5 captions. Using fallback."),ve.usingTextTracks=!1),ve.usingTextTracks){n("TextTracks supported.");for(var i=0;i<o.length;i++){var l=o[i];("captions"===l.kind||"subtitles"===l.kind)&&v(l,"cuechange",function(){ve.captionsContainer.innerHTML="",this.activeCues[0]&&this.activeCues[0].hasOwnProperty("text")&&ve.captionsContainer.appendChild(this.activeCues[0].getCueAsHTML().trim())})}}else if(n("TextTracks not supported so rendering captions manually."),ve.currentCaption="",ve.captions=[],""!==t){var u=new XMLHttpRequest;u.onreadystatechange=function(){if(4===u.readyState)if(200===u.status){var e,t=[],r=u.responseText;t=r.split("\n\n");for(var a=0;a<t.length;a++)e=t[a],ve.captions[a]=[],ve.captions[a]=e.split("\n");ve.captions.shift(),n("Successfully loaded the caption file via AJAX.")}else n("There was a problem loading the caption file via AJAX.",!0)},u.open("get",t,!0),u.send()}if("Safari"===ve.browser.name&&ve.browser.version>=7){n("Safari 7+ detected; removing track from DOM."),o=ve.media.getElementsByTagName("track");for(var c=0;c<o.length;c++)ve.media.removeChild(o[c])}}else y(ve.container,E.classes.captions.enabled)}}function z(){if("audio"!=ve.type&&E.fullscreen.enabled){var e=S.supportsFullScreen;e||E.fullscreen.fallback&&!O()?(n((e?"Native":"Fallback")+" fullscreen enabled."),y(ve.container,E.classes.fullscreen.enabled,!0)):n("Fullscreen not supported and fallback disabled."),w(ve.buttons.fullscreen,!1),E.fullscreen.hideControls&&y(ve.container,E.classes.fullscreen.hideControls,!0)}}function $(){ve.media.play()}function U(){ve.media.pause()}function X(e){e===!0?$():e===!1?U():ve.media[ve.media.paused?"play":"pause"]()}function Y(e){"number"!=typeof e&&(e=E.seekTime),G(ve.media.currentTime-e)}function J(e){"number"!=typeof e&&(e=E.seekTime),G(ve.media.currentTime+e)}function G(e){var t=0,r=ve.media.paused;"number"==typeof e?t=e:"object"!=typeof e||"input"!==e.type&&"change"!==e.type||(t=e.target.value/e.target.max*ve.media.duration),0>t?t=0:t>ve.media.duration&&(t=ve.media.duration);try{ve.media.currentTime=t.toFixed(1)}catch(a){}"embed"in ve&&("youtube"===ve.type&&ve.embed.seekTo(t),"vimeo"===ve.type&&ve.embed.api("seekTo",t),h(ve.media,"timeupdate"),r&&U()),n("Seeking to "+ve.media.currentTime+" seconds"),C(t)}function K(){y(ve.container,E.classes.playing,!ve.media.paused),y(ve.container,E.classes.stopped,ve.media.paused)}function Q(e){function t(){y(ve.container,E.classes.hover,!0),window.clearTimeout(a),o||(a=window.setTimeout(function(){y(ve.container,E.classes.hover,!1)},2e3))}function n(e){o="mouseenter"===e.type}var r=S.supportsFullScreen;e&&e.type===S.fullScreenEventName?ve.isFullscreen=S.isFullScreen(ve.container):r?(S.isFullScreen(ve.container)?S.cancelFullScreen():S.requestFullScreen(ve.container),ve.isFullscreen=S.isFullScreen(ve.container)):(ve.isFullscreen=!ve.isFullscreen,ve.isFullscreen?(v(document,"keyup",Z),document.body.style.overflow="hidden"):(g(document,"keyup",Z),document.body.style.overflow="")),y(ve.container,E.classes.fullscreen.active,ve.isFullscreen),w(ve.buttons.fullscreen,ve.isFullscreen);var a,o=!1;E.fullscreen.hideControls&&(y(ve.controls,E.classes.hover,!1),b(ve.controls,"mouseenter mouseleave",n,ve.isFullscreen),b(ve.container,"mousemove",t,ve.isFullscreen))}function Z(e){27===(e.which||e.charCode||e.keyCode)&&ve.isFullscreen&&Q()}function ee(e){"boolean"!=typeof e&&(e=!ve.media.muted),w(ve.buttons.mute,e),ve.media.muted=e,"youtube"===ve.type&&(ve.embed[ve.media.muted?"mute":"unMute"](),h(ve.media,"volumechange"))}function te(e){"undefined"==typeof e&&(e=E.storage.enabled&&F().supported?window.localStorage[E.storage.key]||E.volume:E.volume),e>10&&(e=10),0>e&&(e=0),ve.media.volume=parseFloat(e/10),E.volume=e,"youtube"===ve.type&&ve.embed.setVolume(100*ve.media.volume),"vimeo"===ve.type&&ve.embed.api("setVolume",ve.media.volume),"embed"in ve&&h(ve.media,"volumechange"),ve.media.muted&&e>0&&ee()}function ne(){var e=ve.media.muted?0:10*ve.media.volume;ve.supported.full&&ve.volume&&(ve.volume.value=e),E.storage.enabled&&F().supported&&window.localStorage.setItem(E.storage.key,e),y(ve.container,E.classes.muted,0===e),ve.supported.full&&ve.buttons.mute&&w(ve.buttons.mute,0===e)}function re(e){ve.supported.full&&ve.buttons.captions&&("boolean"!=typeof e&&(e=-1===ve.container.className.indexOf(E.classes.captions.active)),w(ve.buttons.captions,e),y(ve.container,E.classes.captions.active,e))}function ae(e){var t="waiting"===e.type;clearTimeout(ve.loadingTimer),ve.loadingTimer=setTimeout(function(){y(ve.container,E.classes.loading,t)},t?250:0)}function oe(e){var t=ve.progress.played.bar,n=ve.progress.played.text,r=0;if(e)switch(e.type){case"timeupdate":case"seeking":r=k(ve.media.currentTime,ve.media.duration),"timeupdate"==e.type&&ve.buttons.seek&&(ve.buttons.seek.value=r);break;case"change":case"input":r=e.target.value;break;case"playing":case"progress":t=ve.progress.buffer.bar,n=ve.progress.buffer.text,r=function(){var e=ve.media.buffered;return e&&e.length?k(e.end(0),ve.media.duration):"number"==typeof e?100*e:0}()}t&&(t.value=r),n&&(n.innerHTML=r)}function se(e,t){if(t){isNaN(e)&&(e=0),ve.secs=parseInt(e%60),ve.mins=parseInt(e/60%60),ve.hours=parseInt(e/60/60%60);var n=parseInt(ve.media.duration/60/60%60)>0;ve.secs=("0"+ve.secs).slice(-2),ve.mins=("0"+ve.mins).slice(-2),t.innerHTML=(n?ve.hours+":":"")+ve.mins+":"+ve.secs}}function ie(){var e=ve.media.duration||0;!ve.duration&&E.displayDuration&&ve.media.paused&&se(e,ve.currentTime),ve.duration&&se(e,ve.duration)}function le(e){se(ve.media.currentTime,ve.currentTime),oe(e)}function ue(e,t){if("string"==typeof t)m(e,ve.media,{src:t});else if(t.constructor===Array)for(var n=t.length-1;n>=0;n--)m(e,ve.media,t[n])}function ce(e){if("undefined"!=typeof e){switch(U(),"youtube"===ve.type?(ve.embed.destroy(),window.clearInterval(ve.timer.buffering),window.clearInterval(ve.timer.playing)):"video"===ve.type&&c(ve.videoContainer),c(ve.media),"type"in e&&e.type!==ve.type&&(ve.type=e.type),ve.type){case"video":ve.media=document.createElement("video");break;case"audio":ve.media=document.createElement("audio");break;case"youtube":case"vimeo":ve.media=document.createElement("div"),ve.embedId=e.sources}p(ve.container,ve.media),s(E.types.html5,ve.type)&&(E.crossorigin&&ve.media.setAttribute("crossorigin",""),E.autoplay&&ve.media.setAttribute("autoplay",""),"poster"in e&&ve.media.setAttribute("poster",e.poster),E.loop&&ve.media.setAttribute("loop","")),ve.container.className=ve.originalClassName,E.autoplay=e.autoplay||E.autoplay,s(E.types.embed,ve.type)&&(ve.embedId=e.sources),s(E.types.html5,ve.type)&&ue("source",e.sources),j(),be(),s(E.types.html5,ve.type)&&(te(),ne(),ve.supported.full&&(le(),K()),"tracks"in e&&(ue("track",e.tracks),W()),ve.media.load(),E.autoplay&&$()),"title"in e&&(E.title=e.title,H())}}function pe(e){"video"===ve.type&&ve.media.setAttribute("poster",e)}function de(){function e(){var e=document.activeElement;e&&e!=document.body?document.querySelector&&(e=document.querySelector(":focus")):e=null;for(var t in ve.buttons){var n=ve.buttons[t];y(n,"tab-focus",n===e)}}var t="IE"==ve.browser.name?"change":"input";v(window,"keyup",function(t){var n=t.keyCode?t.keyCode:t.which;9==n&&e()});for(var n in ve.buttons){var r=ve.buttons[n];v(r,"blur",function(){y(r,"tab-focus",!1)})}v(ve.buttons.play,"click",function(){$(),setTimeout(function(){ve.buttons.pause.focus()},100)}),v(ve.buttons.pause,"click",function(){U(),setTimeout(function(){ve.buttons.play.focus()},100)}),v(ve.buttons.restart,"click",G),v(ve.buttons.rewind,"click",Y),v(ve.buttons.forward,"click",J),v(ve.buttons.seek,t,G),v(ve.volume,t,function(){te(this.value)}),v(ve.buttons.mute,"click",ee),v(ve.buttons.fullscreen,"click",Q),S.supportsFullScreen&&v(document,S.fullScreenEventName,Q),v(ve.media,"timeupdate seeking",le),v(ve.media,"timeupdate",C),v(ve.media,"loadedmetadata",ie),v(ve.buttons.captions,"click",re),v(ve.media,"ended",function(){"video"===ve.type&&(ve.captionsContainer.innerHTML=""),K()}),v(ve.media,"progress playing",oe),v(ve.media,"volumechange",ne),v(ve.media,"play pause",K),v(ve.media,"waiting canplay seeked",ae),"video"===ve.type&&E.click&&v(ve.videoContainer,"click",function(){ve.media.paused?h(ve.buttons.play,"click"):ve.media.ended?(G(),h(ve.buttons.play,"click")):h(ve.buttons.pause,"click")})}function me(){if(!ve.init)return null;if(ve.container.setAttribute("class",f(E.selectors.container)),ve.init=!1,c(L(E.selectors.controls)),"youtube"===ve.type)return void ve.embed.destroy();"video"===ve.type&&(c(L(E.selectors.captions)),u(ve.videoContainer)),ve.media.setAttribute("controls","");var e=ve.media.cloneNode(!0);ve.media.parentNode.replaceChild(e,ve.media)}function fe(){if(ve.init)return null;S=x(),ve.browser=r(),ve.media=ve.container.querySelectorAll("audio, video, div")[0],ve.originalClassName=ve.container.className;var t=ve.media.tagName.toLowerCase();if("div"===t?(ve.type=ve.media.getAttribute("data-type"),ve.embedId=ve.media.getAttribute("data-video-id"),ve.media.removeAttribute("data-type"),ve.media.removeAttribute("data-video-id")):(ve.type=t,E.crossorigin=null!==ve.media.getAttribute("crossorigin"),E.autoplay=E.autoplay||null!==ve.media.getAttribute("autoplay"),E.loop=E.loop||null!==ve.media.getAttribute("loop")),ve.supported=e.supported(ve.type),!ve.supported.basic)return!1;if(n(ve.browser.name+" "+ve.browser.version),j(),"video"==ve.type||"audio"==ve.type){if(!ve.supported.full)return void(ve.init=!0);ye(),E.displayDuration&&ie(),H()}ve.init=!0}function ye(){return q(),V()?(W(),be(),te(),void ne()):!1}function be(){z(),de()}var ve=this;return ve.container=T,fe(),ve.init?{media:ve.media,play:$,pause:U,restart:G,rewind:Y,forward:J,seek:G,source:ce,poster:pe,setVolume:te,togglePlay:X,toggleMute:ee,toggleCaptions:re,toggleFullscreen:Q,isFullscreen:function(){return ve.isFullscreen||!1},support:function(e){return a(ve,e)},destroy:me,restore:fe}:{}}var S,E,A={enabled:!0,debug:!1,autoplay:!1,loop:!1,seekTime:10,volume:5,click:!0,tooltips:!1,displayDuration:!0,iconPrefix:"icon",selectors:{container:".plyr",controls:".plyr-controls",labels:"[data-plyr] .sr-only, label .sr-only",buttons:{seek:'[data-plyr="seek"]',play:'[data-plyr="play"]',pause:'[data-plyr="pause"]',restart:'[data-plyr="restart"]',rewind:'[data-plyr="rewind"]',forward:'[data-plyr="fast-forward"]',mute:'[data-plyr="mute"]',volume:'[data-plyr="volume"]',captions:'[data-plyr="captions"]',fullscreen:'[data-plyr="fullscreen"]'},progress:{container:".plyr-progress",buffer:".plyr-progress-buffer",played:".plyr-progress-played"},captions:".plyr-captions",currentTime:".plyr-current-time",duration:".plyr-duration"},classes:{videoWrapper:"plyr-video-wrapper",embedWrapper:"plyr-video-embed",type:"plyr-{0}",stopped:"stopped",playing:"playing",muted:"muted",loading:"loading",tooltip:"plyr-tooltip",hidden:"sr-only",hover:"plyr-hover",captions:{enabled:"captions-enabled",active:"captions-active"},fullscreen:{enabled:"fullscreen-enabled",active:"fullscreen-active",hideControls:"fullscreen-hide-controls"}},captions:{defaultActive:!1},fullscreen:{enabled:!0,fallback:!0,hideControls:!0},storage:{enabled:!0,key:"plyr_volume"},controls:["restart","rewind","play","fast-forward","current-time","duration","mute","volume","captions","fullscreen"],i18n:{restart:"Restart",rewind:"Rewind {seektime} secs",play:"Play",pause:"Pause",forward:"Forward {seektime} secs",played:"played",buffered:"buffered",currentTime:"Current time",duration:"Duration",volume:"Volume",toggleMute:"Toggle Mute",toggleCaptions:"Toggle Captions",toggleFullscreen:"Toggle Fullscreen"},types:{embed:["youtube","vimeo"],html5:["video","audio"]},urls:{vimeo:{api:"https://cdn.rawgit.com/vimeo/player-api/master/javascript/froogaloop.js"},youtube:{api:"https://www.youtube.com/iframe_api"}}};e.supported=function(e){var t,n,a=r(),o="IE"===a.name&&a.version<=9,s=/iPhone|iPod/i.test(navigator.userAgent),i=!!document.createElement("audio").canPlayType,l=!!document.createElement("video").canPlayType;switch(e){case"video":t=l,n=t&&!o&&!s;break;case"audio":t=i,n=t&&!o;break;case"vimeo":case"youtube":t=!0,n=!o&&!s;break;default:t=i&&l,n=t&&!o}return{basic:t,full:n}},e.setup=function(t,n){var r=[];if("string"==typeof t?t=document.querySelectorAll(t):t instanceof HTMLElement?t=[t]:t instanceof NodeList||"string"==typeof t||("undefined"==typeof n&&"object"==typeof t&&(n=t),t=document.querySelectorAll(A.selectors.container)),E=T(A,n),!E.enabled||!e.supported().basic)return!1;for(var a=t.length-1;a>=0;a--){var o=t[a];if("undefined"==typeof o.plyr){var s=new C(o);o.plyr=Object.keys(s).length?s:!1,"function"==typeof E.onSetup&&E.onSetup.apply(o.plyr)}r.push(o.plyr)}return r}}(this.plyr=this.plyr||{}); \ No newline at end of file
diff --git a/docs/dist/docs.css b/docs/dist/docs.css
index 28317928..6a75e430 100644
--- a/docs/dist/docs.css
+++ b/docs/dist/docs.css
@@ -1 +1 @@
-/*! normalize.css v2.1.3 | MIT License | git.io/normalize */a.logo,img,legend{border:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,small,summary{display:block}[hidden],template{display:none}body,figure{margin:0}body,h1,h2{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}body,small{padding:0 10px}.btn-bar,sub,sup{position:relative}.btn-bar,.player{max-width:1200px}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}a{background:0 0;text-decoration:none;color:#3498db;border-bottom:1px solid currentColor;transition:background .3s ease,color .3s ease}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}hr{box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}.btn-bar,nav li{white-space:nowrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}sub,sup{font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}.btn-bar::before,.btn-count::before{content:"";top:50%}sub{bottom:-.25em}svg:not(:root){overflow:hidden}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{padding:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@-webkit-keyframes fade-in{0%{opacity:0}100%{opacity:1}}@keyframes fade-in{0%{opacity:0}100%{opacity:1}}@font-face{font-family:Avenir;src:url(//cdn.plyr.io/fonts/avenir-medium.woff2) format("woff2"),url(//cdn.plyr.io/fonts/avenir-medium.woff) format("woff");font-style:normal;font-weight:400}@font-face{font-family:Avenir;src:url(//cdn.plyr.io/fonts/avenir-bold.woff2) format("woff2"),url(//cdn.plyr.io/fonts/avenir-bold.woff) format("woff");font-style:normal;font-weight:600}h1,h2{letter-spacing:-.025em;color:#2E3C44;margin:0 0 10px;line-height:1.2}h1{font-size:64px;font-size:4rem;color:#3498DB}p,small{margin:0 0 20px}small{font-size:14px;font-size:.875rem}a:focus,a:hover{color:#343f4a}a:focus{outline:#343f4a dotted thin;outline-offset:1px}*,::after,::before{box-sizing:border-box}.btn-bar ul,nav li{display:inline-block}html{height:100%;font-size:100%;background:linear-gradient(#fff,#f2f5f7) fixed}body{font-family:Avenir,"Helvetica Neue",Helvetica,Arial,sans-serif;line-height:1.5;text-align:center;color:#55646b}header{padding:20px;margin-bottom:20px}header p{font-size:18px;font-size:1.125rem}section{padding-bottom:20px}@media (min-width:480px){header{padding-top:60px;padding-bottom:60px}section{padding-bottom:40px}}.icon{fill:currentColor;width:18px;height:18px;vertical-align:-3px}a svg,button svg,label svg{pointer-events:none}.btn .icon,a .icon{margin-right:10px}nav ul{list-style:none;margin:0;padding:0;font-size:0}nav li{margin-top:10px;font-size:16px;font-size:1rem}nav li+li{margin-left:20px}.btn-bar{margin:0 auto 20px}.btn-bar::before{position:absolute;left:0;right:0;height:1px;background:#dbe3e8}.btn-bar ul{position:relative;z-index:1;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn-bar li{margin:0}.btn-bar li:first-child .btn{border-radius:4px 0 0 4px}.btn-bar li:last-child .btn{border-radius:0 4px 4px 0}.btn-bar li+li .btn{margin-left:-1px}.btn-bar .btn{display:block;border-radius:0}.btn-bar .btn.active{box-shadow:inset 0 1px 1px rgba(0,0,0,.2);position:relative;z-index:1}.btn-bar .btn.active .icon{color:inherit}@media (min-width:560px){.btn-bar{margin-bottom:40px}}.btn,.btn-count{display:inline-block;vertical-align:middle;border-radius:4px;font-weight:600;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn{padding:10px 20px;background:#f2f5f7;border:1px solid #cbd0d3;box-shadow:inset 0 1px 0 #fff,0 1px 1px rgba(0,0,0,.05);text-shadow:0 1px 1px #fff;color:#55646b;transition:background .3s ease,border .3s ease,color .3s ease}.btn:focus,.btn:hover{border-color:#b5bcc0;color:#55646b;outline:0}.btn-youtube .icon{color:#cc181e}.btn-vimeo .icon{color:#19b7ed}.btn-twitter .icon{color:#4BAAF4}.btn-bar .active,.btn-primary{background-image:linear-gradient(#3498db,#2791d9);background-color:#3498db;border-color:#217dbb;box-shadow:0 1px 1px rgba(0,0,0,.15);text-shadow:0 1px 1px rgba(0,0,0,.1);color:#fff}.btn-primary:focus,.btn-primary:hover{color:#fff;border-color:#196090}.btn-small{padding-top:7px;padding-bottom:7px}.btn-count{position:relative;margin-left:10px;padding:10px 15px;background:#fff;border:1px solid #cbd0d3}.btn-count::before{position:absolute;display:block;width:8px;height:8px;left:1px;margin-top:-4px;background:inherit;border:inherit;border-width:1px 0 0 1px;-webkit-transform:rotate(-45deg) translate(-50%,-50%);transform:rotate(-45deg) translate(-50%,-50%)}.panel{display:none}.panel.active{display:block;-webkit-animation:fade-in .3s ease;animation:fade-in .3s ease}.error body,html.error{height:100%}.error body{width:100%;display:table;table-layout:fixed}.error main{display:table-cell;width:100%;vertical-align:middle}.player{margin:0 auto 20px}.player-controls{border-radius:0 0 4px 4px}.player-audio{max-width:520px}.player-audio .player-controls{border-radius:4px}.player-audio .player-progress{border-radius:4px 4px 0 0;overflow:hidden}.player-video-embed,video{border-radius:4px}.player-video-embed{-webkit-mask-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC)}.player-video .player-video-embed,.player-video video,.player-vimeo .player-video-embed,.player-vimeo video,.player-youtube .player-video-embed,.player-youtube video{border-radius:4px 4px 0 0}.player-video.fullscreen-active,.player-video.player-fullscreen,.player-vimeo.fullscreen-active,.player-vimeo.player-fullscreen,.player-youtube.fullscreen-active,.player-youtube.player-fullscreen{max-width:none}.player-video.fullscreen-active .player-controls,.player-video.fullscreen-active iframe,.player-video.fullscreen-active video,.player-video.player-fullscreen .player-controls,.player-video.player-fullscreen iframe,.player-video.player-fullscreen video,.player-vimeo.fullscreen-active .player-controls,.player-vimeo.fullscreen-active iframe,.player-vimeo.fullscreen-active video,.player-vimeo.player-fullscreen .player-controls,.player-vimeo.player-fullscreen iframe,.player-vimeo.player-fullscreen video,.player-youtube.fullscreen-active .player-controls,.player-youtube.fullscreen-active iframe,.player-youtube.fullscreen-active video,.player-youtube.player-fullscreen .player-controls,.player-youtube.player-fullscreen iframe,.player-youtube.player-fullscreen video{border-radius:0}.player-video.fullscreen-active iframe,.player-video.player-fullscreen iframe,.player-vimeo.fullscreen-active iframe,.player-vimeo.player-fullscreen iframe,.player-youtube.fullscreen-active iframe,.player-youtube.player-fullscreen iframe{-webkit-mask-image:none} \ No newline at end of file
+/*! normalize.css v2.1.3 | MIT License | git.io/normalize */a.logo,img,legend{border:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,small,summary{display:block}[hidden],template{display:none}body,figure,ul li{margin:0}body,h1,h2{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}body,small{padding:0 10px}nav ul,ul li{list-style:none;padding:0}legend,nav ul,ul li{padding:0}.btn-bar,sub,sup{position:relative}.btn-bar,.plyr{max-width:1200px}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}a{background:0 0;text-decoration:none;color:#3498db;border-bottom:1px dotted currentColor;transition:background .3s ease,color .3s ease,border .3s ease}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}hr{box-sizing:content-box;height:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}.btn-bar,nav li{white-space:nowrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}sub,sup{font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}.btn-bar::before,.btn-count::before{content:"";top:50%}sub{bottom:-.25em}svg:not(:root){overflow:hidden}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}@-webkit-keyframes fade-in{0%{opacity:0}100%{opacity:1}}@keyframes fade-in{0%{opacity:0}100%{opacity:1}}@font-face{font-family:Avenir;src:url(//cdn.plyr.io/fonts/avenir-medium.woff2) format("woff2"),url(//cdn.plyr.io/fonts/avenir-medium.woff) format("woff");font-style:normal;font-weight:400}@font-face{font-family:Avenir;src:url(//cdn.plyr.io/fonts/avenir-bold.woff2) format("woff2"),url(//cdn.plyr.io/fonts/avenir-bold.woff) format("woff");font-style:normal;font-weight:600}h1,h2{letter-spacing:-.025em;color:#2E3C44;margin:0 0 10px;line-height:1.2}h1{font-size:64px;font-size:4rem;color:#3498DB}p,small{margin:0 0 20px}small{font-size:14px;font-size:.875rem}a:focus,a:hover{color:#343f4a;border-bottom-color:transparent}a:focus{outline:#343f4a dotted thin;outline-offset:1px}.color-vimeo{color:#19b7ed}.color-youtube{color:#cc181e}*,::after,::before{box-sizing:border-box}.btn-bar ul,nav li{display:inline-block}html{height:100%;font-size:100%;background:linear-gradient(#fff,#f2f5f7) fixed}body{font-family:Avenir,"Helvetica Neue",Helvetica,Arial,sans-serif;line-height:1.5;text-align:center;color:#55646b}header{padding:20px;margin-bottom:20px}header p{font-size:18px;font-size:1.125rem}section{padding-bottom:20px}@media (min-width:480px){header{padding-top:60px;padding-bottom:60px}section{padding-bottom:40px}}.icon{fill:currentColor;width:18px;height:18px;vertical-align:-3px}a svg,button svg,label svg{pointer-events:none}.btn .icon,a .icon{margin-right:10px}nav ul{margin:0;font-size:0}nav li{margin-top:10px;font-size:16px;font-size:1rem}nav li+li{margin-left:20px}.btn-bar{margin:0 auto 20px}.btn-bar::before{position:absolute;left:0;right:0;height:1px;background:#dbe3e8}.btn-bar ul{position:relative;z-index:1;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn-bar li{margin:0}.btn-bar li:first-child .btn{border-radius:4px 0 0 4px}.btn-bar li:last-child .btn{border-radius:0 4px 4px 0}.btn-bar li+li .btn{margin-left:-1px}.btn-bar .btn{display:block;border-radius:0}.btn-bar .btn.active{box-shadow:inset 0 1px 1px rgba(0,0,0,.2);position:relative;z-index:1}.btn-bar .btn.active .icon{color:inherit}@media (min-width:560px){.btn-bar{margin-bottom:40px}}.btn,.btn-count{display:inline-block;vertical-align:middle;border-radius:4px;font-weight:600;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn{padding:10px 20px;background:#f2f5f7;border:1px solid #cbd0d3;box-shadow:inset 0 1px 0 #fff,0 1px 1px rgba(0,0,0,.05);text-shadow:0 1px 1px #fff;color:#55646b;transition:background .3s ease,border .3s ease,color .3s ease}.btn:focus,.btn:hover{border-color:#b5bcc0;color:#55646b;outline:0}.btn-youtube .icon{color:#cc181e}.btn-vimeo .icon{color:#19b7ed}.btn-twitter .icon{color:#4BAAF4}.btn-bar .active,.btn-primary{background-image:linear-gradient(#3498db,#2791d9);background-color:#3498db;border-color:#217dbb;box-shadow:0 1px 1px rgba(0,0,0,.15);text-shadow:0 1px 1px rgba(0,0,0,.1);color:#fff}.btn-primary:focus,.btn-primary:hover{color:#fff;border-color:#196090}.btn-small{padding-top:7px;padding-bottom:7px}.btn-count{position:relative;margin-left:10px;padding:10px 15px;background:#fff;border:1px solid #cbd0d3}.btn-count::before{position:absolute;display:block;width:8px;height:8px;left:1px;margin-top:-4px;background:inherit;border:inherit;border-width:1px 0 0 1px;-webkit-transform:rotate(-45deg) translate(-50%,-50%);transform:rotate(-45deg) translate(-50%,-50%)}.panel{display:none}.panel.active{display:block;-webkit-animation:fade-in .3s ease;animation:fade-in .3s ease}.error body,html.error{height:100%}.error body{width:100%;display:table;table-layout:fixed}.error main{display:table-cell;width:100%;vertical-align:middle}.plyr{margin:0 auto 20px}.plyr-controls{border-radius:0 0 4px 4px}.plyr-audio{max-width:520px}.plyr-audio .plyr-controls{border-radius:4px}.plyr-audio .plyr-progress{border-radius:4px 4px 0 0;overflow:hidden}.plyr-video-embed,video{border-radius:4px}.plyr-video-embed{-webkit-mask-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC)}.plyr-video .plyr-video-embed,.plyr-video video,.plyr-vimeo .plyr-video-embed,.plyr-vimeo video,.plyr-youtube .plyr-video-embed,.plyr-youtube video{border-radius:4px 4px 0 0}.plyr-video.fullscreen-active,.plyr-video.plyr-fullscreen,.plyr-vimeo.fullscreen-active,.plyr-vimeo.plyr-fullscreen,.plyr-youtube.fullscreen-active,.plyr-youtube.plyr-fullscreen{max-width:none}.plyr-video.fullscreen-active .plyr-controls,.plyr-video.fullscreen-active iframe,.plyr-video.fullscreen-active video,.plyr-video.plyr-fullscreen .plyr-controls,.plyr-video.plyr-fullscreen iframe,.plyr-video.plyr-fullscreen video,.plyr-vimeo.fullscreen-active .plyr-controls,.plyr-vimeo.fullscreen-active iframe,.plyr-vimeo.fullscreen-active video,.plyr-vimeo.plyr-fullscreen .plyr-controls,.plyr-vimeo.plyr-fullscreen iframe,.plyr-vimeo.plyr-fullscreen video,.plyr-youtube.fullscreen-active .plyr-controls,.plyr-youtube.fullscreen-active iframe,.plyr-youtube.fullscreen-active video,.plyr-youtube.plyr-fullscreen .plyr-controls,.plyr-youtube.plyr-fullscreen iframe,.plyr-youtube.plyr-fullscreen video{border-radius:0}.plyr-video.fullscreen-active iframe,.plyr-video.plyr-fullscreen iframe,.plyr-vimeo.fullscreen-active iframe,.plyr-vimeo.plyr-fullscreen iframe,.plyr-youtube.fullscreen-active iframe,.plyr-youtube.plyr-fullscreen iframe{-webkit-mask-image:none}.cite{display:none}.cite .icon{margin-right:5px}.plyr-audio~ul .cite-audio,.plyr-video~ul .cite-video,.plyr-vimeo~ul .cite-vimeo,.plyr-youtube~ul .cite-youtube{display:block} \ No newline at end of file
diff --git a/docs/dist/docs.js b/docs/dist/docs.js
index b034a211..4376d476 100644
--- a/docs/dist/docs.js
+++ b/docs/dist/docs.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 s=function(e){var s=DOMTokenList.prototype[e];DOMTokenList.prototype[e]=function(e){var n,t=arguments.length;for(n=0;t>n;n++)e=arguments[n],s.call(this,e)}};s("add"),s("remove")}if(e.classList.toggle("c3",!1),e.classList.contains("c3")){var n=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(e,s){return 1 in arguments&&!this.contains(e)==!s?s:n.call(this,e)}}e=null}():!function(e){"use strict";if("Element"in e){var s="classList",n="prototype",t=e.Element[n],a=Object,r=String[n].trim||function(){return this.replace(/^\s+|\s+$/g,"")},o=Array[n].indexOf||function(e){for(var s=0,n=this.length;n>s;s++)if(s in this&&this[s]===e)return s;return-1},l=function(e,s){this.name=e,this.code=DOMException[e],this.message=s},i=function(e,s){if(""===s)throw new l("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(s))throw new l("INVALID_CHARACTER_ERR","String contains an invalid character");return o.call(e,s)},c=function(e){for(var s=r.call(e.getAttribute("class")||""),n=s?s.split(/\s+/):[],t=0,a=n.length;a>t;t++)this.push(n[t]);this._updateClassName=function(){e.setAttribute("class",this.toString())}},u=c[n]=[],b=function(){return new c(this)};if(l[n]=Error[n],u.item=function(e){return this[e]||null},u.contains=function(e){return e+="",-1!==i(this,e)},u.add=function(){var e,s=arguments,n=0,t=s.length,a=!1;do e=s[n]+"",-1===i(this,e)&&(this.push(e),a=!0);while(++n<t);a&&this._updateClassName()},u.remove=function(){var e,s,n=arguments,t=0,a=n.length,r=!1;do for(e=n[t]+"",s=i(this,e);-1!==s;)this.splice(s,1),r=!0,s=i(this,e);while(++t<a);r&&this._updateClassName()},u.toggle=function(e,s){e+="";var n=this.contains(e),t=n?s!==!0&&"remove":s!==!1&&"add";return t&&this[t](e),s===!0||s===!1?s:!n},u.toString=function(){return this.join(" ")},a.defineProperty){var p={get:b,enumerable:!0,configurable:!0};try{a.defineProperty(t,s,p)}catch(g){-2146823252===g.number&&(p.enumerable=!1,a.defineProperty(t,s,p))}}else a[n].__defineGetter__&&t.__defineGetter__(s,b)}}(self));var templates={};templates.controls=new Hogan.Template({code:function(e,s,n){var t=this;return t.b(n=n||""),t.b('<div class="player-controls">'),t.b("\n"+n),t.b(' <div class="player-progress">'),t.b("\n"+n),t.b(' <label for="seek{id}" class="sr-only">Seek</label>'),t.b("\n"+n),t.b(' <input id="seek{id}" class="player-progress-seek" type="range" min="0" max="100" step="0.5" value="0" data-player="seek">'),t.b("\n"+n),t.b(' <progress class="player-progress-played" max="100" value="0">'),t.b("\n"+n),t.b(" <span>0</span>% played"),t.b("\n"+n),t.b(" </progress>"),t.b("\n"+n),t.b(' <progress class="player-progress-buffer" max="100" value="0">'),t.b("\n"+n),t.b(" <span>0</span>% buffered"),t.b("\n"+n),t.b(" </progress>"),t.b("\n"+n),t.b(" </div>"),t.b("\n"+n),t.b(' <span class="player-controls-left">'),t.b("\n"+n),t.b(' <button type="button" data-player="restart">'),t.b("\n"+n),t.b(' <svg><use xlink:href="#icon-restart"></use></svg>'),t.b("\n"+n),t.b(' <span class="sr-only">Restart</span>'),t.b("\n"+n),t.b(" </button>"),t.b("\n"+n),t.b(' <button type="button" data-player="rewind">'),t.b("\n"+n),t.b(' <svg><use xlink:href="#icon-rewind"></use></svg>'),t.b("\n"+n),t.b(' <span class="sr-only">Rewind {seektime} secs</span>'),t.b("\n"+n),t.b(" </button>"),t.b("\n"+n),t.b(' <button type="button" data-player="play">'),t.b("\n"+n),t.b(' <svg><use xlink:href="#icon-play"></use></svg>'),t.b("\n"+n),t.b(' <span class="sr-only">Play</span>'),t.b("\n"+n),t.b(" </button>"),t.b("\n"+n),t.b(' <button type="button" data-player="pause">'),t.b("\n"+n),t.b(' <svg><use xlink:href="#icon-pause"></use></svg>'),t.b("\n"+n),t.b(' <span class="sr-only">Pause</span>'),t.b("\n"+n),t.b(" </button>"),t.b("\n"+n),t.b(' <button type="button" data-player="fast-forward">'),t.b("\n"+n),t.b(' <svg><use xlink:href="#icon-fast-forward"></use></svg>'),t.b("\n"+n),t.b(' <span class="sr-only">Forward {seektime} secs</span>'),t.b("\n"+n),t.b(" </button>"),t.b("\n"+n),t.b(' <span class="player-time">'),t.b("\n"+n),t.b(' <span class="sr-only">Current time</span>'),t.b("\n"+n),t.b(' <span class="player-current-time">00:00</span>'),t.b("\n"+n),t.b(" </span>"),t.b("\n"+n),t.b(' <span class="player-time">'),t.b("\n"+n),t.b(' <span class="sr-only">Duration</span>'),t.b("\n"+n),t.b(' <span class="player-duration">00:00</span>'),t.b("\n"+n),t.b(" </span>"),t.b("\n"+n),t.b(" </span>"),t.b("\n"+n),t.b(' <span class="player-controls-right">'),t.b("\n"+n),t.b(' <button type="button" data-player="mute">'),t.b("\n"+n),t.b(' <svg class="icon-muted"><use xlink:href="#icon-muted"></use></svg>'),t.b("\n"+n),t.b(' <svg><use xlink:href="#icon-volume"></use></svg>'),t.b("\n"+n),t.b(' <span class="sr-only">Toggle Mute</span>'),t.b("\n"+n),t.b(" </button>"),t.b("\n"+n),t.b(' <label for="volume{id}" class="sr-only">Volume</label>'),t.b("\n"+n),t.b(' <input id="volume{id}" class="player-volume" type="range" min="0" max="10" step="0.5" value="0" data-player="volume">'),t.b("\n"+n),t.b(' <button type="button" data-player="captions">'),t.b("\n"+n),t.b(' <svg class="icon-captions-on"><use xlink:href="#icon-captions-on"></use></svg>'),t.b("\n"+n),t.b(' <svg><use xlink:href="#icon-captions-off"></use></svg>'),t.b("\n"+n),t.b(' <span class="sr-only">Toggle Captions</span>'),t.b("\n"+n),t.b(" </button>"),t.b("\n"+n),t.b(' <button type="button" data-player="fullscreen">'),t.b("\n"+n),t.b(' <svg class="icon-exit-fullscreen"><use xlink:href="#icon-exit-fullscreen"></use></svg>'),t.b("\n"+n),t.b(' <svg><use xlink:href="#icon-enter-fullscreen"></use></svg>'),t.b("\n"+n),t.b(' <span class="sr-only">Toggle Fullscreen</span>'),t.b("\n"+n),t.b(" </button>"),t.b("\n"+n),t.b(" </span>"),t.b("\n"+n),t.b("</div>"),t.fl()},partials:{},subs:{}}),plyr.setup({debug:!0,title:"Video demo",tooltips:!0,captions:{defaultActive:!0},onSetup:function(){console.log("✓ Setup done")}}),shr.setup({count:{classname:"btn-count"}}),function(){function e(){var e=this,n=e.getAttribute("data-source"),t=document.querySelector(".player").plyr;switch(n){case"video":t.source({type:"video",title:"Bug Buck Bunny",sources:[{src:"https://cdn.selz.com/plyr/1.0/movie.mp4",type:"video/mp4"},{src:"https://cdn.selz.com/plyr/1.0/movie.webm",type:"video/webm"}],poster:"https://cdn.selz.com/plyr/1.0/poster.jpg",tracks:[{kind:"captions",label:"English",srclang:"en",src:"https://cdn.selz.com/plyr/1.0/example_captions_en.vtt","default":!0}]});break;case"audio":t.source({type:"audio",title:"96 by Logistics",sources:[{src:"https://cdn.selz.com/plyr/1.0/logistics-96-sample.mp3",type:"audio/mp3"},{src:"https://cdn.selz.com/plyr/1.0/logistics-96-sample.ogg",type:"audio/ogg"}]});break;case"youtube":t.source({type:"youtube",title:"Introducing Apple Pencil",sources:"iicnVez5U7M"});break;case"vimeo":t.source({type:"vimeo",title:"The Beaten Track",sources:"125220818"})}for(var a=s.length-1;a>=0;a--)s[a].classList.remove("active");event.target.classList.add("active")}for(var s=document.querySelectorAll("[data-source]"),n=s.length-1;n>=0;n--)s[n].addEventListener("click",e)}(),document.domain.indexOf("plyr.io")>-1&&(!function(e,s,n,t,a,r,o){e.GoogleAnalyticsObject=a,e[a]=e[a]||function(){(e[a].q=e[a].q||[]).push(arguments)},e[a].l=1*new Date,r=s.createElement(n),o=s.getElementsByTagName(n)[0],r.async=1,r.src=t,o.parentNode.insertBefore(r,o)}(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 t=document.createElement("_");if(t.classList.add("c1","c2"),!t.classList.contains("c2")){var e=function(t){var e=DOMTokenList.prototype[t];DOMTokenList.prototype[t]=function(t){var s,n=arguments.length;for(s=0;n>s;s++)t=arguments[s],e.call(this,t)}};e("add"),e("remove")}if(t.classList.toggle("c3",!1),t.classList.contains("c3")){var s=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(t,e){return 1 in arguments&&!this.contains(t)==!e?e:s.call(this,t)}}t=null}():!function(t){"use strict";if("Element"in t){var e="classList",s="prototype",n=t.Element[s],i=Object,o=String[s].trim||function(){return this.replace(/^\s+|\s+$/g,"")},r=Array[s].indexOf||function(t){for(var e=0,s=this.length;s>e;e++)if(e in this&&this[e]===t)return e;return-1},c=function(t,e){this.name=t,this.code=DOMException[t],this.message=e},a=function(t,e){if(""===e)throw new c("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(e))throw new c("INVALID_CHARACTER_ERR","String contains an invalid character");return r.call(t,e)},l=function(t){for(var e=o.call(t.getAttribute("class")||""),s=e?e.split(/\s+/):[],n=0,i=s.length;i>n;n++)this.push(s[n]);this._updateClassName=function(){t.setAttribute("class",this.toString())}},u=l[s]=[],p=function(){return new l(this)};if(c[s]=Error[s],u.item=function(t){return this[t]||null},u.contains=function(t){return t+="",-1!==a(this,t)},u.add=function(){var t,e=arguments,s=0,n=e.length,i=!1;do t=e[s]+"",-1===a(this,t)&&(this.push(t),i=!0);while(++s<n);i&&this._updateClassName()},u.remove=function(){var t,e,s=arguments,n=0,i=s.length,o=!1;do for(t=s[n]+"",e=a(this,t);-1!==e;)this.splice(e,1),o=!0,e=a(this,t);while(++n<i);o&&this._updateClassName()},u.toggle=function(t,e){t+="";var s=this.contains(t),n=s?e!==!0&&"remove":e!==!1&&"add";return n&&this[n](t),e===!0||e===!1?e:!s},u.toString=function(){return this.join(" ")},i.defineProperty){var d={get:p,enumerable:!0,configurable:!0};try{i.defineProperty(n,e,d)}catch(m){-2146823252===m.number&&(d.enumerable=!1,i.defineProperty(n,e,d))}}else i[s].__defineGetter__&&n.__defineGetter__(e,p)}}(self)),plyr.setup({debug:!0,title:"Video demo",tooltips:!0,captions:{defaultActive:!0},onSetup:function(){console.log("✓ Setup done")}}),shr.setup({count:{classname:"btn-count"}}),function(){function t(){var t=this,s=t.getAttribute("data-source"),n=document.querySelector(".plyr").plyr;switch(s){case"video":n.source({type:"video",title:"Bug Buck Bunny",sources:[{src:"https://cdn.selz.com/plyr/1.0/movie.mp4",type:"video/mp4"},{src:"https://cdn.selz.com/plyr/1.0/movie.webm",type:"video/webm"}],poster:"https://cdn.selz.com/plyr/1.0/poster.jpg",tracks:[{kind:"captions",label:"English",srclang:"en",src:"https://cdn.selz.com/plyr/1.0/example_captions_en.vtt","default":!0}]});break;case"audio":n.source({type:"audio",title:"96 by Logistics",sources:[{src:"https://cdn.selz.com/plyr/1.0/logistics-96-sample.mp3",type:"audio/mp3"},{src:"https://cdn.selz.com/plyr/1.0/logistics-96-sample.ogg",type:"audio/ogg"}]});break;case"youtube":n.source({type:"youtube",title:"Enovato interview of Dan Cederholm for Made By",sources:"Au87oAJ2jeE"});break;case"vimeo":n.source({type:"vimeo",title:"Yosemite HD II",sources:"87701971"})}for(var i=e.length-1;i>=0;i--)e[i].classList.remove("active");event.target.classList.add("active")}for(var e=document.querySelectorAll("[data-source]"),s=e.length-1;s>=0;s--)e[s].addEventListener("click",t)}(),document.domain.indexOf("plyr.io")>-1&&(!function(t,e,s,n,i,o,r){t.GoogleAnalyticsObject=i,t[i]=t[i]||function(){(t[i].q=t[i].q||[]).push(arguments)},t[i].l=1*new Date,o=e.createElement(s),r=e.getElementsByTagName(s)[0],o.async=1,o.src=n,r.parentNode.insertBefore(o,r)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),ga("create","UA-40881672-11","auto"),ga("send","pageview")); \ No newline at end of file
diff --git a/docs/dist/templates.js b/docs/dist/templates.js
deleted file mode 100644
index 7b523c86..00000000
--- a/docs/dist/templates.js
+++ /dev/null
@@ -1,2 +0,0 @@
- var templates = {};
- templates['controls'] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div class=\"player-controls\">");t.b("\n" + i);t.b(" <div class=\"player-progress\">");t.b("\n" + i);t.b(" <label for=\"seek{id}\" class=\"sr-only\">Seek</label>");t.b("\n" + i);t.b(" <input id=\"seek{id}\" class=\"player-progress-seek\" type=\"range\" min=\"0\" max=\"100\" step=\"0.5\" value=\"0\" data-player=\"seek\">");t.b("\n" + i);t.b(" <progress class=\"player-progress-played\" max=\"100\" value=\"0\">");t.b("\n" + i);t.b(" <span>0</span>% played");t.b("\n" + i);t.b(" </progress>");t.b("\n" + i);t.b(" <progress class=\"player-progress-buffer\" max=\"100\" value=\"0\">");t.b("\n" + i);t.b(" <span>0</span>% buffered");t.b("\n" + i);t.b(" </progress>");t.b("\n" + i);t.b(" </div>");t.b("\n" + i);t.b(" <span class=\"player-controls-left\">");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"restart\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-restart\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Restart</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"rewind\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-rewind\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Rewind {seektime} secs</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"play\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-play\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Play</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"pause\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-pause\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Pause</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"fast-forward\">");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-fast-forward\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Forward {seektime} secs</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <span class=\"player-time\">");t.b("\n" + i);t.b(" <span class=\"sr-only\">Current time</span>");t.b("\n" + i);t.b(" <span class=\"player-current-time\">00:00</span>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b(" <span class=\"player-time\">");t.b("\n" + i);t.b(" <span class=\"sr-only\">Duration</span>");t.b("\n" + i);t.b(" <span class=\"player-duration\">00:00</span>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b(" <span class=\"player-controls-right\">");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"mute\">");t.b("\n" + i);t.b(" <svg class=\"icon-muted\"><use xlink:href=\"#icon-muted\"></use></svg>");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-volume\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Toggle Mute</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <label for=\"volume{id}\" class=\"sr-only\">Volume</label>");t.b("\n" + i);t.b(" <input id=\"volume{id}\" class=\"player-volume\" type=\"range\" min=\"0\" max=\"10\" step=\"0.5\" value=\"0\" data-player=\"volume\">");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"captions\">");t.b("\n" + i);t.b(" <svg class=\"icon-captions-on\"><use xlink:href=\"#icon-captions-on\"></use></svg>");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-captions-off\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Toggle Captions</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" <button type=\"button\" data-player=\"fullscreen\">");t.b("\n" + i);t.b(" <svg class=\"icon-exit-fullscreen\"><use xlink:href=\"#icon-exit-fullscreen\"></use></svg>");t.b("\n" + i);t.b(" <svg><use xlink:href=\"#icon-enter-fullscreen\"></use></svg>");t.b("\n" + i);t.b(" <span class=\"sr-only\">Toggle Fullscreen</span>");t.b("\n" + i);t.b(" </button>");t.b("\n" + i);t.b(" </span>");t.b("\n" + i);t.b("</div>");return t.fl(); },partials: {}, subs: { }}); \ No newline at end of file
diff --git a/docs/src/js/docs.js b/docs/src/js/docs.js
index 549689f8..4e2208ee 100644
--- a/docs/src/js/docs.js
+++ b/docs/src/js/docs.js
@@ -37,7 +37,7 @@ shr.setup({
function newSource() {
var trigger = this,
type = trigger.getAttribute('data-source'),
- player = document.querySelector('.player').plyr;
+ player = document.querySelector('.plyr').plyr;
switch(type) {
case 'video':
@@ -81,16 +81,16 @@ shr.setup({
case 'youtube':
player.source({
type: 'youtube',
- title: 'Introducing Apple Pencil',
- sources: 'iicnVez5U7M'
+ title: 'Enovato interview of Dan Cederholm for Made By',
+ sources: 'Au87oAJ2jeE'
});
break;
case 'vimeo':
player.source({
type: 'vimeo',
- title: 'The Beaten Track',
- sources: '125220818'
+ title: 'Yosemite HD II',
+ sources: '87701971'
});
break;
}
diff --git a/docs/src/less/components/examples.less b/docs/src/less/components/examples.less
index 32ee5e41..5e09cab6 100644
--- a/docs/src/less/components/examples.less
+++ b/docs/src/less/components/examples.less
@@ -3,7 +3,7 @@
// ==========================================================================
// Example players
-.player {
+.plyr {
margin: 0 auto @padding-base;
max-width: @example-width-video;
@@ -11,38 +11,38 @@
border-radius: 0 0 @border-radius-base @border-radius-base;
}
}
-.player-audio {
+.plyr-audio {
max-width: @example-width-audio;
- .player-controls {
+ .plyr-controls {
border-radius: @border-radius-base;
}
- .player-progress {
+ .plyr-progress {
border-radius: @border-radius-base @border-radius-base 0 0;
overflow: hidden;
}
}
video,
-.player-video-embed {
+.plyr-video-embed {
border-radius: @border-radius-base;
}
-.player-video-embed {
+.plyr-video-embed {
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
}
// Style full supported player
-.player-video,
-.player-youtube,
-.player-vimeo {
+.plyr-video,
+.plyr-youtube,
+.plyr-vimeo {
video,
- .player-video-embed {
+ .plyr-video-embed {
border-radius: @border-radius-base @border-radius-base 0 0;
}
- &.player-fullscreen,
+ &.plyr-fullscreen,
&.fullscreen-active {
max-width: none;
- .player-controls,
+ .plyr-controls,
video,
iframe {
border-radius: 0;
@@ -51,4 +51,19 @@ video,
-webkit-mask-image: none;
}
}
+}
+
+.cite {
+ display: none;
+
+ .icon {
+ margin-right: (@padding-base / 4);
+ }
+}
+
+.plyr-video ~ ul .cite-video,
+.plyr-audio ~ ul .cite-audio,
+.plyr-youtube ~ ul .cite-youtube,
+.plyr-vimeo ~ ul .cite-vimeo {
+ display: block;
} \ No newline at end of file
diff --git a/docs/src/less/components/type.less b/docs/src/less/components/type.less
index 97652342..7b214b49 100644
--- a/docs/src/less/components/type.less
+++ b/docs/src/less/components/type.less
@@ -26,17 +26,24 @@ small {
padding: 0 (@padding-base / 2);
.font-size(14);
}
+ul
+li {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
// Links
a {
text-decoration: none;
color: @link-color;
- border-bottom: 1px solid currentColor;
- transition: background .3s ease, color .3s ease;
+ border-bottom: 1px dotted currentColor;
+ transition: background .3s ease, color .3s ease, border .3s ease;
&:hover,
&:focus {
color: @gray-dark;
+ border-bottom-color: rgba(0,0,0,0);
}
&:focus {
.tab-focus();
@@ -44,4 +51,11 @@ a {
&.logo {
border: 0;
}
+}
+
+.color-vimeo {
+ color: @color-vimeo;
+}
+.color-youtube {
+ color: @color-youtube;
} \ No newline at end of file
diff --git a/readme.md b/readme.md
index 53bae968..b853367d 100644
--- a/readme.md
+++ b/readme.md
@@ -100,7 +100,7 @@ and the AJAX technique here:
### HTML
The only extra markup that's needed to use plyr is a `<div>` wrapper. Replace the source, poster and captions with urls for your media.
```html
-<div class="player">
+<div class="plyr">
<video poster="https://cdn.selz.com/plyr/1.0/poster.jpg" controls crossorigin>
<!-- Video files -->
<source src="https://cdn.selz.com/plyr/1.0/movie.mp4" type="video/mp4">
@@ -117,7 +117,7 @@ The only extra markup that's needed to use plyr is a `<div>` wrapper. Replace th
And the same for `<audio>`
```html
-<div class="player">
+<div class="plyr">
<audio controls>
<!-- Audio files -->
<source src="https://cdn.selz.com/plyr/1.0/logistics-96-sample.mp3" type="audio/mp3">
@@ -132,7 +132,7 @@ And the same for `<audio>`
For YouTube, Plyr uses the standard YouTube API markup (an empty `<div>`):
```html
-<div class="player">
+<div class="plyr">
<div data-video-id="L1h9xxCU20g" data-type="youtube"></div>
</div>
```
@@ -144,16 +144,43 @@ More info on CORS here:
[https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)
### JavaScript
-Much of the behaviour of the player is configurable when initialising the library. Here's an example of a default setup:
+
+#### Quick setup
+
+Here's an example of a default setup:
```html
-<script src="dist/plyr.js"></script>
+<script src="https://cdn.plyr.io/1.3.5/plyr.js"></script>
<script>plyr.setup();</script>
```
+This will look for all elements with the `plyr` classname and setup plyr on each element found. You can specify other options, including a different selector hook below.
+
+You can initialise the player a few other ways:
+
+Passing a [NodeList](https://developer.mozilla.org/en-US/docs/Web/API/NodeList):
+```javascript
+plyr.setup(document.querySelectorAll('.js-plyr'), options);
+```
+
+Passing a [HTMLElement](https://developer.mozilla.org/en/docs/Web/API/HTMLElement):
+```javascript
+plyr.setup(document.querySelector('.js-plyr'), options);
+```
+
+Passing a [string selector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll):
+```javascript
+plyr.setup('.js-plyr', options);
+```
+
+Passing just the options object:
+```javascript
+plyr.setup(options);
+```
+
#### Options
-You can pass the following options to the setup method using `plyr.setup({...})`.
+Options must be passed as an object to the `setup()` method as above.
<table class="table" width="100%">
<thead>
@@ -235,7 +262,7 @@ You can pass the following options to the setup method using `plyr.setup({...})`
<td><code>selectors</code></td>
<td>Object</td>
<td>&mdash;</td>
- <td>See <code>plyr.js</code> in <code>/src</code> for more info. The only option you might want to change is <code>player</code> which is the hook used for Plyr, the default is <code>.player</code>.</td>
+ <td>See <code>plyr.js</code> in <code>/src</code> for more info. The only option you might want to change is <code>container</code> which is the hook used for `setup()`, the default is <code>.plyr</code>.</td>
</tr>
<tr>
<td><code>classes</code></td>
@@ -272,10 +299,27 @@ You can pass the following options to the setup method using `plyr.setup({...})`
## API
-A `plyr` object is added to any element that Plyr is initialised on. You can then control the player by accessing methods in the `plyr` object. For example if you wanted to pause Plyr:
+#### Fetching the plyr instance
+A `plyr` object is added to any element that Plyr is initialised on. You can then control the player by accessing methods in the `plyr` object.
+
+There are two ways to access the instance, firstly you re-query the element container you used for setup (e.g. `.js-plyr`) like so:
+
+```javascript
+var player = document.querySelector('.js-plyr');
+```
+
+Or you can use the returned object from your call to the setup method:
+
+```javascript
+var player = plyr.setup('.js-plyr')[0];
+```
+
+This will return an array of plyr instances setup, so you need to specify the index of the instance you want. This is less useful if you are setting up mutliple instances. You can also use the `onSetup` callback documented below which will return each instance one by one, as they are setup.
+
+Once you have your instance, you can use the API methods below on it. For example to pause it:
```javascript
-document.querySelectorAll(".player")[0].plyr.pause();
+player.pause();
```
Here's a list of the methods supported:
@@ -395,7 +439,7 @@ Here's a list of the methods supported:
The `plyr` object on the player element also contains a `media` property which is a reference to the `<audio>` or `<video>` element within the player which you can use to listen for events. Here's an example:
```javascript
-var media = document.querySelectorAll(".player")[0].plyr.media;
+var media = document.querySelector(".plyr").plyr.media;
media.addEventListener("playing", function() {
console.log("playing");
@@ -415,7 +459,7 @@ Currently only YouTube is supported. Vimeo will be coming soon. Some HTML5 media
Due to the way the YouTube API works, the `timeupdate` and `progress` events are triggered by polling every 200ms so the event may trigger without an actual value change. Buffering progress is `media.buffered` in the `plyr` object. It is a a number between 0 and 1 that specifies the percentage of the video that the player shows as buffered.
```javascript
-document.querySelector(".player").plyr.media.addEventListener("play", function() {
+document.querySelector(".plyr").plyr.media.addEventListener("play", function() {
console.log("play");
});
```
@@ -426,7 +470,7 @@ Currently caption control is not supported but I will work on this.
## Fullscreen
-Fullscreen in Plyr is supported for all browsers that [currently support it](http://caniuse.com/#feat=fullscreen). If you're using the default CSS, you can also use a "full browser" mode which will use the full browser window by adding the `player-fullscreen` class to your container.
+Fullscreen in Plyr is supported for all browsers that [currently support it](http://caniuse.com/#feat=fullscreen). If you're using the default CSS, you can also use a "full browser" mode which will use the full browser window by adding the `plyr-fullscreen` class to your container.
## Browser support
diff --git a/src/js/plyr.js b/src/js/plyr.js
index ed4352e0..5e22c680 100644
--- a/src/js/plyr.js
+++ b/src/js/plyr.js
@@ -27,41 +27,41 @@
displayDuration: true,
iconPrefix: 'icon',
selectors: {
- container: '.player',
- controls: '.player-controls',
- labels: '[data-player] .sr-only, label .sr-only',
+ container: '.plyr',
+ controls: '.plyr-controls',
+ labels: '[data-plyr] .sr-only, label .sr-only',
buttons: {
- seek: '[data-player="seek"]',
- play: '[data-player="play"]',
- pause: '[data-player="pause"]',
- restart: '[data-player="restart"]',
- rewind: '[data-player="rewind"]',
- forward: '[data-player="fast-forward"]',
- mute: '[data-player="mute"]',
- volume: '[data-player="volume"]',
- captions: '[data-player="captions"]',
- fullscreen: '[data-player="fullscreen"]'
+ seek: '[data-plyr="seek"]',
+ play: '[data-plyr="play"]',
+ pause: '[data-plyr="pause"]',
+ restart: '[data-plyr="restart"]',
+ rewind: '[data-plyr="rewind"]',
+ forward: '[data-plyr="fast-forward"]',
+ mute: '[data-plyr="mute"]',
+ volume: '[data-plyr="volume"]',
+ captions: '[data-plyr="captions"]',
+ fullscreen: '[data-plyr="fullscreen"]'
},
progress: {
- container: '.player-progress',
- buffer: '.player-progress-buffer',
- played: '.player-progress-played'
+ container: '.plyr-progress',
+ buffer: '.plyr-progress-buffer',
+ played: '.plyr-progress-played'
},
- captions: '.player-captions',
- currentTime: '.player-current-time',
- duration: '.player-duration'
+ captions: '.plyr-captions',
+ currentTime: '.plyr-current-time',
+ duration: '.plyr-duration'
},
classes: {
- videoWrapper: 'player-video-wrapper',
- embedWrapper: 'player-video-embed',
- type: 'player-{0}',
+ videoWrapper: 'plyr-video-wrapper',
+ embedWrapper: 'plyr-video-embed',
+ type: 'plyr-{0}',
stopped: 'stopped',
playing: 'playing',
muted: 'muted',
loading: 'loading',
- tooltip: 'player-tooltip',
+ tooltip: 'plyr-tooltip',
hidden: 'sr-only',
- hover: 'player-hover',
+ hover: 'plyr-hover',
captions: {
enabled: 'captions-enabled',
active: 'captions-active'
@@ -103,6 +103,14 @@
types: {
embed: ['youtube','vimeo'],
html5: ['video', 'audio']
+ },
+ urls: {
+ vimeo: {
+ api: 'https://cdn.rawgit.com/vimeo/player-api/master/javascript/froogaloop.js'
+ },
+ youtube: {
+ api: 'https://www.youtube.com/iframe_api'
+ }
}
};
@@ -110,23 +118,23 @@
function _buildControls() {
// Open and add the progress and seek elements
var html = [
- '<div class="player-controls">',
- '<div class="player-progress">',
+ '<div class="plyr-controls">',
+ '<div class="plyr-progress">',
'<label for="seek{id}" class="sr-only">Seek</label>',
- '<input id="seek{id}" class="player-progress-seek" type="range" min="0" max="100" step="0.5" value="0" data-player="seek">',
- '<progress class="player-progress-played" max="100" value="0">',
+ '<input id="seek{id}" class="plyr-progress-seek" type="range" min="0" max="100" step="0.5" value="0" data-plyr="seek">',
+ '<progress class="plyr-progress-played" max="100" value="0">',
'<span>0</span>% ' + config.i18n.played,
'</progress>',
- '<progress class="player-progress-buffer" max="100" value="0">',
+ '<progress class="plyr-progress-buffer" max="100" value="0">',
'<span>0</span>% ' + config.i18n.buffered,
'</progress>',
'</div>',
- '<span class="player-controls-left">'];
+ '<span class="plyr-controls-left">'];
// Restart button
if (_inArray(config.controls, 'restart')) {
html.push(
- '<button type="button" data-player="restart">',
+ '<button type="button" data-plyr="restart">',
'<svg><use xlink:href="#' + config.iconPrefix + '-restart" /></svg>',
'<span class="sr-only">' + config.i18n.restart + '</span>',
'</button>'
@@ -136,7 +144,7 @@
// Rewind button
if (_inArray(config.controls, 'rewind')) {
html.push(
- '<button type="button" data-player="rewind">',
+ '<button type="button" data-plyr="rewind">',
'<svg><use xlink:href="#' + config.iconPrefix + '-rewind" /></svg>',
'<span class="sr-only">' + config.i18n.rewind + '</span>',
'</button>'
@@ -146,11 +154,11 @@
// Play/pause button
if (_inArray(config.controls, 'play')) {
html.push(
- '<button type="button" data-player="play">',
+ '<button type="button" data-plyr="play">',
'<svg><use xlink:href="#' + config.iconPrefix + '-play" /></svg>',
'<span class="sr-only">' + config.i18n.play + '</span>',
'</button>',
- '<button type="button" data-player="pause">',
+ '<button type="button" data-plyr="pause">',
'<svg><use xlink:href="#' + config.iconPrefix + '-pause" /></svg>',
'<span class="sr-only">' + config.i18n.pause + '</span>',
'</button>'
@@ -160,7 +168,7 @@
// Fast forward button
if (_inArray(config.controls, 'fast-forward')) {
html.push(
- '<button type="button" data-player="fast-forward">',
+ '<button type="button" data-plyr="fast-forward">',
'<svg><use xlink:href="#' + config.iconPrefix + '-fast-forward" /></svg>',
'<span class="sr-only">' + config.i18n.forward + '</span>',
'</button>'
@@ -170,9 +178,9 @@
// Media current time display
if (_inArray(config.controls, 'current-time')) {
html.push(
- '<span class="player-time">',
+ '<span class="plyr-time">',
'<span class="sr-only">' + config.i18n.currentTime + '</span>',
- '<span class="player-current-time">00:00</span>',
+ '<span class="plyr-current-time">00:00</span>',
'</span>'
);
}
@@ -180,9 +188,9 @@
// Media duration display
if (_inArray(config.controls, 'duration')) {
html.push(
- '<span class="player-time">',
+ '<span class="plyr-time">',
'<span class="sr-only">' + config.i18n.duration + '</span>',
- '<span class="player-duration">00:00</span>',
+ '<span class="plyr-duration">00:00</span>',
'</span>'
);
}
@@ -190,13 +198,13 @@
// Close left controls
html.push(
'</span>',
- '<span class="player-controls-right">'
+ '<span class="plyr-controls-right">'
);
// Toggle mute button
if (_inArray(config.controls, 'mute')) {
html.push(
- '<button type="button" data-player="mute">',
+ '<button type="button" data-plyr="mute">',
'<svg class="icon-muted"><use xlink:href="#' + config.iconPrefix + '-muted" /></svg>',
'<svg><use xlink:href="#' + config.iconPrefix + '-volume" /></svg>',
'<span class="sr-only">' + config.i18n.toggleMute + '</span>',
@@ -208,14 +216,14 @@
if (_inArray(config.controls, 'volume')) {
html.push(
'<label for="volume{id}" class="sr-only">' + config.i18n.volume + '</label>',
- '<input id="volume{id}" class="player-volume" type="range" min="0" max="10" value="5" data-player="volume">'
+ '<input id="volume{id}" class="plyr-volume" type="range" min="0" max="10" value="5" data-plyr="volume">'
);
}
// Toggle captions button
if (_inArray(config.controls, 'captions')) {
html.push(
- '<button type="button" data-player="captions">',
+ '<button type="button" data-plyr="captions">',
'<svg class="icon-captions-on"><use xlink:href="#' + config.iconPrefix + '-captions-on" /></svg>',
'<svg><use xlink:href="#' + config.iconPrefix + '-captions-off" /></svg>',
'<span class="sr-only">' + config.i18n.toggleCaptions + '</span>',
@@ -226,7 +234,7 @@
// Toggle fullscreen button
if (_inArray(config.controls, 'fullscreen')) {
html.push(
- '<button type="button" data-player="fullscreen">',
+ '<button type="button" data-plyr="fullscreen">',
'<svg class="icon-exit-fullscreen"><use xlink:href="#' + config.iconPrefix + '-exit-fullscreen" /></svg>',
'<svg><use xlink:href="#' + config.iconPrefix + '-enter-fullscreen" /></svg>',
'<span class="sr-only">' + config.i18n.toggleFullscreen + '</span>',
@@ -322,12 +330,12 @@
// Check for mime type support against a player instance
// Credits: http://diveintohtml5.info/everything.html
- // Related: http://www.leanbackplayer.com/test/h5mt.html
- function _supportMime(player, mimeType) {
- var media = player.media;
+ // Related: http://www.leanbackplyr.com/test/h5mt.html
+ function _supportMime(plyr, mimeType) {
+ var media = plyr.media;
// Only check video types for video players
- if (player.type == 'video') {
+ if (plyr.type == 'video') {
// Check type
switch (mimeType) {
case 'video/webm': return !!(media.canPlayType && media.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/no/, ''));
@@ -337,7 +345,7 @@
}
// Only check audio types for audio players
- else if (player.type == 'audio') {
+ else if (plyr.type == 'audio') {
// Check type
switch (mimeType) {
case 'audio/mpeg': return !!(media.canPlayType && media.canPlayType('audio/mpeg;').replace(/no/, ''));
@@ -636,73 +644,73 @@
// Player instance
function Plyr(container) {
- var player = this;
- player.container = container;
+ var plyr = this;
+ plyr.container = container;
// Captions functions
// Seek the manual caption time and update UI
function _seekManualCaptions(time) {
// If it's not video, or we're using textTracks, bail.
- if (player.usingTextTracks || player.type !== 'video' || !player.supported.full) {
+ if (plyr.usingTextTracks || plyr.type !== 'video' || !plyr.supported.full) {
return;
}
// Reset subcount
- player.subcount = 0;
+ plyr.subcount = 0;
// Check time is a number, if not use currentTime
// IE has a bug where currentTime doesn't go to 0
// https://twitter.com/Sam_Potts/status/573715746506731521
- time = typeof time === 'number' ? time : player.media.currentTime;
+ time = typeof time === 'number' ? time : plyr.media.currentTime;
// If there's no subs available, bail
- if(!player.captions[player.subcount]) {
+ if(!plyr.captions[plyr.subcount]) {
return;
}
- while (_timecodeMax(player.captions[player.subcount][0]) < time.toFixed(1)) {
- player.subcount++;
- if (player.subcount > player.captions.length-1) {
- player.subcount = player.captions.length-1;
+ while (_timecodeMax(plyr.captions[plyr.subcount][0]) < time.toFixed(1)) {
+ plyr.subcount++;
+ if (plyr.subcount > plyr.captions.length-1) {
+ plyr.subcount = plyr.captions.length-1;
break;
}
}
// Check if the next caption is in the current time range
- if (player.media.currentTime.toFixed(1) >= _timecodeMin(player.captions[player.subcount][0]) &&
- player.media.currentTime.toFixed(1) <= _timecodeMax(player.captions[player.subcount][0])) {
- player.currentCaption = player.captions[player.subcount][1];
+ if (plyr.media.currentTime.toFixed(1) >= _timecodeMin(plyr.captions[plyr.subcount][0]) &&
+ plyr.media.currentTime.toFixed(1) <= _timecodeMax(plyr.captions[plyr.subcount][0])) {
+ plyr.currentCaption = plyr.captions[plyr.subcount][1];
// Trim caption text
- var content = player.currentCaption.trim();
+ var content = plyr.currentCaption.trim();
// Render the caption (only if changed)
- if (player.captionsContainer.innerHTML != content) {
+ if (plyr.captionsContainer.innerHTML != content) {
// Empty caption
// Otherwise NVDA reads it twice
- player.captionsContainer.innerHTML = '';
+ plyr.captionsContainer.innerHTML = '';
// Set new caption text
- player.captionsContainer.innerHTML = content;
+ plyr.captionsContainer.innerHTML = content;
}
}
else {
- player.captionsContainer.innerHTML = '';
+ plyr.captionsContainer.innerHTML = '';
}
}
// Display captions container and button (for initialization)
function _showCaptions() {
// If there's no caption toggle, bail
- if (!player.buttons.captions) {
+ if (!plyr.buttons.captions) {
return;
}
- _toggleClass(player.container, config.classes.captions.enabled, true);
+ _toggleClass(plyr.container, config.classes.captions.enabled, true);
if (config.captions.defaultActive) {
- _toggleClass(player.container, config.classes.captions.active, true);
- _toggleState(player.buttons.captions, true);
+ _toggleClass(plyr.container, config.classes.captions.active, true);
+ _toggleState(plyr.buttons.captions, true);
}
}
@@ -734,7 +742,7 @@
// Find all elements
function _getElements(selector) {
- return player.container.querySelectorAll(selector);
+ return plyr.container.querySelectorAll(selector);
}
// Find a single element
@@ -772,7 +780,7 @@
html = _replaceAll(html, '{id}', Math.floor(Math.random() * (10000)));
// Inject into the container
- player.container.insertAdjacentHTML('beforeend', html);
+ plyr.container.insertAdjacentHTML('beforeend', html);
// Setup tooltips
if (config.tooltips) {
@@ -790,44 +798,44 @@
// Find the UI controls and store references
function _findElements() {
try {
- player.controls = _getElement(config.selectors.controls);
+ plyr.controls = _getElement(config.selectors.controls);
// Buttons
- player.buttons = {};
- player.buttons.seek = _getElement(config.selectors.buttons.seek);
- player.buttons.play = _getElement(config.selectors.buttons.play);
- player.buttons.pause = _getElement(config.selectors.buttons.pause);
- player.buttons.restart = _getElement(config.selectors.buttons.restart);
- player.buttons.rewind = _getElement(config.selectors.buttons.rewind);
- player.buttons.forward = _getElement(config.selectors.buttons.forward);
- player.buttons.fullscreen = _getElement(config.selectors.buttons.fullscreen);
+ plyr.buttons = {};
+ plyr.buttons.seek = _getElement(config.selectors.buttons.seek);
+ plyr.buttons.play = _getElement(config.selectors.buttons.play);
+ plyr.buttons.pause = _getElement(config.selectors.buttons.pause);
+ plyr.buttons.restart = _getElement(config.selectors.buttons.restart);
+ plyr.buttons.rewind = _getElement(config.selectors.buttons.rewind);
+ plyr.buttons.forward = _getElement(config.selectors.buttons.forward);
+ plyr.buttons.fullscreen = _getElement(config.selectors.buttons.fullscreen);
// Inputs
- player.buttons.mute = _getElement(config.selectors.buttons.mute);
- player.buttons.captions = _getElement(config.selectors.buttons.captions);
- player.checkboxes = _getElements('[type="checkbox"]');
+ plyr.buttons.mute = _getElement(config.selectors.buttons.mute);
+ plyr.buttons.captions = _getElement(config.selectors.buttons.captions);
+ plyr.checkboxes = _getElements('[type="checkbox"]');
// Progress
- player.progress = {};
- player.progress.container = _getElement(config.selectors.progress.container);
+ plyr.progress = {};
+ plyr.progress.container = _getElement(config.selectors.progress.container);
// Progress - Buffering
- player.progress.buffer = {};
- player.progress.buffer.bar = _getElement(config.selectors.progress.buffer);
- player.progress.buffer.text = player.progress.buffer.bar && player.progress.buffer.bar.getElementsByTagName('span')[0];
+ plyr.progress.buffer = {};
+ plyr.progress.buffer.bar = _getElement(config.selectors.progress.buffer);
+ plyr.progress.buffer.text = plyr.progress.buffer.bar && plyr.progress.buffer.bar.getElementsByTagName('span')[0];
// Progress - Played
- player.progress.played = {};
- player.progress.played.bar = _getElement(config.selectors.progress.played);
- player.progress.played.text = player.progress.played.bar && player.progress.played.bar.getElementsByTagName('span')[0];
+ plyr.progress.played = {};
+ plyr.progress.played.bar = _getElement(config.selectors.progress.played);
+ plyr.progress.played.text = plyr.progress.played.bar && plyr.progress.played.bar.getElementsByTagName('span')[0];
// Volume
- player.volume = _getElement(config.selectors.buttons.volume);
+ plyr.volume = _getElement(config.selectors.buttons.volume);
// Timing
- player.duration = _getElement(config.selectors.duration);
- player.currentTime = _getElement(config.selectors.currentTime);
- player.seekTime = _getElements(config.selectors.seekTime);
+ plyr.duration = _getElement(config.selectors.duration);
+ plyr.currentTime = _getElement(config.selectors.currentTime);
+ plyr.seekTime = _getElements(config.selectors.seekTime);
return true;
}
@@ -835,7 +843,7 @@
_log('It looks like there\'s a problem with your controls html. Bailing.', true);
// Restore native video controls
- player.media.setAttribute('controls', '');
+ plyr.media.setAttribute('controls', '');
return false;
}
@@ -844,64 +852,64 @@
// Setup aria attribute for play
function _setupPlayAria() {
// If there's no play button, bail
- if (!player.buttons.play) {
+ if (!plyr.buttons.play) {
return;
}
// Find the current text
- var label = player.buttons.play.innerText || config.i18n.play;
+ var label = plyr.buttons.play.innerText || config.i18n.play;
// If there's a media title set, use that for the label
if (typeof(config.title) !== 'undefined' && config.title.length) {
label += ', ' + config.title;
}
- player.buttons.play.setAttribute('aria-label', label);
+ plyr.buttons.play.setAttribute('aria-label', label);
}
// Setup media
function _setupMedia() {
// If there's no media, bail
- if (!player.media) {
+ if (!plyr.media) {
_log('No audio or video element found!', true);
return false;
}
- if (player.supported.full) {
+ if (plyr.supported.full) {
// Remove native video controls
- player.media.removeAttribute('controls');
+ plyr.media.removeAttribute('controls');
// Add type class
- _toggleClass(player.container, config.classes.type.replace('{0}', player.type), true);
+ _toggleClass(plyr.container, config.classes.type.replace('{0}', plyr.type), true);
// If there's no autoplay attribute, assume the video is stopped and add state class
- _toggleClass(player.container, config.classes.stopped, config.autoplay);
+ _toggleClass(plyr.container, config.classes.stopped, config.autoplay);
// Add iOS class
- if (player.browser.ios) {
- _toggleClass(player.container, 'ios', true);
+ if (plyr.browser.ios) {
+ _toggleClass(plyr.container, 'ios', true);
}
// Inject the player wrapper
- if (player.type === 'video') {
+ if (plyr.type === 'video') {
// Create the wrapper div
var wrapper = document.createElement('div');
wrapper.setAttribute('class', config.classes.videoWrapper);
// Wrap the video in a container
- _wrap(player.media, wrapper);
+ _wrap(plyr.media, wrapper);
// Cache the container
- player.videoContainer = wrapper;
+ plyr.videoContainer = wrapper;
}
}
// Embeds
- if (_inArray(config.types.embed, player.type)) {
- _setupEmbed(player.embedId, player.type);
+ if (_inArray(config.types.embed, plyr.type)) {
+ _setupEmbed(plyr.embedId, plyr.type);
// Clean up
- player.embedId = null;
+ plyr.embedId = null;
}
else {
// Autoplay
@@ -914,10 +922,10 @@
// Setup YouTube/Vimeo
function _setupEmbed(videoId) {
var container = document.createElement('div'),
- id = player.type + '-' + Math.floor(Math.random() * (10000));
+ id = plyr.type + '-' + Math.floor(Math.random() * (10000));
// Remove old containers
- var containers = _getElements('[id^="' + player.type + '-"]');
+ var containers = _getElements('[id^="' + plyr.type + '-"]');
for (var i = containers.length - 1; i >= 0; i--) {
_remove(containers[i]);
}
@@ -926,13 +934,13 @@
container.setAttribute('id', id);
// Add embed class for responsive
- _toggleClass(player.media, config.classes.videoWrapper, true);
- _toggleClass(player.media, config.classes.embedWrapper, true);
+ _toggleClass(plyr.media, config.classes.videoWrapper, true);
+ _toggleClass(plyr.media, config.classes.embedWrapper, true);
// YouTube
- if (player.type === 'youtube') {
+ if (plyr.type === 'youtube') {
// Create the YouTube container
- player.media.appendChild(container);
+ plyr.media.appendChild(container);
// Setup API
if (typeof YT === 'object') {
@@ -940,14 +948,14 @@
}
else {
// Load the API
- _injectScript('https://www.youtube.com/iframe_api');
+ _injectScript(config.urls.youtube.api);
// Setup callback for the API
window.onYouTubeIframeAPIReady = function () { _youTubeReady(videoId, container); };
}
}
// Vimeo
- else if (player.type === 'vimeo') {
+ else if (plyr.type === 'vimeo') {
// Inject the iframe
var iframe = document.createElement('iframe');
@@ -964,7 +972,7 @@
'frameborder': 0
});
container.appendChild(iframe);
- player.media.appendChild(container);
+ plyr.media.appendChild(container);
// Setup API
if (typeof Froogaloop === 'function') {
@@ -972,7 +980,7 @@
}
else {
// Load the API
- _injectScript('https://rawgit.com/vimeo/player-api/master/javascript/froogaloop.js');
+ _injectScript(config.urls.vimeo.api);
// Wait for fragaloop load
var timer = window.setInterval(function() {
@@ -989,9 +997,9 @@
// When embeds are ready
function _embedReady() {
// Inject and update UI
- if (player.supported.full) {
+ if (plyr.supported.full) {
// Only setup controls once
- if (!player.container.querySelectorAll(config.selectors.controls).length) {
+ if (!plyr.container.querySelectorAll(config.selectors.controls).length) {
_setupInterface();
}
}
@@ -1005,17 +1013,17 @@
function _youTubeReady(videoId, container) {
// Setup timers object
// We have to poll YouTube for updates
- if (!('timer' in player)) {
- player.timer = {};
+ if (!('timer' in plyr)) {
+ plyr.timer = {};
}
// Setup instance
// https://developers.google.com/youtube/iframe_api_reference
- player.embed = new YT.Player(container.id, {
+ plyr.embed = new YT.Player(container.id, {
videoId: videoId,
playerVars: {
autoplay: (config.autoplay ? 1 : 0),
- controls: (player.supported.full ? 0 : 1),
+ controls: (plyr.supported.full ? 0 : 1),
rel: 0,
showinfo: 0,
iv_load_policy: 3,
@@ -1031,31 +1039,31 @@
var instance = event.target;
// Create a faux HTML5 API using the YouTube API
- player.media.play = function() { instance.playVideo(); };
- player.media.pause = function() { instance.pauseVideo(); };
- player.media.stop = function() { instance.stopVideo(); };
- player.media.duration = instance.getDuration();
- player.media.paused = !config.autoplay;
- player.media.currentTime = instance.getCurrentTime();
- player.media.muted = instance.isMuted();
+ plyr.media.play = function() { instance.playVideo(); };
+ plyr.media.pause = function() { instance.pauseVideo(); };
+ plyr.media.stop = function() { instance.stopVideo(); };
+ plyr.media.duration = instance.getDuration();
+ plyr.media.paused = !config.autoplay;
+ plyr.media.currentTime = instance.getCurrentTime();
+ plyr.media.muted = instance.isMuted();
// Trigger timeupdate
- _triggerEvent(player.media, 'timeupdate');
+ _triggerEvent(plyr.media, 'timeupdate');
// Reset timer
- window.clearInterval(player.timer.buffering);
+ window.clearInterval(plyr.timer.buffering);
// Setup buffering
- player.timer.buffering = window.setInterval(function() {
+ plyr.timer.buffering = window.setInterval(function() {
// Get loaded % from YouTube
- player.media.buffered = instance.getVideoLoadedFraction();
+ plyr.media.buffered = instance.getVideoLoadedFraction();
// Trigger progress
- _triggerEvent(player.media, 'progress');
+ _triggerEvent(plyr.media, 'progress');
// Bail if we're at 100%
- if (player.media.buffered === 1) {
- window.clearInterval(player.timer.buffering);
+ if (plyr.media.buffered === 1) {
+ window.clearInterval(plyr.timer.buffering);
}
}, 200);
@@ -1072,7 +1080,7 @@
var instance = event.target;
// Reset timer
- window.clearInterval(player.timer.playing);
+ window.clearInterval(plyr.timer.playing);
// Handle events
// -1 Unstarted
@@ -1083,28 +1091,28 @@
// 5 Video cued
switch (event.data) {
case 0:
- player.media.paused = true;
- _triggerEvent(player.media, 'ended');
+ plyr.media.paused = true;
+ _triggerEvent(plyr.media, 'ended');
break;
case 1:
- player.media.paused = false;
- _triggerEvent(player.media, 'play');
+ plyr.media.paused = false;
+ _triggerEvent(plyr.media, 'play');
// Poll to get playback progress
- player.timer.playing = window.setInterval(function() {
+ plyr.timer.playing = window.setInterval(function() {
// Set the current time
- player.media.currentTime = instance.getCurrentTime();
+ plyr.media.currentTime = instance.getCurrentTime();
// Trigger timeupdate
- _triggerEvent(player.media, 'timeupdate');
+ _triggerEvent(plyr.media, 'timeupdate');
}, 200);
break;
case 2:
- player.media.paused = true;
- _triggerEvent(player.media, 'pause');
+ plyr.media.paused = true;
+ _triggerEvent(plyr.media, 'pause');
}
}
}
@@ -1115,94 +1123,92 @@
function _vimeoReady() {
/* jshint validthis: true */
// Get the frame with fragaloop lib
- player.embed = $f(this);
+ plyr.embed = $f(this);
// Setup on ready
- player.embed.addEvent('ready', function() {
+ plyr.embed.addEvent('ready', function() {
// Create a faux HTML5 API using the Vimeo API
- player.media.play = function() { player.embed.api('play'); };
- player.media.pause = function() { player.embed.api('pause'); };
- player.media.stop = function() { player.embed.api('stop') };
- player.media.paused = !config.autoplay;
- player.media.currentTime = 0;
+ plyr.media.play = function() { plyr.embed.api('play'); };
+ plyr.media.pause = function() { plyr.embed.api('pause'); };
+ plyr.media.stop = function() { plyr.embed.api('stop') };
+ plyr.media.paused = !config.autoplay;
+ plyr.media.currentTime = 0;
// Update UI
_embedReady();
- player.embed.api('getCurrentTime', function (value) {
- player.media.currentTime = value;
+ plyr.embed.api('getCurrentTime', function (value) {
+ plyr.media.currentTime = value;
// Trigger timeupdate
- _triggerEvent(player.media, 'timeupdate');
+ _triggerEvent(plyr.media, 'timeupdate');
});
- player.embed.api('getDuration', function(value) {
- player.media.duration = value;
+ plyr.embed.api('getDuration', function(value) {
+ plyr.media.duration = value;
// Display duration if available
- if (player.supported.full && config.displayDuration) {
+ if (plyr.supported.full && config.displayDuration) {
_displayDuration();
}
});
- player.embed.addEvent('play', function() {
- console.log('play');
- player.media.paused = false;
- _triggerEvent(player.media, 'play');
+ plyr.embed.addEvent('play', function() {
+ plyr.media.paused = false;
+ _triggerEvent(plyr.media, 'play');
});
- player.embed.addEvent('pause', function() {
- console.log('pause');
- player.media.paused = true;
- _triggerEvent(player.media, 'pause');
+ plyr.embed.addEvent('pause', function() {
+ plyr.media.paused = true;
+ _triggerEvent(plyr.media, 'pause');
});
- player.embed.addEvent('playProgress', function(data) {
- player.media.currentTime = data.seconds;
- _triggerEvent(player.media, 'timeupdate');
+ plyr.embed.addEvent('playProgress', function(data) {
+ plyr.media.currentTime = data.seconds;
+ _triggerEvent(plyr.media, 'timeupdate');
});
- player.embed.addEvent('loadProgress', function(data) {
- player.media.buffered = data.percent;
- _triggerEvent(player.media, 'progress');
+ plyr.embed.addEvent('loadProgress', function(data) {
+ plyr.media.buffered = data.percent;
+ _triggerEvent(plyr.media, 'progress');
});
- player.embed.addEvent('finish', function() {
- player.media.paused = true;
- _triggerEvent(player.media, 'ended');
+ plyr.embed.addEvent('finish', function() {
+ plyr.media.paused = true;
+ _triggerEvent(plyr.media, 'ended');
});
/*// Always seek to 0
- player.embed.api('seekTo', 0);
+ plyr.embed.api('seekTo', 0);
// Prevent autoplay if needed (seek will play)
if (!config.autoplay) {
- player.embed.api('pause');
+ plyr.embed.api('pause');
}*/
});
}
// Setup captions
function _setupCaptions() {
- if (player.type === 'video') {
+ if (plyr.type === 'video') {
// Inject the container
if(!_getElement(config.selectors.captions)) {
- player.videoContainer.insertAdjacentHTML('afterbegin', '<div class="' + _getClassname(config.selectors.captions) + '"><span></span></div>');
+ plyr.videoContainer.insertAdjacentHTML('afterbegin', '<div class="' + _getClassname(config.selectors.captions) + '"><span></span></div>');
}
// Cache selector
- player.captionsContainer = _getElement(config.selectors.captions).querySelector('span');
+ plyr.captionsContainer = _getElement(config.selectors.captions).querySelector('span');
// Determine if HTML5 textTracks is supported
- player.usingTextTracks = false;
- if (player.media.textTracks) {
- player.usingTextTracks = true;
+ plyr.usingTextTracks = false;
+ if (plyr.media.textTracks) {
+ plyr.usingTextTracks = true;
}
// Get URL of caption file if exists
var captionSrc = '',
kind,
- children = player.media.childNodes;
+ children = plyr.media.childNodes;
for (var i = 0; i < children.length; i++) {
if (children[i].nodeName.toLowerCase() === 'track') {
@@ -1214,9 +1220,9 @@
}
// Record if caption file exists or not
- player.captionExists = true;
+ plyr.captionExists = true;
if (captionSrc === '') {
- player.captionExists = false;
+ plyr.captionExists = false;
_log('No caption track found.');
}
else {
@@ -1224,36 +1230,36 @@
}
// If no caption file exists, hide container for caption text
- if (!player.captionExists) {
- _toggleClass(player.container, config.classes.captions.enabled);
+ if (!plyr.captionExists) {
+ _toggleClass(plyr.container, config.classes.captions.enabled);
}
// If caption file exists, process captions
else {
// Turn off native caption rendering to avoid double captions
// This doesn't seem to work in Safari 7+, so the <track> elements are removed from the dom below
- var tracks = player.media.textTracks;
+ var tracks = plyr.media.textTracks;
for (var x = 0; x < tracks.length; x++) {
tracks[x].mode = 'hidden';
}
// Enable UI
- _showCaptions(player);
+ _showCaptions(plyr);
// Disable unsupported browsers than report false positive
- if ((player.browser.name === 'IE' && player.browser.version >= 10) ||
- (player.browser.name === 'Firefox' && player.browser.version >= 31) ||
- (player.browser.name === 'Chrome' && player.browser.version >= 43) ||
- (player.browser.name === 'Safari' && player.browser.version >= 7)) {
+ if ((plyr.browser.name === 'IE' && plyr.browser.version >= 10) ||
+ (plyr.browser.name === 'Firefox' && plyr.browser.version >= 31) ||
+ (plyr.browser.name === 'Chrome' && plyr.browser.version >= 43) ||
+ (plyr.browser.name === 'Safari' && plyr.browser.version >= 7)) {
// Debugging
_log('Detected unsupported browser for HTML5 captions. Using fallback.');
// Set to false so skips to 'manual' captioning
- player.usingTextTracks = false;
+ plyr.usingTextTracks = false;
}
// Rendering caption tracks
// Native support required - http://caniuse.com/webvtt
- if (player.usingTextTracks) {
+ if (plyr.usingTextTracks) {
_log('TextTracks supported.');
for (var y = 0; y < tracks.length; y++) {
@@ -1262,11 +1268,11 @@
if (track.kind === 'captions' || track.kind === 'subtitles') {
_on(track, 'cuechange', function() {
// Clear container
- player.captionsContainer.innerHTML = '';
+ plyr.captionsContainer.innerHTML = '';
// Display a cue, if there is one
if (this.activeCues[0] && this.activeCues[0].hasOwnProperty('text')) {
- player.captionsContainer.appendChild(this.activeCues[0].getCueAsHTML().trim());
+ plyr.captionsContainer.appendChild(this.activeCues[0].getCueAsHTML().trim());
}
});
}
@@ -1277,8 +1283,8 @@
_log('TextTracks not supported so rendering captions manually.');
// Render captions from array at appropriate time
- player.currentCaption = '';
- player.captions = [];
+ plyr.currentCaption = '';
+ plyr.captions = [];
if (captionSrc !== '') {
// Create XMLHttpRequest Object
@@ -1295,12 +1301,12 @@
for (var r = 0; r < records.length; r++) {
record = records[r];
- player.captions[r] = [];
- player.captions[r] = record.split('\n');
+ plyr.captions[r] = [];
+ plyr.captions[r] = record.split('\n');
}
// Remove first element ('VTT')
- player.captions.shift();
+ plyr.captions.shift();
_log('Successfully loaded the caption file via AJAX.');
}
@@ -1317,15 +1323,15 @@
}
// If Safari 7+, removing track from DOM [see 'turn off native caption rendering' above]
- if (player.browser.name === 'Safari' && player.browser.version >= 7) {
+ if (plyr.browser.name === 'Safari' && plyr.browser.version >= 7) {
_log('Safari 7+ detected; removing track from DOM.');
// Find all <track> elements
- tracks = player.media.getElementsByTagName('track');
+ tracks = plyr.media.getElementsByTagName('track');
// Loop through and remove one by one
for (var t = 0; t < tracks.length; t++) {
- player.media.removeChild(tracks[t]);
+ plyr.media.removeChild(tracks[t]);
}
}
}
@@ -1334,7 +1340,7 @@
// Setup fullscreen
function _setupFullscreen() {
- if (player.type != 'audio' && config.fullscreen.enabled) {
+ if (plyr.type != 'audio' && config.fullscreen.enabled) {
// Check for native support
var nativeSupport = fullscreen.supportsFullScreen;
@@ -1342,30 +1348,30 @@
_log((nativeSupport ? 'Native' : 'Fallback') + ' fullscreen enabled.');
// Add styling hook
- _toggleClass(player.container, config.classes.fullscreen.enabled, true);
+ _toggleClass(plyr.container, config.classes.fullscreen.enabled, true);
}
else {
_log('Fullscreen not supported and fallback disabled.');
}
// Toggle state
- _toggleState(player.buttons.fullscreen, false);
+ _toggleState(plyr.buttons.fullscreen, false);
// Set control hide class hook
if (config.fullscreen.hideControls) {
- _toggleClass(player.container, config.classes.fullscreen.hideControls, true);
+ _toggleClass(plyr.container, config.classes.fullscreen.hideControls, true);
}
}
}
// Play media
function _play() {
- player.media.play();
+ plyr.media.play();
}
// Pause media
function _pause() {
- player.media.pause();
+ plyr.media.pause();
}
// Toggle playback
@@ -1380,7 +1386,7 @@
}
// True toggle
else {
- player.media[player.media.paused ? 'play' : 'pause']();
+ plyr.media[plyr.media.paused ? 'play' : 'pause']();
}
}
@@ -1390,7 +1396,7 @@
if (typeof seekTime !== 'number') {
seekTime = config.seekTime;
}
- _seek(player.media.currentTime - seekTime);
+ _seek(plyr.media.currentTime - seekTime);
}
// Fast forward
@@ -1399,14 +1405,14 @@
if (typeof seekTime !== 'number') {
seekTime = config.seekTime;
}
- _seek(player.media.currentTime + seekTime);
+ _seek(plyr.media.currentTime + seekTime);
}
// Seek to time
// The input parameter can be an event or a number
function _seek(input) {
var targetTime = 0,
- paused = player.media.paused;
+ paused = plyr.media.paused;
// Explicit position
if (typeof input === 'number') {
@@ -1416,38 +1422,38 @@
else if (typeof input === 'object' && (input.type === 'input' || input.type === 'change')) {
// It's the seek slider
// Seek to the selected time
- targetTime = ((input.target.value / input.target.max) * player.media.duration);
+ targetTime = ((input.target.value / input.target.max) * plyr.media.duration);
}
// Normalise targetTime
if (targetTime < 0) {
targetTime = 0;
}
- else if (targetTime > player.media.duration) {
- targetTime = player.media.duration;
+ else if (targetTime > plyr.media.duration) {
+ targetTime = plyr.media.duration;
}
// Set the current time
// Try/catch incase the media isn't set and we're calling seek() from source() and IE moans
try {
- player.media.currentTime = targetTime.toFixed(1);
+ plyr.media.currentTime = targetTime.toFixed(1);
}
catch(e) {}
// Trigger timeupdate for embed and restore pause state
- if ('embed' in player) {
+ if ('embed' in plyr) {
// YouTube
- if (player.type === 'youtube') {
- player.embed.seekTo(targetTime);
+ if (plyr.type === 'youtube') {
+ plyr.embed.seekTo(targetTime);
}
// Vimeo
- if (player.type === 'vimeo') {
- player.embed.api('seekTo', targetTime);
+ if (plyr.type === 'vimeo') {
+ plyr.embed.api('seekTo', targetTime);
}
// Trigger timeupdate
- _triggerEvent(player.media, 'timeupdate');
+ _triggerEvent(plyr.media, 'timeupdate');
if (paused) {
_pause();
@@ -1455,7 +1461,7 @@
}
// Logging
- _log('Seeking to ' + player.media.currentTime + ' seconds');
+ _log('Seeking to ' + plyr.media.currentTime + ' seconds');
// Special handling for 'manual' captions
_seekManualCaptions(targetTime);
@@ -1463,8 +1469,8 @@
// Check playing state
function _checkPlaying() {
- _toggleClass(player.container, config.classes.playing, !player.media.paused);
- _toggleClass(player.container, config.classes.stopped, player.media.paused);
+ _toggleClass(plyr.container, config.classes.playing, !plyr.media.paused);
+ _toggleClass(plyr.container, config.classes.stopped, plyr.media.paused);
}
// Toggle fullscreen
@@ -1474,13 +1480,13 @@
// If it's a fullscreen change event, it's probably a native close
if (event && event.type === fullscreen.fullScreenEventName) {
- player.isFullscreen = fullscreen.isFullScreen(player.container);
+ plyr.isFullscreen = fullscreen.isFullScreen(plyr.container);
}
// If there's native support, use it
else if (nativeSupport) {
// Request fullscreen
- if (!fullscreen.isFullScreen(player.container)) {
- fullscreen.requestFullScreen(player.container);
+ if (!fullscreen.isFullScreen(plyr.container)) {
+ fullscreen.requestFullScreen(plyr.container);
}
// Bail from fullscreen
else {
@@ -1488,14 +1494,14 @@
}
// Check if we're actually full screen (it could fail)
- player.isFullscreen = fullscreen.isFullScreen(player.container);
+ plyr.isFullscreen = fullscreen.isFullScreen(plyr.container);
}
else {
// Otherwise, it's a simple toggle
- player.isFullscreen = !player.isFullscreen;
+ plyr.isFullscreen = !plyr.isFullscreen;
// Bind/unbind escape key
- if (player.isFullscreen) {
+ if (plyr.isFullscreen) {
_on(document, 'keyup', _handleEscapeFullscreen);
document.body.style.overflow = 'hidden';
}
@@ -1506,10 +1512,10 @@
}
// Set class hook
- _toggleClass(player.container, config.classes.fullscreen.active, player.isFullscreen);
+ _toggleClass(plyr.container, config.classes.fullscreen.active, plyr.isFullscreen);
// Set button state
- _toggleState(player.buttons.fullscreen, player.isFullscreen);
+ _toggleState(plyr.buttons.fullscreen, plyr.isFullscreen);
// Toggle controls visibility based on mouse movement and location
var hoverTimer, isMouseOver = false;
@@ -1517,7 +1523,7 @@
// Show the player controls
function _showControls() {
// Set shown class
- _toggleClass(player.container, config.classes.hover, true);
+ _toggleClass(plyr.container, config.classes.hover, true);
// Clear timer every movement
window.clearTimeout(hoverTimer);
@@ -1525,7 +1531,7 @@
// If the mouse is not over the controls, set a timeout to hide them
if (!isMouseOver) {
hoverTimer = window.setTimeout(function() {
- _toggleClass(player.container, config.classes.hover, false);
+ _toggleClass(plyr.container, config.classes.hover, false);
}, 2000);
}
}
@@ -1537,20 +1543,20 @@
if (config.fullscreen.hideControls) {
// Hide on entering full screen
- _toggleClass(player.controls, config.classes.hover, false);
+ _toggleClass(plyr.controls, config.classes.hover, false);
// Keep an eye on the mouse location in relation to controls
- _toggleHandler(player.controls, 'mouseenter mouseleave', _setMouseOver, player.isFullscreen);
+ _toggleHandler(plyr.controls, 'mouseenter mouseleave', _setMouseOver, plyr.isFullscreen);
// Show the controls on mouse move
- _toggleHandler(player.container, 'mousemove', _showControls, player.isFullscreen);
+ _toggleHandler(plyr.container, 'mousemove', _showControls, plyr.isFullscreen);
}
}
// Bail from faux-fullscreen
function _handleEscapeFullscreen(event) {
// If it's a keypress and not escape, bail
- if ((event.which || event.charCode || event.keyCode) === 27 && player.isFullscreen) {
+ if ((event.which || event.charCode || event.keyCode) === 27 && plyr.isFullscreen) {
_toggleFullscreen();
}
}
@@ -1559,21 +1565,21 @@
function _toggleMute(muted) {
// If the method is called without parameter, toggle based on current value
if (typeof muted !== 'boolean') {
- muted = !player.media.muted;
+ muted = !plyr.media.muted;
}
// Set button state
- _toggleState(player.buttons.mute, muted);
+ _toggleState(plyr.buttons.mute, muted);
// Set mute on the player
- player.media.muted = muted;
+ plyr.media.muted = muted;
// YouTube
- if (player.type === 'youtube') {
- player.embed[player.media.muted ? 'mute' : 'unMute']();
+ if (plyr.type === 'youtube') {
+ plyr.embed[plyr.media.muted ? 'mute' : 'unMute']();
// Trigger timeupdate
- _triggerEvent(player.media, 'volumechange');
+ _triggerEvent(plyr.media, 'volumechange');
}
}
@@ -1599,28 +1605,28 @@
}
// Set the player volume
- player.media.volume = parseFloat(volume / 10);
+ plyr.media.volume = parseFloat(volume / 10);
// Store in config
config.volume = volume;
// YouTube
- if (player.type === 'youtube') {
- player.embed.setVolume(player.media.volume * 100);
+ if (plyr.type === 'youtube') {
+ plyr.embed.setVolume(plyr.media.volume * 100);
}
// Vimeo
- if (player.type === 'vimeo') {
- player.embed.api('setVolume', player.media.volume);
+ if (plyr.type === 'vimeo') {
+ plyr.embed.api('setVolume', plyr.media.volume);
}
// Trigger volumechange for embeds
- if ('embed' in player) {
- _triggerEvent(player.media, 'volumechange');
+ if ('embed' in plyr) {
+ _triggerEvent(plyr.media, 'volumechange');
}
// Toggle muted state
- if (player.media.muted && volume > 0) {
+ if (plyr.media.muted && volume > 0) {
_toggleMute();
}
}
@@ -1628,11 +1634,11 @@
// Update volume UI and storage
function _updateVolume() {
// Get the current volume
- var volume = player.media.muted ? 0 : (player.media.volume * 10);
+ var volume = plyr.media.muted ? 0 : (plyr.media.volume * 10);
// Update the <input type="range"> if present
- if (player.supported.full && player.volume) {
- player.volume.value = volume;
+ if (plyr.supported.full && plyr.volume) {
+ plyr.volume.value = volume;
}
// Store the volume in storage
@@ -1641,31 +1647,31 @@
}
// Toggle class if muted
- _toggleClass(player.container, config.classes.muted, (volume === 0));
+ _toggleClass(plyr.container, config.classes.muted, (volume === 0));
// Update checkbox for mute state
- if (player.supported.full && player.buttons.mute) {
- _toggleState(player.buttons.mute, (volume === 0));
+ if (plyr.supported.full && plyr.buttons.mute) {
+ _toggleState(plyr.buttons.mute, (volume === 0));
}
}
// Toggle captions
function _toggleCaptions(show) {
// If there's no full support, or there's no caption toggle
- if (!player.supported.full || !player.buttons.captions) {
+ if (!plyr.supported.full || !plyr.buttons.captions) {
return;
}
// If the method is called without parameter, toggle based on current value
if (typeof show !== 'boolean') {
- show = (player.container.className.indexOf(config.classes.captions.active) === -1);
+ show = (plyr.container.className.indexOf(config.classes.captions.active) === -1);
}
// Toggle state
- _toggleState(player.buttons.captions, show);
+ _toggleState(plyr.buttons.captions, show);
// Add class hook
- _toggleClass(player.container, config.classes.captions.active, show);
+ _toggleClass(plyr.container, config.classes.captions.active, show);
}
// Check if media is loading
@@ -1673,18 +1679,18 @@
var loading = (event.type === 'waiting');
// Clear timer
- clearTimeout(player.loadingTimer);
+ clearTimeout(plyr.loadingTimer);
// Timer to prevent flicker when seeking
- player.loadingTimer = setTimeout(function() {
- _toggleClass(player.container, config.classes.loading, loading);
+ plyr.loadingTimer = setTimeout(function() {
+ _toggleClass(plyr.container, config.classes.loading, loading);
}, (loading ? 250 : 0));
}
// Update <progress> elements
function _updateProgress(event) {
- var progress = player.progress.played.bar,
- text = player.progress.played.text,
+ var progress = plyr.progress.played.bar,
+ text = plyr.progress.played.text,
value = 0;
if (event) {
@@ -1692,11 +1698,11 @@
// Video playing
case 'timeupdate':
case 'seeking':
- value = _getPercentage(player.media.currentTime, player.media.duration);
+ value = _getPercentage(plyr.media.currentTime, plyr.media.duration);
// Set seek range value only if it's a 'natural' time event
- if (event.type == 'timeupdate' && player.buttons.seek) {
- player.buttons.seek.value = value;
+ if (event.type == 'timeupdate' && plyr.buttons.seek) {
+ plyr.buttons.seek.value = value;
}
break;
@@ -1711,14 +1717,14 @@
// Check buffer status
case 'playing':
case 'progress':
- progress = player.progress.buffer.bar;
- text = player.progress.buffer.text;
+ progress = plyr.progress.buffer.bar;
+ text = plyr.progress.buffer.text;
value = (function() {
- var buffered = player.media.buffered;
+ var buffered = plyr.media.buffered;
// HTML5
if (buffered && buffered.length) {
- return _getPercentage(buffered.end(0), player.media.duration);
+ return _getPercentage(buffered.end(0), plyr.media.duration);
}
// YouTube returns between 0 and 1
else if (typeof buffered === 'number') {
@@ -1751,66 +1757,53 @@
time = 0;
}
- player.secs = parseInt(time % 60);
- player.mins = parseInt((time / 60) % 60);
- player.hours = parseInt(((time / 60) / 60) % 60);
+ plyr.secs = parseInt(time % 60);
+ plyr.mins = parseInt((time / 60) % 60);
+ plyr.hours = parseInt(((time / 60) / 60) % 60);
// Do we need to display hours?
- var displayHours = (parseInt(((player.media.duration / 60) / 60) % 60) > 0);
+ var displayHours = (parseInt(((plyr.media.duration / 60) / 60) % 60) > 0);
// Ensure it's two digits. For example, 03 rather than 3.
- player.secs = ('0' + player.secs).slice(-2);
- player.mins = ('0' + player.mins).slice(-2);
+ plyr.secs = ('0' + plyr.secs).slice(-2);
+ plyr.mins = ('0' + plyr.mins).slice(-2);
// Render
- element.innerHTML = (displayHours ? player.hours + ':' : '') + player.mins + ':' + player.secs;
+ element.innerHTML = (displayHours ? plyr.hours + ':' : '') + plyr.mins + ':' + plyr.secs;
}
// Show the duration on metadataloaded
function _displayDuration() {
- var duration = player.media.duration || 0;
+ var duration = plyr.media.duration || 0;
// If there's only one time display, display duration there
- if (!player.duration && config.displayDuration && player.media.paused) {
- _updateTimeDisplay(duration, player.currentTime);
+ if (!plyr.duration && config.displayDuration && plyr.media.paused) {
+ _updateTimeDisplay(duration, plyr.currentTime);
}
// If there's a duration element, update content
- if (player.duration) {
- _updateTimeDisplay(duration, player.duration);
+ if (plyr.duration) {
+ _updateTimeDisplay(duration, plyr.duration);
}
}
// Handle time change event
function _timeUpdate(event) {
// Duration
- _updateTimeDisplay(player.media.currentTime, player.currentTime);
+ _updateTimeDisplay(plyr.media.currentTime, plyr.currentTime);
// Playing progress
_updateProgress(event);
}
- // Add a source element
- function _addSource(attributes) {
- _insertElement('source', player.media, attributes);
- }
-
- // Add a source element
- function _addTracks(tracks) {
- for (var i = tracks.length - 1; i >= 0; i--) {
- _insertElement('track', player.media, tracks[i]);
+ // Add elements to HTML5 media (source, tracks, etc)
+ function _insertChildElements(type, attributes) {
+ if(typeof attributes === 'string') {
+ _insertElement(type, plyr.media, { src: attributes });
}
- }
-
- // Add sources to HTML5 media
- function _addSources(sources) {
- // Set new sources
- if(typeof sources === 'string') {
- _addSource({ src: sources });
- }
- else if(sources.constructor === Array) {
- for (var i = sources.length - 1; i >= 0; i--) {
- _addSource(sources[i]);
+ else if(attributes.constructor === Array) {
+ for (var i = attributes.length - 1; i >= 0; i--) {
+ _insertElement(type, plyr.media, attributes[i]);
}
}
}
@@ -1826,77 +1819,77 @@
_pause();
// Clean up YouTube stuff
- if(player.type === 'youtube') {
+ if(plyr.type === 'youtube') {
// Destroy the embed instance
- player.embed.destroy();
+ plyr.embed.destroy();
// Clear timer
- window.clearInterval(player.timer.buffering);
- window.clearInterval(player.timer.playing);
+ window.clearInterval(plyr.timer.buffering);
+ window.clearInterval(plyr.timer.playing);
}
- else if (player.type === 'video') {
+ else if (plyr.type === 'video') {
// Remove video wrapper
- _remove(player.videoContainer);
+ _remove(plyr.videoContainer);
}
// Remove the old media
- _remove(player.media);
+ _remove(plyr.media);
// Set the new type
- if('type' in source && source.type !== player.type) {
- player.type = source.type;
+ if('type' in source && source.type !== plyr.type) {
+ plyr.type = source.type;
}
// Create new markup
- switch(player.type) {
+ switch(plyr.type) {
case 'video':
- player.media = document.createElement('video');
+ plyr.media = document.createElement('video');
break;
case 'audio':
- player.media = document.createElement('audio');
+ plyr.media = document.createElement('audio');
break;
case 'youtube':
case 'vimeo':
- player.media = document.createElement('div');
- player.embedId = source.sources;
+ plyr.media = document.createElement('div');
+ plyr.embedId = source.sources;
break;
}
// Inject the new element
- _prependChild(player.container, player.media);
+ _prependChild(plyr.container, plyr.media);
// Set attributes for audio video
- if(_inArray(config.types.html5, player.type)) {
+ if(_inArray(config.types.html5, plyr.type)) {
if(config.crossorigin) {
- player.media.setAttribute('crossorigin', '');
+ plyr.media.setAttribute('crossorigin', '');
}
if (config.autoplay) {
- player.media.setAttribute('autoplay', '');
+ plyr.media.setAttribute('autoplay', '');
}
if ('poster' in source) {
- player.media.setAttribute('poster', source.poster);
+ plyr.media.setAttribute('poster', source.poster);
}
if (config.loop) {
- player.media.setAttribute('loop', '');
+ plyr.media.setAttribute('loop', '');
}
}
// Classname reset
- player.container.className = _getClassname(config.selectors.container);
+ plyr.container.className = plyr.originalClassName;
// Autoplay the new source?
config.autoplay = (source.autoplay || config.autoplay);
// Set media id for embeds
- if(_inArray(config.types.embed, player.type)) {
- player.embedId = source.sources;
+ if(_inArray(config.types.embed, plyr.type)) {
+ plyr.embedId = source.sources;
}
- // Set new sources and tracks for html5
- if(_inArray(config.types.html5, player.type)) {
- _addSources(source.sources);
+ // Set new sources for html5
+ if(_inArray(config.types.html5, plyr.type)) {
+ _insertChildElements('source', source.sources);
}
// Set up from scratch
@@ -1906,13 +1899,13 @@
_mediaUpdated();
// HTML5 stuff
- if(_inArray(config.types.html5, player.type)) {
+ if(_inArray(config.types.html5, plyr.type)) {
// Set volume
_setVolume();
_updateVolume();
// UI updates
- if(player.supported.full) {
+ if(plyr.supported.full) {
// Reset time display
_timeUpdate();
@@ -1922,14 +1915,14 @@
// Setup captions
if('tracks' in source) {
- _addTracks(source.tracks);
+ _insertChildElements('track', source.tracks);
// Captions
_setupCaptions();
}
// Load HTML5 sources
- player.media.load();
+ plyr.media.load();
// Play if autoplay attribute is present
if (config.autoplay) {
@@ -1945,15 +1938,15 @@
// Update poster
function _updatePoster(source) {
- if (player.type === 'video') {
- player.media.setAttribute('poster', source);
+ if (plyr.type === 'video') {
+ plyr.media.setAttribute('poster', source);
}
}
// Listen for events
function _listeners() {
// IE doesn't support input event, so we fallback to change
- var inputEvent = (player.browser.name == 'IE' ? 'change' : 'input');
+ var inputEvent = (plyr.browser.name == 'IE' ? 'change' : 'input');
// Detect tab focus
function checkFocus() {
@@ -1964,8 +1957,8 @@
else if (document.querySelector) {
focused = document.querySelector(':focus');
}
- for (var button in player.buttons) {
- var element = player.buttons[button];
+ for (var button in plyr.buttons) {
+ var element = plyr.buttons[button];
_toggleClass(element, 'tab-focus', (element === focused));
}
@@ -1977,8 +1970,8 @@
checkFocus();
}
});
- for (var button in player.buttons) {
- var element = player.buttons[button];
+ for (var button in plyr.buttons) {
+ var element = plyr.buttons[button];
_on(element, 'blur', function() {
_toggleClass(element, 'tab-focus', false);
@@ -1986,39 +1979,39 @@
}
// Play
- _on(player.buttons.play, 'click', function() {
+ _on(plyr.buttons.play, 'click', function() {
_play();
- setTimeout(function() { player.buttons.pause.focus(); }, 100);
+ setTimeout(function() { plyr.buttons.pause.focus(); }, 100);
});
// Pause
- _on(player.buttons.pause, 'click', function() {
+ _on(plyr.buttons.pause, 'click', function() {
_pause();
- setTimeout(function() { player.buttons.play.focus(); }, 100);
+ setTimeout(function() { plyr.buttons.play.focus(); }, 100);
});
// Restart
- _on(player.buttons.restart, 'click', _seek);
+ _on(plyr.buttons.restart, 'click', _seek);
// Rewind
- _on(player.buttons.rewind, 'click', _rewind);
+ _on(plyr.buttons.rewind, 'click', _rewind);
// Fast forward
- _on(player.buttons.forward, 'click', _forward);
+ _on(plyr.buttons.forward, 'click', _forward);
// Seek
- _on(player.buttons.seek, inputEvent, _seek);
+ _on(plyr.buttons.seek, inputEvent, _seek);
// Set volume
- _on(player.volume, inputEvent, function() {
+ _on(plyr.volume, inputEvent, function() {
_setVolume(this.value);
});
// Mute
- _on(player.buttons.mute, 'click', _toggleMute);
+ _on(plyr.buttons.mute, 'click', _toggleMute);
// Fullscreen
- _on(player.buttons.fullscreen, 'click', _toggleFullscreen);
+ _on(plyr.buttons.fullscreen, 'click', _toggleFullscreen);
// Handle user exiting fullscreen by escaping etc
if (fullscreen.supportsFullScreen) {
@@ -2026,22 +2019,22 @@
}
// Time change on media
- _on(player.media, 'timeupdate seeking', _timeUpdate);
+ _on(plyr.media, 'timeupdate seeking', _timeUpdate);
// Update manual captions
- _on(player.media, 'timeupdate', _seekManualCaptions);
+ _on(plyr.media, 'timeupdate', _seekManualCaptions);
// Display duration
- _on(player.media, 'loadedmetadata', _displayDuration);
+ _on(plyr.media, 'loadedmetadata', _displayDuration);
// Captions
- _on(player.buttons.captions, 'click', _toggleCaptions);
+ _on(plyr.buttons.captions, 'click', _toggleCaptions);
// Handle the media finishing
- _on(player.media, 'ended', function() {
+ _on(plyr.media, 'ended', function() {
// Clear
- if (player.type === 'video') {
- player.captionsContainer.innerHTML = '';
+ if (plyr.type === 'video') {
+ plyr.captionsContainer.innerHTML = '';
}
// Reset UI
@@ -2049,29 +2042,29 @@
});
// Check for buffer progress
- _on(player.media, 'progress playing', _updateProgress);
+ _on(plyr.media, 'progress playing', _updateProgress);
// Handle native mute
- _on(player.media, 'volumechange', _updateVolume);
+ _on(plyr.media, 'volumechange', _updateVolume);
// Handle native play/pause
- _on(player.media, 'play pause', _checkPlaying);
+ _on(plyr.media, 'play pause', _checkPlaying);
// Loading
- _on(player.media, 'waiting canplay seeked', _checkLoading);
+ _on(plyr.media, 'waiting canplay seeked', _checkLoading);
// Click video
- if (player.type === 'video' && config.click) {
- _on(player.videoContainer, 'click', function() {
- if (player.media.paused) {
- _triggerEvent(player.buttons.play, 'click');
+ if (plyr.type === 'video' && config.click) {
+ _on(plyr.videoContainer, 'click', function() {
+ if (plyr.media.paused) {
+ _triggerEvent(plyr.buttons.play, 'click');
}
- else if (player.media.ended) {
+ else if (plyr.media.ended) {
_seek();
- _triggerEvent(player.buttons.play, 'click');
+ _triggerEvent(plyr.buttons.play, 'click');
}
else {
- _triggerEvent(player.buttons.pause, 'click');
+ _triggerEvent(plyr.buttons.pause, 'click');
}
});
}
@@ -2082,47 +2075,47 @@
// http://stackoverflow.com/questions/12528049/if-a-dom-element-is-removed-are-its-listeners-also-removed-from-memory
function _destroy() {
// Bail if the element is not initialized
- if (!player.init) {
+ if (!plyr.init) {
return null;
}
// Reset container classname
- player.container.setAttribute('class', _getClassname(config.selectors.container));
+ plyr.container.setAttribute('class', _getClassname(config.selectors.container));
// Remove init flag
- player.init = false;
+ plyr.init = false;
// Remove controls
_remove(_getElement(config.selectors.controls));
// YouTube
- if (player.type === 'youtube') {
- player.embed.destroy();
+ if (plyr.type === 'youtube') {
+ plyr.embed.destroy();
return;
}
// If video, we need to remove some more
- if (player.type === 'video') {
+ if (plyr.type === 'video') {
// Remove captions
_remove(_getElement(config.selectors.captions));
// Remove video wrapper
- _unwrap(player.videoContainer);
+ _unwrap(plyr.videoContainer);
}
// Restore native video controls
- player.media.setAttribute('controls', '');
+ plyr.media.setAttribute('controls', '');
// Clone the media element to remove listeners
// http://stackoverflow.com/questions/19469881/javascript-remove-all-event-listeners-of-specific-type
- var clone = player.media.cloneNode(true);
- player.media.parentNode.replaceChild(clone, player.media);
+ var clone = plyr.media.cloneNode(true);
+ plyr.media.parentNode.replaceChild(clone, plyr.media);
}
// Setup a player
function _init() {
// Bail if the element is initialized
- if (player.init) {
+ if (plyr.init) {
return null;
}
@@ -2130,49 +2123,52 @@
fullscreen = _fullscreen();
// Sniff out the browser
- player.browser = _browserSniff();
+ plyr.browser = _browserSniff();
// Get the media element
- player.media = player.container.querySelectorAll('audio, video, div')[0];
+ plyr.media = plyr.container.querySelectorAll('audio, video, div')[0];
+
+ // Get original classname
+ plyr.originalClassName = plyr.container.className;
// Set media type based on tag or data attribute
// Supported: video, audio, vimeo, youtube
- var tagName = player.media.tagName.toLowerCase();
+ var tagName = plyr.media.tagName.toLowerCase();
if (tagName === 'div') {
- player.type = player.media.getAttribute('data-type');
- player.embedId = player.media.getAttribute('data-video-id');
+ plyr.type = plyr.media.getAttribute('data-type');
+ plyr.embedId = plyr.media.getAttribute('data-video-id');
// Clean up
- player.media.removeAttribute('data-type');
- player.media.removeAttribute('data-video-id');
+ plyr.media.removeAttribute('data-type');
+ plyr.media.removeAttribute('data-video-id');
}
else {
- player.type = tagName;
- config.crossorigin = (player.media.getAttribute('crossorigin') !== null);
- config.autoplay = (config.autoplay || (player.media.getAttribute('autoplay') !== null));
- config.loop = (config.loop || (player.media.getAttribute('loop') !== null));
+ plyr.type = tagName;
+ config.crossorigin = (plyr.media.getAttribute('crossorigin') !== null);
+ config.autoplay = (config.autoplay || (plyr.media.getAttribute('autoplay') !== null));
+ config.loop = (config.loop || (plyr.media.getAttribute('loop') !== null));
}
// Check for full support
- player.supported = api.supported(player.type);
+ plyr.supported = api.supported(plyr.type);
// If no native support, bail
- if (!player.supported.basic) {
+ if (!plyr.supported.basic) {
return false;
}
// Debug info
- _log(player.browser.name + ' ' + player.browser.version);
+ _log(plyr.browser.name + ' ' + plyr.browser.version);
// Setup media
_setupMedia();
// Setup interface
- if (player.type == 'video' || player.type == 'audio') {
+ if (plyr.type == 'video' || plyr.type == 'audio') {
// Bail if no support
- if (!player.supported.full) {
+ if (!plyr.supported.full) {
// Successful setup
- player.init = true;
+ plyr.init = true;
// Don't inject controls if no full support
return;
@@ -2191,7 +2187,7 @@
}
// Successful setup
- player.init = true;
+ plyr.init = true;
}
function _setupInterface() {
@@ -2226,12 +2222,12 @@
_init();
// If init failed, return an empty object
- if (!player.init) {
+ if (!plyr.init) {
return {};
}
return {
- media: player.media,
+ media: plyr.media,
play: _play,
pause: _pause,
restart: _seek,
@@ -2245,8 +2241,8 @@
toggleMute: _toggleMute,
toggleCaptions: _toggleCaptions,
toggleFullscreen: _toggleFullscreen,
- isFullscreen: function() { return player.isFullscreen || false; },
- support: function(mimeType) { return _supportMime(player, mimeType); },
+ isFullscreen: function() { return plyr.isFullscreen || false; },
+ support: function(mimeType) { return _supportMime(plyr, mimeType); },
destroy: _destroy,
restore: _init
};
@@ -2290,7 +2286,30 @@
};
// Expose setup function
- api.setup = function(options) {
+ api.setup = function(elements, options) {
+ // Get the players
+ var instances = [];
+
+ // Select the elements
+ // Assume elements is a NodeList by default
+ if(typeof elements === 'string') {
+ elements = document.querySelectorAll(elements);
+ }
+ // Single HTMLElement passed
+ else if(elements instanceof HTMLElement) {
+ elements = [elements];
+ }
+ // No selector passed, possibly options as first argument
+ else if (!(elements instanceof NodeList) && typeof elements !== 'string') {
+ // If options are the first argument
+ if(typeof options === 'undefined' && typeof elements === 'object') {
+ options = elements;
+ }
+
+ // Use default selector
+ elements = document.querySelectorAll(defaults.selectors.container);
+ }
+
// Extend the default options with user specified
config = _extend(defaults, options);
@@ -2300,10 +2319,6 @@
return false;
}
- // Get the players
- var elements = document.querySelectorAll(config.selectors.container),
- players = [];
-
// Create a player instance for each element
for (var i = elements.length - 1; i >= 0; i--) {
// Get the current element
@@ -2324,10 +2339,10 @@
}
// Add to return array even if it's already setup
- players.push(element.plyr);
+ instances.push(element.plyr);
}
- return players;
+ return instances;
};
}(this.plyr = this.plyr || {}));
diff --git a/src/less/plyr.less b/src/less/plyr.less
index ad393c18..72217a88 100644
--- a/src/less/plyr.less
+++ b/src/less/plyr.less
@@ -144,7 +144,7 @@
// Styles
// -------------------------------
// Base
-.player {
+.plyr {
position: relative;
max-width: 100%;
min-width: 290px;
@@ -227,7 +227,7 @@
font-size: @font-size-captions-large;
}
- // Player controls
+ // Plyr controls
&-controls {
.clearfix();
.font-smoothing();
@@ -294,8 +294,8 @@
display: none;
}
- // Player time
- .player-time {
+ // plyr time
+ .plyr-time {
display: inline-block;
vertical-align: middle;
margin-left: @control-spacing;
@@ -306,7 +306,7 @@
}
// Media duration hidden on small screens
- .player-time + .player-time {
+ .plyr-time + .plyr-time {
display: none;
@media (min-width: @bp-control-split) {
@@ -358,16 +358,16 @@
border-width: 0 1px 1px 0;
}
}
- button:hover .player-tooltip,
- button.tab-focus:focus .player-tooltip {
+ button:hover .plyr-tooltip,
+ button.tab-focus:focus .plyr-tooltip {
opacity: 1;
transform: translate(-50%, 0) scale(1);
}
- button:hover .player-tooltip {
+ button:hover .plyr-tooltip {
z-index: 3;
}
- // Player progress
+ // Playback progress
// <progress> element
&-progress {
position: absolute;
@@ -466,7 +466,7 @@
}
// Loading state
- &.loading .player-progress-buffer {
+ &.loading .plyr-progress-buffer {
animation: progress 1s linear infinite;
background-size: @progress-loading-size @progress-loading-size;
background-repeat: repeat-x;
@@ -484,11 +484,11 @@
}
// States
- &-controls [data-player='pause'],
- &.playing .player-controls [data-player='play'] {
+ &-controls [data-plyr='pause'],
+ &.playing .plyr-controls [data-plyr='play'] {
display: none;
}
- &.playing .player-controls [data-player='pause'] {
+ &.playing .plyr-controls [data-plyr='pause'] {
display: inline-block;
}
@@ -560,7 +560,7 @@
// It's not supported to change volume using JavaScript:
// https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html
&.ios &-volume,
- &.ios [data-player='mute'],
+ &.ios [data-plyr='mute'],
&-audio.ios &-controls-right {
display: none;
}
@@ -571,10 +571,10 @@
// Audio specific styles
// Position the progress within the container
- &-audio .player-controls {
+ &-audio .plyr-controls {
padding-top: (@control-spacing * 2);
}
- &-audio .player-progress {
+ &-audio .plyr-progress {
bottom: auto;
top: 0;
background: @off-white;
@@ -596,11 +596,11 @@
video {
height: 100%;
}
- .player-video-wrapper {
+ .plyr-video-wrapper {
height: 100%;
width: 100%;
}
- .player-controls {
+ .plyr-controls {
position: absolute;
bottom: 0;
left: 0;
@@ -609,22 +609,22 @@
// Hide controls when playing in full screen
&.fullscreen-hide-controls.playing {
- .player-controls {
+ .plyr-controls {
transform: translateY(100%) translateY(@control-spacing / 2);
transition: transform .3s .2s ease;
}
- &.player-hover .player-controls {
+ &.plyr-hover .plyr-controls {
transform: translateY(0);
}
- .player-captions {
+ .plyr-captions {
bottom: (@control-spacing / 2);
transition: bottom .3s .2s ease;
}
}
// Captions
- .player-captions,
- &.fullscreen-hide-controls.playing.player-hover .player-captions {
+ .plyr-captions,
+ &.fullscreen-hide-controls.playing.plyr-hover .plyr-captions {
top: auto;
bottom: 90px;
@@ -636,8 +636,8 @@
// Change icons on state change
&.fullscreen-active .icon-exit-fullscreen,
- &.muted .player-controls .icon-muted,
- &.captions-active .player-controls .icon-captions-on {
+ &.muted .plyr-controls .icon-muted,
+ &.captions-active .plyr-controls .icon-captions-on {
display: block;
& + svg {
@@ -646,12 +646,12 @@
}
// Some options are hidden by default
- [data-player='captions'],
- [data-player='fullscreen'] {
+ [data-plyr='captions'],
+ [data-plyr='fullscreen'] {
display: none;
}
- &.captions-enabled [data-player='captions'],
- &.fullscreen-enabled [data-player='fullscreen'] {
+ &.captions-enabled [data-plyr='captions'],
+ &.fullscreen-enabled [data-plyr='fullscreen'] {
display: inline-block;
}
} \ No newline at end of file