From 1960d35d8b8319614adb4a7852a9614dfa8c1eb1 Mon Sep 17 00:00:00 2001 From: Sam Potts Date: Tue, 25 Apr 2017 18:37:31 +1000 Subject: [PATCH] More work on menus and tidy up --- dist/plyr.css | 2 +- dist/plyr.js | 4 +- notes.md | 7 +- src/js/plyr.js | 929 ++++++++++++++++----------------------------- src/less/plyr.less | 5 + 5 files changed, 341 insertions(+), 606 deletions(-) diff --git a/dist/plyr.css b/dist/plyr.css index 74730c03..2fd4001b 100644 --- a/dist/plyr.css +++ b/dist/plyr.css @@ -1 +1 @@ -.plyr input[type=range]:focus,.plyr:focus{outline:0}@keyframes plyr-progress{to{background-position:25px 0}}@keyframes plyr-popup{from{transform:translateY(10px);opacity:.5}to{transform:translateY(0);opacity:1}}.plyr{position:relative;max-width:100%;min-width:200px;font-family:Avenir,'Avenir Next','Helvetica Neue','Segoe UI',Helvetica,Arial,sans-serif;font-weight:500;direction:ltr}.plyr,.plyr *,.plyr ::after,.plyr ::before{box-sizing:border-box}.plyr a,.plyr button,.plyr input,.plyr label{-ms-touch-action:manipulation;touch-action:manipulation}.plyr [aria-hidden=true]{display:none}.plyr audio,.plyr video{width:100%;height:auto;vertical-align:middle;border-radius:inherit}.plyr input[type=range]{display:block;height:20px;width:100%;margin:0;padding:0;vertical-align:middle;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;border:none;background:0 0}.plyr input[type=range]::-webkit-slider-runnable-track{height:8px;background:0 0;border:0;border-radius:4px;-webkit-user-select:none;user-select:none}.plyr input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;margin-top:-4px;position:relative;height:16px;width:16px;background:#fff;border:2px solid transparent;border-radius:100%;transition:background .2s ease,border .2s ease,transform .2s ease;box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(52,63,74,.2);box-sizing:border-box}.plyr input[type=range]::-moz-range-track{height:8px;background:0 0;border:0;border-radius:4px;-moz-user-select:none;user-select:none}.plyr input[type=range]::-moz-range-thumb{position:relative;height:16px;width:16px;background:#fff;border:2px solid transparent;border-radius:100%;transition:background .2s ease,border .2s ease,transform .2s ease;box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(52,63,74,.2);box-sizing:border-box}.plyr input[type=range]::-ms-track{height:8px;background:0 0;border:0;color:transparent}.plyr input[type=range]::-ms-fill-upper{height:8px;background:0 0;border:0;border-radius:4px;-ms-user-select:none;user-select:none}.plyr input[type=range]::-ms-fill-lower{height:8px;border:0;border-radius:4px;-ms-user-select:none;user-select:none;background:#3498db}.plyr input[type=range]::-ms-thumb{position:relative;height:16px;width:16px;background:#fff;border:2px solid transparent;border-radius:100%;transition:background .2s ease,border .2s ease,transform .2s ease;box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(52,63,74,.2);box-sizing:border-box;margin-top:0}.plyr input[type=range]::-ms-tooltip{display:none}.plyr input[type=range]::-moz-focus-outer{border:0}.plyr input[type=range].tab-focus:focus{outline-offset:3px}.plyr input[type=range]:active::-webkit-slider-thumb{background:#3498db;border-color:#fff;transform:scale(1.25)}.plyr input[type=range]:active::-moz-range-thumb{background:#3498db;border-color:#fff;transform:scale(1.25)}.plyr input[type=range]:active::-ms-thumb{background:#3498db;border-color:#fff;transform:scale(1.25)}.plyr--video input[type=range].tab-focus:focus{outline:rgba(255,255,255,.5) dotted 1px}.plyr--audio input[type=range].tab-focus:focus{outline:rgba(86,93,100,.5) dotted 1px}.plyr__sr-only{clip:rect(1px,1px,1px,1px);overflow:hidden;position:absolute!important;padding:0!important;border:0!important;height:1px!important;width:1px!important}.plyr__video-embed,.plyr__video-wrapper{border-radius:inherit;overflow:hidden;z-index:0}.plyr__video-wrapper{position:relative;background:#000}.plyr__video-embed{padding-bottom:56.25%;height:0}.plyr__video-embed iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.plyr__video-embed>div{position:relative;padding-bottom:200%;transform:translateY(-35.95%)}.plyr .plyr__video-embed iframe{pointer-events:none}.plyr video::-webkit-media-text-track-container{display:none}.plyr__captions{display:none;position:absolute;bottom:0;left:0;width:100%;padding:20px;transform:translateY(-40px);transition:transform .3s ease;color:#fff;font-size:16px;text-align:center}.plyr__captions span{border-radius:2px;padding:3px 10px;background:rgba(0,0,0,.6);-webkit-box-decoration-break:clone;box-decoration-break:clone;line-height:150%}.plyr__captions span:empty{display:none}@media (min-width:768px){.plyr__captions{font-size:24px}}.plyr--captions-active .plyr__captions{display:block}.plyr--hide-controls .plyr__captions{transform:translateY(-15px)}@media (min-width:1024px){.plyr--fullscreen-active .plyr__captions{font-size:32px}}.plyr ::-webkit-media-controls{display:none}.plyr__controls{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;line-height:1;text-align:center}.plyr__controls .plyr__menu,.plyr__controls .plyr__progress,.plyr__controls .plyr__time,.plyr__controls>.plyr__control{margin-left:5px}.plyr__controls .plyr__menu:first-child,.plyr__controls .plyr__menu:first-child+[data-plyr=pause],.plyr__controls .plyr__progress:first-child,.plyr__controls .plyr__progress:first-child+[data-plyr=pause],.plyr__controls .plyr__time:first-child,.plyr__controls .plyr__time:first-child+[data-plyr=pause],.plyr__controls>.plyr__control:first-child,.plyr__controls>.plyr__control:first-child+[data-plyr=pause]{margin-left:0}.plyr__controls .plyr__volume{margin-left:5px}@media (min-width:480px){.plyr__controls .plyr__menu,.plyr__controls .plyr__progress,.plyr__controls .plyr__time,.plyr__controls>.plyr__control{margin-left:10px}.plyr__controls .plyr__menu+.plyr__control,.plyr__controls>.plyr__control+.plyr__control,.plyr__controls>.plyr__control+.plyr__menu{margin-left:5px}}.plyr--hide-controls .plyr__controls{opacity:0;pointer-events:none}.plyr__control{position:relative;display:inline-block;-ms-flex-negative:0;flex-shrink:0;overflow:visible;vertical-align:middle;padding:7px;border:0;background:0 0;border-radius:3px;cursor:pointer;transition:background .3s ease,color .3s ease,opacity .3s ease;color:inherit}.plyr__control svg{width:18px;height:18px;display:block;fill:currentColor;pointer-events:none}.plyr__control .icon--captions-on,.plyr__control .icon--exit-fullscreen,.plyr__control .icon--muted{display:none}.plyr__control:focus{outline:0}.plyr--video .plyr__controls{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:50px 10px 10px;background:linear-gradient(rgba(0,0,0,0),rgba(0,0,0,.7));border-bottom-left-radius:inherit;border-bottom-right-radius:inherit;color:#fff;transition:opacity .3s ease}.plyr--video .plyr__controls .plyr__control.tab-focus:focus,.plyr--video .plyr__controls .plyr__control:hover,.plyr--video .plyr__controls .plyr__control[aria-expanded=true]{background:#3498db;color:#fff}.plyr--audio .plyr__controls{padding:10px;border-radius:inherit;background:#fff;border:1px solid #dbe3e8;color:#565D64}.plyr--audio .plyr__controls .plyr__control.tab-focus:focus,.plyr--audio .plyr__controls .plyr__control:hover,.plyr--audio .plyr__controls .plyr__control[aria-expanded=true]{background:#3498db;color:#fff}.plyr__play-large{display:none;position:absolute;z-index:1;top:50%;left:50%;transform:translate(-50%,-50%);padding:10px;background:#3498db;border:4px solid currentColor;border-radius:100%;box-shadow:0 1px 1px rgba(0,0,0,.15);color:#fff;transition:all .3s ease}.plyr__play-large svg{position:relative;left:2px;width:20px;height:20px;display:block;fill:currentColor;pointer-events:none}.plyr__play-large:focus{outline:rgba(255,255,255,.5) dotted 1px}.plyr .plyr__play-large{display:inline-block}.plyr--audio .plyr__play-large,.plyr--playing .plyr__controls [data-plyr=play],.plyr__controls [data-plyr=pause]{display:none}.plyr--playing .plyr__play-large{opacity:0;visibility:hidden}.plyr--playing .plyr__controls [data-plyr=pause]{display:inline-block}.plyr--captions-active .plyr__control .icon--captions-on,.plyr--fullscreen-active .plyr__control .icon--exit-fullscreen,.plyr--muted .plyr__control .icon--muted{display:block}.plyr [data-plyr=pip],.plyr [data-plyr=airplay],.plyr [data-plyr=captions],.plyr [data-plyr=fullscreen],.plyr--captions-active .plyr__control .icon--captions-on+svg,.plyr--fullscreen-active .plyr__control .icon--exit-fullscreen+svg,.plyr--muted .plyr__control .icon--muted+svg{display:none}.plyr--airplay-enabled [data-plyr=airplay],.plyr--captions-enabled [data-plyr=captions],.plyr--fullscreen-enabled [data-plyr=fullscreen],.plyr--pip-enabled [data-plyr=pip]{display:inline-block}.plyr__menu{position:relative}.plyr__menu .plyr__control svg{transition:transform .3s ease}.plyr__menu__container.is-resizing,.plyr__menu__container>div{overflow:hidden;transition:height .35s cubic-bezier(.4,0,.2,1),width .35s cubic-bezier(.4,0,.2,1)}.plyr__menu .plyr__control[aria-expanded=true] svg{transform:rotate(45deg)}.plyr__menu .plyr__control[aria-expanded=true] .plyr__tooltip{display:none}.plyr__menu__container{position:absolute;z-index:1;bottom:100%;right:-5px;margin-bottom:10px;animation:plyr-popup .2s ease;background:rgba(52,63,74,.9);border-radius:4px;white-space:nowrap;text-align:left;color:#fff;font-size:14px}.plyr__menu__container::after{content:"";position:absolute;top:100%;right:15px;height:0;width:0;border:6px solid transparent;border-top-color:rgba(52,63,74,.9)}.plyr__menu__container ul{margin:0;padding:7px;list-style:none;overflow:hidden}.plyr__menu__container .plyr__control{display:-ms-flexbox;display:flex;width:100%;padding:7px 14px;color:#fff;font-weight:600;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.plyr__menu__container .plyr__control::after{content:"";position:absolute;top:50%;transform:translateY(-50%);border:5px solid transparent}.plyr__menu__container .plyr__control--forward{padding-right:28px}.plyr__menu__container .plyr__control--forward::after{right:5px;border-left-color:rgba(255,255,255,.8)}.plyr__menu__container .plyr__control--back{position:relative;width:calc(100% - 14px);margin:7px 7px 3px;padding-left:28px;font-weight:500}.plyr__menu__container .plyr__control--back::after{left:5px;border-right-color:rgba(255,255,255,.8)}.plyr__menu__container .plyr__control--back::before{content:"";position:absolute;top:100%;left:0;right:0;height:1px;overflow:hidden;margin-top:4px;background:rgba(0,0,0,.15);box-shadow:0 1px 0 rgba(255,255,255,.1)}.plyr__menu__container label.plyr__control{padding-left:18px}.plyr__menu__container label.plyr__control input[type=radio]{position:relative;left:-7px}.plyr__menu__container .plyr__menu__value{display:inherit;margin-left:auto;padding-left:25px;pointer-events:none;overflow:hidden;font-weight:500;color:rgba(255,255,255,.8)}.plyr__menu__container .plyr__menu__value .plyr__badge{font-weight:600}.plyr__badge{padding:2px 4px;border-radius:2px;background:#fff;color:rgba(52,63,74,.9);font-size:10px}.plyr__tooltip{position:absolute;z-index:2;bottom:100%;margin-bottom:10px;padding:5px 7.5px;pointer-events:none;opacity:0;background:rgba(52,63,74,.9);border-radius:3px;color:#fff;font-size:14px;font-weight:500;line-height:1.3;transform:translate(-50%,10px) scale(.8);transform-origin:50% 100%;transition:transform .2s .1s ease,opacity .2s .1s ease}.plyr__tooltip::before{content:'';position:absolute;width:0;height:0;left:50%;transform:translateX(-50%);bottom:-4px;border-right:4px solid transparent;border-top:4px solid rgba(52,63,74,.9);border-left:4px solid transparent;z-index:2}.plyr .plyr__control.tab-focus:focus .plyr__tooltip,.plyr .plyr__control:hover .plyr__tooltip,.plyr__tooltip--visible{opacity:1;transform:translate(-50%,0) scale(1)}.plyr .plyr__control:hover .plyr__tooltip{z-index:3}.plyr__controls>.plyr__control:first-child .plyr__tooltip,.plyr__controls>.plyr__control:first-child+.plyr__control .plyr__tooltip{left:0;transform:translate(0,10px) scale(.8);transform-origin:0 100%}.plyr__controls>.plyr__control:first-child .plyr__tooltip::before,.plyr__controls>.plyr__control:first-child+.plyr__control .plyr__tooltip::before{left:16px}.plyr__controls>.plyr__control:last-child .plyr__tooltip{right:0;transform:translate(0,10px) scale(.8);transform-origin:100% 100%}.plyr__controls>.plyr__control:last-child .plyr__tooltip::before{left:auto;right:16px;transform:translateX(50%)}.plyr__controls>.plyr__control:first-child .plyr__tooltip--visible,.plyr__controls>.plyr__control:first-child+.plyr__control .plyr__tooltip--visible,.plyr__controls>.plyr__control:first-child+.plyr__control.tab-focus:focus .plyr__tooltip,.plyr__controls>.plyr__control:first-child+.plyr__control:hover .plyr__tooltip,.plyr__controls>.plyr__control:first-child.tab-focus:focus .plyr__tooltip,.plyr__controls>.plyr__control:first-child:hover .plyr__tooltip,.plyr__controls>.plyr__control:last-child .plyr__tooltip--visible,.plyr__controls>.plyr__control:last-child.tab-focus:focus .plyr__tooltip,.plyr__controls>.plyr__control:last-child:hover .plyr__tooltip{transform:translate(0,0) scale(1)}.plyr__progress{position:relative;display:none;-ms-flex:1;flex:1}.plyr__progress input[type=range]{position:relative;z-index:2}.plyr__progress input[type=range]::-webkit-slider-runnable-track{background:0 0}.plyr__progress input[type=range]::-moz-range-track{background:0 0}.plyr__progress input[type=range]::-ms-fill-upper{background:0 0}.plyr__progress .plyr__tooltip{left:0}.plyr .plyr__progress{display:inline-block}.plyr__progress--buffer,.plyr__progress--played,.plyr__volume--display{position:absolute;left:0;top:50%;width:100%;height:8px;margin:-4px 0 0;padding:0;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;border-radius:100px}.plyr__progress--buffer::-webkit-progress-bar,.plyr__progress--played::-webkit-progress-bar,.plyr__volume--display::-webkit-progress-bar{background:0 0}.plyr__progress--buffer::-webkit-progress-value,.plyr__progress--played::-webkit-progress-value,.plyr__volume--display::-webkit-progress-value{background:currentColor;border-radius:100px;min-width:8px}.plyr__progress--buffer::-moz-progress-bar,.plyr__progress--played::-moz-progress-bar,.plyr__volume--display::-moz-progress-bar{background:currentColor;border-radius:100px;min-width:8px}.plyr__progress--buffer::-ms-fill,.plyr__progress--played::-ms-fill,.plyr__volume--display::-ms-fill{border-radius:100px}.plyr__progress--played,.plyr__volume--display{z-index:1;color:#3498db;background:0 0;transition:none}.plyr__progress--played::-webkit-progress-value,.plyr__volume--display::-webkit-progress-value{min-width:8px;max-width:99%;border-top-right-radius:0;border-bottom-right-radius:0;transition:none}.plyr__progress--played::-moz-progress-bar,.plyr__volume--display::-moz-progress-bar{min-width:8px;max-width:99%;border-top-right-radius:0;border-bottom-right-radius:0;transition:none}.plyr__progress--played::-ms-fill,.plyr__volume--display::-ms-fill{display:none}.plyr__progress--buffer::-webkit-progress-value{transition:width .2s ease}.plyr__progress--buffer::-moz-progress-bar{transition:width .2s ease}.plyr__progress--buffer::-ms-fill{transition:width .2s ease}.plyr--video .plyr__progress--buffer,.plyr--video .plyr__volume--display{background:rgba(255,255,255,.25)}.plyr--video .plyr__progress--buffer{color:rgba(255,255,255,.25)}.plyr--audio .plyr__progress--buffer,.plyr--audio .plyr__volume--display{background:rgba(198,214,219,.66)}.plyr--audio .plyr__progress--buffer{color:rgba(198,214,219,.66)}.plyr--loading .plyr__progress--buffer{animation:plyr-progress 1s linear infinite;background-size:25px 25px;background-repeat:repeat-x;background-image:linear-gradient(-45deg,rgba(52,63,74,.2) 25%,transparent 25%,transparent 50%,rgba(52,63,74,.2) 50%,rgba(52,63,74,.2) 75%,transparent 75%,transparent);color:transparent}.plyr--video.plyr--loading .plyr__progress--buffer{background-color:rgba(255,255,255,.25)}.plyr--audio.plyr--loading .plyr__progress--buffer{background-color:rgba(198,214,219,.66)}.plyr__time{display:inline-block;vertical-align:middle;font-size:14px}.plyr__time+.plyr__time{display:none}@media (min-width:768px){.plyr__time+.plyr__time{display:inline-block}}.plyr__time+.plyr__time::before{content:'\2044';margin-right:10px}.plyr__volume{display:none}.plyr .plyr__volume{-ms-flex:1;flex:1;position:relative}.plyr .plyr__volume input[type=range]{position:relative;z-index:2}@media (min-width:480px){.plyr .plyr__volume{display:block;max-width:60px}}@media (min-width:768px){.plyr .plyr__volume{max-width:100px}}.plyr--is-ios .plyr__volume,.plyr--is-ios [data-plyr=mute]{display:none!important}.plyr--fullscreen-active{position:fixed;top:0;left:0;right:0;bottom:0;height:100%;width:100%;z-index:10000000;background:#000;border-radius:0!important}.plyr--fullscreen-active video{height:100%}.plyr--fullscreen-active .plyr__video-wrapper{height:100%;width:100%}.plyr--fullscreen-active .plyr__video-embed{overflow:visible}.plyr--fullscreen-active .plyr__controls{position:absolute;bottom:0;left:0;right:0}.plyr--fullscreen-active.plyr--vimeo .plyr__video-wrapper{height:0;top:50%;transform:translateY(-50%)} \ No newline at end of file +.plyr input[type=range]:focus,.plyr:focus{outline:0}@keyframes plyr-progress{to{background-position:25px 0}}@keyframes plyr-popup{from{transform:translateY(10px);opacity:.5}to{transform:translateY(0);opacity:1}}.plyr{position:relative;max-width:100%;min-width:200px;font-family:Avenir,'Avenir Next','Helvetica Neue','Segoe UI',Helvetica,Arial,sans-serif;font-weight:500;direction:ltr}.plyr,.plyr *,.plyr ::after,.plyr ::before{box-sizing:border-box}.plyr a,.plyr button,.plyr input,.plyr label{-ms-touch-action:manipulation;touch-action:manipulation}.plyr [aria-hidden=true]{display:none}.plyr audio,.plyr video{width:100%;height:auto;vertical-align:middle;border-radius:inherit}.plyr input[type=range]{display:block;height:20px;width:100%;margin:0;padding:0;vertical-align:middle;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;border:none;background:0 0}.plyr input[type=range]::-webkit-slider-runnable-track{height:8px;background:0 0;border:0;border-radius:4px;-webkit-user-select:none;user-select:none}.plyr input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;margin-top:-4px;position:relative;height:16px;width:16px;background:#fff;border:2px solid transparent;border-radius:100%;transition:background .2s ease,border .2s ease,transform .2s ease;box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(52,63,74,.2);box-sizing:border-box}.plyr input[type=range]::-moz-range-track{height:8px;background:0 0;border:0;border-radius:4px;-moz-user-select:none;user-select:none}.plyr input[type=range]::-moz-range-thumb{position:relative;height:16px;width:16px;background:#fff;border:2px solid transparent;border-radius:100%;transition:background .2s ease,border .2s ease,transform .2s ease;box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(52,63,74,.2);box-sizing:border-box}.plyr input[type=range]::-ms-track{height:8px;background:0 0;border:0;color:transparent}.plyr input[type=range]::-ms-fill-upper{height:8px;background:0 0;border:0;border-radius:4px;-ms-user-select:none;user-select:none}.plyr input[type=range]::-ms-fill-lower{height:8px;border:0;border-radius:4px;-ms-user-select:none;user-select:none;background:#3498db}.plyr input[type=range]::-ms-thumb{position:relative;height:16px;width:16px;background:#fff;border:2px solid transparent;border-radius:100%;transition:background .2s ease,border .2s ease,transform .2s ease;box-shadow:0 1px 1px rgba(0,0,0,.15),0 0 0 1px rgba(52,63,74,.2);box-sizing:border-box;margin-top:0}.plyr input[type=range]::-ms-tooltip{display:none}.plyr input[type=range]::-moz-focus-outer{border:0}.plyr input[type=range].tab-focus:focus{outline-offset:3px}.plyr input[type=range]:active::-webkit-slider-thumb{background:#3498db;border-color:#fff;transform:scale(1.25)}.plyr input[type=range]:active::-moz-range-thumb{background:#3498db;border-color:#fff;transform:scale(1.25)}.plyr input[type=range]:active::-ms-thumb{background:#3498db;border-color:#fff;transform:scale(1.25)}.plyr--video input[type=range].tab-focus:focus{outline:rgba(255,255,255,.5) dotted 1px}.plyr--audio input[type=range].tab-focus:focus{outline:rgba(86,93,100,.5) dotted 1px}.plyr__sr-only{clip:rect(1px,1px,1px,1px);overflow:hidden;position:absolute!important;padding:0!important;border:0!important;height:1px!important;width:1px!important}.plyr__video-embed,.plyr__video-wrapper{border-radius:inherit;overflow:hidden;z-index:0}.plyr__video-wrapper{position:relative;background:#000}.plyr__video-embed{padding-bottom:56.25%;height:0}.plyr__video-embed iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.plyr__video-embed>div{position:relative;padding-bottom:200%;transform:translateY(-35.95%)}.plyr .plyr__video-embed iframe{pointer-events:none}.plyr video::-webkit-media-text-track-container{display:none}.plyr__captions{display:none;position:absolute;bottom:0;left:0;width:100%;padding:20px;transform:translateY(-40px);transition:transform .3s ease;color:#fff;font-size:16px;text-align:center}.plyr__captions span{border-radius:2px;padding:3px 10px;background:rgba(0,0,0,.6);-webkit-box-decoration-break:clone;box-decoration-break:clone;line-height:150%}.plyr__captions span div{display:inline}.plyr__captions span:empty{display:none}@media (min-width:768px){.plyr__captions{font-size:24px}}.plyr--captions-active .plyr__captions{display:block}.plyr--hide-controls .plyr__captions{transform:translateY(-15px)}@media (min-width:1024px){.plyr--fullscreen-active .plyr__captions{font-size:32px}}.plyr ::-webkit-media-controls{display:none}.plyr__controls{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;line-height:1;text-align:center}.plyr__controls .plyr__menu,.plyr__controls .plyr__progress,.plyr__controls .plyr__time,.plyr__controls>.plyr__control{margin-left:5px}.plyr__controls .plyr__menu:first-child,.plyr__controls .plyr__menu:first-child+[data-plyr=pause],.plyr__controls .plyr__progress:first-child,.plyr__controls .plyr__progress:first-child+[data-plyr=pause],.plyr__controls .plyr__time:first-child,.plyr__controls .plyr__time:first-child+[data-plyr=pause],.plyr__controls>.plyr__control:first-child,.plyr__controls>.plyr__control:first-child+[data-plyr=pause]{margin-left:0}.plyr__controls .plyr__volume{margin-left:5px}@media (min-width:480px){.plyr__controls .plyr__menu,.plyr__controls .plyr__progress,.plyr__controls .plyr__time,.plyr__controls>.plyr__control{margin-left:10px}.plyr__controls .plyr__menu+.plyr__control,.plyr__controls>.plyr__control+.plyr__control,.plyr__controls>.plyr__control+.plyr__menu{margin-left:5px}}.plyr--hide-controls .plyr__controls{opacity:0;pointer-events:none}.plyr__control{position:relative;display:inline-block;-ms-flex-negative:0;flex-shrink:0;overflow:visible;vertical-align:middle;padding:7px;border:0;background:0 0;border-radius:3px;cursor:pointer;transition:background .3s ease,color .3s ease,opacity .3s ease;color:inherit}.plyr__control svg{width:18px;height:18px;display:block;fill:currentColor;pointer-events:none}.plyr__control .icon--captions-on,.plyr__control .icon--exit-fullscreen,.plyr__control .icon--muted{display:none}.plyr__control:focus{outline:0}.plyr--video .plyr__controls{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:50px 10px 10px;background:linear-gradient(rgba(0,0,0,0),rgba(0,0,0,.7));border-bottom-left-radius:inherit;border-bottom-right-radius:inherit;color:#fff;transition:opacity .3s ease}.plyr--video .plyr__controls .plyr__control.tab-focus:focus,.plyr--video .plyr__controls .plyr__control:hover,.plyr--video .plyr__controls .plyr__control[aria-expanded=true]{background:#3498db;color:#fff}.plyr--audio .plyr__controls{padding:10px;border-radius:inherit;background:#fff;border:1px solid #dbe3e8;color:#565D64}.plyr--audio .plyr__controls .plyr__control.tab-focus:focus,.plyr--audio .plyr__controls .plyr__control:hover,.plyr--audio .plyr__controls .plyr__control[aria-expanded=true]{background:#3498db;color:#fff}.plyr__play-large{display:none;position:absolute;z-index:1;top:50%;left:50%;transform:translate(-50%,-50%);padding:10px;background:#3498db;border:4px solid currentColor;border-radius:100%;box-shadow:0 1px 1px rgba(0,0,0,.15);color:#fff;transition:all .3s ease}.plyr__play-large svg{position:relative;left:2px;width:20px;height:20px;display:block;fill:currentColor;pointer-events:none}.plyr__play-large:focus{outline:rgba(255,255,255,.5) dotted 1px}.plyr .plyr__play-large{display:inline-block}.plyr--audio .plyr__play-large,.plyr--playing .plyr__controls [data-plyr=play],.plyr__controls [data-plyr=pause]{display:none}.plyr--playing .plyr__play-large{opacity:0;visibility:hidden}.plyr--playing .plyr__controls [data-plyr=pause]{display:inline-block}.plyr--captions-active .plyr__control .icon--captions-on,.plyr--fullscreen-active .plyr__control .icon--exit-fullscreen,.plyr--muted .plyr__control .icon--muted{display:block}.plyr [data-plyr=pip],.plyr [data-plyr=airplay],.plyr [data-plyr=captions],.plyr [data-plyr=fullscreen],.plyr--captions-active .plyr__control .icon--captions-on+svg,.plyr--fullscreen-active .plyr__control .icon--exit-fullscreen+svg,.plyr--muted .plyr__control .icon--muted+svg{display:none}.plyr--airplay-enabled [data-plyr=airplay],.plyr--captions-enabled [data-plyr=captions],.plyr--fullscreen-enabled [data-plyr=fullscreen],.plyr--pip-enabled [data-plyr=pip]{display:inline-block}.plyr__menu{position:relative}.plyr__menu .plyr__control svg{transition:transform .3s ease}.plyr__menu__container.is-resizing,.plyr__menu__container>div{overflow:hidden;transition:height .35s cubic-bezier(.4,0,.2,1),width .35s cubic-bezier(.4,0,.2,1)}.plyr__menu .plyr__control[aria-expanded=true] svg{transform:rotate(45deg)}.plyr__menu .plyr__control[aria-expanded=true] .plyr__tooltip{display:none}.plyr__menu__container{position:absolute;z-index:1;bottom:100%;right:-5px;margin-bottom:10px;animation:plyr-popup .2s ease;background:rgba(52,63,74,.9);border-radius:4px;white-space:nowrap;text-align:left;color:#fff;font-size:14px}.plyr__menu__container::after{content:"";position:absolute;top:100%;right:15px;height:0;width:0;border:6px solid transparent;border-top-color:rgba(52,63,74,.9)}.plyr__menu__container ul{margin:0;padding:7px;list-style:none;overflow:hidden}.plyr__menu__container .plyr__control{display:-ms-flexbox;display:flex;width:100%;padding:7px 14px;color:#fff;font-weight:600;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.plyr__menu__container .plyr__control::after{content:"";position:absolute;top:50%;transform:translateY(-50%);border:5px solid transparent}.plyr__menu__container .plyr__control--forward{padding-right:28px}.plyr__menu__container .plyr__control--forward::after{right:5px;border-left-color:rgba(255,255,255,.8)}.plyr__menu__container .plyr__control--back{position:relative;width:calc(100% - 14px);margin:7px 7px 3px;padding-left:28px;font-weight:500}.plyr__menu__container .plyr__control--back::after{left:5px;border-right-color:rgba(255,255,255,.8)}.plyr__menu__container .plyr__control--back::before{content:"";position:absolute;top:100%;left:0;right:0;height:1px;overflow:hidden;margin-top:4px;background:rgba(0,0,0,.15);box-shadow:0 1px 0 rgba(255,255,255,.1)}.plyr__menu__container label.plyr__control{padding-left:18px}.plyr__menu__container label.plyr__control input[type=radio]{position:relative;left:-7px}.plyr__menu__container .plyr__menu__value{display:inherit;margin-left:auto;padding-left:25px;pointer-events:none;overflow:hidden;font-weight:500;color:rgba(255,255,255,.8)}.plyr__menu__container .plyr__menu__value .plyr__badge{font-weight:600}.plyr__badge{padding:2px 4px;border-radius:2px;background:#fff;color:rgba(52,63,74,.9);font-size:10px}.plyr__tooltip{position:absolute;z-index:2;bottom:100%;margin-bottom:10px;padding:5px 7.5px;pointer-events:none;opacity:0;background:rgba(52,63,74,.9);border-radius:3px;color:#fff;font-size:14px;font-weight:500;line-height:1.3;transform:translate(-50%,10px) scale(.8);transform-origin:50% 100%;transition:transform .2s .1s ease,opacity .2s .1s ease}.plyr__tooltip::before{content:'';position:absolute;width:0;height:0;left:50%;transform:translateX(-50%);bottom:-4px;border-right:4px solid transparent;border-top:4px solid rgba(52,63,74,.9);border-left:4px solid transparent;z-index:2}.plyr .plyr__control.tab-focus:focus .plyr__tooltip,.plyr .plyr__control:hover .plyr__tooltip,.plyr__tooltip--visible{opacity:1;transform:translate(-50%,0) scale(1)}.plyr .plyr__control:hover .plyr__tooltip{z-index:3}.plyr__controls>.plyr__control:first-child .plyr__tooltip,.plyr__controls>.plyr__control:first-child+.plyr__control .plyr__tooltip{left:0;transform:translate(0,10px) scale(.8);transform-origin:0 100%}.plyr__controls>.plyr__control:first-child .plyr__tooltip::before,.plyr__controls>.plyr__control:first-child+.plyr__control .plyr__tooltip::before{left:16px}.plyr__controls>.plyr__control:last-child .plyr__tooltip{right:0;transform:translate(0,10px) scale(.8);transform-origin:100% 100%}.plyr__controls>.plyr__control:last-child .plyr__tooltip::before{left:auto;right:16px;transform:translateX(50%)}.plyr__controls>.plyr__control:first-child .plyr__tooltip--visible,.plyr__controls>.plyr__control:first-child+.plyr__control .plyr__tooltip--visible,.plyr__controls>.plyr__control:first-child+.plyr__control.tab-focus:focus .plyr__tooltip,.plyr__controls>.plyr__control:first-child+.plyr__control:hover .plyr__tooltip,.plyr__controls>.plyr__control:first-child.tab-focus:focus .plyr__tooltip,.plyr__controls>.plyr__control:first-child:hover .plyr__tooltip,.plyr__controls>.plyr__control:last-child .plyr__tooltip--visible,.plyr__controls>.plyr__control:last-child.tab-focus:focus .plyr__tooltip,.plyr__controls>.plyr__control:last-child:hover .plyr__tooltip{transform:translate(0,0) scale(1)}.plyr__progress{position:relative;display:none;-ms-flex:1;flex:1}.plyr__progress input[type=range]{position:relative;z-index:2}.plyr__progress input[type=range]::-webkit-slider-runnable-track{background:0 0}.plyr__progress input[type=range]::-moz-range-track{background:0 0}.plyr__progress input[type=range]::-ms-fill-upper{background:0 0}.plyr__progress .plyr__tooltip{left:0}.plyr .plyr__progress{display:inline-block}.plyr__progress--buffer,.plyr__progress--played,.plyr__volume--display{position:absolute;left:0;top:50%;width:100%;height:8px;margin:-4px 0 0;padding:0;vertical-align:top;-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;border-radius:100px}.plyr__progress--buffer::-webkit-progress-bar,.plyr__progress--played::-webkit-progress-bar,.plyr__volume--display::-webkit-progress-bar{background:0 0}.plyr__progress--buffer::-webkit-progress-value,.plyr__progress--played::-webkit-progress-value,.plyr__volume--display::-webkit-progress-value{background:currentColor;border-radius:100px;min-width:8px}.plyr__progress--buffer::-moz-progress-bar,.plyr__progress--played::-moz-progress-bar,.plyr__volume--display::-moz-progress-bar{background:currentColor;border-radius:100px;min-width:8px}.plyr__progress--buffer::-ms-fill,.plyr__progress--played::-ms-fill,.plyr__volume--display::-ms-fill{border-radius:100px}.plyr__progress--played,.plyr__volume--display{z-index:1;color:#3498db;background:0 0;transition:none}.plyr__progress--played::-webkit-progress-value,.plyr__volume--display::-webkit-progress-value{min-width:8px;max-width:99%;border-top-right-radius:0;border-bottom-right-radius:0;transition:none}.plyr__progress--played::-moz-progress-bar,.plyr__volume--display::-moz-progress-bar{min-width:8px;max-width:99%;border-top-right-radius:0;border-bottom-right-radius:0;transition:none}.plyr__progress--played::-ms-fill,.plyr__volume--display::-ms-fill{display:none}.plyr__progress--buffer::-webkit-progress-value{transition:width .2s ease}.plyr__progress--buffer::-moz-progress-bar{transition:width .2s ease}.plyr__progress--buffer::-ms-fill{transition:width .2s ease}.plyr--video .plyr__progress--buffer,.plyr--video .plyr__volume--display{background:rgba(255,255,255,.25)}.plyr--video .plyr__progress--buffer{color:rgba(255,255,255,.25)}.plyr--audio .plyr__progress--buffer,.plyr--audio .plyr__volume--display{background:rgba(198,214,219,.66)}.plyr--audio .plyr__progress--buffer{color:rgba(198,214,219,.66)}.plyr--loading .plyr__progress--buffer{animation:plyr-progress 1s linear infinite;background-size:25px 25px;background-repeat:repeat-x;background-image:linear-gradient(-45deg,rgba(52,63,74,.2) 25%,transparent 25%,transparent 50%,rgba(52,63,74,.2) 50%,rgba(52,63,74,.2) 75%,transparent 75%,transparent);color:transparent}.plyr--video.plyr--loading .plyr__progress--buffer{background-color:rgba(255,255,255,.25)}.plyr--audio.plyr--loading .plyr__progress--buffer{background-color:rgba(198,214,219,.66)}.plyr__time{display:inline-block;vertical-align:middle;font-size:14px}.plyr__time+.plyr__time{display:none}@media (min-width:768px){.plyr__time+.plyr__time{display:inline-block}}.plyr__time+.plyr__time::before{content:'\2044';margin-right:10px}.plyr__volume{display:none}.plyr .plyr__volume{-ms-flex:1;flex:1;position:relative}.plyr .plyr__volume input[type=range]{position:relative;z-index:2}@media (min-width:480px){.plyr .plyr__volume{display:block;max-width:60px}}@media (min-width:768px){.plyr .plyr__volume{max-width:100px}}.plyr--is-ios .plyr__volume,.plyr--is-ios [data-plyr=mute]{display:none!important}.plyr--fullscreen-active{position:fixed;top:0;left:0;right:0;bottom:0;height:100%;width:100%;z-index:10000000;background:#000;border-radius:0!important}.plyr--fullscreen-active video{height:100%}.plyr--fullscreen-active .plyr__video-wrapper{height:100%;width:100%}.plyr--fullscreen-active .plyr__video-embed{overflow:visible}.plyr--fullscreen-active .plyr__controls{position:absolute;bottom:0;left:0;right:0}.plyr--fullscreen-active.plyr--vimeo .plyr__video-wrapper{height:0;top:50%;transform:translateY(-50%)} \ No newline at end of file diff --git a/dist/plyr.js b/dist/plyr.js index 3fb7951f..7251860f 100644 --- a/dist/plyr.js +++ b/dist/plyr.js @@ -1,2 +1,2 @@ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=t(e,document):"function"==typeof define&&define.amd?define([],function(){return t(e,document)}):e.plyr=t(e,document)}("undefined"!=typeof window?window:this,function(e,t){"use strict";function n(){var e,n,a,s=navigator.userAgent,l=navigator.appName,i=""+parseFloat(navigator.appVersion),r=parseInt(navigator.appVersion,10),o=!1,u=!1,c=!1,d=!1;return navigator.appVersion.indexOf("Windows NT")!==-1&&navigator.appVersion.indexOf("rv:11")!==-1?(o=!0,l="IE",i="11"):(n=s.indexOf("MSIE"))!==-1?(o=!0,l="IE",i=s.substring(n+5)):(n=s.indexOf("Chrome"))!==-1?(c=!0,l="Chrome",i=s.substring(n+7)):(n=s.indexOf("Safari"))!==-1?(d=!0,l="Safari",i=s.substring(n+7),(n=s.indexOf("Version"))!==-1&&(i=s.substring(n+8))):(n=s.indexOf("Firefox"))!==-1?(u=!0,l="Firefox",i=s.substring(n+8)):(e=s.lastIndexOf(" ")+1)<(n=s.lastIndexOf("/"))&&(l=s.substring(e,n),i=s.substring(n+1),l.toLowerCase()===l.toUpperCase()&&(l=navigator.appName)),(a=i.indexOf(";"))!==-1&&(i=i.substring(0,a)),(a=i.indexOf(" "))!==-1&&(i=i.substring(0,a)),r=parseInt(""+i,10),isNaN(r)&&(i=""+parseFloat(navigator.appVersion),r=parseInt(navigator.appVersion,10)),{name:l,version:r,isIE:o,isFirefox:u,isChrome:c,isSafari:d,isIos:/(iPad|iPhone|iPod)/g.test(navigator.platform),isTouch:"ontouchstart"in t.documentElement}}function a(e){if(!t.querySelectorAll('script[src="'+e+'"]').length){var n=t.createElement("script");n.src=e;var a=t.getElementsByTagName("script")[0];a.parentNode.insertBefore(n,a)}}function s(){try{return e.self!==e.top}catch(e){return!0}}function l(e,t){return Array.prototype.indexOf&&e.indexOf(t)!==-1}function i(e,t){e.length||(e=[e]);for(var n=e.length-1;n>=0;n--){var a=n>0?t.cloneNode(!0):t,s=e[n],l=s.parentNode,i=s.nextSibling;return a.appendChild(s),i?l.insertBefore(a,i):l.appendChild(a),a}}function r(e){e&&e.parentNode.removeChild(e)}function o(e,t){e.insertBefore(t,e.firstChild)}function u(e,t){for(var n in t)e.setAttribute(n,t[n])}function c(e,t){if(!j.string(e)||j.empty(e))return{};var n={};return e.split(",").forEach(function(e){e=e.trim();var a=e.charAt(0);switch(a){case".":var s=e.replace(".","");j.object(t)&&j.string(t.class)&&(t.class+=" "+s),n.class=s;break;case"#":n.id=e.replace("#","");break;case"[":e=e.replace(/[\[\]]/g,"");var l=e.split("="),i=l[0],r=l.length>1?l[1].replace(/[\"\']/g,""):"";n[i]=r}}),n}function d(e,n,a){var s=t.createElement(e);return j.object(n)&&u(s,n),j.string(a)&&(s.textContent=a),s}function p(e,t,n,a){var s=d(e,n,a);o(t,s)}function m(e){for(var t=e.childNodes.length;t--;)e.removeChild(e.lastChild)}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){return!!e&&(e.classList?e.classList.contains(t):new RegExp("(\\s|^)"+t+"(\\s|$)").test(e.className))}function v(e,n){var a=Element.prototype,s=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.msMatchesSelector||function(e){return[].indexOf.call(t.querySelectorAll(e),this)!==-1};return s.call(e,n)}function g(){var e=t.activeElement;return e=e&&e!==t.body?t.querySelector(":focus"):null}function h(e,t,n,a,s){w(e,t,function(t){n&&n.apply(e,[t]),a.apply(e,[t])},s)}function k(e,t,n,a,s){var l=t.split(" ");if(j.boolean(s)||(s=!1),e instanceof NodeList)for(var i=0;i'),rt.captions.textTracks=!1,rt.elements.media.textTracks&&(rt.captions.textTracks=!0);var e=[],t="";if(rt.elements.media.childNodes.forEach(function(t){"track"===t.nodeName.toLowerCase()&&("captions"!==t.kind&&"subtitles"!==t.kind||e.push(t.getAttribute("src")))}),rt.captions.exist=!0,0===e.length?(rt.captions.exist=!1,ct("No caption track found")):Number(I.captions.selectedIndex)+1>e.length?(rt.captions.exist=!1,ct("Caption index out of bound")):(t=e[I.captions.selectedIndex],ct("Caption track found; URI: "+t)),rt.captions.exist){var n=rt.elements.media.textTracks;if([].forEach.call(n,function(e){C(e,"cuechange",ne),e.mode="hidden"}),re(rt),(rt.browser.isIE&&rt.browser.version>=10||rt.browser.isFirefox&&rt.browser.version>=31)&&(ct("Detected browser with known TextTrack issues - using manual fallback"),rt.captions.textTracks=!1),rt.captions.textTracks){ct("TextTracks supported");var a=n[I.captions.selectedIndex];"captions"!==a.kind&&"subtitles"!==a.kind||(w(a,"cuechange",ne),a.activeCues&&a.activeCues.length>0&&ne(a))}else if(ct("TextTracks not supported so rendering captions manually"),rt.captions.current="",rt.captions.captions=[],""!==t){var s=new XMLHttpRequest;s.onreadystatechange=function(){if(4===s.readyState)if(200===s.status){var e=s.responseText,t="\r\n";e.indexOf(t+t)===-1&&(t=e.indexOf("\r\r")!==-1?"\r":"\n");var n=e.split(t+t);rt.captions.captions=n.map(function(e){var n=e.split(t),a=0;return n[a].indexOf(":")!==-1&&(a=1),[n[a],n[a+1]]}),rt.captions.captions.shift(),ct("Successfully loaded the caption file via AJAX")}else dt(I.logPrefix+"There was a problem loading the caption file via AJAX")},s.open("get",t,!0),s.send()}}else y(rt.elements.container,I.classes.captions.enabled)}}function se(e){I.captions.selectedIndex=e||I.captions.selectedIndex,le(),ae()}function le(e){var t=W(I.selectors.captions);if(j.htmlElement(t)){var n=d("span");m(t),j.undefined(e)&&(e=""),j.string(e)?n.innerHTML=e.trim():n.appendChild(e),t.appendChild(n)}}function ie(e){function t(e,t){var n=[];n=e.split(" --> ");for(var a=0;art.captions.captions.length-1){rt.captions.count=rt.captions.captions.length-1;break}rt.elements.media.currentTime.toFixed(1)>=n(rt.captions[rt.subcount][0])&&rt.elements.media.currentTime.toFixed(1)<=a(rt.captions[rt.subcount][0])?(rt.captions.current=rt.captions.captions[rt.captions.count][1],le(rt.captions.current)):le()}}function re(){if(rt.elements.buttons.captions){y(rt.elements.container,I.classes.captions.enabled,!0);var e=rt.storage.captions;j.boolean(e)||(e=I.captions.defaultActive),e&&(y(rt.elements.container,I.classes.captions.active,!0),T(rt.elements.buttons.captions,!0))}}function oe(e){rt.supported.full&&rt.elements.buttons.captions&&(j.boolean(e)||(e=rt.elements.container.className.indexOf(I.classes.captions.active)===-1),rt.captions.enabled=e,T(rt.elements.buttons.captions,rt.captions.enabled),y(rt.elements.container,I.classes.captions.active,rt.captions.enabled),V(rt.elements.container,rt.captions.enabled?"captionsenabled":"captionsdisabled",!0),fe({captions:rt.captions.enabled}))}function ue(){if(I.loadSprite){var e=Y();e.absolute?(ct("AJAX loading absolute SVG sprite"+(rt.browser.isIE?" (due to IE)":"")),P(e.url,"sprite-plyr")):ct("Sprite will be used as external resource directly")}l(I.controls,"play-large")&&(rt.elements.buttons.playLarge=K("play-large"),rt.elements.container.appendChild(rt.elements.buttons.playLarge)),rt.id=Math.floor(1e4*Math.random());var n,a=G({id:rt.id,seektime:I.seekTime,speed:Ee(),quality:"HD",captions:"English",loop:"None"});if(j.string(I.selectors.controls.container)&&(n=t.querySelector(I.selectors.controls.container)),j.htmlElement(n)||(n=rt.elements.container),n.appendChild(a),I.tooltips.controls)for(var s=D([I.selectors.controls.wrapper," ",I.selectors.labels," .",I.classes.hidden].join("")),i=s.length-1;i>=0;i--){var r=s[i];y(r,I.classes.hidden,!1),y(r,I.classes.tooltip,!0)}}function ce(){y(rt.elements.container,I.selectors.container.replace(".",""),rt.supported.full)}function de(e){e&&l(I.types.html5,rt.type)?rt.elements.media.setAttribute("controls",""):rt.elements.media.removeAttribute("controls")}function pe(e){var t=I.i18n.play;j.string(I.title)&&I.title.length&&(t+=", "+I.title,rt.elements.container.setAttribute("aria-label",I.title)),rt.supported.full&&(j.htmlElement(rt.elements.buttons.play)&&rt.elements.buttons.play.setAttribute("aria-label",t),j.htmlElement(rt.elements.buttons.playLarge)&&rt.elements.buttons.playLarge.setAttribute("aria-label",t)),j.htmlElement(e)&&e.setAttribute("title",I.i18n.frameTitle.replace("{title}",I.title))}function me(){var t=null;rt.storage={},R.storage&&I.storage.enabled&&(e.localStorage.removeItem("plyr-volume"),t=e.localStorage.getItem(I.storage.key),t&&(/^\d+(\.\d+)?$/.test(t)?fe({volume:parseFloat(t)}):rt.storage=JSON.parse(t)))}function fe(t){R.storage&&I.storage.enabled&&(E(rt.storage,t),e.localStorage.setItem(I.storage.key,JSON.stringify(rt.storage)))}function ye(){if(!rt.elements.media)return void dt("No media element found!");if(rt.supported.full&&(y(rt.elements.container,I.classes.type.replace("{0}",rt.type),!0),l(I.types.embed,rt.type)&&y(rt.elements.container,I.classes.type.replace("{0}","video"),!0),y(rt.elements.container,I.classes.pip.enabled,R.pip&&"video"===rt.type),y(rt.elements.container,I.classes.airplay.enabled,R.airplay&&l(I.types.html5,rt.type)),y(rt.elements.container,I.classes.stopped,I.autoplay),y(rt.elements.container,I.classes.isIos,rt.browser.isIos),y(rt.elements.container,I.classes.isTouch,rt.browser.isTouch),"video"===rt.type)){var e=d("div");e.setAttribute("class",I.classes.videoWrapper),i(rt.elements.media,e),rt.elements.wrapper=e}l(I.types.embed,rt.type)&&be()}function be(){var t,n=d("div"),s=rt.type+"-"+Math.floor(1e4*Math.random());switch(rt.type){case"youtube":t=A(rt.embedId);break;case"vimeo":t=_(rt.embedId);break;default:t=rt.embedId}for(var l=D('[id^="'+rt.type+'-"]'),i=l.length-1;i>=0;i--)r(l[i]);if(y(rt.elements.media,I.classes.videoWrapper,!0),y(rt.elements.media,I.classes.embedWrapper,!0),"youtube"===rt.type)rt.elements.media.appendChild(n),n.setAttribute("id",s),j.object(e.YT)?ge(t,n):(a(I.urls.youtube.api),e.onYouTubeReadyCallbacks=e.onYouTubeReadyCallbacks||[],e.onYouTubeReadyCallbacks.push(function(){ge(t,n)}),e.onYouTubeIframeAPIReady=function(){e.onYouTubeReadyCallbacks.forEach(function(e){e()})});else if("vimeo"===rt.type)if(rt.supported.full?rt.elements.media.appendChild(n):n=rt.elements.media,n.setAttribute("id",s),j.object(e.Vimeo))he(t,n);else{a(I.urls.vimeo.api);var o=e.setInterval(function(){j.object(e.Vimeo)&&(e.clearInterval(o),he(t,n))},50)}else if("soundcloud"===rt.type){var c=d("iframe");c.loaded=!1,w(c,"load",function(){c.loaded=!0}),u(c,{src:"https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/"+t,id:s}),n.appendChild(c),rt.elements.media.appendChild(n),e.SC||a(I.urls.soundcloud.api);var p=e.setInterval(function(){e.SC&&c.loaded&&(e.clearInterval(p),ke.call(c))},50)}}function ve(){rt.supported.full&&(st(),lt()),pe(W("iframe"))}function ge(t,n){rt.embed=new e.YT.Player(n.id,{videoId:t,playerVars:{autoplay:I.autoplay?1:0,controls:rt.supported.full?0:1,rel:0,showinfo:0,iv_load_policy:3,cc_load_policy:I.captions.defaultActive?1:0,cc_lang_pref:"en",wmode:"transparent",modestbranding:1,disablekb:1,origin:"*"},events:{onError:function(e){V(rt.elements.container,"error",!0,{code:e.data,embed:e.target})},onPlaybackQualityChange:function(e){var t=e.target,n=t.getPlaybackQuality();console.warn(n)},onReady:function(t){var n=t.target;rt.elements.media.play=function(){n.playVideo(),rt.elements.media.paused=!1},rt.elements.media.pause=function(){n.pauseVideo(),rt.elements.media.paused=!0},rt.elements.media.stop=function(){n.stopVideo(),rt.elements.media.paused=!0},rt.elements.media.duration=n.getDuration(),rt.elements.media.paused=!0,rt.elements.media.currentTime=0,rt.elements.media.muted=n.isMuted();var a=n.getPlaybackRate(),s=n.getAvailablePlaybackRates();console.warn(a,s),I.title=n.getVideoData().title,rt.supported.full&&rt.elements.media.querySelector("iframe").setAttribute("tabindex","-1"),ve(),V(rt.elements.media,"timeupdate"),V(rt.elements.media,"durationchange"),e.clearInterval(ot.buffering),ot.buffering=e.setInterval(function(){rt.elements.media.buffered=n.getVideoLoadedFraction(),(null===rt.elements.media.lastBuffered||rt.elements.media.lastBuffered=n)return;I.loop.end=n,I.loop.indicator.end=rt.elements.display.played.value;break;case"all":I.loop.start=0,I.loop.end=rt.elements.media.duration-2,I.loop.indicator.start=0,I.loop.indicator.end=100;break;case"toggle":I.loop.active?(I.loop.start=0,I.loop.end=null):(I.loop.start=0,I.loop.end=rt.elements.media.duration-2);break;default:I.loop.start=0,I.loop.end=null}I.loop.active=j.number(I.loop.start)&&j.number(I.loop.end);var a=(Ye(I.loop.start,W('[data-plyr-loop="start"]')),null);j.number(I.loop.end)&&(a=Ye(I.loop.end,t.querySelector('[data-loop__value="loopout"]'))),I.loop.active}function Se(e){if(j.undefined(e)&&(e=rt.storage.speed||I.defaultSpeed),!j.array(I.speeds))return void dt("Invalid speeds format");if(!j.number(e)){var t=I.speeds.indexOf(I.currentSpeed);if(t!==-1){var n=t+1;n>=I.speeds.length&&(n=0),e=I.speeds[n]}else e=I.defaultSpeed}I.currentSpeed=e,rt.elements.media.playbackRate=e,fe({speed:e})}function Ee(){return I.currentSpeed.toFixed(1).toString().replace(".0","")+"×"}function Ae(e){j.number(e)||(e=I.seekTime),Ie(rt.elements.media.currentTime-e)}function _e(e){j.number(e)||(e=I.seekTime),Ie(rt.elements.media.currentTime+e)}function Ie(e){var t=0,n=rt.elements.media.paused,a=Pe();j.number(e)?t=e:j.event(e)&&l(["input","change"],e.type)&&(t=e.target.value/e.target.max*a),t<0?t=0:t>a&&(t=a),Je(t);try{rt.elements.media.currentTime=t.toFixed(4)}catch(e){}if(l(I.types.embed,rt.type)){switch(rt.type){case"youtube":rt.embed.seekTo(t);break;case"vimeo":rt.embed.setCurrentTime(t.toFixed(0));break;case"soundcloud":rt.embed.seekTo(1e3*t)}n&&Ce(),V(rt.elements.media,"timeupdate"),rt.elements.media.seeking=!0,V(rt.elements.media,"seeking")}ct("Seeking to "+rt.elements.media.currentTime+" seconds"),ie(t)}function Pe(){var e=parseInt(I.duration),t=0;return null===rt.elements.media.duration||isNaN(rt.elements.media.duration)||(t=rt.elements.media.duration),isNaN(e)?t:e}function Ne(){y(rt.elements.container,I.classes.playing,!rt.elements.media.paused),y(rt.elements.container,I.classes.stopped,rt.elements.media.paused),Qe(rt.elements.media.paused)}function Fe(){L={x:e.pageXOffset||0,y:e.pageYOffset||0}}function qe(){e.scrollTo(L.x,L.y)}function Le(e){var n=R.fullscreen;if(n){if(!e||e.type!==M.eventType)return M.isFullScreen(rt.elements.container)?M.cancelFullScreen():(Fe(),M.requestFullScreen(rt.elements.container)),void(rt.fullscreen.active=M.isFullScreen(rt.elements.container));rt.fullscreen.active=M.isFullScreen(rt.elements.container)}else rt.fullscreen.active=!rt.fullscreen.active,t.body.style.overflow=rt.fullscreen.active?"hidden":"";y(rt.elements.container,I.classes.fullscreen.active,rt.fullscreen.active),H(rt.fullscreen.active),rt.elements.buttons&&rt.elements.buttons.fullscreen&&T(rt.elements.buttons.fullscreen,rt.fullscreen.active),V(rt.elements.container,rt.fullscreen.active?"enterfullscreen":"exitfullscreen",!0),!rt.fullscreen.active&&n&&qe()}function Oe(n){var a=rt.elements.settings.menu.parentNode,s=n.target,l=t.getElementById(s.getAttribute("aria-controls")),i="false"===s.getAttribute("aria-expanded");if(j.htmlElement(l)){var o,u,c,d="tabpanel"===l.getAttribute("role");if(d){var p=a.querySelector('[role="tabpanel"][aria-hidden="false"]');c=p.parentNode,[].forEach.call(a.querySelectorAll('[aria-controls="'+p.getAttribute("id")+'"]'),function(e){e.setAttribute("aria-expanded",!1)}),c.style.width=p.scrollWidth+"px",c.style.height=p.scrollHeight+"px",p.setAttribute("aria-hidden",!0),p.setAttribute("tabindex",-1);var m=l.cloneNode(!0);m.style.position="absolute",m.style.opacity=0,m.setAttribute("aria-hidden",!1),c.appendChild(m),o=m.scrollWidth,u=m.scrollHeight,r(m)}l.setAttribute("aria-hidden",!i),s.setAttribute("aria-expanded",i),l.setAttribute("tabindex",0),d&&(c.style.width=o+"px",c.style.height=u+"px",e.setTimeout(function(){c.style.width="",c.style.height=""},300))}}function je(e){if(j.boolean(e)||(e=!rt.elements.media.muted),T(rt.elements.buttons.mute,e),rt.elements.media.muted=e,0===rt.elements.media.volume&&Me(I.volume),l(I.types.embed,rt.type)){switch(rt.type){case"youtube":rt.embed[rt.elements.media.muted?"mute":"unMute"]();break;case"vimeo":case"soundcloud":rt.embed.setVolume(rt.elements.media.muted?0:parseFloat(I.volume/10))}V(rt.elements.media,"volumechange")}}function Me(e){var t=10,n=0;if(j.event(e)&&(e=e.target.value),j.undefined(e)&&(e=rt.storage.volume),(null===e||isNaN(e))&&(e=I.volume),e>t&&(e=t),e0&&je()}function Re(e){var t=rt.elements.media.muted?0:10*rt.elements.media.volume;j.number(e)||(e=1),Me(t+e)}function Ve(e){var t=rt.elements.media.muted?0:10*rt.elements.media.volume;j.number(e)||(e=1),Me(t-e)}function De(){var e=rt.elements.media.muted?0:10*rt.elements.media.volume;rt.supported.full&&(rt.elements.inputs.volume&&(rt.elements.inputs.volume.value=e),rt.elements.display.volume&&(rt.elements.display.volume.value=e)),fe({volume:e}),y(rt.elements.container,I.classes.muted,0===e),rt.supported.full&&rt.elements.buttons.mute&&T(rt.elements.buttons.mute,0===e)}function We(e){var t="waiting"===e.type;clearTimeout(ot.loading),ot.loading=setTimeout(function(){y(rt.elements.container,I.classes.loading,t),Qe(t)},t?250:0)}function He(e){if(rt.supported.full){var t=rt.elements.display.played,n=0,a=Pe();if(e)switch(e.type){case"timeupdate":case"seeking":if(rt.elements.controls.pressed)return;n=S(rt.elements.media.currentTime,a),"timeupdate"===e.type&&rt.elements.inputs.seek&&(rt.elements.inputs.seek.value=n);break;case"playing":case"progress":t=rt.elements.display.buffer,n=function(){var e=rt.elements.media.buffered;return e&&e.length?S(e.end(0),a):j.number(e)?100*e:0}()}j.number(I.loop.start)&&j.number(I.loop.end)&&rt.elements.media.currentTime>=I.loop.end&&Ie(I.loop.start),Be(t,n)}}function Be(e,t){if(rt.supported.full){if(j.undefined(t)&&(t=0),j.undefined(e)){if(!j.htmlElement(rt.elements.display.buffer))return;e=rt.elements.display.buffer}if(j.htmlElement(e)){e.value=t;var n=e.getElementsByTagName("span")[0];j.htmlElement(n)&&(n.childNodes[0].nodeValue=t)}}}function Ye(e,t){if(t){isNaN(e)&&(e=0); -var n=parseInt(e%60),a=parseInt(e/60%60),s=parseInt(e/60/60%60),l=parseInt(Pe()/60/60%60)>0;n=("0"+n).slice(-2),a=("0"+a).slice(-2);var i=(l?s+":":"")+a+":"+n;return t.textContent=i,i}}function Xe(){if(rt.supported.full){var e=Pe()||0;!rt.elements.display.duration&&I.displayDuration&&rt.elements.media.paused&&Ye(e,rt.elements.display.currentTime),rt.elements.display.duration&&Ye(e,rt.elements.display.duration),Ke()}}function Ue(e){Ye(rt.elements.media.currentTime,rt.elements.display.currentTime),e&&"timeupdate"===e.type&&rt.elements.media.seeking||He(e)}function Je(e){j.number(e)||(e=0);var t=Pe(),n=S(e,t);rt.elements.progress&&rt.elements.display.played&&(rt.elements.display.played.value=n),rt.elements.buttons&&rt.elements.inputs.seek&&(rt.elements.inputs.seek.value=n)}function Ke(e){var t=Pe();if(I.tooltips.seek&&j.htmlElement(rt.elements.inputs.seek)&&j.htmlElement(rt.elements.display.seekTooltip)&&0!==t){var n=rt.elements.inputs.seek.getBoundingClientRect(),a=0,s=I.classes.tooltip+"--visible";if(j.event(e))a=100/n.width*(e.pageX-n.left);else{if(!b(rt.elements.display.seekTooltip,s))return;a=rt.elements.display.seekTooltip.style.left.replace("%","")}a<0?a=0:a>100&&(a=100),Ye(t/100*a,rt.elements.display.seekTooltip),rt.elements.display.seekTooltip.style.left=a+"%",j.event(e)&&l(["mouseenter","mouseleave"],e.type)&&y(rt.elements.display.seekTooltip,s,"mouseenter"===e.type)}}function Qe(t){if(I.hideControls&&"audio"!==rt.type){var n=0,a=!1,s=t,i=b(rt.elements.container,I.classes.loading);if(j.boolean(t)||(t&&t.type?(a="enterfullscreen"===t.type,s=l(["mousemove","touchstart","mouseenter","focus"],t.type),l(["mousemove","touchmove"],t.type)&&(n=2e3),"focus"===t.type&&(n=3e3)):s=b(rt.elements.container,I.classes.hideControls)),e.clearTimeout(ot.hover),s||rt.elements.media.paused||i){if(y(rt.elements.container,I.classes.hideControls,!1),rt.elements.media.paused||i)return;rt.browser.isTouch&&(n=3e3)}s&&rt.elements.media.paused||(ot.hover=e.setTimeout(function(){(!rt.elements.controls.pressed&&!rt.elements.controls.hover||a)&&y(rt.elements.container,I.classes.hideControls,!0)},n))}}function ze(e){if(!j.undefined(e))return void $e(e);var t;switch(rt.type){case"youtube":t=rt.embed.getVideoUrl();break;case"vimeo":rt.embed.getVideoUrl.then(function(e){t=e});break;case"soundcloud":rt.embed.getCurrentSound(function(e){t=e.permalink_url});break;default:t=rt.elements.media.currentSrc}return t||""}function $e(e){function t(){if(rt.embed=null,r(rt.elements.media),"video"===rt.type&&rt.elements.wrapper&&r(rt.elements.wrapper),rt.elements.container&&rt.elements.container.removeAttribute("class"),"type"in e&&(rt.type=e.type,"video"===rt.type)){var t=e.sources[0];"type"in t&&l(I.types.embed,t.type)&&(rt.type=t.type)}switch(rt.supported=N(rt.type),rt.type){case"video":rt.elements.media=d("video");break;case"audio":rt.elements.media=d("audio");break;case"youtube":case"vimeo":case"soundcloud":rt.elements.media=d("div"),rt.embedId=e.sources[0].src}o(rt.elements.container,rt.elements.media),j.boolean(e.autoplay)&&(I.autoplay=e.autoplay),l(I.types.html5,rt.type)&&(I.crossorigin&&rt.elements.media.setAttribute("crossorigin",""),I.autoplay&&rt.elements.media.setAttribute("autoplay",""),"poster"in e&&rt.elements.media.setAttribute("poster",e.poster),I.loop.active&&rt.elements.media.setAttribute("loop","")),y(rt.elements.container,I.classes.fullscreen.active,rt.fullscreen.active),y(rt.elements.container,I.classes.captions.active,rt.captions.enabled),ce(),l(I.types.html5,rt.type)&&B("source",e.sources),ye(),l(I.types.html5,rt.type)&&("tracks"in e&&B("track",e.tracks),rt.elements.media.load()),(l(I.types.html5,rt.type)||l(I.types.embed,rt.type)&&!rt.supported.full)&&(st(),lt()),I.title=e.title,pe()}return j.object(e)&&"sources"in e&&e.sources.length?(y(rt.elements.container,I.classes.ready,!1),Ce(),Je(),Be(),tt(),void nt(t,!1)):void dt("Invalid source format")}function Ge(e){"video"===rt.type&&rt.elements.media.setAttribute("poster",e)}function Ze(){function n(){var e=xe(),t=rt.elements.buttons[e?"play":"pause"],n=rt.elements.buttons[e?"pause":"play"];if(n){var a=b(t,I.classes.tabFocus);setTimeout(function(){n.focus(),a&&(y(t,I.classes.tabFocus,!1),y(n,I.classes.tabFocus,!0))},100)}}function a(e){return e.keyCode?e.keyCode:e.which}function s(e){for(var t in rt.elements.buttons){var n=rt.elements.buttons[t];if(j.nodeList(n))for(var a=0;a0)&&(t?(Ve(n),a=-1):(Re(n),a=1)),(e.deltaY>0||e.deltaX<0)&&(t?(Re(n),a=1):(Ve(n),a=-1)),(1===a&&rt.elements.media.volume<1||a===-1&&rt.elements.media.volume>0)&&e.preventDefault()}),R.fullscreen&&w(t,M.eventType,Le)}function et(){if(w(rt.elements.media,"timeupdate seeking",Ue),w(rt.elements.media,"timeupdate",ie),w(rt.elements.media,"durationchange loadedmetadata",Xe),w(rt.elements.media,"ended",function(){"video"===rt.type&&I.showPosterOnEnd&&("video"===rt.type&&le(),Ie(),rt.elements.media.load())}),w(rt.elements.media,"progress playing",He),w(rt.elements.media,"volumechange",De),w(rt.elements.media,"play pause ended",Ne),w(rt.elements.media,"waiting canplay seeked",We),I.clickToPlay&&"audio"!==rt.type){var e=W("."+I.classes.videoWrapper);if(!e)return;e.style.cursor="pointer",w(e,"click",function(){I.hideControls&&rt.browser.isTouch&&!rt.elements.media.paused||(rt.elements.media.paused?we():rt.elements.media.ended?(Ie(),we()):Ce())})}I.disableContextMenu&&w(rt.elements.media,"contextmenu",function(e){e.preventDefault()}),w(rt.elements.media,I.events.concat(["keyup","keydown"]).join(" "),function(e){V(rt.elements.container,e.type,!0)})}function tt(){if(l(I.types.html5,rt.type)){for(var e=rt.elements.media.querySelectorAll("source"),t=0;t=0;n--){var a=n>0?t.cloneNode(!0):t,l=e[n],s=l.parentNode,i=l.nextSibling;return a.appendChild(l),i?s.insertBefore(a,i):s.appendChild(a),a}}function r(e){e&&e.parentNode.removeChild(e)}function o(e,t){e.insertBefore(t,e.firstChild)}function u(e,t){for(var n in t)e.setAttribute(n,t[n])}function c(e,t){if(!j.string(e)||j.empty(e))return{};var n={};return e.split(",").forEach(function(e){e=e.trim();var a=e.charAt(0);switch(a){case".":var l=e.replace(".","");j.object(t)&&j.string(t.class)&&(t.class+=" "+l),n.class=l;break;case"#":n.id=e.replace("#","");break;case"[":e=e.replace(/[\[\]]/g,"");var s=e.split("="),i=s[0],r=s.length>1?s[1].replace(/[\"\']/g,""):"";n[i]=r}}),n}function d(e,n,a){var l=t.createElement(e);return j.object(n)&&u(l,n),j.string(a)&&(l.textContent=a),l}function p(e,t,n,a){var l=d(e,n,a);o(t,l)}function m(e){for(var t=e.childNodes.length;t--;)e.removeChild(e.lastChild)}function f(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 y(e,t){return!!e&&(e.classList?e.classList.contains(t):new RegExp("(\\s|^)"+t+"(\\s|$)").test(e.className))}function b(e,n){var a=Element.prototype,l=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.msMatchesSelector||function(e){return[].indexOf.call(t.querySelectorAll(e),this)!==-1};return l.call(e,n)}function g(){var e=t.activeElement;return e=e&&e!==t.body?t.querySelector(":focus"):null}function v(e,t,n,a,l){k(e,t,function(t){n&&n.apply(e,[t]),a.apply(e,[t])},l)}function h(e,t,n,a,l){var s=t.split(" ");if(j.boolean(l)||(l=!1),e instanceof NodeList)for(var i=0;i0&&se(t)),te()}}function le(){return!V.textTracks||j.empty(ot.captions.tracks)?"No Subs":ot.captions.enabled?ot.captions.currentTrack.label:"Disabled"}function se(e){j.event(e)&&(e=e.target);var t=e.activeCues[0];j.cue(t)?re(t.getCueAsHTML()):re()}function ie(e){j.string(e)?_.captions.language=e.toLowerCase():j.event(e)&&(_.captions.language=e.target.value.toLowerCase()),re(),ae()}function re(e){var t=W(_.selectors.captions);if(j.htmlElement(t)){var n=d("span");m(t),j.undefined(e)&&(e=""),j.string(e)?n.textContent=e.trim():n.appendChild(e),t.appendChild(n)}}function oe(){if(ot.elements.buttons.captions){f(ot.elements.container,_.classes.captions.enabled,!0);var e=ot.storage.captions;j.boolean(e)||(e=_.captions.defaultActive),e&&(f(ot.elements.container,_.classes.captions.active,!0),T(ot.elements.buttons.captions,!0))}}function ue(e){ot.supported.full&&ot.elements.buttons.captions&&(j.boolean(e)||(e=ot.elements.container.className.indexOf(_.classes.captions.active)===-1),ot.captions.enabled=e,T(ot.elements.buttons.captions,ot.captions.enabled),f(ot.elements.container,_.classes.captions.active,ot.captions.enabled),R(ot.elements.container,ot.captions.enabled?"captionsenabled":"captionsdisabled",!0),ye({captions:ot.captions.enabled}))}function ce(){if(_.loadSprite){var e=H();e.absolute?(dt("AJAX loading absolute SVG sprite"+(ot.browser.isIE?" (due to IE)":"")),P(e.url,"sprite-plyr")):dt("Sprite will be used as external resource directly")}s(_.controls,"play-large")&&(ot.elements.buttons.playLarge=X("play-large"),ot.elements.container.appendChild(ot.elements.buttons.playLarge)),ot.id=Math.floor(1e4*Math.random());var n,a=$({id:ot.id,seektime:_.seekTime,speed:Ae(),quality:"HD",captions:le(),loop:"None"});if(j.string(_.selectors.controls.container)&&(n=t.querySelector(_.selectors.controls.container)),j.htmlElement(n)||(n=ot.elements.container),n.appendChild(a),_.tooltips.controls)for(var l=D([_.selectors.controls.wrapper," ",_.selectors.labels," .",_.classes.hidden].join("")),i=l.length-1;i>=0;i--){var r=l[i];f(r,_.classes.hidden,!1),f(r,_.classes.tooltip,!0)}}function de(){f(ot.elements.container,_.selectors.container.replace(".",""),ot.supported.full)}function pe(e){e&&s(O.html5,ot.type)?ot.elements.media.setAttribute("controls",""):ot.elements.media.removeAttribute("controls")}function me(e){var t=_.i18n.play;j.string(_.title)&&_.title.length&&(t+=", "+_.title,ot.elements.container.setAttribute("aria-label",_.title)),ot.supported.full&&(j.htmlElement(ot.elements.buttons.play)&&ot.elements.buttons.play.setAttribute("aria-label",t),j.htmlElement(ot.elements.buttons.playLarge)&&ot.elements.buttons.playLarge.setAttribute("aria-label",t)),j.htmlElement(e)&&e.setAttribute("title",_.i18n.frameTitle.replace("{title}",_.title))}function fe(){var t=null;ot.storage={},V.storage&&_.storage.enabled&&(e.localStorage.removeItem("plyr-volume"),t=e.localStorage.getItem(_.storage.key),t&&(/^\d+(\.\d+)?$/.test(t)?ye({volume:parseFloat(t)}):ot.storage=JSON.parse(t)))}function ye(t){V.storage&&_.storage.enabled&&(E(ot.storage,t),e.localStorage.setItem(_.storage.key,JSON.stringify(ot.storage)))}function be(){if(!ot.elements.media)return void pt("No media element found!");if(ot.supported.full&&(f(ot.elements.container,_.classes.type.replace("{0}",ot.type),!0),s(O.embed,ot.type)&&f(ot.elements.container,_.classes.type.replace("{0}","video"),!0),f(ot.elements.container,_.classes.pip.enabled,V.pip&&"video"===ot.type),f(ot.elements.container,_.classes.airplay.enabled,V.airplay&&s(O.html5,ot.type)),f(ot.elements.container,_.classes.stopped,_.autoplay),f(ot.elements.container,_.classes.isIos,ot.browser.isIos),f(ot.elements.container,_.classes.isTouch,ot.browser.isTouch),"video"===ot.type)){var e=d("div");e.setAttribute("class",_.classes.videoWrapper),i(ot.elements.media,e),ot.elements.wrapper=e}s(O.embed,ot.type)&&ge()}function ge(){var t,n=d("div"),l=ot.type+"-"+Math.floor(1e4*Math.random());switch(ot.type){case"youtube":t=x(ot.embedId);break;case"vimeo":t=A(ot.embedId);break;default:t=ot.embedId}for(var s=D('[id^="'+ot.type+'-"]'),i=s.length-1;i>=0;i--)r(s[i]);if(f(ot.elements.media,_.classes.videoWrapper,!0),f(ot.elements.media,_.classes.embedWrapper,!0),"youtube"===ot.type)ot.elements.media.appendChild(n),n.setAttribute("id",l),j.object(e.YT)?he(t,n):(a(_.urls.youtube.api),e.onYouTubeReadyCallbacks=e.onYouTubeReadyCallbacks||[],e.onYouTubeReadyCallbacks.push(function(){he(t,n)}),e.onYouTubeIframeAPIReady=function(){e.onYouTubeReadyCallbacks.forEach(function(e){e()})});else if("vimeo"===ot.type)if(ot.supported.full?ot.elements.media.appendChild(n):n=ot.elements.media,n.setAttribute("id",l),j.object(e.Vimeo))ke(t,n);else{a(_.urls.vimeo.api);var o=e.setInterval(function(){j.object(e.Vimeo)&&(e.clearInterval(o),ke(t,n))},50)}else if("soundcloud"===ot.type){var c=d("iframe");c.loaded=!1,k(c,"load",function(){c.loaded=!0}),u(c,{src:"https://w.soundcloud.com/player/?url=https://api.soundcloud.com/tracks/"+t,id:l}),n.appendChild(c),ot.elements.media.appendChild(n),e.SC||a(_.urls.soundcloud.api);var p=e.setInterval(function(){e.SC&&c.loaded&&(e.clearInterval(p),Ce.call(c))},50)}}function ve(){ot.supported.full&&(st(),it()),me(W("iframe"))}function he(t,n){ot.embed=new e.YT.Player(n.id,{videoId:t,playerVars:{autoplay:_.autoplay?1:0,controls:ot.supported.full?0:1,rel:0,showinfo:0,iv_load_policy:3,cc_load_policy:_.captions.defaultActive?1:0,cc_lang_pref:"en",wmode:"transparent",modestbranding:1,disablekb:1,origin:"*"},events:{onError:function(e){R(ot.elements.container,"error",!0,{code:e.data,embed:e.target})},onPlaybackQualityChange:function(e){var t=e.target,n=t.getPlaybackQuality();console.warn(n)},onReady:function(t){var n=t.target;ot.elements.media.play=function(){n.playVideo(),ot.elements.media.paused=!1},ot.elements.media.pause=function(){n.pauseVideo(),ot.elements.media.paused=!0},ot.elements.media.stop=function(){n.stopVideo(),ot.elements.media.paused=!0},ot.elements.media.duration=n.getDuration(),ot.elements.media.paused=!0,ot.elements.media.currentTime=0,ot.elements.media.muted=n.isMuted();var a=n.getPlaybackRate(),l=n.getAvailablePlaybackRates();console.warn(a,l),_.title=n.getVideoData().title,ot.supported.full&&ot.elements.media.querySelector("iframe").setAttribute("tabindex","-1"),ve(),R(ot.elements.media,"timeupdate"),R(ot.elements.media,"durationchange"),e.clearInterval(ut.buffering),ut.buffering=e.setInterval(function(){ot.elements.media.buffered=n.getVideoLoadedFraction(),(null===ot.elements.media.lastBuffered||ot.elements.media.lastBuffered=n)return;_.loop.end=n,_.loop.indicator.end=ot.elements.display.played.value;break;case"all":_.loop.start=0,_.loop.end=ot.elements.media.duration-2,_.loop.indicator.start=0,_.loop.indicator.end=100;break;case"toggle":_.loop.active?(_.loop.start=0,_.loop.end=null):(_.loop.start=0,_.loop.end=ot.elements.media.duration-2);break;default:_.loop.start=0,_.loop.end=null}_.loop.active=j.number(_.loop.start)&&j.number(_.loop.end);var a=(Ue(_.loop.start,W('[data-plyr-loop="start"]')),null);j.number(_.loop.end)&&(a=Ue(_.loop.end,t.querySelector('[data-loop__value="loopout"]'))),_.loop.active}function xe(e){if(j.undefined(e)&&(e=ot.storage.speed||_.defaultSpeed),!j.array(_.speeds))return void pt("Invalid speeds format");if(!j.number(e)){var t=_.speeds.indexOf(_.currentSpeed);if(t!==-1){var n=t+1;n>=_.speeds.length&&(n=0),e=_.speeds[n]}else e=_.defaultSpeed}_.currentSpeed=e,ot.elements.media.playbackRate=e,ye({speed:e})}function Ae(){return _.currentSpeed.toFixed(1).toString().replace(".0","")+"×"}function _e(e){j.number(e)||(e=_.seekTime),Ie(ot.elements.media.currentTime-e)}function Pe(e){j.number(e)||(e=_.seekTime),Ie(ot.elements.media.currentTime+e)}function Ie(e){var t=0,n=ot.elements.media.paused,a=Ne();j.number(e)?t=e:j.event(e)&&s(["input","change"],e.type)&&(t=e.target.value/e.target.max*a),t<0?t=0:t>a&&(t=a),Xe(t);try{ot.elements.media.currentTime=t.toFixed(4)}catch(e){}if(s(O.embed,ot.type)){switch(ot.type){case"youtube":ot.embed.seekTo(t);break;case"vimeo":ot.embed.setCurrentTime(t.toFixed(0));break;case"soundcloud":ot.embed.seekTo(1e3*t)}n&&Te(),R(ot.elements.media,"timeupdate"),ot.elements.media.seeking=!0,R(ot.elements.media,"seeking")}dt("Seeking to "+ot.elements.media.currentTime+" seconds")}function Ne(){var e=parseInt(_.duration),t=0;return null===ot.elements.media.duration||isNaN(ot.elements.media.duration)||(t=ot.elements.media.duration),isNaN(e)?t:e}function Fe(){f(ot.elements.container,_.classes.playing,!ot.elements.media.paused),f(ot.elements.container,_.classes.stopped,ot.elements.media.paused),Ge(ot.elements.media.paused)}function qe(){q={x:e.pageXOffset||0,y:e.pageYOffset||0}}function Le(){e.scrollTo(q.x,q.y)}function Oe(e){var n=V.fullscreen;if(n){if(!e||e.type!==M.eventType)return M.isFullScreen(ot.elements.container)?M.cancelFullScreen():(qe(),M.requestFullScreen(ot.elements.container)),void(ot.fullscreen.active=M.isFullScreen(ot.elements.container));ot.fullscreen.active=M.isFullScreen(ot.elements.container)}else ot.fullscreen.active=!ot.fullscreen.active,t.body.style.overflow=ot.fullscreen.active?"hidden":"";f(ot.elements.container,_.classes.fullscreen.active,ot.fullscreen.active),B(ot.fullscreen.active),ot.elements.buttons&&ot.elements.buttons.fullscreen&&T(ot.elements.buttons.fullscreen,ot.fullscreen.active),R(ot.elements.container,ot.fullscreen.active?"enterfullscreen":"exitfullscreen",!0),!ot.fullscreen.active&&n&&Le()}function je(n){var a=ot.elements.settings.menu.parentNode,l=n.target,s=t.getElementById(l.getAttribute("aria-controls")),i="false"===l.getAttribute("aria-expanded");if(j.htmlElement(s)){var o,u,c,d="tabpanel"===s.getAttribute("role");if(d){var p=a.querySelector('[role="tabpanel"][aria-hidden="false"]');c=p.parentNode,[].forEach.call(a.querySelectorAll('[aria-controls="'+p.getAttribute("id")+'"]'),function(e){e.setAttribute("aria-expanded",!1)}),c.style.width=p.scrollWidth+"px",c.style.height=p.scrollHeight+"px",p.setAttribute("aria-hidden",!0),p.setAttribute("tabindex",-1);var m=s.cloneNode(!0);m.style.position="absolute",m.style.opacity=0,m.setAttribute("aria-hidden",!1),c.appendChild(m),o=m.scrollWidth,u=m.scrollHeight,r(m)}s.setAttribute("aria-hidden",!i),l.setAttribute("aria-expanded",i),s.setAttribute("tabindex",0),d&&(c.style.width=o+"px",c.style.height=u+"px",e.setTimeout(function(){c.style.width="",c.style.height=""},300))}}function Me(e){if(j.boolean(e)||(e=!ot.elements.media.muted),T(ot.elements.buttons.mute,e),ot.elements.media.muted=e,0===ot.elements.media.volume&&Ve(_.volume),s(O.embed,ot.type)){switch(ot.type){case"youtube":ot.embed[ot.elements.media.muted?"mute":"unMute"]();break;case"vimeo":case"soundcloud":ot.embed.setVolume(ot.elements.media.muted?0:parseFloat(_.volume/10))}R(ot.elements.media,"volumechange")}}function Ve(e){var t=10,n=0;if(j.event(e)&&(e=e.target.value),j.undefined(e)&&(e=ot.storage.volume),(null===e||isNaN(e))&&(e=_.volume),e>t&&(e=t),e0&&Me()}function Re(e){var t=ot.elements.media.muted?0:10*ot.elements.media.volume;j.number(e)||(e=1),Ve(t+e)}function De(e){var t=ot.elements.media.muted?0:10*ot.elements.media.volume;j.number(e)||(e=1),Ve(t-e)}function We(){var e=ot.elements.media.muted?0:10*ot.elements.media.volume;ot.supported.full&&(ot.elements.inputs.volume&&(ot.elements.inputs.volume.value=e),ot.elements.display.volume&&(ot.elements.display.volume.value=e)),ye({volume:e}),f(ot.elements.container,_.classes.muted,0===e),ot.supported.full&&ot.elements.buttons.mute&&T(ot.elements.buttons.mute,0===e)}function Be(e){var t="waiting"===e.type;clearTimeout(ut.loading),ut.loading=setTimeout(function(){f(ot.elements.container,_.classes.loading,t),Ge(t)},t?250:0)}function Ye(e){if(ot.supported.full){var t=ot.elements.display.played,n=0,a=Ne();if(e)switch(e.type){case"timeupdate":case"seeking":if(ot.elements.controls.pressed)return;n=S(ot.elements.media.currentTime,a),"timeupdate"===e.type&&ot.elements.inputs.seek&&(ot.elements.inputs.seek.value=n);break;case"playing":case"progress":t=ot.elements.display.buffer,n=function(){var e=ot.elements.media.buffered;return e&&e.length?S(e.end(0),a):j.number(e)?100*e:0}()}j.number(_.loop.start)&&j.number(_.loop.end)&&ot.elements.media.currentTime>=_.loop.end&&Ie(_.loop.start),He(t,n)}}function He(e,t){if(ot.supported.full){if(j.undefined(t)&&(t=0),j.undefined(e)){if(!j.htmlElement(ot.elements.display.buffer))return;e=ot.elements.display.buffer}if(j.htmlElement(e)){e.value=t;var n=e.getElementsByTagName("span")[0];j.htmlElement(n)&&(n.childNodes[0].nodeValue=t)}}}function Ue(e,t){if(t){isNaN(e)&&(e=0);var n=parseInt(e%60),a=parseInt(e/60%60),l=parseInt(e/60/60%60),s=parseInt(Ne()/60/60%60)>0;n=("0"+n).slice(-2),a=("0"+a).slice(-2);var i=(s?l+":":"")+a+":"+n;return t.textContent=i,i}}function Ke(){if(ot.supported.full){var e=Ne()||0;!ot.elements.display.duration&&_.displayDuration&&ot.elements.media.paused&&Ue(e,ot.elements.display.currentTime),ot.elements.display.duration&&Ue(e,ot.elements.display.duration),ze()}}function Qe(e){Ue(ot.elements.media.currentTime,ot.elements.display.currentTime),e&&"timeupdate"===e.type&&ot.elements.media.seeking||Ye(e)}function Xe(e){j.number(e)||(e=0);var t=Ne(),n=S(e,t);ot.elements.progress&&ot.elements.display.played&&(ot.elements.display.played.value=n),ot.elements.buttons&&ot.elements.inputs.seek&&(ot.elements.inputs.seek.value=n)}function ze(e){var t=Ne();if(_.tooltips.seek&&j.htmlElement(ot.elements.inputs.seek)&&j.htmlElement(ot.elements.display.seekTooltip)&&0!==t){var n=ot.elements.inputs.seek.getBoundingClientRect(),a=0,l=_.classes.tooltip+"--visible";if(j.event(e))a=100/n.width*(e.pageX-n.left);else{if(!y(ot.elements.display.seekTooltip,l))return;a=ot.elements.display.seekTooltip.style.left.replace("%","")}a<0?a=0:a>100&&(a=100),Ue(t/100*a,ot.elements.display.seekTooltip),ot.elements.display.seekTooltip.style.left=a+"%", +j.event(e)&&s(["mouseenter","mouseleave"],e.type)&&f(ot.elements.display.seekTooltip,l,"mouseenter"===e.type)}}function Ge(t){if(_.hideControls&&"audio"!==ot.type){var n=0,a=!1,l=t,i=y(ot.elements.container,_.classes.loading);if(j.boolean(t)||(t&&t.type?(a="enterfullscreen"===t.type,l=s(["mousemove","touchstart","mouseenter","focus"],t.type),s(["mousemove","touchmove"],t.type)&&(n=2e3),"focus"===t.type&&(n=3e3)):l=y(ot.elements.container,_.classes.hideControls)),e.clearTimeout(ut.hover),l||ot.elements.media.paused||i){if(f(ot.elements.container,_.classes.hideControls,!1),ot.elements.media.paused||i)return;ot.browser.isTouch&&(n=3e3)}l&&ot.elements.media.paused||(ut.hover=e.setTimeout(function(){(!ot.elements.controls.pressed&&!ot.elements.controls.hover||a)&&f(ot.elements.container,_.classes.hideControls,!0)},n))}}function Je(e){if(!j.undefined(e))return void $e(e);var t;switch(ot.type){case"youtube":t=ot.embed.getVideoUrl();break;case"vimeo":ot.embed.getVideoUrl.then(function(e){t=e});break;case"soundcloud":ot.embed.getCurrentSound(function(e){t=e.permalink_url});break;default:t=ot.elements.media.currentSrc}return t||""}function $e(e){function t(){if(ot.embed=null,r(ot.elements.media),"video"===ot.type&&ot.elements.wrapper&&r(ot.elements.wrapper),ot.elements.container&&ot.elements.container.removeAttribute("class"),"type"in e&&(ot.type=e.type,"video"===ot.type)){var t=e.sources[0];"type"in t&&s(O.embed,t.type)&&(ot.type=t.type)}switch(ot.supported=I(ot.type),ot.type){case"video":ot.elements.media=d("video");break;case"audio":ot.elements.media=d("audio");break;case"youtube":case"vimeo":case"soundcloud":ot.elements.media=d("div"),ot.embedId=e.sources[0].src}o(ot.elements.container,ot.elements.media),j.boolean(e.autoplay)&&(_.autoplay=e.autoplay),s(O.html5,ot.type)&&(_.crossorigin&&ot.elements.media.setAttribute("crossorigin",""),_.autoplay&&ot.elements.media.setAttribute("autoplay",""),"poster"in e&&ot.elements.media.setAttribute("poster",e.poster),_.loop.active&&ot.elements.media.setAttribute("loop","")),f(ot.elements.container,_.classes.fullscreen.active,ot.fullscreen.active),f(ot.elements.container,_.classes.captions.active,ot.captions.enabled),de(),s(O.html5,ot.type)&&Y("source",e.sources),be(),s(O.html5,ot.type)&&("tracks"in e&&Y("track",e.tracks),ot.elements.media.load()),(s(O.html5,ot.type)||s(O.embed,ot.type)&&!ot.supported.full)&&(st(),it()),_.title=e.title,me()}return j.object(e)&&"sources"in e&&e.sources.length?(f(ot.elements.container,_.classes.ready,!1),Te(),Xe(),He(),nt(),void at(t,!1)):void pt("Invalid source format")}function Ze(e){"video"===ot.type&&ot.elements.media.setAttribute("poster",e)}function et(){function n(){var e=Se(),t=ot.elements.buttons[e?"play":"pause"],n=ot.elements.buttons[e?"pause":"play"];if(n){var a=y(t,_.classes.tabFocus);setTimeout(function(){n.focus(),a&&(f(t,_.classes.tabFocus,!1),f(n,_.classes.tabFocus,!0))},100)}}function a(e){return e.keyCode?e.keyCode:e.which}function l(e){for(var t in ot.elements.buttons){var n=ot.elements.buttons[t];if(j.nodeList(n))for(var a=0;a0)&&(t?(De(n),a=-1):(Re(n),a=1)),(e.deltaY>0||e.deltaX<0)&&(t?(Re(n),a=1):(De(n),a=-1)),(1===a&&ot.elements.media.volume<1||a===-1&&ot.elements.media.volume>0)&&e.preventDefault()}),V.fullscreen&&k(t,M.eventType,Oe)}function tt(){if(k(ot.elements.media,"timeupdate seeking",Qe),k(ot.elements.media,"durationchange loadedmetadata",Ke),k(ot.elements.media,"ended",function(){"video"===ot.type&&_.showPosterOnEnd&&("video"===ot.type&&re(),Ie(),ot.elements.media.load())}),k(ot.elements.media,"progress playing",Ye),k(ot.elements.media,"volumechange",We),k(ot.elements.media,"play pause ended",Fe),k(ot.elements.media,"waiting canplay seeked",Be),_.clickToPlay&&"audio"!==ot.type){var e=W("."+_.classes.videoWrapper);if(!e)return;e.style.cursor="pointer",k(e,"click",function(){_.hideControls&&ot.browser.isTouch&&!ot.elements.media.paused||(ot.elements.media.paused?we():ot.elements.media.ended?(Ie(),we()):Te())})}_.disableContextMenu&&k(ot.elements.media,"contextmenu",function(e){e.preventDefault()}),k(ot.elements.media,_.events.concat(["keyup","keydown"]).join(" "),function(e){R(ot.elements.container,e.type,!0)})}function nt(){if(s(O.html5,ot.type)){for(var e=ot.elements.media.querySelectorAll("source"),t=0;t or src attribute (or maybe use currentSrc?) for HTML5 and links for embedded players +- Controls hide/show events # Notes - No quality HTML5 support (yet) - No Vimeo quality support - No Vimeo or YouTube caption support - No PiP or AirPlay for Vimeo/YouTube +- Settings won't be supported for custom controls (coming soon, need to work on templating) #### Bugs - Fix audio setup bug when calling .setup() again @@ -26,7 +25,7 @@ - Look at Vimeo's "background" option #### Breaking changes -- Custom controls HTML removed (temporarily, will return) - perhaps can re-instate but no options UI +- New config options for loop - Selectors changes (new `input` and `display` object) - DOCUMENT ## Added diff --git a/src/js/plyr.js b/src/js/plyr.js index 55bdd252..99a70b88 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -37,20 +37,8 @@ enabled: true, debug: false, autoplay: false, - loop: { - active: false, - start: 0, - end: null, - indicator: { - start: 0, - end: 0 - } - }, seekTime: 10, volume: 10, - defaultSpeed: 1.0, - currentSpeed: 1, - speeds: [0.5, 1.0, 1.5, 2.0], duration: null, displayDuration: true, loadSprite: true, @@ -60,18 +48,44 @@ hideControls: true, showPosterOnEnd: false, disableContextMenu: true, + + // Quality settings quality: { - options: false + default: 'auto', + selected: 'auto' }, + + // Set loops + loop: { + active: false, + start: 0, + end: null, + indicator: { + start: 0, + end: 0 + } + }, + + // Speed up/down + speed: { + selected: 1.0, + options: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0] + }, + + // Keyboard shortcut settings keyboardShortcuts: { focused: true, global: false }, + + // Display tooltips tooltips: { controls: false, seek: true }, - tracks: [], + + // Selectors + // Change these to match your template if using custom HTML selectors: { html5: 'video, audio', embed: '[data-type]', @@ -94,14 +108,14 @@ pip: '[data-plyr="pip"]', airplay: '[data-plyr="airplay"]', settings: '[data-plyr="settings"]', - speed: '[data-plyr="speed"]', - loop: '[data-plyr="loop"]', - language: '[data-plyr="language"]', - quality: '[data-plyr="quality"]' + loop: '[data-plyr="loop"]' }, inputs: { seek: '[data-plyr="seek"]', - volume: '[data-plyr="volume"]' + volume: '[data-plyr="volume"]', + speed: '[data-plyr="speed"]', + language: '[data-plyr="language"]', + quality: '[data-plyr="quality"]' }, display: { currentTime: '.plyr__time--current', @@ -117,6 +131,8 @@ quality: '.js-plyr__menu__list--quality' } }, + + // Class hooks added to the player in different states classes: { setup: 'plyr--setup', ready: 'plyr--ready', @@ -156,19 +172,27 @@ }, tabFocus: 'tab-focus' }, + + // Captions settings captions: { defaultActive: false, - selectedIndex: 0 + language: window.navigator.language.split("-")[0] }, + + // Fullscreen settings fullscreen: { enabled: true, fallback: true, allowAudio: false }, + + // Local storage storage: { enabled: true, key: 'plyr' }, + + // Default controls controls: [ 'play-large', 'play', @@ -182,6 +206,8 @@ 'airplay', 'fullscreen' ], + + // Localisation i18n: { restart: 'Restart', rewind: 'Rewind {seektime} secs', @@ -208,10 +234,7 @@ all: 'All', reset: 'Reset', }, - types: { - embed: ['youtube', 'vimeo', 'soundcloud'], - html5: ['video', 'audio'] - }, + // URLs urls: { vimeo: { @@ -224,6 +247,7 @@ api: 'https://w.soundcloud.com/player/api.js' } }, + // Custom control listeners listeners: { seek: null, @@ -243,7 +267,8 @@ loop: null, language: null }, - // Events to watch on HTML5 media elements + + // Events to watch on HTML5 media elements and bubble events: [ 'ready', 'ended', @@ -265,10 +290,17 @@ 'seeked', 'emptied' ], + // Logging logPrefix: '' }; + // Types + var types = { + embed: ['youtube', 'vimeo', 'soundcloud'], + html5: ['video', 'audio'] + }; + // Check variable types var is = { object: function(input) { @@ -298,6 +330,12 @@ event: function(input) { return input !== null && input instanceof Event; }, + cue: function(input) { + return input !== null && (input instanceof window.TextTrackCue || input instanceof window.VTTCue); + }, + track: function(input) { + return input !== null && input instanceof window.TextTrack; + }, undefined: function(input) { return input !== null && typeof input === 'undefined'; }, @@ -389,13 +427,14 @@ } // Inject a script - function injectScript(source) { - if (document.querySelectorAll('script[src="' + source + '"]').length) { + function injectScript(url) { + // Check script is not already referenced + if (document.querySelectorAll('script[src="' + url + '"]').length) { return; } var tag = document.createElement('script'); - tag.src = source; + tag.src = url; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); @@ -569,11 +608,6 @@ } } - // Get a classname from selector - function getClassname(selector) { - return selector.replace('.', ''); - } - // Toggle class on an element function toggleClass(element, className, state) { if (element) { @@ -860,7 +894,8 @@ var support = { // Fullscreen support and set prefix fullscreen: fullscreen.prefix !== false, - // Local storage mode + + // Local storage // We can't assume if local storage is present that we can use it storage: (function() { if (!('localStorage' in window)) { @@ -887,16 +922,19 @@ return false; })(), + // Picture-in-picture support // Safari only currently pip: (function() { return is.function(createElement('video').webkitSetPresentationMode); })(), + // Airplay support // Safari only currently airplay: (function() { return is.function(window.WebKitPlaybackTargetAvailabilityEvent); })(), + // Check for mime type support against a player instance // Credits: http://diveintohtml5.info/everything.html // Related: http://www.leanbackplayer.com/test/h5mt.html @@ -935,7 +973,12 @@ // If we got this far, we're stuffed return false; - } + }, + + // Check for textTracks support + textTracks: (function() { + return 'textTracks' in document.createElement('video'); + })() }; // Player instance @@ -950,6 +993,7 @@ // Elements cache player.elements = { + container: null, buttons: {}, display: {}, progress: {}, @@ -959,37 +1003,29 @@ panes: {}, tabs: {} }, - media: media + media: media, + captions: null }; // Captions player.captions = { enabled: false, - textTracks: false, - captions: [] + captions: [], + tracks: [], + currentTrack: null }; // Set media var original = media.cloneNode(true); // Debugging - function logger(type, args) { - if (config.debug && window.console) { - args = Array.prototype.slice.call(args); - - if (is.string(config.logPrefix) && config.logPrefix.length) { - args.unshift(config.logPrefix); - } - - window.console[type].apply(window.console, args); - } + var log = function() {}; + var warn = function() {}; + if (config.debug && 'console' in window) { + log = window.console.log; + warn = window.console.warn; } - var log = function() { - logger('log', arguments); - }; - var warn = function() { - logger('warn', arguments); - }; + // Log config options and support log('Config', config); log('Support', support); @@ -1200,7 +1236,8 @@ min: 0, max: 100, step: 0.1, - value: 0 + value: 0, + autocomplete: 'off' }, attributes)); player.elements.inputs[type] = input; @@ -1394,8 +1431,7 @@ id: 'plyr-settings-' + data.id + '-home', 'aria-hidden': false, 'aria-labelled-by': 'plyr-settings-toggle-' + data.id, - role: 'tabpanel', - tabindex: -1 + role: 'tabpanel' }); var tabs = createElement('ul', { @@ -1440,7 +1476,7 @@ var pane = createElement('div', { id: 'plyr-settings-' + data.id + '-' + type, 'aria-hidden': true, - 'aria-labelled-by': 'plyr-settings-tab-' + data.id, + 'aria-labelled-by': 'plyr-settings-' + data.id + '-' + type + '-tab', role: 'tabpanel', tabindex: -1 }); @@ -1457,29 +1493,6 @@ var options = createElement('ul'); - /*switch (type) { - case 'captions': - if (is.array(config.tracks)) { - config.tracks.forEach(function(track, index) { - if (is.function(track)) { - return; - } - - var option = createElement('li'); - - var button = createButton('language', { - 'data-language': track.srclang, - 'data-index': index - }, track.label); - - option.appendChild(button); - - options.appendChild(options); - }); - } - break; - }*/ - pane.appendChild(options); inner.appendChild(pane); @@ -1494,183 +1507,6 @@ controls.appendChild(menu); player.elements.settings.menu = menu; - - /*html.push( - '
', - '', - '', - '
' - ); */ } // Picture in picture button @@ -1691,6 +1527,7 @@ player.elements.controls = controls; setLoopMenu(); + setSpeedMenu(); return controls; } @@ -1698,15 +1535,11 @@ // Set the YouTube quality menu // TODO: Support for HTML5 // YouTube: "hd2160", "hd1440", "hd1080", "hd720", "large", "medium", "small", "tiny", "auto" - function setQualityMenu(available, current) { - if (is.object(player.quality)) { - return; - } + function setQualityMenu(options, current) { + var list = player.elements.settings.panes.quality.querySelector('ul'); - player.quality = { - available: available, - current: current - }; + // Empty the menu + emptyElement(list); // Get the badge HTML for HD, 4K etc function getBadge(quality) { @@ -1756,28 +1589,28 @@ } } - if (is.array(available) && available.length) { + if (is.array(options) && !is.empty(options)) { // Remove any unwanted quality levels - var filtered = available.filter(function(quality) { + var filtered = options.filter(function(quality) { return ['tiny', 'small'].indexOf(quality) === -1; }); - var list = player.elements.settings.panes.quality.querySelector('ul'); - filtered.forEach(function(quality) { var item = createElement('li'); var label = createElement('label', { - class: config.classes.control + class: config.classes.control, + for: 'plyr-quality-' + quality }); - var radio = createElement('input', { + var radio = createElement('input', extend(getAttributesFromSelector(config.selectors.inputs.quality), { type: 'radio', - name: 'quality', + id: 'plyr-quality-' + quality, + name: 'plyr-quality', value: quality, - }); + })); - if (quality === player.quality.current) { + if (quality === config.quality.selected) { radio.setAttribute('checked', ''); } @@ -1801,15 +1634,17 @@ var options = ['start', 'end', 'all', 'reset']; var list = player.elements.settings.panes.loop.querySelector('ul'); + // Empty the menu + emptyElement(list); + options.forEach(function(option) { var item = createElement('li'); - var button = createElement('button', { + var button = createElement('button', extend(getAttributesFromSelector(config.selectors.buttons.loop), { type: 'button', class: config.classes.control, - 'data-plyr': 'loop', 'data-plyr-loop-action': option - }, config.i18n[option]); + }), config.i18n[option]); if (inArray(['start', 'end'], option)) { var badge = createBadge('0:00'); @@ -1822,6 +1657,91 @@ }); } + // Set a list of available captions languages + function setCaptionsMenu() { + var list = player.elements.settings.panes.captions.querySelector('ul'); + + // Empty the menu + emptyElement(list); + + // If there's no captions, bail + if (is.empty(player.captions.tracks)) { + return; + } + + [].forEach.call(player.captions.tracks, function(track) { + if (is.function(track)) { + return; + } + + var item = createElement('li'); + + var label = createElement('label', { + class: config.classes.control, + for: 'plyr-language-' + track.language + }); + + var radio = createElement('input', extend(getAttributesFromSelector(config.selectors.inputs.language), { + type: 'radio', + id: 'plyr-language-' + track.language, + name: 'plyr-language', + value: track.language, + })); + + if (track.language === config.captions.language.toLowerCase()) { + radio.setAttribute('checked', ''); + } + + label.appendChild(radio); + label.appendChild(document.createTextNode(track.label || track.language)); + label.appendChild(createBadge(track.language.toUpperCase())); + + item.appendChild(label); + + list.appendChild(item); + }); + } + + // Set a list of available captions languages + function setSpeedMenu(options) { + var list = player.elements.settings.panes.speed.querySelector('ul'); + + // Empty the menu + emptyElement(list); + + // If there's no captions, bail + if (!is.array(options)) { + options = config.speed.options; + } + + options.forEach(function(speed) { + var item = createElement('li'); + + var label = createElement('label', { + class: config.classes.control, + for: 'plyr-speed-' + speed.toString().replace('.', '-') + }); + + var radio = createElement('input', extend(getAttributesFromSelector(config.selectors.inputs.speed), { + type: 'radio', + id: 'plyr-speed-' + speed.toString().replace('.', '-'), + name: 'plyr-speed', + value: speed, + })); + + if (speed === config.speed.selected) { + radio.setAttribute('checked', ''); + } + + label.appendChild(radio); + label.insertAdjacentHTML('beforeend', '×' + speed); + + item.appendChild(label); + + list.appendChild(item); + }); + } + // Setup fullscreen function setupFullscreen() { if (!player.supported.full) { @@ -1851,6 +1771,80 @@ } } + // Setup captions + function setupCaptions() { + // Bail if not HTML5 video or textTracks not supported + if (player.type !== 'video' || !support.textTracks) { + return; + } + + // Inject the container + if (!is.htmlElement(player.elements.captions)) { + player.elements.captions = createElement('div', getAttributesFromSelector(config.selectors.captions)); + player.elements.wrapper.appendChild(player.elements.captions); + } + + // Get tracks + player.captions.tracks = player.elements.media.textTracks; + + // If no caption file exists, hide container for caption text + if (is.empty(player.captions.tracks)) { + toggleClass(player.elements.container, config.classes.captions.enabled); + } else { + var language = config.captions.language.toLowerCase(); + + // Turn off native caption rendering to avoid double captions + [].forEach.call(player.captions.tracks, function(track) { + // Remove previous bindings (if we've changed source or language) + off(track, 'cuechange', setActiveCue); + + // Hide captions + track.mode = 'hidden'; + + // If language matches, it's the selected track + if (track.language === language) { + player.captions.currentTrack = track; + } + }); + + // If we couldn't get the requested language, we get the first + if (!is.track(player.captions.currentTrack)) { + warn('No language found to match ' + language + ' in tracks'); + player.captions.currentTrack = player.captions.tracks[0]; + } + + // Enable UI + showCaptions(player); + + // If it's a caption or subtitle, render it + var track = player.captions.currentTrack; + if (is.track(track) && inArray(['captions', 'subtitles'], track.kind)) { + on(track, 'cuechange', setActiveCue); + + // If we change the active track while a cue is already displayed we need to update it + if (track.activeCues && track.activeCues.length > 0) { + setActiveCue(track); + } + } + + // Set available languages in list + setCaptionsMenu(); + } + } + + // Get current selected caption language + function getLanguage() { + if (!support.textTracks || is.empty(player.captions.tracks)) { + return 'No Subs'; + } + + if (player.captions.enabled) { + return player.captions.currentTrack.label; + } else { + return 'Disabled'; + } + } + // Display active caption if it contains text function setActiveCue(track) { // Get the track from the event if needed @@ -1858,187 +1852,30 @@ track = track.target; } + var active = track.activeCues[0]; + // Display a cue, if there is one - if (track.activeCues[0] && 'text' in track.activeCues[0]) { - setCaption(track.activeCues[0].getCueAsHTML()); + if (is.cue(active)) { + setCaption(active.getCueAsHTML()); } else { setCaption(); } } - // Setup captions - function setupCaptions() { - // Bail if not HTML5 video - if (player.type !== 'video') { - return; - } - - // Inject the container - if (!getElement(config.selectors.captions)) { - player.elements.wrapper.insertAdjacentHTML('afterbegin', '
'); - } - - // Determine if HTML5 textTracks is supported - player.captions.textTracks = false; - if (player.elements.media.textTracks) { - player.captions.textTracks = true; - } - - // Get URL of caption file if exists - var captionSources = []; - var captionSrc = ''; - - player.elements.media.childNodes.forEach(function(child) { - if (child.nodeName.toLowerCase() === 'track') { - if (child.kind === 'captions' || child.kind === 'subtitles') { - captionSources.push(child.getAttribute('src')); - } - } - }); - - // Record if caption file exists or not - player.captions.exist = true; - if (captionSources.length === 0) { - player.captions.exist = false; - log('No caption track found'); - } else if ((Number(config.captions.selectedIndex) + 1) > captionSources.length) { - player.captions.exist = false; - log('Caption index out of bound'); - } else { - captionSrc = captionSources[config.captions.selectedIndex]; - log('Caption track found; URI: ' + captionSrc); - } - - // If no caption file exists, hide container for caption text - if (!player.captions.exist) { - toggleClass(player.elements.container, config.classes.captions.enabled); - } else { - var tracks = player.elements.media.textTracks; - - // Turn off native caption rendering to avoid double captions - // This doesn't seem to work in Safari 7+, so the elements are removed from the dom below - [].forEach.call(tracks, function(track) { - // Remove the listener to prevent event overlapping - off(track, 'cuechange', setActiveCue); - - // Hide captions - track.mode = 'hidden'; - }); - - // Enable UI - showCaptions(player); - - // Disable unsupported browsers than report false positive - // Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1033144 - if ((player.browser.isIE && player.browser.version >= 10) || - (player.browser.isFirefox && player.browser.version >= 31)) { - - // Debugging - log('Detected browser with known TextTrack issues - using manual fallback'); - - // Set to false so skips to 'manual' captioning - player.captions.textTracks = false; - } - - // Rendering caption tracks - // Native support required - http://caniuse.com/webvtt - if (player.captions.textTracks) { - log('TextTracks supported'); - - var track = tracks[config.captions.selectedIndex]; - - if (track.kind === 'captions' || track.kind === 'subtitles') { - on(track, 'cuechange', setActiveCue); - - // If we change the active track while a cue is already displayed we need to update it - if (track.activeCues && track.activeCues.length > 0) { - setActiveCue(track); - } - } - } else { - // Caption tracks not natively supported - log('TextTracks not supported so rendering captions manually'); - - // Render captions from array at appropriate time - player.captions.current = ''; - player.captions.captions = []; - - if (captionSrc !== '') { - // Create XMLHttpRequest Object - var xhr = new XMLHttpRequest(); - - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - if (xhr.status === 200) { - var response = xhr.responseText; - - // According to webvtt spec, line terminator consists of one of the following - // CRLF (U+000D U+000A), LF (U+000A) or CR (U+000D) - var lineSeparator = '\r\n'; - if (response.indexOf(lineSeparator + lineSeparator) === -1) { - if (response.indexOf('\r\r') !== -1) { - lineSeparator = '\r'; - } else { - lineSeparator = '\n'; - } - } - - var captions = response.split(lineSeparator + lineSeparator); - - player.captions.captions = captions.map(function(caption) { - var parts = caption.split(lineSeparator); - var index = 0; - - // Incase caption numbers are added - if (parts[index].indexOf(":") !== -1) { - index = 1; - } - - return [parts[index], parts[index + 1]]; - }); - - player.captions.captions.shift(); - - log('Successfully loaded the caption file via AJAX'); - } else { - warn(config.logPrefix + 'There was a problem loading the caption file via AJAX'); - } - } - }; - - xhr.open('get', captionSrc, true); - - xhr.send(); - } - } - } - } - // Select active caption - function setCaptionIndex(index) { - // Save active caption - config.captions.selectedIndex = index || config.captions.selectedIndex; + function setLanguage(language) { + // Save config + if (is.string(language)) { + config.captions.language = language.toLowerCase(); + } else if (is.event(language)) { + config.captions.language = language.target.value.toLowerCase(); + } // Clear caption setCaption(); // Re-run setup setupCaptions(); - - //getElement('[data-captions="settings"]').innerHTML = getSelectedLanguage(); - } - - // Get current selected caption language - function getSelectedLanguage() { - if (config.tracks.length === 0) { - return 'No Subs'; - } - - if (player.captions.enabled || !is.boolean(player.captions.enabled) && player.storage.captions) { - return config.tracks[config.captions.selectedIndex].label; - } else { - return 'Disabled'; - } } // Set the current caption @@ -2058,7 +1895,7 @@ // Set the span content if (is.string(caption)) { - content.innerHTML = caption.trim(); + content.textContent = caption.trim(); } else { content.appendChild(caption); } @@ -2071,86 +1908,6 @@ } } - // Captions functions - // Seek the manual caption time and update UI - function seekManualCaptions(time) { - // Utilities for caption time codes - function timecodeCommon(timecode, pos) { - var parts = []; - parts = timecode.split(' --> '); - for (var i = 0; i < parts.length; i++) { - // WebVTT allows for extra meta data after the timestamp line - // So get rid of this if it exists - parts[i] = parts[i].replace(/(\d+:\d+:\d+\.\d+).*/, "$1"); - } - return subTcSecs(parts[pos]); - } - - function timecodeMin(timecode) { - return timecodeCommon(timecode, 0); - } - - function timecodeMax(timecode) { - return timecodeCommon(timecode, 1); - } - - function subTcSecs(timecode) { - if (is.undefined(timecode)) { - return 0; - } else { - var tc1 = []; - var tc2 = []; - var seconds = 0; - tc1 = timecode.split(','); - tc2 = tc1[0].split(':'); - - for (var i = 0, len = tc2.length; i < len; i++) { - seconds += Math.floor(tc2[i] * (Math.pow(60, len - (i + 1)))); - } - - return seconds; - } - } - - // If it's not video, or we're using textTracks, bail. - if (player.captions.textTracks || player.type !== 'video' || !player.supported.full) { - return; - } - - // Reset subcount - player.captions.count = 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 = is.number(time) ? time : player.elements.media.currentTime; - - // If there's no subs available, bail - if (!player.captions.captions[player.captions.count]) { - return; - } - - while (timecodeMax(player.captions.captions[player.captions.count][0]) < time.toFixed(1)) { - player.captions.count++; - - if (player.captions.count > player.captions.captions.length - 1) { - player.captions.count = player.captions.captions.length - 1; - break; - } - } - - // Check if the next caption is in the current time range - if (player.elements.media.currentTime.toFixed(1) >= timecodeMin(player.captions[player.subcount][0]) && - player.elements.media.currentTime.toFixed(1) <= timecodeMax(player.captions[player.subcount][0])) { - player.captions.current = player.captions.captions[player.captions.count][1]; - - // Render the caption - setCaption(player.captions.current); - } else { - setCaption(); - } - } - // Display captions container and button (for initialization) function showCaptions() { // If there's no caption toggle, bail @@ -2188,12 +1945,6 @@ // Set global player.captions.enabled = show; - //player.elements.buttons.captions_menu.innerHTML = show ? 'Off' : 'On'; - //TODO: display lang getElement('[data-captions="settings"]').innerHTML = getSubsLangValue(); - - // Set current language etc - //elements.buttons.captions_menu.innerHTML = show ? 'Off' : 'On'; - //getElement('[data-captions="settings"]').innerHTML = getSubsLangValue(); // Toggle state toggleState(player.elements.buttons.captions, player.captions.enabled); @@ -2238,11 +1989,11 @@ var controls = createControls({ id: player.id, seektime: config.seekTime, - speed: getSpeedDisplayValue(), + speed: getSpeed(), // TODO: Get current quality quality: 'HD', // TODO: Set language automatically based on UA? - captions: 'English', + captions: getLanguage(), // TODO: Get loop loop: 'None' }); @@ -2278,7 +2029,7 @@ } // Find the UI controls and store references - // TODO: Restore when re-enabling custom HTML + // TODO: Re-configure for new elements /*function findElements() { try { player.elements.controls = getElement(config.selectors.controls.wrapper); @@ -2341,7 +2092,7 @@ // Toggle native controls function toggleNativeControls(toggle) { - if (toggle && inArray(config.types.html5, player.type)) { + if (toggle && inArray(types.html5, player.type)) { player.elements.media.setAttribute('controls', ''); } else { player.elements.media.removeAttribute('controls'); @@ -2439,7 +2190,7 @@ // Add video class for embeds // This will require changes if audio embeds are added - if (inArray(config.types.embed, player.type)) { + if (inArray(types.embed, player.type)) { toggleClass(player.elements.container, config.classes.type.replace('{0}', 'video'), true); } @@ -2447,7 +2198,7 @@ toggleClass(player.elements.container, config.classes.pip.enabled, support.pip && player.type === 'video'); // Check for airplay support - toggleClass(player.elements.container, config.classes.airplay.enabled, support.airplay && inArray(config.types.html5, player.type)); + toggleClass(player.elements.container, config.classes.airplay.enabled, support.airplay && inArray(types.html5, player.type)); // If there's no autoplay attribute, assume the video is stopped and add state class toggleClass(player.elements.container, config.classes.stopped, config.autoplay); @@ -2473,7 +2224,7 @@ } // Embeds - if (inArray(config.types.embed, player.type)) { + if (inArray(types.embed, player.type)) { setupEmbed(); } } @@ -2625,7 +2376,7 @@ wmode: 'transparent', modestbranding: 1, disablekb: 1, - origin: '*' // https://code.google.com/p/gdata-issues/issues/detail?id=5788#c45 + origin: 'https://plyr.io' }, events: { 'onError': function(event) { @@ -2677,7 +2428,7 @@ // Set the tabindex if (player.supported.full) { - player.elements.media.querySelector('iframe').setAttribute('tabindex', '-1'); + player.elements.media.querySelector('iframe').setAttribute('tabindex', -1); } // Update UI @@ -2840,7 +2591,7 @@ // Fix keyboard focus issues // https://github.com/Selz/plyr/issues/317 if (is.htmlElement(player.embed.element) && player.supported.full) { - player.embed.element.setAttribute('tabindex', '-1'); + player.embed.element.setAttribute('tabindex', -1); } }); @@ -3068,47 +2819,47 @@ // Set playback speed function setSpeed(speed) { // Load speed from storage or default value - if (is.undefined(speed)) { - speed = player.storage.speed || config.defaultSpeed; + if (is.event(speed)) { + speed = parseFloat(speed.target.value); + } else if (!is.number(speed)) { + speed = parseFloat(player.storage.speed || config.speed.selected); } - if (!is.array(config.speeds)) { + if (!is.array(config.speed.options)) { warn('Invalid speeds format'); return; } if (!is.number(speed)) { - var index = config.speeds.indexOf(config.currentSpeed); + var index = config.speed.options.indexOf(config.speed.selected); if (index !== -1) { - var nextIndex = index + 1; - if (nextIndex >= config.speeds.length) { - nextIndex = 0; + var next = index + 1; + if (next >= config.speeds.length) { + next = 0; } - speed = config.speeds[nextIndex]; + speed = config.speed.options[next]; } else { - speed = config.defaultSpeed; + speed = config.speed.selected; } } // Store current speed - config.currentSpeed = speed; + config.speed.selected = speed; // Set HTML5 speed + // TODO: set YouTube player.elements.media.playbackRate = speed; // Save speed to localStorage updateStorage({ speed: speed }); - - // Update current value of menu - // document.querySelector('[data-menu="speed"]').innerHTML = getSpeedDisplayValue(); } // Get the current speed value - function getSpeedDisplayValue() { - return config.currentSpeed.toFixed(1).toString().replace('.0', '') + '×' + function getSpeed() { + return config.speed.selected.toFixed(1).toString().replace('.0', '') + '×' } // Rewind @@ -3161,7 +2912,7 @@ } catch (e) {} // Embeds - if (inArray(config.types.embed, player.type)) { + if (inArray(types.embed, player.type)) { switch (player.type) { case 'youtube': player.embed.seekTo(targetTime); @@ -3193,9 +2944,6 @@ // Logging log('Seeking to ' + player.elements.media.currentTime + ' seconds'); - - // Special handling for 'manual' captions - seekManualCaptions(targetTime); } // Get the duration (or custom if set) @@ -3339,7 +3087,7 @@ target.setAttribute('aria-hidden', !show); toggle.setAttribute('aria-expanded', show); - target.setAttribute('tabindex', 0); + target.removeAttribute('tabindex'); if (isTab) { container.style.width = targetWidth + 'px'; @@ -3371,7 +3119,7 @@ } // Embeds - if (inArray(config.types.embed, player.type)) { + if (inArray(types.embed, player.type)) { // YouTube switch (player.type) { case 'youtube': @@ -3427,7 +3175,7 @@ } // Embeds - if (inArray(config.types.embed, player.type)) { + if (inArray(types.embed, player.type)) { switch (player.type) { case 'youtube': player.embed.setVolume(player.elements.media.volume * 100); @@ -3894,7 +3642,7 @@ if (player.type === 'video') { var firstSource = source.sources[0]; - if ('type' in firstSource && inArray(config.types.embed, firstSource.type)) { + if ('type' in firstSource && inArray(types.embed, firstSource.type)) { player.type = firstSource.type; } } @@ -3930,7 +3678,7 @@ } // Set attributes for audio and video - if (inArray(config.types.html5, player.type)) { + if (inArray(types.html5, player.type)) { if (config.crossorigin) { player.elements.media.setAttribute('crossorigin', ''); } @@ -3951,7 +3699,7 @@ toggleStyleHook(); // Set new sources for html5 - if (inArray(config.types.html5, player.type)) { + if (inArray(types.html5, player.type)) { insertElements('source', source.sources); } @@ -3959,7 +3707,7 @@ setupMedia(); // HTML5 stuff - if (inArray(config.types.html5, player.type)) { + if (inArray(types.html5, player.type)) { // Setup captions if ('tracks' in source) { insertElements('track', source.tracks); @@ -3970,7 +3718,7 @@ } // If HTML5 or embed but not fully supported, setupInterface and call ready now - if (inArray(config.types.html5, player.type) || (inArray(config.types.embed, player.type) && !player.supported.full)) { + if (inArray(types.html5, player.type) || (inArray(types.embed, player.type) && !player.supported.full)) { // Setup interface setupInterface(); @@ -4030,16 +3778,10 @@ // Detect tab focus function checkTabFocus(focused) { - for (var button in player.elements.buttons) { - var element = player.elements.buttons[button]; + toggleClass(getElements('.' + config.classes.tabFocus), config.classes.tabFocus, false); - if (is.nodeList(element)) { - for (var i = 0; i < element.length; i++) { - toggleClass(element[i], config.classes.tabFocus, (element[i] === focused)); - } - } else { - toggleClass(element, config.classes.tabFocus, (element === focused)); - } + if (player.elements.container.contains(focused)) { + toggleClass(focused, config.classes.tabFocus, true); } } @@ -4295,22 +4037,19 @@ // Settings menu items - use event delegation as items are added/removed on(player.elements.settings.menu, 'click', function(event) { // Settings - Speed - if (matches(event.target, config.selectors.buttons.speed)) { - handlerProxy.call(this, event, config.listeners.speed, function() { - //var speedValue = document.querySelector('[data-plyr="speed"]:checked').value; - //setSpeed(Number(speedValue)); - console.warn("Set speed"); - }); + if (matches(event.target, config.selectors.inputs.speed)) { + handlerProxy.call(this, event, config.listeners.speed, setSpeed); } // Settings - Quality - else if (matches(event.target, config.selectors.buttons.quality)) { + else if (matches(event.target, config.selectors.inputs.quality)) { handlerProxy.call(this, event, config.listeners.quality, function() { console.warn("Set quality"); }); } // Settings - Looping + // TODO: use toggle buttons else if (matches(event.target, config.selectors.buttons.loop)) { handlerProxy.call(this, event, config.listeners.loop, function() { // TODO: This should be done in the method itself I think @@ -4323,12 +4062,8 @@ } // Settings - Language - else if (matches(event.target, config.selectors.buttons.language)) { - handlerProxy.call(this, event, config.listeners.language, function(event) { - // TODO: This should be done in the method itself I think - var index = event.target.attributes.getNamedItem("data-index").value; - setCaptionIndex(index); - }); + else if (matches(event.target, config.selectors.inputs.language)) { + handlerProxy.call(this, event, config.listeners.language, setLanguage); } }); @@ -4408,9 +4143,6 @@ // Time change on media on(player.elements.media, 'timeupdate seeking', timeUpdate); - // Update manual captions - on(player.elements.media, 'timeupdate', seekManualCaptions); - // Display duration on(player.elements.media, 'durationchange loadedmetadata', displayDuration); @@ -4491,7 +4223,7 @@ // Cancel current network requests // See https://github.com/Selz/plyr/issues/174 function cancelRequests() { - if (!inArray(config.types.html5, player.type)) { + if (!inArray(types.html5, player.type)) { return; } @@ -4650,7 +4382,7 @@ // Setup interface // If embed but not fully supported, setupInterface (to avoid flash of controls) and call ready now - if (inArray(config.types.html5, player.type) || (inArray(config.types.embed, player.type) && !player.supported.full)) { + if (inArray(types.html5, player.type) || (inArray(types.embed, player.type) && !player.supported.full)) { // Setup UI setupInterface(); @@ -4708,7 +4440,6 @@ // Captions setupCaptions(); - setCaptionIndex(); // Set volume setVolume(); @@ -4789,7 +4520,7 @@ toggleCaptions: toggleCaptions, toggleFullscreen: toggleFullscreen, toggleControls: toggleControls, - setCaptionIndex: setCaptionIndex, + setLanguage: setLanguage, isFullscreen: function() { return player.fullscreen.active || false; }, diff --git a/src/less/plyr.less b/src/less/plyr.less index 8e08cf40..98917f96 100644 --- a/src/less/plyr.less +++ b/src/less/plyr.less @@ -251,6 +251,11 @@ background: @plyr-captions-bg; box-decoration-break: clone; line-height: 150%; + + // Firefox adds a
when using getCueAsHTML() + div { + display: inline; + } } span:empty { display: none;