Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mediaelement

Package Overview
Dependencies
Maintainers
4
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mediaelement - npm Package Compare versions

Comparing version 5.1.1 to 6.0.0

build/english_chapters.vtt

0

build/renderers/dailymotion.js

@@ -0,0 +0,0 @@ /*!

@@ -0,0 +0,0 @@ /*!

@@ -0,0 +0,0 @@ /*!

@@ -0,0 +0,0 @@ /*!

@@ -0,0 +0,0 @@ /*!

2

build/renderers/youtube.js

@@ -66,3 +66,3 @@ /*!

mejs.version = '5.1.1';
mejs.version = '6.0.0';

@@ -69,0 +69,0 @@ mejs.html5media = {

@@ -12,2 +12,2 @@ /*!

*/
!function o(i,u,s){function l(r,e){if(!u[r]){if(!i[r]){var t="function"==typeof require&&require;if(!e&&t)return t(r,!0);if(d)return d(r,!0);var n=new Error("Cannot find module '"+r+"'");throw n.code="MODULE_NOT_FOUND",n}var a=u[r]={exports:{}};i[r][0].call(a.exports,function(e){var t=i[r][1][e];return l(t||e)},a,a.exports,o,i,u,s)}return u[r].exports}for(var d="function"==typeof require&&require,e=0;e<s.length;e++)l(s[e]);return l}({1:[function(e,t,r){},{}],2:[function(a,o,e){(function(e){var t,r=void 0!==e?e:"undefined"!=typeof window?window:{},n=a(1);"undefined"!=typeof document?t=document:(t=r["__GLOBAL_DOCUMENT_CACHE@4"])||(t=r["__GLOBAL_DOCUMENT_CACHE@4"]=n),o.exports=t}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{1:1}],3:[function(e,r,t){(function(e){var t;t="undefined"!=typeof window?window:void 0!==e?e:"undefined"!=typeof self?self:{},r.exports=t}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],4:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n,a=e(3);var o={version:"5.1.1",html5media:{properties:["volume","src","currentTime","muted","duration","paused","ended","buffered","error","networkState","readyState","seeking","seekable","currentSrc","preload","bufferedBytes","bufferedTime","initialTime","startOffsetTime","defaultPlaybackRate","playbackRate","played","autoplay","loop","controls"],readOnlyProperties:["duration","paused","ended","buffered","error","networkState","readyState","seeking","seekable"],methods:["load","play","pause","canPlayType"],events:["loadstart","durationchange","loadedmetadata","loadeddata","progress","canplay","canplaythrough","suspend","abort","error","emptied","stalled","play","playing","pause","waiting","seeking","seeked","timeupdate","ended","ratechange","volumechange"],mediaTypes:["audio/mp3","audio/ogg","audio/oga","audio/wav","audio/x-wav","audio/wave","audio/x-pn-wav","audio/mpeg","audio/mp4","video/mp4","video/webm","video/ogg","video/ogv"]}};((n=a)&&n.__esModule?n:{default:n}).default.mejs=o,r.default=o},{3:3}],5:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.renderer=void 0;var n,a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=function(){function n(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),e}}(),i=e(4),u=(n=i)&&n.__esModule?n:{default:n};var s=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.renderers={},this.order=[]}return o(e,[{key:"add",value:function(e){if(void 0===e.name)throw new TypeError("renderer must contain at least `name` property");this.renderers[e.name]=e,this.order.push(e.name)}},{key:"select",value:function(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:[],r=t.length;if(t=t.length?t:this.order,!r){var n=[/^(html5|native)/i,/^flash/i,/iframe$/i],a=function(e){for(var t=0,r=n.length;t<r;t++)if(n[t].test(e))return t;return n.length};t.sort(function(e,t){return a(e)-a(t)})}for(var o=0,i=t.length;o<i;o++){var u=t[o],s=this.renderers[u];if(null!=s)for(var l=0,d=e.length;l<d;l++)if("function"==typeof s.canPlayType&&"string"==typeof e[l].type&&s.canPlayType(e[l].type))return{rendererName:s.name,src:e[l].src}}return null}},{key:"order",set:function(e){if(!Array.isArray(e))throw new TypeError("order must be an array of strings.");this._order=e},get:function(){return this._order}},{key:"renderers",set:function(e){if(null!==e&&"object"!==(void 0===e?"undefined":a(e)))throw new TypeError("renderers must be an array of objects.");this._renderers=e},get:function(){return this._renderers}}]),e}(),l=r.renderer=new s;u.default.Renderers=l},{4:4}],6:[function(e,t,r){"use strict";var k=i(e(3)),x=i(e(2)),U=i(e(4)),n=e(5),I=e(8),a=e(9),o=e(7);function i(e){return e&&e.__esModule?e:{default:e}}var _={isIframeStarted:!1,isIframeLoaded:!1,iframeQueue:[],enqueueIframe:function(e){_.isLoaded="undefined"!=typeof YT&&YT.loaded,_.isLoaded?_.createIframe(e):(_.loadIframeApi(),_.iframeQueue.push(e))},loadIframeApi:function(){_.isIframeStarted||((0,o.loadScript)("https://www.youtube.com/player_api"),_.isIframeStarted=!0)},iFrameReady:function(){for(_.isLoaded=!0,_.isIframeLoaded=!0;0<_.iframeQueue.length;){var e=_.iframeQueue.pop();_.createIframe(e)}},createIframe:function(e){return new YT.Player(e.containerId,e)},getYouTubeId:function(e){var t="";return 0<e.indexOf("?")?""===(t=_.getYouTubeIdFromParam(e))&&(t=_.getYouTubeIdFromUrl(e)):t=_.getYouTubeIdFromUrl(e),(t=t.substring(t.lastIndexOf("/")+1).split("?"))[0]},getYouTubeIdFromParam:function(e){if(null==e||!e.trim().length)return null;for(var t=e.split("?")[1].split("&"),r="",n=0,a=t.length;n<a;n++){var o=t[n].split("=");if("v"===o[0]){r=o[1];break}}return r},getYouTubeIdFromUrl:function(e){return null!=e&&e.trim().length?(e=e.split("?")[0]).substring(e.lastIndexOf("/")+1):null},getYouTubeNoCookieUrl:function(e){if(null==e||!e.trim().length||-1===e.indexOf("//www.youtube"))return e;var t=e.split("/");return t[2]=t[2].replace(".com","-nocookie.com"),t.join("/")}},u={name:"youtube_iframe",options:{prefix:"youtube_iframe",youtube:{autoplay:0,controls:0,disablekb:1,end:0,loop:0,modestbranding:0,playsinline:0,rel:0,showinfo:0,start:0,iv_load_policy:3,nocookie:!1,imageQuality:null}},canPlayType:function(e){return~["video/youtube","video/x-youtube"].indexOf(e.toLowerCase())},create:function(m,r,n){var v={},y=[],g=null,o=!0,i=!1,h=null;v.options=r,v.id=m.id+"_"+r.prefix,v.mediaElement=m;for(var e=U.default.html5media.properties,t=function(a){var e=""+a.substring(0,1).toUpperCase()+a.substring(1);v["get"+e]=function(){if(null!==g){switch(a){case"currentTime":return g.getCurrentTime();case"duration":return g.getDuration();case"volume":return g.getVolume()/100;case"playbackRate":return g.getPlaybackRate();case"paused":return o;case"ended":return i;case"muted":return g.isMuted();case"buffered":var e=g.getVideoLoadedFraction(),t=g.getDuration();return{start:function(){return 0},end:function(){return e*t},length:1};case"src":return g.getVideoUrl();case"readyState":return 4}return null}return null},v["set"+e]=function(e){if(null!==g)switch(a){case"src":var t="string"==typeof e?e:e[0].src,r=_.getYouTubeId(t);m.originalNode.autoplay?g.loadVideoById(r):g.cueVideoById(r);break;case"currentTime":g.seekTo(e);break;case"muted":e?g.mute():g.unMute(),setTimeout(function(){var e=(0,I.createEvent)("volumechange",v);m.dispatchEvent(e)},50);break;case"volume":e,g.setVolume(100*e),setTimeout(function(){var e=(0,I.createEvent)("volumechange",v);m.dispatchEvent(e)},50);break;case"playbackRate":g.setPlaybackRate(e),setTimeout(function(){var e=(0,I.createEvent)("ratechange",v);m.dispatchEvent(e)},50);break;case"readyState":var n=(0,I.createEvent)("canplay",v);m.dispatchEvent(n)}else y.push({type:"set",propName:a,value:e})}},a=0,u=e.length;a<u;a++)t(e[a]);for(var s=U.default.html5media.methods,l=function(e){v[e]=function(){if(null!==g)switch(e){case"play":return o=!1,g.playVideo();case"pause":return o=!0,g.pauseVideo();case"load":return null}else y.push({type:"call",methodName:e})}},d=0,f=s.length;d<f;d++)l(s[d]);var c=x.default.createElement("div");c.id=v.id,v.options.youtube.nocookie&&(m.originalNode.src=_.getYouTubeNoCookieUrl(n[0].src)),m.originalNode.parentNode.insertBefore(c,m.originalNode),m.originalNode.style.display="none";var p="audio"===m.originalNode.tagName.toLowerCase(),b=p?"1":m.originalNode.height,w=p?"1":m.originalNode.width,T=_.getYouTubeId(n[0].src),E={id:v.id,containerId:c.id,videoId:T,height:b,width:w,host:v.options.youtube&&v.options.youtube.nocookie?"https://www.youtube-nocookie.com":void 0,playerVars:Object.assign({controls:0,rel:0,disablekb:1,showinfo:0,modestbranding:0,html5:1,iv_load_policy:3},v.options.youtube),origin:k.default.location.host,events:{onReady:function(e){if(m.youTubeApi=g=e.target,m.youTubeState={paused:!0,ended:!1},y.length)for(var t=0,r=y.length;t<r;t++){var n=y[t];if("set"===n.type){var a=n.propName,o=""+a.substring(0,1).toUpperCase()+a.substring(1);v["set"+o](n.value)}else"call"===n.type&&v[n.methodName]()}h=g.getIframe(),m.originalNode.muted&&g.mute();for(var i=["mouseover","mouseout"],u=function(e){var t=(0,I.createEvent)(e.type,v);m.dispatchEvent(t)},s=0,l=i.length;s<l;s++)h.addEventListener(i[s],u,!1);for(var d=["rendererready","loadedmetadata","loadeddata","canplay"],f=0,c=d.length;f<c;f++){var p=(0,I.createEvent)(d[f],v);m.dispatchEvent(p)}},onStateChange:function(e){var t=[];switch(e.data){case-1:t=["loadedmetadata"],o=!0,i=!1;break;case 0:t=["ended"],o=!1,i=!v.options.youtube.loop,v.options.youtube.loop||v.stopInterval();break;case 1:t=["play","playing"],i=o=!1,v.startInterval();break;case 2:t=["pause"],o=!0,i=!1,v.stopInterval();break;case 3:t=["progress"],i=!1;break;case 5:t=["loadeddata","loadedmetadata","canplay"],o=!0,i=!1}for(var r=0,n=t.length;r<n;r++){var a=(0,I.createEvent)(t[r],v);m.dispatchEvent(a)}},onError:function(e){return function(e){var t="";switch(e.data){case 2:t="The request contains an invalid parameter value. Verify that video ID has 11 characters and that contains no invalid characters, such as exclamation points or asterisks.";break;case 5:t="The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.";break;case 100:t="The video requested was not found. Either video has been removed or has been marked as private.";break;case 101:case 105:t="The owner of the requested video does not allow it to be played in embedded players.";break;default:t="Unknown error."}m.generateError("Code "+e.data+": "+t,n)}(e)}}};return(p||m.originalNode.hasAttribute("playsinline"))&&(E.playerVars.playsinline=1),m.originalNode.controls&&(E.playerVars.controls=1),m.originalNode.autoplay&&(E.playerVars.autoplay=1),m.originalNode.loop&&(E.playerVars.loop=1),(E.playerVars.loop&&1===parseInt(E.playerVars.loop,10)||-1<m.originalNode.src.indexOf("loop="))&&!E.playerVars.playlist&&-1===m.originalNode.src.indexOf("playlist=")&&(E.playerVars.playlist=_.getYouTubeId(m.originalNode.src)),_.enqueueIframe(E),v.onEvent=function(e,t,r){null!=r&&(m.youTubeState=r)},v.setSize=function(e,t){null!==g&&g.setSize(e,t)},v.hide=function(){v.stopInterval(),v.pause(),h&&(h.style.display="none")},v.show=function(){h&&(h.style.display="")},v.destroy=function(){g.destroy()},v.interval=null,v.startInterval=function(){v.interval=setInterval(function(){var e=(0,I.createEvent)("timeupdate",v);m.dispatchEvent(e)},250)},v.stopInterval=function(){v.interval&&clearInterval(v.interval)},v.getPosterUrl=function(){var e=r.youtube.imageQuality,t=_.getYouTubeId(m.originalNode.src);return e&&-1<["default","hqdefault","mqdefault","sddefault","maxresdefault"].indexOf(e)&&t?"https://img.youtube.com/vi/"+t+"/"+e+".jpg":""},v}};k.default.onYouTubePlayerAPIReady=function(){_.iFrameReady()},a.typeChecks.push(function(e){return/\/\/(www\.youtube|youtu\.?be)/i.test(e)?"video/x-youtube":null}),n.renderer.add(u)},{2:2,3:3,4:4,5:5,7:7,8:8,9:9}],7:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.removeClass=r.addClass=r.hasClass=void 0,r.loadScript=i,r.offset=u,r.toggleClass=v,r.fadeOut=y,r.fadeIn=g,r.siblings=h,r.visible=b,r.ajax=w;var s=o(e(3)),a=o(e(2)),n=o(e(4));function o(e){return e&&e.__esModule?e:{default:e}}function i(n){return new Promise(function(e,t){var r=a.default.createElement("script");r.src=n,r.async=!0,r.onload=function(){r.remove(),e()},r.onerror=function(){r.remove(),t()},a.default.head.appendChild(r)})}function u(e){var t=e.getBoundingClientRect(),r=s.default.pageXOffset||a.default.documentElement.scrollLeft,n=s.default.pageYOffset||a.default.documentElement.scrollTop;return{top:t.top+n,left:t.left+r}}var l=void 0,d=void 0,f=void 0;"classList"in a.default.documentElement?(l=function(e,t){return void 0!==e.classList&&e.classList.contains(t)},d=function(e,t){return e.classList.add(t)},f=function(e,t){return e.classList.remove(t)}):(l=function(e,t){return new RegExp("\\b"+t+"\\b").test(e.className)},d=function(e,t){c(e,t)||(e.className+=" "+t)},f=function(e,t){e.className=e.className.replace(new RegExp("\\b"+t+"\\b","g"),"")});var c=r.hasClass=l,p=r.addClass=d,m=r.removeClass=f;function v(e,t){c(e,t)?m(e,t):p(e,t)}function y(a){var o=1<arguments.length&&void 0!==arguments[1]?arguments[1]:400,i=arguments[2];a.style.opacity||(a.style.opacity=1);var u=null;s.default.requestAnimationFrame(function e(t){var r=t-(u=u||t),n=parseFloat(1-r/o,2);a.style.opacity=n<0?0:n,o<r?i&&"function"==typeof i&&i():s.default.requestAnimationFrame(e)})}function g(a){var o=1<arguments.length&&void 0!==arguments[1]?arguments[1]:400,i=arguments[2];a.style.opacity||(a.style.opacity=0);var u=null;s.default.requestAnimationFrame(function e(t){var r=t-(u=u||t),n=parseFloat(r/o,2);a.style.opacity=1<n?1:n,o<r?i&&"function"==typeof i&&i():s.default.requestAnimationFrame(e)})}function h(e,t){var r=[];for(e=e.parentNode.firstChild;t&&!t(e)||r.push(e),e=e.nextSibling;);return r}function b(e){return void 0!==e.getClientRects&&"function"===e.getClientRects?!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length):!(!e.offsetWidth&&!e.offsetHeight)}function w(e,t,r,n){var a=s.default.XMLHttpRequest?new XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP"),o="application/x-www-form-urlencoded; charset=UTF-8",i=!1,u="*/".concat("*");switch(t){case"text":o="text/plain";break;case"json":o="application/json, text/javascript";break;case"html":o="text/html";break;case"xml":o="application/xml, text/xml"}"application/x-www-form-urlencoded"!==o&&(u=o+", */*; q=0.01"),a&&(a.open("GET",e,!0),a.setRequestHeader("Accept",u),a.onreadystatechange=function(){if(!i&&4===a.readyState)if(200===a.status){i=!0;var e=void 0;switch(t){case"json":e=JSON.parse(a.responseText);break;case"xml":e=a.responseXML;break;default:e=a.responseText}r(e)}else"function"==typeof n&&n(a.status)},a.send())}n.default.Utils=n.default.Utils||{},n.default.Utils.offset=u,n.default.Utils.hasClass=c,n.default.Utils.addClass=p,n.default.Utils.removeClass=m,n.default.Utils.toggleClass=v,n.default.Utils.fadeIn=g,n.default.Utils.fadeOut=y,n.default.Utils.siblings=h,n.default.Utils.visible=b,n.default.Utils.ajax=w,n.default.Utils.loadScript=i},{2:2,3:3,4:4}],8:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.escapeHTML=i,r.debounce=u,r.isObjectEmpty=s,r.splitEvents=l,r.createEvent=d,r.isNodeAfter=f,r.isString=c;var n,a=e(4),o=(n=a)&&n.__esModule?n:{default:n};function i(e){if("string"!=typeof e)throw new Error("Argument passed must be a string");var t={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"};return e.replace(/[&<>"]/g,function(e){return t[e]})}function u(n,a){var o=this,i=arguments,u=2<arguments.length&&void 0!==arguments[2]&&arguments[2];if("function"!=typeof n)throw new Error("First argument must be a function");if("number"!=typeof a)throw new Error("Second argument must be a numeric value");var s=void 0;return function(){var e=o,t=i,r=u&&!s;clearTimeout(s),s=setTimeout(function(){s=null,u||n.apply(e,t)},a),r&&n.apply(e,t)}}function s(e){return Object.getOwnPropertyNames(e).length<=0}function l(e,r){var n=/^((after|before)print|(before)?unload|hashchange|message|o(ff|n)line|page(hide|show)|popstate|resize|storage)\b/,a={d:[],w:[]};return(e||"").split(" ").forEach(function(e){var t=e+(r?"."+r:"");t.startsWith(".")?(a.d.push(t),a.w.push(t)):a[n.test(e)?"w":"d"].push(t)}),a.d=a.d.join(" "),a.w=a.w.join(" "),a}function d(e,t){if("string"!=typeof e)throw new Error("Event name must be a string");var r=e.match(/([a-z]+\.([a-z]+))/i),n={target:t};return null!==r&&(e=r[1],n.namespace=r[2]),new window.CustomEvent(e,{detail:n})}function f(e,t){return!!(e&&t&&2&e.compareDocumentPosition(t))}function c(e){return"string"==typeof e}o.default.Utils=o.default.Utils||{},o.default.Utils.escapeHTML=i,o.default.Utils.debounce=u,o.default.Utils.isObjectEmpty=s,o.default.Utils.splitEvents=l,o.default.Utils.createEvent=d,o.default.Utils.isNodeAfter=f,o.default.Utils.isString=c},{4:4}],9:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.typeChecks=void 0,r.absolutizeUrl=s,r.formatType=l,r.getMimeFromType=d,r.getTypeFromFile=f,r.getExtension=c,r.normalizeExtension=p;var n,a=e(4),o=(n=a)&&n.__esModule?n:{default:n},i=e(8);var u=r.typeChecks=[];function s(e){if("string"!=typeof e)throw new Error("`url` argument must be a string");var t=document.createElement("div");return t.innerHTML='<a href="'+(0,i.escapeHTML)(e)+'">x</a>',t.firstChild.href}function l(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:"";return e&&!t?f(e):t}function d(e){if("string"!=typeof e)throw new Error("`type` argument must be a string");return e&&-1<e.indexOf(";")?e.substr(0,e.indexOf(";")):e}function f(e){if("string"!=typeof e)throw new Error("`url` argument must be a string");for(var t=0,r=u.length;t<r;t++){var n=u[t](e);if(n)return n}var a=p(c(e)),o="video/mp4";return a&&(~["mp4","m4v","ogg","ogv","webm","flv","mpeg"].indexOf(a)?o="video/"+a:"mov"===a?o="video/quicktime":~["mp3","oga","wav","mid","midi"].indexOf(a)&&(o="audio/"+a)),o}function c(e){if("string"!=typeof e)throw new Error("`url` argument must be a string");var t=e.split("?")[0].split("\\").pop().split("/").pop();return~t.indexOf(".")?t.substring(t.lastIndexOf(".")+1):""}function p(e){if("string"!=typeof e)throw new Error("`extension` argument must be a string");switch(e){case"mp4":case"m4v":return"mp4";case"webm":case"webma":case"webmv":return"webm";case"ogg":case"oga":case"ogv":return"ogg";default:return e}}o.default.Utils=o.default.Utils||{},o.default.Utils.typeChecks=u,o.default.Utils.absolutizeUrl=s,o.default.Utils.formatType=l,o.default.Utils.getMimeFromType=d,o.default.Utils.getTypeFromFile=f,o.default.Utils.getExtension=c,o.default.Utils.normalizeExtension=p},{4:4,8:8}]},{},[6]);
!function o(i,u,s){function l(r,e){if(!u[r]){if(!i[r]){var t="function"==typeof require&&require;if(!e&&t)return t(r,!0);if(d)return d(r,!0);var n=new Error("Cannot find module '"+r+"'");throw n.code="MODULE_NOT_FOUND",n}var a=u[r]={exports:{}};i[r][0].call(a.exports,function(e){var t=i[r][1][e];return l(t||e)},a,a.exports,o,i,u,s)}return u[r].exports}for(var d="function"==typeof require&&require,e=0;e<s.length;e++)l(s[e]);return l}({1:[function(e,t,r){},{}],2:[function(a,o,e){(function(e){var t,r=void 0!==e?e:"undefined"!=typeof window?window:{},n=a(1);"undefined"!=typeof document?t=document:(t=r["__GLOBAL_DOCUMENT_CACHE@4"])||(t=r["__GLOBAL_DOCUMENT_CACHE@4"]=n),o.exports=t}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{1:1}],3:[function(e,r,t){(function(e){var t;t="undefined"!=typeof window?window:void 0!==e?e:"undefined"!=typeof self?self:{},r.exports=t}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],4:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0});var n,a=e(3);var o={version:"6.0.0",html5media:{properties:["volume","src","currentTime","muted","duration","paused","ended","buffered","error","networkState","readyState","seeking","seekable","currentSrc","preload","bufferedBytes","bufferedTime","initialTime","startOffsetTime","defaultPlaybackRate","playbackRate","played","autoplay","loop","controls"],readOnlyProperties:["duration","paused","ended","buffered","error","networkState","readyState","seeking","seekable"],methods:["load","play","pause","canPlayType"],events:["loadstart","durationchange","loadedmetadata","loadeddata","progress","canplay","canplaythrough","suspend","abort","error","emptied","stalled","play","playing","pause","waiting","seeking","seeked","timeupdate","ended","ratechange","volumechange"],mediaTypes:["audio/mp3","audio/ogg","audio/oga","audio/wav","audio/x-wav","audio/wave","audio/x-pn-wav","audio/mpeg","audio/mp4","video/mp4","video/webm","video/ogg","video/ogv"]}};((n=a)&&n.__esModule?n:{default:n}).default.mejs=o,r.default=o},{3:3}],5:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.renderer=void 0;var n,a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=function(){function n(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(e,t,r){return t&&n(e.prototype,t),r&&n(e,r),e}}(),i=e(4),u=(n=i)&&n.__esModule?n:{default:n};var s=function(){function e(){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.renderers={},this.order=[]}return o(e,[{key:"add",value:function(e){if(void 0===e.name)throw new TypeError("renderer must contain at least `name` property");this.renderers[e.name]=e,this.order.push(e.name)}},{key:"select",value:function(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:[],r=t.length;if(t=t.length?t:this.order,!r){var n=[/^(html5|native)/i,/^flash/i,/iframe$/i],a=function(e){for(var t=0,r=n.length;t<r;t++)if(n[t].test(e))return t;return n.length};t.sort(function(e,t){return a(e)-a(t)})}for(var o=0,i=t.length;o<i;o++){var u=t[o],s=this.renderers[u];if(null!=s)for(var l=0,d=e.length;l<d;l++)if("function"==typeof s.canPlayType&&"string"==typeof e[l].type&&s.canPlayType(e[l].type))return{rendererName:s.name,src:e[l].src}}return null}},{key:"order",set:function(e){if(!Array.isArray(e))throw new TypeError("order must be an array of strings.");this._order=e},get:function(){return this._order}},{key:"renderers",set:function(e){if(null!==e&&"object"!==(void 0===e?"undefined":a(e)))throw new TypeError("renderers must be an array of objects.");this._renderers=e},get:function(){return this._renderers}}]),e}(),l=r.renderer=new s;u.default.Renderers=l},{4:4}],6:[function(e,t,r){"use strict";var k=i(e(3)),x=i(e(2)),U=i(e(4)),n=e(5),I=e(8),a=e(9),o=e(7);function i(e){return e&&e.__esModule?e:{default:e}}var _={isIframeStarted:!1,isIframeLoaded:!1,iframeQueue:[],enqueueIframe:function(e){_.isLoaded="undefined"!=typeof YT&&YT.loaded,_.isLoaded?_.createIframe(e):(_.loadIframeApi(),_.iframeQueue.push(e))},loadIframeApi:function(){_.isIframeStarted||((0,o.loadScript)("https://www.youtube.com/player_api"),_.isIframeStarted=!0)},iFrameReady:function(){for(_.isLoaded=!0,_.isIframeLoaded=!0;0<_.iframeQueue.length;){var e=_.iframeQueue.pop();_.createIframe(e)}},createIframe:function(e){return new YT.Player(e.containerId,e)},getYouTubeId:function(e){var t="";return 0<e.indexOf("?")?""===(t=_.getYouTubeIdFromParam(e))&&(t=_.getYouTubeIdFromUrl(e)):t=_.getYouTubeIdFromUrl(e),(t=t.substring(t.lastIndexOf("/")+1).split("?"))[0]},getYouTubeIdFromParam:function(e){if(null==e||!e.trim().length)return null;for(var t=e.split("?")[1].split("&"),r="",n=0,a=t.length;n<a;n++){var o=t[n].split("=");if("v"===o[0]){r=o[1];break}}return r},getYouTubeIdFromUrl:function(e){return null!=e&&e.trim().length?(e=e.split("?")[0]).substring(e.lastIndexOf("/")+1):null},getYouTubeNoCookieUrl:function(e){if(null==e||!e.trim().length||-1===e.indexOf("//www.youtube"))return e;var t=e.split("/");return t[2]=t[2].replace(".com","-nocookie.com"),t.join("/")}},u={name:"youtube_iframe",options:{prefix:"youtube_iframe",youtube:{autoplay:0,controls:0,disablekb:1,end:0,loop:0,modestbranding:0,playsinline:0,rel:0,showinfo:0,start:0,iv_load_policy:3,nocookie:!1,imageQuality:null}},canPlayType:function(e){return~["video/youtube","video/x-youtube"].indexOf(e.toLowerCase())},create:function(m,r,n){var v={},y=[],g=null,o=!0,i=!1,h=null;v.options=r,v.id=m.id+"_"+r.prefix,v.mediaElement=m;for(var e=U.default.html5media.properties,t=function(a){var e=""+a.substring(0,1).toUpperCase()+a.substring(1);v["get"+e]=function(){if(null!==g){switch(a){case"currentTime":return g.getCurrentTime();case"duration":return g.getDuration();case"volume":return g.getVolume()/100;case"playbackRate":return g.getPlaybackRate();case"paused":return o;case"ended":return i;case"muted":return g.isMuted();case"buffered":var e=g.getVideoLoadedFraction(),t=g.getDuration();return{start:function(){return 0},end:function(){return e*t},length:1};case"src":return g.getVideoUrl();case"readyState":return 4}return null}return null},v["set"+e]=function(e){if(null!==g)switch(a){case"src":var t="string"==typeof e?e:e[0].src,r=_.getYouTubeId(t);m.originalNode.autoplay?g.loadVideoById(r):g.cueVideoById(r);break;case"currentTime":g.seekTo(e);break;case"muted":e?g.mute():g.unMute(),setTimeout(function(){var e=(0,I.createEvent)("volumechange",v);m.dispatchEvent(e)},50);break;case"volume":e,g.setVolume(100*e),setTimeout(function(){var e=(0,I.createEvent)("volumechange",v);m.dispatchEvent(e)},50);break;case"playbackRate":g.setPlaybackRate(e),setTimeout(function(){var e=(0,I.createEvent)("ratechange",v);m.dispatchEvent(e)},50);break;case"readyState":var n=(0,I.createEvent)("canplay",v);m.dispatchEvent(n)}else y.push({type:"set",propName:a,value:e})}},a=0,u=e.length;a<u;a++)t(e[a]);for(var s=U.default.html5media.methods,l=function(e){v[e]=function(){if(null!==g)switch(e){case"play":return o=!1,g.playVideo();case"pause":return o=!0,g.pauseVideo();case"load":return null}else y.push({type:"call",methodName:e})}},d=0,f=s.length;d<f;d++)l(s[d]);var c=x.default.createElement("div");c.id=v.id,v.options.youtube.nocookie&&(m.originalNode.src=_.getYouTubeNoCookieUrl(n[0].src)),m.originalNode.parentNode.insertBefore(c,m.originalNode),m.originalNode.style.display="none";var p="audio"===m.originalNode.tagName.toLowerCase(),b=p?"1":m.originalNode.height,w=p?"1":m.originalNode.width,T=_.getYouTubeId(n[0].src),E={id:v.id,containerId:c.id,videoId:T,height:b,width:w,host:v.options.youtube&&v.options.youtube.nocookie?"https://www.youtube-nocookie.com":void 0,playerVars:Object.assign({controls:0,rel:0,disablekb:1,showinfo:0,modestbranding:0,html5:1,iv_load_policy:3},v.options.youtube),origin:k.default.location.host,events:{onReady:function(e){if(m.youTubeApi=g=e.target,m.youTubeState={paused:!0,ended:!1},y.length)for(var t=0,r=y.length;t<r;t++){var n=y[t];if("set"===n.type){var a=n.propName,o=""+a.substring(0,1).toUpperCase()+a.substring(1);v["set"+o](n.value)}else"call"===n.type&&v[n.methodName]()}h=g.getIframe(),m.originalNode.muted&&g.mute();for(var i=["mouseover","mouseout"],u=function(e){var t=(0,I.createEvent)(e.type,v);m.dispatchEvent(t)},s=0,l=i.length;s<l;s++)h.addEventListener(i[s],u,!1);for(var d=["rendererready","loadedmetadata","loadeddata","canplay"],f=0,c=d.length;f<c;f++){var p=(0,I.createEvent)(d[f],v);m.dispatchEvent(p)}},onStateChange:function(e){var t=[];switch(e.data){case-1:t=["loadedmetadata"],o=!0,i=!1;break;case 0:t=["ended"],o=!1,i=!v.options.youtube.loop,v.options.youtube.loop||v.stopInterval();break;case 1:t=["play","playing"],i=o=!1,v.startInterval();break;case 2:t=["pause"],o=!0,i=!1,v.stopInterval();break;case 3:t=["progress"],i=!1;break;case 5:t=["loadeddata","loadedmetadata","canplay"],o=!0,i=!1}for(var r=0,n=t.length;r<n;r++){var a=(0,I.createEvent)(t[r],v);m.dispatchEvent(a)}},onError:function(e){return function(e){var t="";switch(e.data){case 2:t="The request contains an invalid parameter value. Verify that video ID has 11 characters and that contains no invalid characters, such as exclamation points or asterisks.";break;case 5:t="The requested content cannot be played in an HTML5 player or another error related to the HTML5 player has occurred.";break;case 100:t="The video requested was not found. Either video has been removed or has been marked as private.";break;case 101:case 105:t="The owner of the requested video does not allow it to be played in embedded players.";break;default:t="Unknown error."}m.generateError("Code "+e.data+": "+t,n)}(e)}}};return(p||m.originalNode.hasAttribute("playsinline"))&&(E.playerVars.playsinline=1),m.originalNode.controls&&(E.playerVars.controls=1),m.originalNode.autoplay&&(E.playerVars.autoplay=1),m.originalNode.loop&&(E.playerVars.loop=1),(E.playerVars.loop&&1===parseInt(E.playerVars.loop,10)||-1<m.originalNode.src.indexOf("loop="))&&!E.playerVars.playlist&&-1===m.originalNode.src.indexOf("playlist=")&&(E.playerVars.playlist=_.getYouTubeId(m.originalNode.src)),_.enqueueIframe(E),v.onEvent=function(e,t,r){null!=r&&(m.youTubeState=r)},v.setSize=function(e,t){null!==g&&g.setSize(e,t)},v.hide=function(){v.stopInterval(),v.pause(),h&&(h.style.display="none")},v.show=function(){h&&(h.style.display="")},v.destroy=function(){g.destroy()},v.interval=null,v.startInterval=function(){v.interval=setInterval(function(){var e=(0,I.createEvent)("timeupdate",v);m.dispatchEvent(e)},250)},v.stopInterval=function(){v.interval&&clearInterval(v.interval)},v.getPosterUrl=function(){var e=r.youtube.imageQuality,t=_.getYouTubeId(m.originalNode.src);return e&&-1<["default","hqdefault","mqdefault","sddefault","maxresdefault"].indexOf(e)&&t?"https://img.youtube.com/vi/"+t+"/"+e+".jpg":""},v}};k.default.onYouTubePlayerAPIReady=function(){_.iFrameReady()},a.typeChecks.push(function(e){return/\/\/(www\.youtube|youtu\.?be)/i.test(e)?"video/x-youtube":null}),n.renderer.add(u)},{2:2,3:3,4:4,5:5,7:7,8:8,9:9}],7:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.removeClass=r.addClass=r.hasClass=void 0,r.loadScript=i,r.offset=u,r.toggleClass=v,r.fadeOut=y,r.fadeIn=g,r.siblings=h,r.visible=b,r.ajax=w;var s=o(e(3)),a=o(e(2)),n=o(e(4));function o(e){return e&&e.__esModule?e:{default:e}}function i(n){return new Promise(function(e,t){var r=a.default.createElement("script");r.src=n,r.async=!0,r.onload=function(){r.remove(),e()},r.onerror=function(){r.remove(),t()},a.default.head.appendChild(r)})}function u(e){var t=e.getBoundingClientRect(),r=s.default.pageXOffset||a.default.documentElement.scrollLeft,n=s.default.pageYOffset||a.default.documentElement.scrollTop;return{top:t.top+n,left:t.left+r}}var l=void 0,d=void 0,f=void 0;"classList"in a.default.documentElement?(l=function(e,t){return void 0!==e.classList&&e.classList.contains(t)},d=function(e,t){return e.classList.add(t)},f=function(e,t){return e.classList.remove(t)}):(l=function(e,t){return new RegExp("\\b"+t+"\\b").test(e.className)},d=function(e,t){c(e,t)||(e.className+=" "+t)},f=function(e,t){e.className=e.className.replace(new RegExp("\\b"+t+"\\b","g"),"")});var c=r.hasClass=l,p=r.addClass=d,m=r.removeClass=f;function v(e,t){c(e,t)?m(e,t):p(e,t)}function y(a){var o=1<arguments.length&&void 0!==arguments[1]?arguments[1]:400,i=arguments[2];a.style.opacity||(a.style.opacity=1);var u=null;s.default.requestAnimationFrame(function e(t){var r=t-(u=u||t),n=parseFloat(1-r/o,2);a.style.opacity=n<0?0:n,o<r?i&&"function"==typeof i&&i():s.default.requestAnimationFrame(e)})}function g(a){var o=1<arguments.length&&void 0!==arguments[1]?arguments[1]:400,i=arguments[2];a.style.opacity||(a.style.opacity=0);var u=null;s.default.requestAnimationFrame(function e(t){var r=t-(u=u||t),n=parseFloat(r/o,2);a.style.opacity=1<n?1:n,o<r?i&&"function"==typeof i&&i():s.default.requestAnimationFrame(e)})}function h(e,t){var r=[];for(e=e.parentNode.firstChild;t&&!t(e)||r.push(e),e=e.nextSibling;);return r}function b(e){return void 0!==e.getClientRects&&"function"===e.getClientRects?!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length):!(!e.offsetWidth&&!e.offsetHeight)}function w(e,t,r,n){var a=s.default.XMLHttpRequest?new XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP"),o="application/x-www-form-urlencoded; charset=UTF-8",i=!1,u="*/".concat("*");switch(t){case"text":o="text/plain";break;case"json":o="application/json, text/javascript";break;case"html":o="text/html";break;case"xml":o="application/xml, text/xml"}"application/x-www-form-urlencoded"!==o&&(u=o+", */*; q=0.01"),a&&(a.open("GET",e,!0),a.setRequestHeader("Accept",u),a.onreadystatechange=function(){if(!i&&4===a.readyState)if(200===a.status){i=!0;var e=void 0;switch(t){case"json":e=JSON.parse(a.responseText);break;case"xml":e=a.responseXML;break;default:e=a.responseText}r(e)}else"function"==typeof n&&n(a.status)},a.send())}n.default.Utils=n.default.Utils||{},n.default.Utils.offset=u,n.default.Utils.hasClass=c,n.default.Utils.addClass=p,n.default.Utils.removeClass=m,n.default.Utils.toggleClass=v,n.default.Utils.fadeIn=g,n.default.Utils.fadeOut=y,n.default.Utils.siblings=h,n.default.Utils.visible=b,n.default.Utils.ajax=w,n.default.Utils.loadScript=i},{2:2,3:3,4:4}],8:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.escapeHTML=i,r.debounce=u,r.isObjectEmpty=s,r.splitEvents=l,r.createEvent=d,r.isNodeAfter=f,r.isString=c;var n,a=e(4),o=(n=a)&&n.__esModule?n:{default:n};function i(e){if("string"!=typeof e)throw new Error("Argument passed must be a string");var t={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"};return e.replace(/[&<>"]/g,function(e){return t[e]})}function u(n,a){var o=this,i=arguments,u=2<arguments.length&&void 0!==arguments[2]&&arguments[2];if("function"!=typeof n)throw new Error("First argument must be a function");if("number"!=typeof a)throw new Error("Second argument must be a numeric value");var s=void 0;return function(){var e=o,t=i,r=u&&!s;clearTimeout(s),s=setTimeout(function(){s=null,u||n.apply(e,t)},a),r&&n.apply(e,t)}}function s(e){return Object.getOwnPropertyNames(e).length<=0}function l(e,r){var n=/^((after|before)print|(before)?unload|hashchange|message|o(ff|n)line|page(hide|show)|popstate|resize|storage)\b/,a={d:[],w:[]};return(e||"").split(" ").forEach(function(e){var t=e+(r?"."+r:"");t.startsWith(".")?(a.d.push(t),a.w.push(t)):a[n.test(e)?"w":"d"].push(t)}),a.d=a.d.join(" "),a.w=a.w.join(" "),a}function d(e,t){if("string"!=typeof e)throw new Error("Event name must be a string");var r=e.match(/([a-z]+\.([a-z]+))/i),n={target:t};return null!==r&&(e=r[1],n.namespace=r[2]),new window.CustomEvent(e,{detail:n})}function f(e,t){return!!(e&&t&&2&e.compareDocumentPosition(t))}function c(e){return"string"==typeof e}o.default.Utils=o.default.Utils||{},o.default.Utils.escapeHTML=i,o.default.Utils.debounce=u,o.default.Utils.isObjectEmpty=s,o.default.Utils.splitEvents=l,o.default.Utils.createEvent=d,o.default.Utils.isNodeAfter=f,o.default.Utils.isString=c},{4:4}],9:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),r.typeChecks=void 0,r.absolutizeUrl=s,r.formatType=l,r.getMimeFromType=d,r.getTypeFromFile=f,r.getExtension=c,r.normalizeExtension=p;var n,a=e(4),o=(n=a)&&n.__esModule?n:{default:n},i=e(8);var u=r.typeChecks=[];function s(e){if("string"!=typeof e)throw new Error("`url` argument must be a string");var t=document.createElement("div");return t.innerHTML='<a href="'+(0,i.escapeHTML)(e)+'">x</a>',t.firstChild.href}function l(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:"";return e&&!t?f(e):t}function d(e){if("string"!=typeof e)throw new Error("`type` argument must be a string");return e&&-1<e.indexOf(";")?e.substr(0,e.indexOf(";")):e}function f(e){if("string"!=typeof e)throw new Error("`url` argument must be a string");for(var t=0,r=u.length;t<r;t++){var n=u[t](e);if(n)return n}var a=p(c(e)),o="video/mp4";return a&&(~["mp4","m4v","ogg","ogv","webm","flv","mpeg"].indexOf(a)?o="video/"+a:"mov"===a?o="video/quicktime":~["mp3","oga","wav","mid","midi"].indexOf(a)&&(o="audio/"+a)),o}function c(e){if("string"!=typeof e)throw new Error("`url` argument must be a string");var t=e.split("?")[0].split("\\").pop().split("/").pop();return~t.indexOf(".")?t.substring(t.lastIndexOf(".")+1):""}function p(e){if("string"!=typeof e)throw new Error("`extension` argument must be a string");switch(e){case"mp4":case"m4v":return"mp4";case"webm":case"webma":case"webmv":return"webm";case"ogg":case"oga":case"ogv":return"ogg";default:return e}}o.default.Utils=o.default.Utils||{},o.default.Utils.typeChecks=u,o.default.Utils.absolutizeUrl=s,o.default.Utils.formatType=l,o.default.Utils.getMimeFromType=d,o.default.Utils.getTypeFromFile=f,o.default.Utils.getExtension=c,o.default.Utils.normalizeExtension=p},{4:4,8:8}]},{},[6]);

@@ -135,8 +135,7 @@ # API and Configuration

useFakeFullscreen | boolean | `false` | Flag to bypass native capabilities on mobile devices and use the fake-fullscreen mode
tracksAriaLive | boolean | `false` | By default, no WAI-ARIA live region - don't make a screen reader speak captions over an audio track.
hideCaptionsButtonWhenEmpty | boolean | `true` | Option to remove the `[cc]` button when no `<track kind="subtitles">` are present
captionTextPreprocessor | function | _not set_ | Option to preprocess the caption text before it is displayed. If set, it expects a function which takes in caption text and returns a preprocessed version thereof. If it is not set, the caption text is displayed as is.
toggleCaptionsButtonWhenOnlyOne | boolean | `false` | If true and we only have one track, change captions to toggle button
startLanguage | string | _(empty)_ | Automatically turn on a `<track>` element. Note: Will not work when toggleCaptionsButtonWhenOnlyOne is set to `true`
slidesSelector | string | _(empty)_ | Selector for slides; could be any valid JavaScript selector (`#id`, `.class`, `img`, etc.)
defaultTrackLine | number/boolean | -3 | Default cue line in which to display cues if the cue is set to "auto" (no line entry in VTT). Can be set to `false` to disable.
autoplayCaptionLanguage | string | `null` | Automatically turn on a subtitles/captions of the corresponfing language; overrides "default" attribute on track element.
chaptersLanguage | string | `null` | Set the language of the chapters track. If only one chapter track exists it will always be used. If multiple chapter tracks exist the player will try to find one using `chaptersLanguage` or the current player language. If none is found the first one defined will be used for the chapter display.
hideScreenReaderTitle | boolean | false | Hide the video player screen reader title so it can be added by the website

@@ -143,0 +142,0 @@ tracksText | string | `null` | Title for Closed Captioning button for WARIA purposes

# Migration Guide
## Migrating from `5.x` to `6.x` version
Version 6.0.0 removed the custom subtitle parsing in favor of browser native support which has greatly improved over the
last years. VTT subtitles can be used for styled subtitles (using the ::cue CSS selector) and positioning etc. For a
list of currently supported features, please refer to https://developer.mozilla.org/en-US/docs/Web/API/WebVTT_API#browser_compatibility.
* The support for "slides"-tracks was removed as it was non-functional in the last versions and is not natively supported. If you need this feature you can add a "metadata" track and add custom logic to display the data therein.
* "tracksAriaLive", "captionTextPreprocessor", "slidesSelector" options are no longer used and can be removed
* "startLanguage" option was renamed to "autoplayCaptionLanguage"
## Migrating from `4.x` to `5.x` version

@@ -4,0 +15,0 @@

Package.describe({
name: 'johndyer:mediaelement',
summary: '*Official* MediaElement.js: <video> and <audio> made easy. One file. Any browser. Same UI.',
version: '5.1.1',
version: '6.0.0',
git: 'https://github.com/mediaelement/mediaelement'

@@ -6,0 +6,0 @@ });

{
"name": "mediaelement",
"license": "MIT",
"version": "5.1.1",
"version": "6.0.0",
"main": "full.js",

@@ -6,0 +6,0 @@ "repository": {

@@ -9,3 +9,3 @@ 'use strict';

// version number
mejs.version = '5.1.1';
mejs.version = '6.0.0';

@@ -12,0 +12,0 @@ // Basic HTML5 settings

@@ -8,5 +8,4 @@ 'use strict';

import MediaElementPlayer from '../player';
import {convertSMPTEtoSeconds} from '../utils/time';
import {isString, createEvent} from '../utils/general';
import {addClass, removeClass, hasClass, siblings, ajax, fadeIn, fadeOut, visible} from '../utils/dom';
import {addClass, removeClass, hasClass, siblings} from '../utils/dom';
import {generateControlButton} from '../utils/generate';

@@ -23,763 +22,743 @@

Object.assign(config, {
/**
* Default language to start media using ISO 639-2 Language Code List (en, es, it, etc.)
* If there are multiple tracks for one language, the last track node found is activated
* @see https://www.loc.gov/standards/iso639-2/php/code_list.php
* @type {String}
*/
startLanguage: '',
/**
* @type {?String}
*/
tracksText: null,
/**
* @type {?String}
*/
chaptersText: null,
/**
* Avoid to screen reader speak captions over an audio track.
*
* @type {Boolean}
*/
tracksAriaLive: false,
/**
* Remove the [cc] button when no track nodes are present
* @type {Boolean}
*/
hideCaptionsButtonWhenEmpty: true,
/**
* Change captions to pop-up if true and only one track node is found
* @type {Boolean}
*/
toggleCaptionsButtonWhenOnlyOne: false,
/**
* @type {String}
*/
slidesSelector: ''
/**
* Default language to start media using ISO 639-2 Language Code List (en, es, it, etc.)
* If there are multiple tracks for one language, the last track node loaded is activated
* @see https://www.loc.gov/standards/iso639-2/php/code_list.php
* @type {?String}
*/
autoplayCaptionLanguage: null,
/**
* Default cue line in which to display cues if the cue is set to "auto" (no line entry in VTT). The default of -3 is
* positioned slightly above the player controls.
* @type {?(Number|Boolean)}
*/
defaultTrackLine: -3,
/**
* @type {?String}
*/
tracksText: null,
/**
* @type {?String}
*/
chaptersText: null,
/**
* Language to use if multiple chapter tracks are present. If not set, the first available chapter will be used.
* ISO 639-2 Language Code (en, es, it, etc.)
* @type {?String}
*/
chaptersLanguage: null,
/**
* Remove the [cc] button when no track nodes are present
* @type {Boolean}
*/
hideCaptionsButtonWhenEmpty: true,
/**
* Change captions to pop-up if true and only one track node is found
* @type {Boolean}
*/
toggleCaptionsButtonWhenOnlyOne: false,
});
Object.assign(MediaElementPlayer.prototype, {
/**
* @type {Boolean}
*/
hasChapters: false,
/**
* @type {Boolean}
*/
hasChapters: false,
/**
* Feature constructor.
*
* Always has to be prefixed with `build` and the name that will be used in MepDefaults.features list
* @param {MediaElementPlayer} player
* @param {HTMLElement} controls
* @param {HTMLElement} layers
* @param {HTMLElement} media
*/
buildtracks (player, controls, layers, media) {
/**
* Feature constructor.
*
* Always has to be prefixed with `build` and the name that will be used in MepDefaults.features list
* @param {MediaElementPlayer} player
* @param {HTMLElement} controls
*/
buildtracks (player, controls) {
this.initTracks(player);
this.findTracks();
if (!player.tracks.length && (!player.trackFiles || !player.trackFiles.length === 0)) {
return;
}
if (!player.tracks.length && (!player.trackFiles || !player.trackFiles.length === 0)) {
return;
}
const
t = this,
tracksTitle = isString(t.options.tracksText) ? t.options.tracksText : i18n.t('mejs.captions-subtitles'),
chaptersTitle = isString(t.options.chaptersText) ? t.options.chaptersText : i18n.t('mejs.captions-chapters')
;
const
t = this,
attr = t.options.tracksAriaLive ? ' role="log" aria-live="assertive" aria-atomic="false"' : '',
tracksTitle = isString(t.options.tracksText) ? t.options.tracksText : i18n.t('mejs.captions-subtitles'),
chaptersTitle = isString(t.options.chaptersText) ? t.options.chaptersText : i18n.t('mejs.captions-chapters'),
total = player.trackFiles === null ? player.tracks.length : player.trackFiles.length
;
// Hide all tracks initially (mode 'hidden' triggers loading)
t.hideAllTracks();
// If browser will do native captions, prefer mejs captions, loop through tracks and hide
if (t.domNode.textTracks) {
for (let i = t.domNode.textTracks.length - 1; i >= 0; i--) {
t.domNode.textTracks[i].mode = 'hidden';
}
}
t.clearTrackHtml(player);
t.cleartracks(player);
player.captionsButton = document.createElement('div');
player.captionsButton.className = `${t.options.classPrefix}button ${t.options.classPrefix}captions-button`;
player.captionsButton.innerHTML =
generateControlButton(t.id, tracksTitle, tracksTitle, `${t.media.options.iconSprite}`, ['icon-captions'], `${t.options.classPrefix}`) +
`<div class="${t.options.classPrefix}captions-selector ${t.options.classPrefix}offscreen">` +
`<ul class="${t.options.classPrefix}captions-selector-list">` +
`<li class="${t.options.classPrefix}captions-selector-list-item">` +
`<input type="radio" class="${t.options.classPrefix}captions-selector-input" ` +
`name="${player.id}_captions" id="${player.id}_captions_none" ` +
`value="none" checked disabled>` +
`<label class="${t.options.classPrefix}captions-selector-label ` +
`${t.options.classPrefix}captions-selected" ` +
`for="${player.id}_captions_none">${i18n.t('mejs.none')}</label>` +
`</li>` +
`</ul>` +
`</div>`;
player.captions = document.createElement('div');
player.captions.className = `${t.options.classPrefix}captions-layer ${t.options.classPrefix}layer`;
player.captions.innerHTML = `<div class="${t.options.classPrefix}captions-position ${t.options.classPrefix}captions-position-hover"${attr}>` +
`<span class="${t.options.classPrefix}captions-text"></span>` +
`</div>`;
player.captions.style.display = 'none';
layers.insertBefore(player.captions, layers.firstChild);
t.addControlElement(player.captionsButton, 'tracks');
player.captionsText = player.captions.querySelector(`.${t.options.classPrefix}captions-text`);
player.captionsButton.querySelector(`.${t.options.classPrefix}captions-selector-input`).disabled = false;
player.captionsButton = document.createElement('div');
player.captionsButton.className = `${t.options.classPrefix}button ${t.options.classPrefix}captions-button`;
player.captionsButton.innerHTML =
generateControlButton(t.id, tracksTitle, tracksTitle, `${t.media.options.iconSprite}`, ['icon-captions'], `${t.options.classPrefix}`) +
`<div class="${t.options.classPrefix}captions-selector ${t.options.classPrefix}offscreen">` +
`<ul class="${t.options.classPrefix}captions-selector-list">` +
`<li class="${t.options.classPrefix}captions-selector-list-item">` +
`<input type="radio" class="${t.options.classPrefix}captions-selector-input" ` +
`name="${player.id}_captions" id="${player.id}_captions_none" ` +
`value="none" checked disabled>` +
`<label class="${t.options.classPrefix}captions-selector-label ` +
`${t.options.classPrefix}captions-selected" ` +
`for="${player.id}_captions_none">${i18n.t('mejs.none')}</label>` +
`</li>` +
`</ul>` +
`</div>`;
player.chaptersButton = document.createElement('div');
player.chaptersButton.className = `${t.options.classPrefix}button ${t.options.classPrefix}chapters-button`;
player.chaptersButton.innerHTML =
generateControlButton(t.id, chaptersTitle, chaptersTitle, `${t.media.options.iconSprite}`, ['icon-chapters'], `${t.options.classPrefix}`) +
`<div class="${t.options.classPrefix}chapters-selector ${t.options.classPrefix}offscreen">` +
`<ul class="${t.options.classPrefix}chapters-selector-list"></ul>` +
`</div>`;
t.addControlElement(player.captionsButton, 'tracks');
const subtitles = t.getSubtitles();
const chapters = t.getChapters();
player.captionsButton.querySelector(`.${t.options.classPrefix}captions-selector-input`).disabled = false;
// add chapters button
if (chapters.length > 0 && !controls.querySelector(`.${t.options.classPrefix}chapter-selector`)) {
player.captionsButton.parentNode.insertBefore(player.chaptersButton, player.captionsButton);
}
player.chaptersButton = document.createElement('div');
player.chaptersButton.className = `${t.options.classPrefix}button ${t.options.classPrefix}chapters-button`;
player.chaptersButton.innerHTML =
generateControlButton(t.id, chaptersTitle, chaptersTitle, `${t.media.options.iconSprite}`, ['icon-chapters'], `${t.options.classPrefix}`) +
`<div class="${t.options.classPrefix}chapters-selector ${t.options.classPrefix}offscreen">` +
`<ul class="${t.options.classPrefix}chapters-selector-list"></ul>` +
`</div>`;
// add subtitles
for (let i = 0; i < subtitles.length; i++) {
player.addTrackButton(subtitles[i]);
if (subtitles[i].isLoaded) {
// subtitles can already be loaded by the browser before UI exists, so the UI could not be updated by the load
// event. So we enable the button, if its state show it has been loaded.
t.enableTrackButton(subtitles[i]);
}
}
let subtitleCount = 0;
player.trackToLoad = -1;
player.selectedTrack = null;
player.isLoadingTrack = false;
for (let i = 0; i < total; i++) {
const
kind = player.tracks[i].kind,
src = player.tracks[i].src
;
if (src.trim()) {
if (kind === 'subtitles' || kind === 'captions') {
subtitleCount++;
} else if (kind === 'chapters' && !controls.querySelector(`.${t.options.classPrefix}chapter-selector`)) {
player.captionsButton.parentNode.insertBefore(player.chaptersButton, player.captionsButton);
}
}
}
const
inEvents = ['mouseenter', 'focusin'],
outEvents = ['mouseleave', 'focusout']
;
player.trackToLoad = -1;
player.selectedTrack = null;
player.isLoadingTrack = false;
// if only one language then just make the button a toggle
if (t.options.toggleCaptionsButtonWhenOnlyOne && subtitles.length === 1) {
player.captionsButton.addEventListener('click', (e) => {
let trackId = 'none';
if (player.selectedTrack === null) {
trackId = player.getSubtitles()[0].trackId;
}
const keyboard = e.keyCode || e.which;
player.setTrack(trackId, (typeof keyboard !== 'undefined'));
});
} else {
const
labels = player.captionsButton.querySelectorAll(`.${t.options.classPrefix}captions-selector-label`),
captions = player.captionsButton.querySelectorAll('input[type=radio]')
;
// add to list
for (let i = 0; i < total; i++) {
const kind = player.tracks[i].kind;
if (player.tracks[i].src.trim() && (kind === 'subtitles' || kind === 'captions')) {
player.addTrackButton(player.tracks[i].trackId, player.tracks[i].srclang, player.tracks[i].label);
}
}
for (let i = 0; i < inEvents.length; i++) {
player.captionsButton.addEventListener(inEvents[i], function () {
removeClass(this.querySelector(`.${t.options.classPrefix}captions-selector`), `${t.options.classPrefix}offscreen`);
});
}
// start loading tracks
player.loadNextTrack();
for (let i = 0; i < outEvents.length; i++) {
player.captionsButton.addEventListener(outEvents[i], function () {
addClass(this.querySelector(`.${t.options.classPrefix}captions-selector`), `${t.options.classPrefix}offscreen`);
});
}
const
inEvents = ['mouseenter', 'focusin'],
outEvents = ['mouseleave', 'focusout']
;
for (let i = 0; i < captions.length; i++) {
captions[i].addEventListener('click', function (e) {
// value is trackId, same as the actual id, and we're using it here
// because the "none" checkbox doesn't have a trackId
// to use, but we want to know when "none" is clicked
const keyboard = e.keyCode || e.which;
if (!e.target.disabled) {
player.setTrack(this.value, (typeof keyboard !== 'undefined'));
}
});
}
// if only one language then just make the button a toggle
if (t.options.toggleCaptionsButtonWhenOnlyOne && subtitleCount === 1) {
player.captionsButton.addEventListener('click', (e) => {
let trackId = 'none';
if (player.selectedTrack === null) {
trackId = player.tracks[0].trackId;
}
const keyboard = e.keyCode || e.which;
player.setTrack(trackId, (typeof keyboard !== 'undefined'));
});
} else {
const
labels = player.captionsButton.querySelectorAll(`.${t.options.classPrefix}captions-selector-label`),
captions = player.captionsButton.querySelectorAll('input[type=radio]')
;
for (let i = 0; i < labels.length; i++) {
labels[i].addEventListener('click', function (e) {
const
radio = siblings(this, (el) => el.tagName === 'INPUT')[0],
event = createEvent('click', radio)
;
radio.dispatchEvent(event);
e.preventDefault();
});
}
for (let i = 0, total = inEvents.length; i < total; i++) {
player.captionsButton.addEventListener(inEvents[i], function () {
removeClass(this.querySelector(`.${t.options.classPrefix}captions-selector`), `${t.options.classPrefix}offscreen`);
});
}
//Allow up/down arrow to change the selected radio without changing the volume.
player.captionsButton.addEventListener('keydown', (e) => {
e.stopPropagation();
});
}
for (let i = 0, total = outEvents.length; i < total; i++) {
player.captionsButton.addEventListener(outEvents[i], function () {
addClass(this.querySelector(`.${t.options.classPrefix}captions-selector`), `${t.options.classPrefix}offscreen`);
});
}
for (let i = 0; i < inEvents.length; i++) {
player.chaptersButton.addEventListener(inEvents[i], function () {
if (this.querySelector(`.${t.options.classPrefix}chapters-selector-list`).children.length) {
removeClass(this.querySelector(`.${t.options.classPrefix}chapters-selector`), `${t.options.classPrefix}offscreen`);
}
});
}
for (let i = 0, total = captions.length; i < total; i++) {
captions[i].addEventListener('click', function (e) {
// value is trackId, same as the actual id, and we're using it here
// because the "none" checkbox doesn't have a trackId
// to use, but we want to know when "none" is clicked
const keyboard = e.keyCode || e.which;
player.setTrack(this.value, (typeof keyboard !== 'undefined'));
});
}
for (let i = 0; i < outEvents.length; i++) {
player.chaptersButton.addEventListener(outEvents[i], function () {
addClass(this.querySelector(`.${t.options.classPrefix}chapters-selector`), `${t.options.classPrefix}offscreen`);
});
}
for (let i = 0, total = labels.length; i < total; i++) {
labels[i].addEventListener('click', function (e) {
const
radio = siblings(this, (el) => el.tagName === 'INPUT')[0],
event = createEvent('click', radio)
;
radio.dispatchEvent(event);
e.preventDefault();
});
}
//Allow up/down arrow to change the selected radio without changing the volume.
player.chaptersButton.addEventListener('keydown', (e) => {
e.stopPropagation();
});
//Allow up/down arrow to change the selected radio without changing the volume.
player.captionsButton.addEventListener('keydown', (e) => {
e.stopPropagation();
});
}
// trigger track load checks in case the browser loaded them before the UI was set up (can happen with "default")
t.checkAllCaptionsLoadedOrError();
t.checkAllChaptersLoadedOrError();
},
for (let i = 0, total = inEvents.length; i < total; i++) {
player.chaptersButton.addEventListener(inEvents[i], function () {
if (this.querySelector(`.${t.options.classPrefix}chapters-selector-list`).children.length) {
removeClass(this.querySelector(`.${t.options.classPrefix}chapters-selector`), `${t.options.classPrefix}offscreen`);
}
});
}
/**
* Feature destructor.
*
* Always has to be prefixed with `clean` and the name that was used in MepDefaults.features list
* @param {MediaElementPlayer} player
*/
clearTrackHtml (player) {
if (player) {
if (player.captionsButton) {
player.captionsButton.remove();
}
if (player.chaptersButton) {
player.chaptersButton.remove();
}
}
},
for (let i = 0, total = outEvents.length; i < total; i++) {
player.chaptersButton.addEventListener(outEvents[i], function () {
addClass(this.querySelector(`.${t.options.classPrefix}chapters-selector`), `${t.options.classPrefix}offscreen`);
});
}
rebuildtracks () {
const t = this;
t.findTracks();
t.buildtracks(t, t.getElement(t.controls));
},
//Allow up/down arrow to change the selected radio without changing the volume.
player.chaptersButton.addEventListener('keydown', (e) => {
e.stopPropagation();
});
/**
* Check for track files and setup event handlers and local track data.
* @param {MediaElementPlayer} player
*/
initTracks (player) {
const
t = this,
trackFiles = t.trackFiles === null ? t.node.querySelectorAll('track') : t.trackFiles
;
// store for use by plugins
t.tracks = [];
if (!player.options.alwaysShowControls) {
// move with controls
player.getElement(player.container).addEventListener('controlsshown', () => {
// push captions above controls
addClass(player.getElement(player.container).querySelector(`.${t.options.classPrefix}captions-position`), `${t.options.classPrefix}captions-position-hover`);
});
if (trackFiles) {
player.trackFiles = trackFiles;
for (let i = 0; i < trackFiles.length; i++) {
const
track = trackFiles[i],
srclang = track.getAttribute('srclang').toLowerCase() || '',
trackId = track.getAttribute('id') || `${t.id}_track_${i}_${track.getAttribute('kind')}_${srclang}`
;
track.setAttribute('id', trackId);
player.getElement(player.container).addEventListener('controlshidden', () => {
if (!media.paused) {
// move back to normal place
removeClass(player.getElement(player.container).querySelector(`.${t.options.classPrefix}captions-position`), `${t.options.classPrefix}captions-position-hover`);
}
});
} else {
addClass(player.getElement(player.container).querySelector(`.${t.options.classPrefix}captions-position`), `${t.options.classPrefix}captions-position-hover`);
}
const trackData = {
trackId: trackId,
srclang: srclang,
src: track.getAttribute('src'),
kind: track.getAttribute('kind'),
label: track.getAttribute('label') || '',
entries: [],
isDefault: track.hasAttribute('default'),
isError: false,
isLoaded: false
};
t.tracks.push(trackData);
media.addEventListener('timeupdate', () => {
player.displayCaptions();
});
if (track.getAttribute('kind') === 'captions' || track.getAttribute('kind') === 'subtitles') {
// caption / subtitle handling
switch (track.readyState) {
case 2:
// already loaded
t.handleCaptionsLoaded(track);
break;
case 3:
// quit loading with error
t.handleCaptionsError(track);
break;
default:
// is going to be loaded
track.addEventListener('load', (event) => {
t.handleCaptionsLoaded(event.target);
});
track.addEventListener('error', (event) => {
t.handleCaptionsError(event.target);
});
break;
}
} else if (track.getAttribute('kind') === 'chapters') {
// chapter handling
switch (track.readyState) {
case 2:
t.handleChaptersLoaded(track);
break;
case 3:
t.handleChaptersError(track);
break;
default:
track.addEventListener('load', (event) => {
t.handleChaptersLoaded(event.target);
});
track.addEventListener('error', (event) => {
t.handleChaptersError(event.target);
});
break;
}
}
}
}
},
if (player.options.slidesSelector !== '') {
player.slidesContainer = document.querySelectorAll(player.options.slidesSelector);
/**
* Load handler for captions and subtitles. Change cue lines if set to auto.
* @param {Element} target Video track element
*/
handleCaptionsLoaded(target) {
const
textTracks = this.domNode.textTracks,
playerTrack = this.getTrackById(target.getAttribute('id'));
media.addEventListener('timeupdate', () => {
player.displaySlides();
});
}
},
// Set default cue line
if (Number.isInteger(this.options.defaultTrackLine)) {
for (let i = 0; i < textTracks.length; i++) {
if (target.getAttribute('srclang') === textTracks[i].language
&& target.getAttribute('kind') === textTracks[i].kind) {
const cues = textTracks[i].cues;
for (let c = 0; c < cues.length; c++) {
if (cues[c].line === 'auto' || cues[c].line === undefined || cues[c].line === null) {
cues[c].line = this.options.defaultTrackLine;
}
}
break;
}
}
}
/**
* Feature destructor.
*
* Always has to be prefixed with `clean` and the name that was used in MepDefaults.features list
* @param {MediaElementPlayer} player
*/
cleartracks (player) {
if (player) {
if (player.captions) {
player.captions.remove();
}
if (player.chapters) {
player.chapters.remove();
}
if (player.captionsText) {
player.captionsText.remove();
}
if (player.captionsButton) {
player.captionsButton.remove();
}
if (player.chaptersButton) {
player.chaptersButton.remove();
}
}
},
// set state & active player button
playerTrack.isLoaded = true;
this.enableTrackButton(playerTrack);
this.checkAllCaptionsLoadedOrError();
},
rebuildtracks () {
const t = this;
t.findTracks();
t.buildtracks(t, t.getElement(t.controls), t.getElement(t.layers), t.media);
},
/**
* Error handler for captions and subtitles. Removs the captions button for erroneous tracks.
* @param {Element} target Video track element
*/
handleCaptionsError(target) {
const playerTrack = this.getTrackById(target.getAttribute('id'));
findTracks () {
const
t = this,
tracktags = t.trackFiles === null ? t.node.querySelectorAll('track') : t.trackFiles,
total = tracktags.length
;
playerTrack.isError = true;
this.removeTrackButton(playerTrack);
this.checkAllCaptionsLoadedOrError();
},
// store for use by plugins
t.tracks = [];
for (let i = 0; i < total; i++) {
const
track = tracktags[i],
srclang = track.getAttribute('srclang').toLowerCase() || '',
trackId = `${t.id}_track_${i}_${track.getAttribute('kind')}_${srclang}`
;
t.tracks.push({
trackId: trackId,
srclang: srclang,
src: track.getAttribute('src'),
kind: track.getAttribute('kind'),
label: track.getAttribute('label') || '',
entries: [],
isLoaded: false
});
}
},
/**
* Load handler for chapters tracks.
* @param {Element} target Video track element
*/
handleChaptersLoaded(target) {
const playerTrack = this.getTrackById(target.getAttribute('id'));
/**
*
* @param {String} trackId, or "none" to disable captions
* @param {Boolean} setByKeyboard
*/
setTrack (trackId, setByKeyboard) {
this.hasChapters = true;
playerTrack.isLoaded = true;
this.checkAllChaptersLoadedOrError();
},
const
t = this,
radios = t.captionsButton.querySelectorAll('input[type="radio"]'),
captions = t.captionsButton.querySelectorAll(`.${t.options.classPrefix}captions-selected`),
track = t.captionsButton.querySelector(`input[value="${trackId}"]`)
;
/**
* Error handler for chapters tracks.
* @param {Element} target Video track element
*/
handleChaptersError(target) {
const playerTrack = this.getTrackById(target.getAttribute('id'));
playerTrack.isError = true;
this.checkAllChaptersLoadedOrError();
},
for (let i = 0, total = radios.length; i < total; i++) {
radios[i].checked = false;
}
/**
* Once all captions/subtitles are loaded, check if we need to autoplay one of them.
*/
checkAllCaptionsLoadedOrError() {
const subtitles = this.getSubtitles();
if (subtitles.length === subtitles.filter(({isLoaded, isError}) => isLoaded || isError).length) {
// no captions/subtitles OR all captions/subtitles loaded or quit loading with error
this.removeCaptionsIfEmpty();
this.checkForAutoPlay();
}
},
for (let i = 0, total = captions.length; i < total; i++) {
removeClass(captions[i], `${t.options.classPrefix}captions-selected`);
}
/**
* Once all chapters are loaded, determine which chapter file should be displayed as the chapters menu.
*/
checkAllChaptersLoadedOrError() {
const chapters = this.getChapters(),
readyChapters = chapters.filter(({isLoaded}) => isLoaded);
if (chapters.length === chapters.filter(({isLoaded, isError}) => isLoaded || isError).length) {
// no chapters OR all chapters loaded or quit loading with error
if (readyChapters.length === 0) {
// no chapters -> remove chapters button
this.chaptersButton.remove();
} else {
// try to find a chapter track in the language set in `options.chaptersLanguage`
let langChapter = readyChapters.find(({srclang}) => srclang === this.options.chaptersLanguage);
// if none was found try to find one using the current player language
langChapter = langChapter || readyChapters.find(({srclang}) => srclang === i18n.lang);
track.checked = true;
const labels = siblings(track, (el) => hasClass(el, `${t.options.classPrefix}captions-selector-label`));
for (let i = 0, total = labels.length; i < total; i++) {
addClass(labels[i], `${t.options.classPrefix}captions-selected`)
}
if (readyChapters.length === 1 || !langChapter) {
// use first chapter track if only one exists or no chapter with the correct lanmguage was loaded
this.drawChapters(readyChapters[0].trackId);
} else {
// use the chapter with the correct language
this.drawChapters(langChapter.trackId);
}
}
}
},
if (trackId === 'none') {
t.selectedTrack = null;
removeClass(t.captionsButton, `${t.options.classPrefix}captions-enabled`);
} else {
for (let i = 0, total = t.tracks.length; i < total; i++) {
const track = t.tracks[i];
if (track.trackId === trackId) {
if (t.selectedTrack === null) {
addClass(t.captionsButton, `${t.options.classPrefix}captions-enabled`);
}
t.selectedTrack = track;
t.captions.setAttribute('lang', t.selectedTrack.srclang);
t.displayCaptions();
break;
}
}
}
/**
*
* @param {String} trackId, or "none" to disable captions
* @param {Boolean} setByKeyboard
*/
setTrack (trackId, setByKeyboard) {
const
t = this,
radios = t.captionsButton.querySelectorAll('input[type="radio"]'),
captions = t.captionsButton.querySelectorAll(`.${t.options.classPrefix}captions-selected`),
track = t.captionsButton.querySelector(`input[value="${trackId}"]`)
;
const event = createEvent('captionschange', t.media);
event.detail.caption = t.selectedTrack;
t.media.dispatchEvent(event);
for (let i = 0; i < radios.length; i++) {
radios[i].checked = false;
}
if (!setByKeyboard) {
setTimeout(function() {
t.getElement(t.container).focus();
}, 500);
}
},
for (let i = 0; i < captions.length; i++) {
removeClass(captions[i], `${t.options.classPrefix}captions-selected`);
}
/**
*
*/
loadNextTrack () {
const t = this;
track.checked = true;
const labels = siblings(track, (el) => hasClass(el, `${t.options.classPrefix}captions-selector-label`));
for (let i = 0; i < labels.length; i++) {
addClass(labels[i], `${t.options.classPrefix}captions-selected`)
}
t.trackToLoad++;
if (t.trackToLoad < t.tracks.length) {
t.isLoadingTrack = true;
t.loadTrack(t.trackToLoad);
} else {
// add done?
t.isLoadingTrack = false;
t.checkForTracks();
}
},
if (trackId === 'none') {
t.selectedTrack = null;
removeClass(t.captionsButton, `${t.options.classPrefix}captions-enabled`);
t.deactivateVideoTracks();
} else {
const track = t.getTrackById(trackId);
if (track) {
if (t.selectedTrack === null) {
addClass(t.captionsButton, `${t.options.classPrefix}captions-enabled`);
}
t.selectedTrack = track;
t.activateVideoTrack(t.selectedTrack.srclang);
}
}
/**
*
* @param index
*/
loadTrack (index) {
const
t = this,
track = t.tracks[index]
;
const event = createEvent('captionschange', t.media);
event.detail.caption = t.selectedTrack;
t.media.dispatchEvent(event);
if (track !== undefined && (track.src !== undefined || track.src !== "")) {
ajax(track.src, 'text', (d) => {
track.entries = typeof d === 'string' && (/<tt\s+xml/ig).exec(d) ?
mejs.TrackFormatParser.dfxp.parse(d) : mejs.TrackFormatParser.webvtt.parse(d);
if (!setByKeyboard) {
setTimeout(function() {
t.getElement(t.container).focus();
}, 500);
}
},
track.isLoaded = true;
t.enableTrackButton(track);
t.loadNextTrack();
/**
* Set mode for all tracks to 'hidden' (causes player to load them).
*/
hideAllTracks() {
if (this.domNode.textTracks) {
// parse through TextTrackList (not an Array)
for (let i = 0; i < this.domNode.textTracks.length; i++) {
this.domNode.textTracks[i].mode = 'hidden';
}
}
},
if (track.kind === 'slides') {
t.setupSlides(track);
}
// Load by default the first track with `chapters` kind
else if (track.kind === 'chapters' && !t.hasChapters) {
t.drawChapters(track);
t.hasChapters = true;
}
}, () => {
t.removeTrackButton(track.trackId);
t.loadNextTrack();
});
}
},
/**
* Hide all subtitles/captions.
*/
deactivateVideoTracks() {
if (this.domNode.textTracks) {
// parse through TextTrackList (not an Array)
for (let i = 0; i < this.domNode.textTracks.length; i++) {
const track = this.domNode.textTracks[i];
if (track.kind === 'subtitles' || track.kind === 'captions') {
track.mode = 'hidden';
}
}
}
},
/**
*
* @param {String} track - The language code
*/
enableTrackButton (track) {
const
t = this,
lang = track.srclang,
target = document.getElementById(`${track.trackId}`)
;
/**
* Display a specific language and hide all other subtitles/captions.
* @param {string} srclang Language code of the subtitles to display
*/
activateVideoTrack(srclang) {
// parse through TextTrackList (not an Array)
for (let i = 0; i < this.domNode.textTracks.length; i++) {
const track = this.domNode.textTracks[i];
// For the 'subtitles-off' button, the first condition will never match so all will subtitles be turned off
if (track.kind === 'subtitles' || track.kind === 'captions') {
if (track.language === srclang) {
track.mode = 'showing';
} else {
track.mode = 'hidden';
}
}
}
},
if (!target) {
return;
}
/**
* Check if we need to start playing any subtitle track.
*/
checkForAutoPlay() {
// select track to automatically play; prefer autoplayCaptionLanguage to default
const
readySubtitles = this.getSubtitles().filter(({isError}) => !isError),
autoplayTrack =
readySubtitles.find(({srclang}) => this.options.autoplayCaptionLanguage === srclang) ||
readySubtitles.find(({isDefault}) => isDefault);
let label = track.label;
if (autoplayTrack) {
if (this.options.toggleCaptionsButtonWhenOnlyOne && readySubtitles.length === 1 && this.captionsButton) {
this.captionsButton.dispatchEvent(createEvent('click', this.captionsButton));
} else {
const target = document.getElementById(`${autoplayTrack.trackId}-btn`)
if (target) {
target.checked = true;
target.dispatchEvent(createEvent('click', target));
}
}
}
},
if (label === '') {
label = i18n.t(mejs.language.codes[lang]) || lang;
}
target.disabled = false;
const targetSiblings = siblings(target, (el) => hasClass(el, `${t.options.classPrefix}captions-selector-label`));
for (let i = 0, total = targetSiblings.length; i < total; i++) {
targetSiblings[i].innerHTML = label;
}
/**
* Enable the input for the caption/subtitle and remove the "loading" notification from the label.
* @param {object} track
*/
enableTrackButton (track) {
const
t = this,
lang = track.srclang,
target = document.getElementById(`${track.trackId}-btn`)
;
if (!target) {
return;
}
// auto select
if (t.options.startLanguage === lang) {
target.checked = true;
const event = createEvent('click', target);
target.dispatchEvent(event);
}
},
let label = track.label;
/**
*
* @param {String} trackId
*/
removeTrackButton (trackId) {
const element = document.getElementById(`${trackId}`);
if (element) {
const button = element.closest('li');
if (button) {
button.remove();
}
}
},
if (label === '') {
label = i18n.t(mejs.language.codes[lang]) || lang;
}
target.disabled = false;
const targetSiblings = siblings(target, (el) => hasClass(el, `${t.options.classPrefix}captions-selector-label`));
for (let i = 0; i < targetSiblings.length; i++) {
targetSiblings[i].innerHTML = label;
}
},
/**
*
* @param {String} trackId
* @param {String} lang - The language code
* @param {String} label
*/
addTrackButton (trackId, lang, label) {
const t = this;
if (label === '') {
label = i18n.t(mejs.language.codes[lang]) || lang;
}
/**
* Removes a track button.
* @param {object} track
*/
removeTrackButton (track) {
const element = document.getElementById(`${track.trackId}-btn`);
if (element) {
const button = element.closest('li');
if (button) {
button.remove();
}
}
},
// trackId is used in the value, too, because the "none"
// caption option doesn't have a trackId but we need to be able
// to set it, too
t.captionsButton.querySelector('ul').innerHTML += `<li class="${t.options.classPrefix}captions-selector-list-item">` +
`<input type="radio" class="${t.options.classPrefix}captions-selector-input" ` +
`name="${t.id}_captions" id="${trackId}" value="${trackId}" disabled>` +
`<label class="${t.options.classPrefix}captions-selector-label"` +
`for="${trackId}">${label} (loading)</label>` +
`</li>`;
},
/**
* Adds a new track button.
* @param {object} track
*/
addTrackButton (track) {
const
t = this,
label = track.label || i18n.t(mejs.language.codes[track.srclang]) || track.srclang;
/**
*
*/
checkForTracks () {
const t = this;
// trackId is used in the value, too, because the "none"
// caption option doesn't have a trackId but we need to be able
// to set it, too
t.captionsButton.querySelector('ul').innerHTML += `<li class="${t.options.classPrefix}captions-selector-list-item">` +
`<input type="radio" class="${t.options.classPrefix}captions-selector-input" ` +
`name="${t.id}_captions" id="${track.trackId}-btn" value="${track.trackId}" disabled>` +
`<label class="${t.options.classPrefix}captions-selector-label"` +
`for="${track.trackId}">${label} (loading)</label>` +
`</li>`;
},
let hasSubtitles = false;
/**
* If no captions exist, remove the button.
*/
removeCaptionsIfEmpty() {
if (this.captionsButton && this.options.hideCaptionsButtonWhenEmpty) {
const subtitleCount = this.getSubtitles().filter(({isError}) => !isError).length;
this.captionsButton.style.display = subtitleCount > 0 ? '' : 'none';
this.setControlsSize();
}
},
// check if any subtitles
if (t.options.hideCaptionsButtonWhenEmpty) {
for (let i = 0, total = t.tracks.length; i < total; i++) {
const kind = t.tracks[i].kind;
if ((kind === 'subtitles' || kind === 'captions') && t.tracks[i].isLoaded) {
hasSubtitles = true;
break;
}
}
/**
* Draw the chapters menu.
*/
drawChapters (chapterTrackId) {
const
t = this,
chapter = this.domNode.textTracks.getTrackById(chapterTrackId),
numberOfChapters = chapter.cues.length
;
t.captionsButton.style.display = hasSubtitles ? '' : 'none';
t.setControlsSize();
}
},
if (!numberOfChapters) {
return;
}
/**
*
*/
displayCaptions () {
if (this.tracks === undefined) {
return;
}
t.chaptersButton.querySelector('ul').innerHTML = '';
const
t = this,
track = t.selectedTrack,
sanitize = (html) => {
const div = document.createElement('div');
div.innerHTML = html;
for (let i = 0; i < numberOfChapters; i++) {
t.chaptersButton.querySelector('ul').innerHTML += `<li class="${t.options.classPrefix}chapters-selector-list-item" ` +
`role="menuitemcheckbox" aria-live="polite" aria-disabled="false" aria-checked="false">` +
`<input type="radio" class="${t.options.classPrefix}captions-selector-input" ` +
`name="${t.id}_chapters" id="${t.id}_chapters_${i}" value="${chapter.cues[i].startTime}" disabled>` +
`<label class="${t.options.classPrefix}chapters-selector-label"`+
`for="${t.id}_chapters_${i}">${chapter.cues[i].text}</label>` +
`</li>`;
}
// Remove all `<script>` tags first
const scripts = div.getElementsByTagName('script');
let i = scripts.length;
while (i--) {
scripts[i].remove();
}
const
radios = t.chaptersButton.querySelectorAll('input[type="radio"]'),
labels = t.chaptersButton.querySelectorAll(`.${t.options.classPrefix}chapters-selector-label`)
;
// Loop the elements and remove anything that contains value="javascript:" or an `on*` attribute
// (`onerror`, `onclick`, etc.)
const allElements = div.getElementsByTagName('*');
for (let i = 0, n = allElements.length; i < n; i++) {
const
attributesObj = allElements[i].attributes,
attributes = Array.prototype.slice.call(attributesObj)
;
for (let i = 0; i < radios.length; i++) {
radios[i].disabled = false;
radios[i].checked = false;
radios[i].addEventListener('click', function (e) {
const
self = this,
listItems = t.chaptersButton.querySelectorAll('li'),
label = siblings(self, (el) => hasClass(el, `${t.options.classPrefix}chapters-selector-label`))[0]
;
for (let j = 0, total = attributes.length; j < total; j++) {
if (attributes[j].name.startsWith('on') || attributes[j].value.startsWith('javascript')) {
allElements[i].remove();
} else if (attributes[j].name === 'style') {
allElements[i].removeAttribute(attributes[j].name);
}
}
self.checked = true;
self.parentNode.setAttribute('aria-checked', true);
addClass(label, `${t.options.classPrefix}chapters-selected`);
removeClass(t.chaptersButton.querySelector(`.${t.options.classPrefix}chapters-selected`), `${t.options.classPrefix}chapters-selected`);
}
return div.innerHTML;
}
;
for (let i = 0; i < listItems.length; i++) {
listItems[i].setAttribute('aria-checked', false);
}
if (track !== null && track.isLoaded) {
let i = t.searchTrackPosition(track.entries, t.media.currentTime);
if (i > -1) {
// Set the line before the timecode as a class so the cue can be targeted if needed
var text = track.entries[i].text;
if (typeof t.options.captionTextPreprocessor === 'function')
text = t.options.captionTextPreprocessor(text);
t.captionsText.innerHTML = sanitize(text);
t.captionsText.className = `${t.options.classPrefix}captions-text ${(track.entries[i].identifier || '')}`;
t.captions.style.display = '';
t.captions.style.height = '0px';
return; // exit out if one is visible;
}
t.captions.style.display = 'none';
} else {
t.captions.style.display = 'none';
}
},
const keyboard = e.keyCode || e.which;
if (typeof keyboard === 'undefined') {
setTimeout(function() {
t.getElement(t.container).focus();
}, 500);
}
/**
*
* @param {HTMLElement} track
*/
setupSlides (track) {
const t = this;
t.slides = track;
t.slides.entries.imgs = [t.slides.entries.length];
t.showSlide(0);
},
t.media.setCurrentTime(parseFloat(self.value));
if (t.media.paused) {
t.media.play();
}
});
}
/**
*
* @param {Number} index
*/
showSlide (index) {
const t = this;
for (let i = 0; i < labels.length; i++) {
labels[i].addEventListener('click', function (e) {
const
radio = siblings(this, (el) => el.tagName === 'INPUT')[0],
event = createEvent('click', radio)
;
radio.dispatchEvent(event);
e.preventDefault();
});
}
},
if (t.tracks === undefined || t.slidesContainer === undefined) {
return;
}
/**
* Get a track object using its id.
* @param {string} trackId
* @returns {object|undefined} The track object with the given id or undefined if it doesn't exist.
*/
getTrackById(trackId) {
return this.tracks.find(track => track.trackId === trackId);
},
const url = t.slides.entries[index].text;
/**
* Fetch all chapter tracks.
* @returns {object[]} Array containing all track of type "chapters"
*/
getChapters() {
return this.tracks.filter(({kind}) => kind === 'chapters');
},
let img = t.slides.entries[index].imgs;
/**
* Fetch all subtitle/captions tracks.
* @returns {object[]} Array containing all track of type "subtitles"/"captions".
*/
getSubtitles() {
return this.tracks.filter(({kind}) => kind === 'subtitles' || kind === 'captions');
},
if (img === undefined || img.fadeIn === undefined) {
const image = document.createElement('img');
image.src = url;
image.addEventListener('load', () => {
const
self = this,
visible = siblings(self, (el) => visible(el))
;
self.style.display = 'none';
t.slidesContainer.innerHTML += self.innerHTML;
fadeIn(t.slidesContainer.querySelector(image));
for (let i = 0, total = visible.length; i < total; i++) {
fadeOut(visible[i], 400);
}
/**
* Perform binary search to look for proper track index
*
* @param {Object[]} tracks
* @param {Number} currentTime
* @return {Number}
*/
searchTrackPosition (tracks, currentTime) {
let
lo = 0,
hi = tracks.length - 1,
mid,
start,
stop
;
});
t.slides.entries[index].imgs = img = image;
while (lo <= hi) {
mid = ((lo + hi) >> 1);
start = tracks[mid].start;
stop = tracks[mid].stop;
} else if (!visible(img)) {
const visible = siblings(self, (el) => visible(el));
fadeIn(t.slidesContainer.querySelector(img));
for (let i = 0, total = visible.length; i < total; i++) {
fadeOut(visible[i]);
}
}
if (currentTime >= start && currentTime < stop) {
return mid;
} else if (start < currentTime) {
lo = mid + 1;
} else if (start > currentTime) {
hi = mid - 1;
}
}
},
/**
*
*/
displaySlides () {
const t = this;
if (this.slides === undefined) {
return;
}
const
slides = t.slides,
i = t.searchTrackPosition(slides.entries, t.media.currentTime)
;
if (i > -1) {
t.showSlide(i);
}
},
/**
*
* @param {Object} chapters
*/
drawChapters (chapters) {
const
t = this,
total = chapters.entries.length
;
if (!total) {
return;
}
t.chaptersButton.querySelector('ul').innerHTML = '';
for (let i = 0; i < total; i++) {
t.chaptersButton.querySelector('ul').innerHTML += `<li class="${t.options.classPrefix}chapters-selector-list-item" ` +
`role="menuitemcheckbox" aria-live="polite" aria-disabled="false" aria-checked="false">` +
`<input type="radio" class="${t.options.classPrefix}captions-selector-input" ` +
`name="${t.id}_chapters" id="${t.id}_chapters_${i}" value="${chapters.entries[i].start}" disabled>` +
`<label class="${t.options.classPrefix}chapters-selector-label"`+
`for="${t.id}_chapters_${i}">${chapters.entries[i].text}</label>` +
`</li>`;
}
const
radios = t.chaptersButton.querySelectorAll('input[type="radio"]'),
labels = t.chaptersButton.querySelectorAll(`.${t.options.classPrefix}chapters-selector-label`)
;
for (let i = 0, total = radios.length; i < total; i++) {
radios[i].disabled = false;
radios[i].checked = false;
radios[i].addEventListener('click', function (e) {
const
self = this,
listItems = t.chaptersButton.querySelectorAll('li'),
label = siblings(self, (el) => hasClass(el, `${t.options.classPrefix}chapters-selector-label`))[0]
;
self.checked = true;
self.parentNode.setAttribute('aria-checked', true);
addClass(label, `${t.options.classPrefix}chapters-selected`);
removeClass(t.chaptersButton.querySelector(`.${t.options.classPrefix}chapters-selected`), `${t.options.classPrefix}chapters-selected`);
for (let i = 0, total = listItems.length; i < total; i++) {
listItems[i].setAttribute('aria-checked', false);
}
const keyboard = e.keyCode || e.which;
if (typeof keyboard === 'undefined') {
setTimeout(function() {
t.getElement(t.container).focus();
}, 500);
}
t.media.setCurrentTime(parseFloat(self.value));
if (t.media.paused) {
t.media.play();
}
});
}
for (let i = 0, total = labels.length; i < total; i++) {
labels[i].addEventListener('click', function (e) {
const
radio = siblings(this, (el) => el.tagName === 'INPUT')[0],
event = createEvent('click', radio)
;
radio.dispatchEvent(event);
e.preventDefault();
});
}
},
/**
* Perform binary search to look for proper track index
*
* @param {Object[]} tracks
* @param {Number} currentTime
* @return {Number}
*/
searchTrackPosition (tracks, currentTime) {
let
lo = 0,
hi = tracks.length - 1,
mid,
start,
stop
;
while (lo <= hi) {
mid = ((lo + hi) >> 1);
start = tracks[mid].start;
stop = tracks[mid].stop;
if (currentTime >= start && currentTime < stop) {
return mid;
} else if (start < currentTime) {
lo = mid + 1;
} else if (start > currentTime) {
hi = mid - 1;
}
}
return -1;
}
return -1;
}
});

@@ -793,201 +772,59 @@

mejs.language = {
codes: {
af: 'mejs.afrikaans',
sq: 'mejs.albanian',
ar: 'mejs.arabic',
be: 'mejs.belarusian',
bg: 'mejs.bulgarian',
ca: 'mejs.catalan',
zh: 'mejs.chinese',
'zh-cn': 'mejs.chinese-simplified',
'zh-tw': 'mejs.chines-traditional',
hr: 'mejs.croatian',
cs: 'mejs.czech',
da: 'mejs.danish',
nl: 'mejs.dutch',
en: 'mejs.english',
et: 'mejs.estonian',
fl: 'mejs.filipino',
fi: 'mejs.finnish',
fr: 'mejs.french',
gl: 'mejs.galician',
de: 'mejs.german',
el: 'mejs.greek',
ht: 'mejs.haitian-creole',
iw: 'mejs.hebrew',
hi: 'mejs.hindi',
hu: 'mejs.hungarian',
is: 'mejs.icelandic',
id: 'mejs.indonesian',
ga: 'mejs.irish',
it: 'mejs.italian',
ja: 'mejs.japanese',
ko: 'mejs.korean',
lv: 'mejs.latvian',
lt: 'mejs.lithuanian',
mk: 'mejs.macedonian',
ms: 'mejs.malay',
mt: 'mejs.maltese',
no: 'mejs.norwegian',
fa: 'mejs.persian',
pl: 'mejs.polish',
pt: 'mejs.portuguese',
ro: 'mejs.romanian',
ru: 'mejs.russian',
sr: 'mejs.serbian',
sk: 'mejs.slovak',
sl: 'mejs.slovenian',
es: 'mejs.spanish',
sw: 'mejs.swahili',
sv: 'mejs.swedish',
tl: 'mejs.tagalog',
th: 'mejs.thai',
tr: 'mejs.turkish',
uk: 'mejs.ukrainian',
vi: 'mejs.vietnamese',
cy: 'mejs.welsh',
yi: 'mejs.yiddish'
}
codes: {
af: 'mejs.afrikaans',
sq: 'mejs.albanian',
ar: 'mejs.arabic',
be: 'mejs.belarusian',
bg: 'mejs.bulgarian',
ca: 'mejs.catalan',
zh: 'mejs.chinese',
'zh-cn': 'mejs.chinese-simplified',
'zh-tw': 'mejs.chines-traditional',
hr: 'mejs.croatian',
cs: 'mejs.czech',
da: 'mejs.danish',
nl: 'mejs.dutch',
en: 'mejs.english',
et: 'mejs.estonian',
fl: 'mejs.filipino',
fi: 'mejs.finnish',
fr: 'mejs.french',
gl: 'mejs.galician',
de: 'mejs.german',
el: 'mejs.greek',
ht: 'mejs.haitian-creole',
iw: 'mejs.hebrew',
hi: 'mejs.hindi',
hu: 'mejs.hungarian',
is: 'mejs.icelandic',
id: 'mejs.indonesian',
ga: 'mejs.irish',
it: 'mejs.italian',
ja: 'mejs.japanese',
ko: 'mejs.korean',
lv: 'mejs.latvian',
lt: 'mejs.lithuanian',
mk: 'mejs.macedonian',
ms: 'mejs.malay',
mt: 'mejs.maltese',
no: 'mejs.norwegian',
fa: 'mejs.persian',
pl: 'mejs.polish',
pt: 'mejs.portuguese',
ro: 'mejs.romanian',
ru: 'mejs.russian',
sr: 'mejs.serbian',
sk: 'mejs.slovak',
sl: 'mejs.slovenian',
es: 'mejs.spanish',
sw: 'mejs.swahili',
sv: 'mejs.swedish',
tl: 'mejs.tagalog',
th: 'mejs.thai',
tr: 'mejs.turkish',
uk: 'mejs.ukrainian',
vi: 'mejs.vietnamese',
cy: 'mejs.welsh',
yi: 'mejs.yiddish'
}
};
/*
Parses WebVTT format which should be formatted as
================================
WEBVTT
1
00:00:01,1 --> 00:00:05,000
A line of text
2
00:01:15,1 --> 00:02:05,000
A second line of text
===============================
Adapted from: http://www.delphiki.com/html5/playr
*/
mejs.TrackFormatParser = {
webvtt: {
/**
* @type {String}
*/
pattern: /^((?:[0-9]{1,2}:)?[0-9]{2}:[0-9]{2}([,.][0-9]{1,3})?) --\> ((?:[0-9]{1,2}:)?[0-9]{2}:[0-9]{2}([,.][0-9]{3})?)(.*)$/,
/**
*
* @param {String} trackText
* @returns {{text: Array, times: Array}}
*/
parse (trackText) {
const
lines = trackText.split(/\r?\n/),
entries = []
;
let
timecode,
text,
identifier
;
for (let i = 0, total = lines.length; i < total; i++) {
timecode = this.pattern.exec(lines[i]);
if (timecode && i < lines.length) {
if ((i - 1) >= 0 && lines[i - 1] !== '') {
identifier = lines[i - 1];
}
i++;
// grab all the (possibly multi-line) text that follows
text = lines[i];
i++;
while (lines[i] !== '' && i < lines.length) {
text = `${text}\n${lines[i]}`;
i++;
}
text = text === null ? '' : text.trim().replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig, "<a href='$1' target='_blank'>$1</a>");
entries.push({
identifier: identifier,
start: (convertSMPTEtoSeconds(timecode[1]) === 0) ? 0.200 : convertSMPTEtoSeconds(timecode[1]),
stop: convertSMPTEtoSeconds(timecode[3]),
text: text,
settings: timecode[5]
});
}
identifier = '';
}
return entries;
}
},
// Thanks to Justin Capella: https://github.com/johndyer/mediaelement/pull/420
dfxp: {
/**
*
* @param {String} trackText
* @returns {{text: Array, times: Array}}
*/
parse (trackText) {
const trackElem = document.adoptNode(new DOMParser().parseFromString(trackText, 'application/xml').documentElement),
container = trackElem.querySelector('div'),
lines = container.querySelectorAll('p'),
styleNode = document.getElementById(container.getAttribute('style')),
entries = []
;
let styles;
if (styleNode) {
styleNode.removeAttribute('id');
const attributes = styleNode.attributes;
if (attributes.length) {
styles = {};
for (let i = 0, total = attributes.length; i < total; i++) {
styles[attributes[i].name.split(":")[1]] = attributes[i].value;
}
}
}
for (let i = 0, total = lines.length; i < total; i++) {
let
style,
_temp = {
start: null,
stop: null,
style: null,
text: null
}
;
if (lines[i].getAttribute('begin')) {
_temp.start = convertSMPTEtoSeconds(lines[i].getAttribute('begin'));
}
if (!_temp.start && lines[i - 1].getAttribute('end')) {
_temp.start = convertSMPTEtoSeconds(lines[i - 1].getAttribute('end'));
}
if (lines[i].getAttribute('end')) {
_temp.stop = convertSMPTEtoSeconds(lines[i].getAttribute('end'));
}
if (!_temp.stop && lines[i + 1].getAttribute('begin')) {
_temp.stop = convertSMPTEtoSeconds(lines[i + 1].getAttribute('begin'));
}
if (styles) {
style = '';
for (let _style in styles) {
style += `${_style}: ${styles[_style] };`;
}
}
if (style) {
_temp.style = style;
}
if (_temp.start === 0) {
_temp.start = 0.200;
}
_temp.text = lines[i].innerHTML.trim().replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_| !:, .; ]*[-A-Z0-9+&@#\/%=~_|])/ig, "<a href='$1' target='_blank'>$1</a>");
entries.push(_temp);
}
return entries;
}
}
};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc