diff --git a/embed/min/player.js b/embed/min/player.js index e1e6233b..7a270e7a 100644 --- a/embed/min/player.js +++ b/embed/min/player.js @@ -1 +1 @@ -var MistUtil={format:{time:function(e,t){if(isNaN(e)||!isFinite(e))return e;t||(t={});var i=e<0?" ago":"";e=Math.abs(e);var r=Math.floor(e/86400);e-=86400*r;var n=Math.floor(e/3600);e-=3600*n;var a=Math.floor(e/60),o=Math.round(e%1*1e3);e=Math.floor(e-60*a);var s=[];return r&&(r=r+" day"+(r>1?"s":"")+", "),n||r?(s.push(n),s.push(("0"+a).slice(-2))):s.push(a),s.push(("0"+Math.floor(e)).slice(-2)),t.ms&&(s[s.length-1]+="."+("000"+o).slice(-3)),(r||"")+s.join(":")+i},ucFirst:function(e){return e.charAt(0).toUpperCase()+e.slice(1)},number:function(e){if(isNaN(Number(e))||0==Number(e))return e;var t=Math.max(3,Math.ceil(Math.log(e)/Math.LN10)),i=Math.pow(10,t-Math.floor(Math.log(e)/Math.LN10)-1);if((e=Math.round(e*i)/i)>=1e4){number=e.toString().split(".");for(var r=/(\d+)(\d{3})/;r.test(number[0]);)number[0]=number[0].replace(r,"$1 $2");e=number.join(".")}return e},bytes:function(e,t){if(isNaN(Number(e)))return e;var i=t?["bits","Kb","Mb","Gb","Tb","Pb"]:["bytes","KB","MB","GB","TB","PB"];if(0==e)unit=i[0];else{var r=Math.floor(Math.log(Math.abs(e))/Math.log(1024));r<0?unit=i[0]:(e/=Math.pow(1024,r),unit=i[r])}return this.number(e)+unit},bits:function(e){return this.bytes(e,!0)},mime2human:function(e){switch(e){case"html5/video/webm":return"WebM";case"html5/application/vnd.apple.mpegurl":return"HLS (TS)";case"html5/application/vnd.apple.mpegurl;version=7":return"HLS (CMAF)";case"flash/10":return"Flash (RTMP)";case"flash/11":return"Flash (HDS)";case"flash/7":return"Flash (Progressive)";case"html5/video/mpeg":return"TS";case"html5/application/vnd.ms-sstr+xml":case"html5/application/vnd.ms-ss":return"Smooth Streaming";case"dash/video/mp4":return"DASH";case"webrtc":return"WebRTC";case"silverlight":return"Smooth streaming (Silverlight)";case"html5/text/vtt":return"VTT subtitles";case"html5/text/plain":return"SRT subtitles";default:return e.replace("html5/","").replace("video/","").replace("audio/","").toLocaleUpperCase()}}},class:{add:function(e,t){if("classList"in e)e.classList.add(t);else{var i=this.get(e);i.push(t),this.set(e,i)}},remove:function(e,t){if("classList"in e)e.classList.remove(t);else{for(var i=this.get(e),r=i.length-1;r>=0;r--)i[r]==t&&i.splice(r);this.set(e,i)}},get:function(e){var t=e.getAttribute("class");return t&&""!=t?t.split(" "):[]},set:function(e,t){e.setAttribute("class",t.join(" "))},has:function(e,t){return e.className.split(" ").indexOf(t)>=0}},object:{extend:function(e,t,i){for(var r in t)!i||"object"!=typeof t[r]||"nodeType"in t[r]?e[r]=t[r]:(r in e||(MistUtil.array.is(t[r])?e[r]=[]:e[r]={}),this.extend(e[r],t[r],!0));return e},keys:function(e,t){var i=[];for(var r in e)i.push(r);return t&&("function"!=typeof t&&(t=function(e,t){return e.localeCompare(t)}),i.sort(function(i,r){return t(i,r,e[i],e[r])})),i},values:function(e,t){var i=this.keys(e,t);for(var r in values=[],i)values.push(e[i[r]]);return values}},array:{indexOf:function(e,t){if(!(e instanceof Array))throw"Tried to use indexOf on something that is not an array";if("indexOf"in e)return e.indexOf(t);for(var i;i=0?r:i.length}if("function"==typeof e)return e(t);if("object"==typeof e){if(e instanceof Array)return i(t,e[0],e[1]);for(var r in e)return i(t,r,e[r])}if(e in t)return t[e];throw"Invalid sorting rule: "+e+". This should be a function, object or key of "+JSON.stringify(t)+"."}return e.sort(function(e,n){var a=0;for(var o in t){var s=t[o];if(0!=(a=i(r(s,e),r(s,n))))break}return a}),e}},createUnique:function(){var e="uid"+Math.random().toString().replace("0.","");return document.querySelector("."+e)?createUnique():e},http:{getpost:function(e,t,i,r,n){var a=new XMLHttpRequest;if(a.open(e,t,!0),"POST"==e&&a.setRequestHeader("Content-type","application/x-www-form-urlencoded"),n&&(a.timeout=8e3),a.onload=function(){var e=a.status;e>=200&&e<300?r(a.response):n&&n(a)},n&&(a.onerror=function(){n(a)},a.ontimeout=a.onerror),"POST"==e){var o,s=[];for(var l in i)s.push(l+"="+encodeURIComponent(i[l]));s.length&&(o=s.join("&")),a.send(o)}else a.send()},get:function(e,t,i){this.getpost("GET",e,null,t,i)},post:function(e,t,i,r){this.getpost("POST",e,t,i,r)},url:{addParam:function(e,t){var i=e.split("?"),r=[i.shift()],n=[];for(var a in i.length&&(n=i[0].split("&")),t)n.push(a+"="+t[a]);return n.length&&r.push(n.join("&")),r.join("?")},split:function(e){var t=document.createElement("a");return t.href=e,{protocol:t.protocol,host:t.hostname,hash:t.hash,port:t.port,path:t.pathname.replace(/\/*$/,"")}},sanitizeHost:function(e){var t=MistUtil.http.url.split(e);return t.protocol+"//"+t.host+(t.port&&""!=t.port?":"+t.port:"")+(t.hash&&""!=t.hash?"#"+t.hash:"")+(t.path?"/"==t.path.charAt(0)?t.path:"/"+t.path:"")}}},css:{cache:{},load:function(e,t,i){var r=document.createElement("style");r.type="text/css",r.setAttribute("data-source",e),i&&(r.callback=i);var n=this.cache;function a(e){var i=MistUtil.css.applyColors(e,t);"callback"in r?r.callback(i):r.textContent=i}if(e in n)n[e]instanceof Array?n[e].push(a):a(n[e]);else{n[e]=[a];var o=3;!function t(){MistUtil.http.get(e,function(t){for(var i in n[e])n[e][i](t);n[e]=t},function(){if(o>0)o--,setTimeout(t,2e3);else{var i="/*Failed to load*/";for(var r in n[e])n[e][r](i);n[e]=i}})}()}return r},applyColors:function(e,t){return e.replace(/\$([^\s^;^}]*)/g,function(e,i){var r=i.split("."),n=t;for(var a in r)n=n[r[a]];return n})},createStyle:function(e,t,i){var r=document.createElement("style");return r.type="text/css",e&&(t&&(e=this.prependClass(e,t,i)),r.textContent=e),r},prependClass:function(e,t,i){var r=!1;"string"!=typeof e&&("unprepended"in(r=e)||(r.unprepended=r.textContent),e=r.unprepended);var n=(e=e.replace(/\/\*.*?\*\//g,"")).match(/@[^}]*}/g);for(var a in n){e=e.replace(n[a],"@@#@@");for(var o=1;o0)o=r.bps>131072?Math.round(r.bps/1024/1024*8)+"mbps":Math.round(r.bps/1024*8)+"kbps",n[a]=o;break;case"fpks":r.fpks>0&&(n[a]=r.fpks/1e3+"fps");break;case"channels":r.channels>0&&(n[a]=1==r.channels?"Mono":2==r.channels?"Stereo":"Surround ("+r.channels+"ch)");break;case"rate":n[a]=Math.round(r.rate)+"Khz";break;case"language":"Undetermined"!=r[a]&&(n[a]=r[a]);break;case"codec":if("meta"==r.codec)continue;n[a]=r[a]}r.describe=n}for(var s in t){var l=!1;for(var i in t[s])if(l){if(MistUtil.object.keys(t[s]).length>1)for(var a in t[s][i].describe)l[a]!=t[s][i].describe[a]&&delete l[a]}else l=MistUtil.object.extend({},t[s][i].describe);for(var i in t[s]){var c={},d={};for(var a in t[s][i].describe)a in l?d[a]=t[s][i].describe[a]:c[a]=t[s][i].describe[a];t[s][i].different=c,t[s][i].same=d;var u=MistUtil.object.values(c);t[s][i].displayName=u.length?u.join(", "):MistUtil.object.values(t[s][i].describe).join(" ")}var p={};for(var i in t[s]){if(t[s][i].displayName in p){var h=1;for(var i in t[s])t[s][i].different.trackid=h+")",t[s][i].displayName="Track "+h+" ("+t[s][i].displayName+")",h++;break}p[t[s][i].displayName]=1}}return t}},isTouchDevice:function(){return"ontouchstart"in window||navigator.msMaxTouchPoints>0},getPos:function(e,t){e.currentStyle||window.getComputedStyle(e,null);for(var i=1,r=e;r;)r.style.zoom&&""!=r.style.zoom&&(i*=parseFloat(r.style.zoom,10)),r=r.parentElement;var n=e.getBoundingClientRect().left-(parseInt(e.borderLeftWidth,10)||0),a=e.getBoundingClientRect().width,o=Math.max(0,(t.clientX/i-n)/a);return o=Math.min(o,1)},createGraph:function(e,t){var i="http://www.w3.org/2000/svg",r=document.createElementNS(i,"svg");r.setAttributeNS(null,"height","100%"),r.setAttributeNS(null,"width","100%"),r.setAttributeNS(null,"class","mist icon graph"),r.setAttributeNS(null,"preserveAspectRatio","none");var n=e.x[0],a=e.y[0];if(t.differentiate)for(var o=1;ot.x.count&&(l.shift(),d()),d(e.x-n,-1*e.y),this.setAttributeNS(null,"d","M"+l.join(" L")),h()}},r.addData=function(e){m.addData(e)},r},getBrowser:function(){var e=window.navigator.userAgent;return e.indexOf("MSIE ")>=0||e.indexOf("Trident/")>=0?"ie":e.indexOf("Edge/")>=0?"edge":e.indexOf("Opera")>=0||e.indexOf("OPR")>=0?"opera":e.indexOf("Chrome")>=0?"chrome":e.indexOf("Safari")>=0?"safari":e.indexOf("Firefox")>=0&&"firefox"},getAndroid:function(){var e=navigator.userAgent.toLowerCase().match(/android\s([\d\.]*)/i);return!!e&&e[1]}};if(void 0===MistSkins)var MistSkins={};if("undefined"!=typeof mistoptions&&"host"in mistoptions)var misthost=MistUtil.http.url.sanitizeHost(mistoptions.host);else misthost="..";function MistSkin(e){e.skin=this,this.applySkinOptions=function(t){var i;return"string"==typeof t&&t in MistSkins&&(t=MistUtil.object.extend({},MistSkins[t],!0)),i="inherit"in t&&t.inherit&&t.inherit in MistSkins?this.applySkinOptions(t.inherit):MistSkins.default,this.structure=MistUtil.object.extend({},i.structure),t&&"structure"in t&&MistUtil.object.extend(this.structure,t.structure),this.blueprints=MistUtil.object.extend({},i.blueprints),t&&"blueprints"in t&&MistUtil.object.extend(this.blueprints,t.blueprints),this.icons=MistUtil.object.extend({},i.icons,!0),t&&"icons"in t&&MistUtil.object.extend(this.icons.blueprints,t.icons),this.icons.build=function(t,i,r){i||(i=22);var n,a=this.blueprints[t];n="function"==typeof a.svg?a.svg.call(e,r):a.svg,"object"!=typeof i&&(i={height:i,width:i}),"object"!=typeof a.size&&(a.size={height:a.size,width:a.size}),(!("width"in i)&&"height"in i||!("height"in i)&&"width"in i)&&("width"in i&&(i.height=i.width*a.size.height/a.size.width),"height"in i&&(i.width=i.height*a.size.width/a.size.height));var o="";o+='',o+='',o+=n,o+="",o+="";var s=document.createElement("div");return s.innerHTML=o,s.firstChild},this.colors=MistUtil.object.extend({},i.colors),t&&"colors"in t&&MistUtil.object.extend(this.colors,t.colors,!0),this.css=MistUtil.object.extend({},i.css),t&&"css"in t&&MistUtil.object.extend(this.css,t.css),this},this.applySkinOptions("skin"in e.options?e.options.skin:"default");var t=[];for(var i in this.css)if("string"==typeof this.css[i]){var r=MistUtil.css.load(e.urlappend(this.css[i]),this.colors);t.push(r)}this.css=t}function MistUI(e,t){e.UI=this,this.elements=[],this.buildStructure=function(t){if("function"==typeof t&&(t=t.call(e)),"if"in t){var i=!1;if(t.if.call(e,t)?i=t.then:"else"in t&&(i=t.else),!i)return;for(var r in t)["if","then","else"].indexOf(r)<0&&(r in i?(i[r]instanceof Array||(i[r]=[i[r]]),i[r]=i[r].concat(t[r])):i[r]=t[r]);return this.buildStructure(i)}if("type"in t&&t.type in e.skin.blueprints){var n=e.skin.blueprints[t.type].call(e,t);if(!n)return;if(MistUtil.class.add(n,"mistvideo-"+t.type),"css"in t){var a=MistUtil.createUnique();for(var r in t.css=[].concat(t.css),t.css){var o=MistUtil.css.createStyle(t.css[r],a);n.appendChild(o)}MistUtil.class.add(n,a),n.uid=a}if("classes"in t)for(var r in t.classes)MistUtil.class.add(n,t.classes[r]);if("title"in t&&(n.title=t.title),"style"in t)for(var r in t.style)n.style[r]=t.style[r];if("children"in t)for(var r in t.children){var s=this.buildStructure(t.children[r]);s&&n.appendChild(s)}return e.UI.elements.push(n),n}return!1},this.build=function(){return this.buildStructure(t||e.skin.structure.main)};var i=this.build(),r=MistUtil.createUnique(),n=0;for(var a in e.skin.css.length&&(i.style.opacity=0),e.skin.css){var o=e.skin.css[a];o.callback=function(t){"/*Failed to load*/"==t?(this.textContent=t,e.showError("Failed to load CSS from "+this.getAttribute("data-source"))):this.textContent=MistUtil.css.prependClass(t,r,!0),n++,e.skin.css.length<=n&&(i.style.opacity="")},""!=o.textContent&&o.callback(o.textContent),i.appendChild(o)}MistUtil.class.add(i,r);var s=MistUtil.getBrowser();return s&&MistUtil.class.add(i,"browser-"+s),i}MistSkins.default={structure:{main:{if:function(){return!!this.info.hasVideo&&"audio"!=this.source.type.split("/")[1]},then:{type:"placeholder",classes:["mistvideo"],children:[{type:"hoverWindow",mode:"pos",style:{position:"relative"},transition:{hide:"left: 0; right: 0; bottom: -43px;",show:"bottom: 0;",viewport:"left:0; right: 0; top: -1000px; bottom: 0;"},button:{type:"videocontainer"},children:[{type:"loading"},{type:"error"}],window:{type:"controls"}}]},else:{type:"container",classes:["mistvideo"],style:{overflow:"visible"},children:[{type:"controls",classes:["mistvideo-novideo"],style:{width:"480px"}},{type:"loading"},{type:"error"},{if:function(){return"stock"==this.options.controls},then:{type:"video",style:{position:"absolute"}},else:{type:"video",style:{position:"absolute",display:"none"}}}]}},videocontainer:{type:"container",children:[{type:"videobackground",alwaysDisplay:!1,delay:5},{type:"video"}]},controls:{if:function(){return!!(this.player&&this.player.api&&this.player.api.play)},then:{type:"container",classes:["mistvideo-column"],children:[{type:"progress",classes:["mistvideo-pointer"]},{type:"container",classes:["mistvideo-main","mistvideo-padding","mistvideo-row","mistvideo-background"],children:[{type:"play",classes:["mistvideo-pointer"]},{type:"currentTime"},{if:function(){return"size"in this&&this.size.width>300||!this.info.hasVideo||"audio"==this.source.type.split("/")[1]},then:{type:"totalTime"}},{type:"container",classes:["mistvideo-align-right"],children:[{type:"container",children:[{type:"container",classes:["mistvideo-volume_container"],children:[{type:"volume",mode:"horizontal",size:{height:22},classes:["mistvideo-pointer"]}]},{type:"speaker",classes:["mistvideo-pointer"],style:{"margin-left":"-2px"}}]},{if:function(){return"size"in this&&this.size.width>300||!this.info.hasVideo||"audio"==this.source.type.split("/")[1]},then:{type:"container",children:[{type:"loop",classes:["mistvideo-pointer"]},{type:"fullscreen",classes:["mistvideo-pointer"]}]}},{type:"hoverWindow",mode:"pos",transition:{hide:"right: -1000px; bottom: 44px;",show:"right: 5px;",viewport:"right: 0; left: 0; bottom: 0; top: -1000px"},button:{type:"settings",classes:["mistvideo-pointer"]},window:{type:"submenu"}}]}]}]},else:{if:function(){return!(!this.player||!this.player.api)},then:{type:"hoverWindow",mode:"pos",transition:{hide:"right: -1000px; bottom: 44px;",show:"right: 2.5px;",viewport:"right: 0; left: -1000px; bottom: 0; top: -1000px"},style:{right:"5px",left:"auto"},button:{type:"settings",classes:["mistvideo-background","mistvideo-padding"]},window:{type:"submenu"}}}},submenu:{type:"container",style:{width:"80%",maxWidth:"25em",zIndex:2},classes:["mistvideo-padding","mistvideo-column","mistvideo-background"],children:[{type:"tracks"},{if:function(){return"size"in this&&this.size.width<=300},then:{type:"container",classes:["mistvideo-center"],children:[{type:"loop",classes:["mistvideo-pointer"]},{type:"fullscreen",classes:["mistvideo-pointer"]}]}}]},placeholder:{type:"container",classes:["mistvideo","mistvideo-delay-display"],children:[{type:"placeholder"},{type:"loading"},{type:"error"}]},secondaryVideo:function(e){return{type:"hoverWindow",classes:["mistvideo"],mode:"pos",transition:{hide:"left: 10px; bottom: -40px;",show:"bottom: 10px;",viewport:"left: 0; right: 0; top: 0; bottom: 0"},button:{type:"container",children:[{type:"videocontainer"}]},window:{type:"switchVideo",classes:["mistvideo-controls","mistvideo-padding","mistvideo-background","mistvideo-pointer"],containers:e}}}},css:{skin:misthost+"/skins/default.css"},icons:{blueprints:{play:{size:45,svg:''},largeplay:{size:45,svg:''},pause:{size:45,svg:''},speaker:{size:45,svg:''},volume:{size:{width:100,height:45},svg:function(){var e=MistUtil.createUnique();return''}},muted:{size:45,svg:''},fullscreen:{size:45,svg:''},loop:{size:45,svg:''},settings:{size:45,svg:''},loading:{size:100,svg:''},timeout:{size:25,svg:function(e){e&&e.delay||(e={delay:10});var t=e.delay,i=MistUtil.createUnique();return''}},popout:{size:45,svg:''},switchvideo:{size:45,svg:''}}},blueprints:{container:function(){return document.createElement("div")},video:function(){var e=this;if(MistUtil.event.addListener(e.video,"contextmenu",function(t){t.preventDefault(),e.container.setAttribute("data-show-submenu",""),e.container.removeAttribute("data-hide-submenu"),e.container.removeAttribute("data-hidecursor");var i=function(){e.container.removeAttribute("data-show-submenu"),e.container.removeEventListener("mouseout",i)};MistUtil.event.addListener(e.container,"mouseout",i)}),e.video.hideTimer=!1,e.video.hideCursor=function(){this.hideTimer&&clearTimeout(this.hideTimer),this.hideTimer=e.timers.start(function(){e.container.setAttribute("data-hidecursor","");var t=e.container.querySelector(".mistvideo-controls");t&&t.parentNode.setAttribute("data-hidecursor","")},3e3)},MistUtil.event.addListener(e.video,"mousemove",function(){e.container.removeAttribute("data-hidecursor");var t=e.container.querySelector(".mistvideo-controls");t&&t.parentNode.removeAttribute("data-hidecursor"),e.video.hideCursor()}),MistUtil.event.addListener(e.video,"mouseout",function(){e.video.hideTimer&&e.timers.stop(e.video.hideTimer)}),e.options.autoplay)var t=MistUtil.event.addListener(e.video,"canplay",function(){if(e.player.api&&e.player.api.paused){var i=e.player.api.play();i&&i.catch(function(t){if(!e.destroyed)if(e.log("Autoplay failed. Retrying with muted audio.."),e.info.hasVideo){e.player.api.muted=!0,MistUtil.event.send("volumechange",null,e.video);var i=e.player.api.play();i&&i.then(function(){e.reporting&&(e.reporting.stats.d.autoplay="success")}).then(function(){if(!e.destroyed){e.log("Autoplay worked! Video will be unmuted on mouseover if the page has been interacted with."),e.reporting&&(e.reporting.stats.d.autoplay="muted");var t=e.skin.icons.build("muted",100);MistUtil.class.add(t,"mistvideo-pointer"),e.container.appendChild(t),MistUtil.event.addListener(t,"click",function(){e.player.api.muted=!1,e.container.removeChild(t)});var i=!1,r=function(){i=!0,document.body.removeEventListener("click",r)};MistUtil.event.addListener(document.body,"click",r,e.video);var n=function(){i&&(e.player.api.muted=!1,e.video.removeEventListener("mouseenter",n),e.log("Re-enabled sound"))};MistUtil.event.addListener(e.video,"mouseenter",n);var a=function(){e.video.muted||(t.parentNode&&e.container.removeChild(t),e.video.removeEventListener("volumechange",a),document.body.removeEventListener("click",r),e.video.removeEventListener("mouseenter",n))};MistUtil.event.addListener(e.video,"volumechange",a)}}).catch(function(){if(!e.destroyed){e.log("Autoplay failed even with muted video. Unmuting and showing play button."),e.timers.start(function(){e.player.api.paused&&(e.player.api.pause(),e.monitor&&e.monitor.destroy())},5e3),e.reporting&&(e.reporting.stats.d.autoplay="failed"),e.player.api.muted=!1;var t=e.skin.icons.build("largeplay",150);MistUtil.class.add(t,"mistvideo-pointer"),e.container.appendChild(t),MistUtil.event.addListener(t,"click",function(){e.player.api.paused&&e.player.api.play()});var i=function(){e.container.removeChild(t),e.video.removeEventListener("play",i)};MistUtil.event.addListener(e.video,"play",i)}})}else e.reporting&&(e.reporting.stats.d.autoplay="failed")})}else e.reporting&&(e.reporting.stats.d.autoplay="success");MistUtil.event.removeListener(t)});return this.video},videocontainer:function(){return this.UI.buildStructure(this.skin.structure.videocontainer)},secondaryVideo:function(e){e||(e={}),e.options||(e.options={});var t=this;"secondary"in t||(t.secondary=[]);var i=MistUtil.object.extend({},t.options);i=MistUtil.object.extend(i,e.options),t.secondary.push(i);var r={primary:t,secondary:!1};i.target=document.createElement("div"),delete i.container;var n={};return i.MistVideoObject=n,MistUtil.event.addListener(i.target,"initialized",function(){var e=n.reference;i.MistVideo=e,r.secondary=e,e.player.api.muted=!0,e.player.api.loop=!1;for(var a=i.target.querySelectorAll(".mistvideo-controls"),o=0;o30)e.player.api.pausedesync=!0,e.player.api.currentTime=this.currentTime,e.log("Re-syncing with main video by seeking (desync: "+t+"s)");else if(i>.01){var r=.1;i<1&&(r=.05),(r=1+r*Math.sign(t))!=e.player.api.playbackRate&&e.log("Re-syncing by changing the playback rate (desync: "+Math.round(1e3*t)+"ms, rate: "+r+")"),e.player.api.playbackRate=r}else 1!=e.player.api.playbackRate&&(e.player.api.playbackRate=1,e.log("Sync with main video achieved (desync: "+Math.round(1e3*t)+"ms)"))}},i.target),MistUtil.event.addListener(e.video,"seeked",function(){e.player.api.pausedesync=!1})}),i.skin=MistUtil.object.extend({},t.skin,!0),i.skin.structure.main=MistUtil.object.extend({},t.skin.structure.secondaryVideo(r)),mistPlay(t.stream,i),i.target},switchVideo:function(e){var t=document.createElement("div");return t.appendChild(this.skin.icons.build("switchvideo")),MistUtil.event.addListener(t,"click",function(){var t=e.containers.primary,i=e.containers.secondary;function r(e,t){if(e.video.currentTarget==t)return e.video;if(e.secondary)for(var i=0;i300&&(e.style.zoom=1.5),e}},submenu:function(){return this.UI.buildStructure(this.skin.structure.submenu)},hoverWindow:function(e){var t={type:"container",classes:"classes"in e?e.classes:[],children:"children"in e?e.children:[]};switch(t.classes.push("hover_window_container"),"classes"in e.window||(e.window.classes=[]),e.window.classes.push("inner_window"),e.window.classes.push("mistvideo-container"),e.window={type:"container",classes:["outer_window"],children:[e.window]},"classes"in e.button||(e.button.classes=[]),e.button.classes.push("pointer"),e.mode){case"left":t.classes.push("horizontal"),t.children=[e.window,e.button];break;case"right":t.classes.push("horizontal"),t.children=[e.button,e.window];break;case"top":t.classes.push("vertical"),t.children=[e.button,e.window];break;case"bottom":t.classes.push("vertical"),t.children=[e.window,e.button];break;case"pos":t.children=[e.button,e.window],"classes"in e.window||(e.window.classes=[]);break;default:throw"Unsupported mode for structure type hoverWindow"}return"transition"in e&&("css"in t||(t.css=[]),t.css.push(".hover_window_container:hover > .outer_window:not([data-hidecursor]) > .inner_window { "+e.transition.show+" }\n.hover_window_container > .outer_window { "+e.transition.viewport+" }\n.hover_window_container > .outer_window > .inner_window { "+e.transition.hide+" }")),t.classes.push(e.mode),this.UI.buildStructure(t)},draggable:function(e){var t=this.skin.blueprints.container(e),i=this,r=this.skin.icons.build("fullscreen",16);MistUtil.class.remove(r,"fullscreen"),MistUtil.class.add(r,"draggable-icon"),t.appendChild(r),r.style.alignSelf="flex-end",r.style.position="absolute",r.style.cursor="move";var n={},a=function(e){t.style.left=e.clientX-n.x+"px",t.style.top=e.clientY-n.y+"px"},o=function(e){window.removeEventListener("mousemove",a),window.removeEventListener("click",o),MistUtil.event.addListener(r,"click",s)},s=function(e){e.stopPropagation(),r.removeEventListener("click",s),n.x=i.container.getBoundingClientRect().left-(t.getBoundingClientRect().left-e.clientX),n.y=i.container.getBoundingClientRect().top-(t.getBoundingClientRect().top-e.clientY),t.style.position="absolute",t.style.right="auto",t.style.bottom="auto",i.container.appendChild(t),a(e),MistUtil.event.addListener(window,"mousemove",a,t),MistUtil.event.addListener(window,"click",o,t)};return MistUtil.event.addListener(r,"click",s),t},progress:function(){var e=document.createElement("div"),t=document.createElement("div");e.appendChild(t),t.kids={},t.kids.bar=document.createElement("div"),t.kids.bar.className="bar",t.appendChild(t.kids.bar);var i=this.video,r=this;t.updateBar=function(e){if(this.kids.bar){if(!isFinite(r.player.api.duration))return void(this.kids.bar.style.display="none");this.kids.bar.style.display="",w=Math.min(1,Math.max(0,this.time2perc(e))),this.kids.bar.style.width=100*w+"%"}},t.time2perc=function(e){if(!isFinite(r.player.api.duration))return 0;var t=0;if("live"==r.info.type){var i=.001*r.info.meta.buffer_window;t=(e-r.player.api.duration+i)/i}else t=e/r.player.api.duration;return Math.min(1,Math.max(0,t))},t.buildBuffer=function(e,t){var i=document.createElement("div");return i.className="buffer",i.style.left=100*this.time2perc(e)+"%",i.style.width=100*(this.time2perc(t)-this.time2perc(e))+"%",i},t.updateBuffers=function(e){for(var t=this.querySelectorAll(".buffer"),i=0;i1e3?(t.updateBuffers(r.player.api.buffered),n=(new Date).getTime()):a||(a=r.timers.start(function(){e(),a=!1},1e3))}()},t);var o=0,s=!1;MistUtil.event.addListener(i,"timeupdate",function(){!function e(){(new Date).getTime()-o>200&&!c?(t.updateBar(r.player.api.currentTime),o=(new Date).getTime()):s||(s=r.timers.start(function(){e(),s=!1},1e3))}()},t),MistUtil.event.addListener(i,"seeking",function(){t.updateBar(r.player.api.currentTime)},t),t.getPos=function(e){var t=MistUtil.getPos(this,e);return"live"==r.info.type?(t-1)*(.001*r.info.meta.buffer_window)+r.player.api.duration:!!isFinite(r.player.api.duration)&&t*r.player.api.duration},t.seek=function(e){var t=this.getPos(e);r.player.api.currentTime=t},MistUtil.event.addListener(e,"mouseup",function(e){1==e.which&&t.seek(e)});var l=r.UI.buildStructure({type:"tooltip"});l.style.opacity=0,t.appendChild(l),MistUtil.event.addListener(e,"mouseout",function(){c||(l.style.opacity=0)}),t.moveTooltip=function(e){var t=this.getPos(e);if(!1!==t){l.setText(MistUtil.format.time(t)),l.style.opacity=1;var i=MistUtil.getPos(this,e),r={bottom:20};i>.5?(r.right=100*(1-i)+"%",l.triangle.setMode("bottom","right")):(r.left=100*i+"%",l.triangle.setMode("bottom","left")),l.setPos(r)}else l.style.opacity=0},MistUtil.event.addListener(e,"mousemove",function(e){t.moveTooltip(e)});var c=!1;return MistUtil.event.addListener(e,"mousedown",function(i){if(1==i.which){c=!0,t.updateBar(t.getPos(i));var r=MistUtil.event.addListener(document,"mousemove",function(e){t.updateBar(t.getPos(e)),t.moveTooltip(e)},t),n=MistUtil.event.addListener(document,"mouseup",function(i){1==i.which&&(c=!1,MistUtil.event.removeListener(r),MistUtil.event.removeListener(n),l.style.opacity=0,(!i.path||MistUtil.array.indexOf(i.path,e)<0)&&t.seek(i))},t)}}),e},play:function(){var e=this,t=document.createElement("div");t.appendChild(this.skin.icons.build("play")),t.appendChild(this.skin.icons.build("pause")),t.setState=function(e){this.setAttribute("data-state",e)},t.setState("paused");var i=this.video;return MistUtil.event.addListener(i,"playing",function(){t.setState("playing"),e.options.autoplay=!0},t),MistUtil.event.addListener(i,"pause",function(){t.setState("paused")},t),MistUtil.event.addListener(i,"paused",function(){t.setState("paused")},t),MistUtil.event.addListener(i,"ended",function(){t.setState("paused")},t),MistUtil.event.addListener(t,"click",function(){e.player.api.error&&e.player.api.load(),e.player.api.paused?e.player.api.play():(e.player.api.pause(),e.options.autoplay=!1)}),e.player.api&&MistUtil.event.addListener(e.video,"click",function(){e.player.api.paused?e.player.api.play():MistUtil.isTouchDevice()||(e.player.api.pause(),e.options.autoplay=!1)},t),t},speaker:function(){var e=!1,t=this.info.meta.tracks;for(var i in t)if("audio"==t[i].type){e=!0;break}if(!e)return!1;var r=this.skin.icons.build("speaker"),n=this,a=this.video;return MistUtil.event.addListener(a,"volumechange",function(){n.player.api.volume&&!n.player.api.muted?MistUtil.class.remove(r,"off"):MistUtil.class.add(r,"off")},r),MistUtil.event.addListener(r,"click",function(e){n.player.api.muted=!n.player.api.muted}),r},volume:function(e){var t=!1,i=this.info.meta.tracks;for(var r in i)if("audio"==i[r].type){t=!0;break}if(!t)return!1;var n=document.createElement("div"),a=this.skin.icons.build("volume","size"in e&&e.size);n.appendChild(a);var o=this;a.mode="mode"in e?e.mode:"vertical","vertical"==a.mode&&(a.style.transform="rotate(90deg)"),a.margin={start:.15,end:.1};var s=this.video;a.set=function(e){100!=(e=100-100*Math.pow(1-e/100,2))&&0!=e&&(e=100*this.addPadding(e/100));for(var t=a.querySelectorAll(".slider"),i=0;ii(t)?1:i(e)t[i]?1:t[e]1&&"player"in e&&"api"in e.player&&("setTrack"in e.player.api||"setTracks"in e.player.api||"setSource"in e.player.api)){var b=document.createElement("select");if(b.title="Select another "+l+" track",r[l]=b,b.trackType=l,m.appendChild(b),"subtitle"!=l){var M=document.createElement("option");b.appendChild(M),M.value="",M.appendChild(document.createTextNode("Automatic"))}var w=g(c[MistUtil.object.keys(c)[0]].same);if(w.length)(T=document.createElement("span")).className="mistvideo-description",m.appendChild(T),m.appendChild(document.createTextNode(w.join(" ")));function k(e){return""==e?-1:Number(e)}var U=MistUtil.object.keys(c,function(e,t){return k(e)-k(t)});for(var u in U){var x=c[U[u]];M=document.createElement("option");b.appendChild(M),M.value="idx"in x?x.idx:x.trackid,MistUtil.object.keys(x.different).length?M.appendChild(document.createTextNode(g(x.different).join(" "))):M.appendChild(document.createTextNode("Track "+(Number(u)+1)))}if(MistUtil.event.addListener(e.video,"playerUpdate_trackChanged",function(t){t.message.type==l&&"none"!=t.message.trackid&&(b.value=t.message.trackid,e.log("Player selected "+l+" track with id "+t.message.trackid))},b),"subtitle"==l){if(MistUtil.event.addListener(b,"change",function(){try{localStorage.mistSubtitleLanguage=c[this.value].lang}catch(e){}if(""!=this.value){var t=MistUtil.object.extend({},c[this.value]);t.label=g(t.describe).join(" "),t.src=MistUtil.http.url.addParam(d,{track:this.value}),e.player.api.setSubtitle(t)}else e.player.api.setSubtitle()}),"localStorage"in window&&null!=localStorage&&"mistSubtitleLanguage"in localStorage)for(var u in c)if(c[u].lang==localStorage.mistSubtitleLanguage){b.value=u;var C=document.createEvent("Event");C.initEvent("change"),b.dispatchEvent(C);break}}else MistUtil.event.addListener(b,"change",function(){this.trackType in n&&(n[this.trackType].checked=!0),a(this.trackType,this.value)})}else{var T;(T=document.createElement("span")).className="mistvideo-description",m.appendChild(T),T.appendChild(document.createTextNode(g(c[y[0]].same).join(" ")))}}}},text:function(e){var t=document.createElement("span");return t.appendChild(document.createTextNode(e.text)),t},placeholder:function(){var e=document.createElement("div"),t=this.calcSize();return e.style.width=t.width+"px",e.style.height=t.height+"px",this.options.poster&&(e.style.background="url('"+this.options.poster+"') no-repeat 50%/contain"),e},timeout:function(e){if(!(!1 in e)){var t="delay"in e?e.delay:5,i=this.skin.icons.build("timeout",!1,{delay:t});return i.timeout=this.timers.start(function(){e.function()},1e3*t),i}},polling:function(){var e=document.createElement("div"),t=this.skin.icons.build("loading");return e.appendChild(t),e},loading:function(){var e=this,t=this.skin.icons.build("loading",50);if("player"in e&&e.player.api){var i=!1;function r(t){e.container.setAttribute("data-loading",t.type),function t(){i||(i=e.timers.start(function(){i=!1,e.monitor.vars&&e.monitor.vars.score>=.999?n():t()},1e3))}()}function n(){e.container.removeAttribute("data-loading"),i&&e.timers.stop(i),i=!1}var a=["waiting","seeking","stalled"];for(var o in a)MistUtil.event.addListener(e.video,a[o],function(t){!this.paused&&"container"in e&&r(t)},t);a=["seeked","playing","canplay","paused","ended"];for(var o in a)MistUtil.event.addListener(e.video,a[o],function(t){"container"in e&&n()},t),MistUtil.event.addListener(e.video,"progress",function(t){"container"in e&&"monitor"in e&&"vars"in e.monitor&&"score"in e.monitor.vars&&e.monitor.vars.score>.99&&n()},t)}return t},error:function(){var e=this,t=document.createElement("div");t.message=function(t,i,r){MistUtil.empty(this);var n=document.createElement("div");if(n.className="message",this.appendChild(n),!r.polling&&!r.passive&&!r.hideTitle){var a=document.createElement("h3");n.appendChild(a),a.appendChild(document.createTextNode("The player has encountered a problem"))}var o=document.createElement("p");if(n.appendChild(o),n.update=function(e){MistUtil.empty(o),o.innerHTML=e},t){e.info.on_error&&(t=e.info.on_error.replace(/\/,t)),n.update(t);var s=document.createElement("p");if(s.className="details mistvideo-description",n.appendChild(s),i)s.appendChild(document.createTextNode(i));else if("decodingIssues"in e.skin.blueprints){if("player"in e&&"api"in e.player&&e.video){if(i=[],void 0!==e.state&&i.push(["Stream state:",e.state]),void 0!==e.player.api.currentTime&&i.push(["Current video time:",MistUtil.format.time(e.player.api.currentTime)]),"video"in e&&"getVideoPlaybackQuality"in e.video){var l=e.video.getVideoPlaybackQuality();"droppedVideoFrames"in l&&"totalVideoFrames"in l&&l.totalVideoFrames&&i.push(["Frames dropped/total:",MistUtil.format.number(l.droppedVideoFrames)+"/"+MistUtil.format.number(l.totalVideoFrames)]),"corruptedVideoFrames"in l&&l.corruptedVideoFrames&&i.push(["Corrupted frames:",MistUtil.format.number(l.corruptedVideoFrames)])}i.push({0:["NETWORK EMPTY:","not yet initialized"],1:["NETWORK IDLE:","resource selected, but not in use"],2:["NETWORK LOADING:","data is being downloaded"],3:["NETWORK NO SOURCE:","could not locate source"]}[e.video.networkState]);if(i.push({0:["HAVE NOTHING:","no information about ready state"],1:["HAVE METADATA:","metadata has been loaded"],2:["HAVE CURRENT DATA:","data for the current playback position is available, but not for the next frame"],3:["HAVE FUTURE DATA:","data for current and next frame is available"],4:["HAVE ENOUGH DATA:","can start playing"]}[e.video.readyState]),!r.passive){var c=document.createElement("table");for(var d in i){var u=document.createElement("tr");for(var p in c.appendChild(u),i[d]){var h=document.createElement("td");u.appendChild(h),h.appendChild(document.createTextNode(i[d][p]))}}s.appendChild(c)}}var m,f=document.createElement("div");f.className="mistvideo-container mistvideo-column",f.style.textAlign="left",f.style.marginBottom="1em",n.appendChild(f),(m=e.UI.buildStructure({type:"forcePlayer"}))&&f.appendChild(m),(m=e.UI.buildStructure({type:"forceType"}))&&f.appendChild(m)}}return n};var i,r=!1,n=!1,a={};if(this.showError=function(o,s){s||(s={softReload:!!(e.player&&e.player.api&&e.player.api.load),reload:!0,nextCombo:!!e.info,polling:!1,passive:!1});var l=s.type?s.type:o;if(!(l in a)){if(!0===s.reload&&(e.options.reloadDelay&&!isNaN(Number(e.options.reloadDelay))?s.reload=Number(e.options.reloadDelay):s.reload=10),s.passive){if(!0===r)return;if(r)return i.update(o),void(n=(new Date).getTime());t.setAttribute("data-passive","")}else t.removeAttribute("data-passive");r&&t.clear(),r=!s.passive||"passive",n=(new Date).getTime();var c=this.log(o,"error"),d=t.message(o,!1,s);i=d;var u=document.createElement("div");if(u.className="mistvideo-buttoncontainer",d.appendChild(u),MistUtil.empty(u),s.softReload){var p={type:"button",label:"Reload video",onclick:function(){e.player.api.load()}};isNaN(s.softReload+"")||(p.delay=s.softReload),u.appendChild(e.UI.buildStructure(p))}if(s.reload){p={type:"button",label:"Reload player",onclick:function(){e.reload("Reloading because reload button was clicked.")}};isNaN(s.reload+"")||(p.delay=s.reload),u.appendChild(e.UI.buildStructure(p))}if(s.nextCombo){p={type:"button",label:"Next source",onclick:function(){e.nextCombo()}};isNaN(s.nextCombo+"")||(p.delay=s.nextCombo),u.appendChild(e.UI.buildStructure(p))}if(s.ignore){p={type:"button",label:"Ignore",onclick:function(){this.clearError(),a[l]=!0}};isNaN(s.ignore+"")||(p.delay=s.ignore),u.appendChild(e.UI.buildStructure(p))}s.polling&&u.appendChild(e.UI.buildStructure({type:"polling"})),MistUtil.class.add(t,"show"),"container"in e&&e.container.removeAttribute("data-loading"),c.defaultPrevented&&t.clear()}},t.clear=function(){for(var i=t.querySelectorAll("svg.icon.timeout"),n=0;n=r.length&&(o=0);var a=r[o],l=a._context;a.width=i.video.videoWidth,a.height=i.video.videoHeight,l.drawImage(i.video,0,0),a.setAttribute("data-front","")}i.player.api.paused?s=!1:i.timers.start(function(){n()},1e3*e.delay)}(),s=!0)}),t}},colors:{fill:"#fff",semiFill:"rgba(255,255,255,0.5)",stroke:"#fff",strokeWidth:1.5,background:"rgba(0,0,0,0.8)",progressBackground:"#333",accent:"#0f0"}},MistSkins.dev={structure:MistUtil.object.extend({},MistSkins.default.structure,!0),blueprints:{timeout:function(){return!1!==this.options.reloadDelay&&MistSkins.default.blueprints.timeout.apply(this,arguments)},log:function(){var e=document.createElement("div");e.appendChild(document.createTextNode("Logs"));var t=document.createElement("div");t.className="logs",e.appendChild(t);var i=document.createElement("table");t.appendChild(i);var r=this,n={message:!1},a=!1,o=!0;function s(e,r,s){if(s||(s={}),n.message==r)return a++,n.counter.nodeValue=a,void(2==a&&n.counter.parentElement&&(n.counter.parentElement.style.display=""));a=1;var l=document.createElement("tr");l.className="entry",s.type&&"log"!=s.type&&(MistUtil.class.add(l,"type-"+s.type),r=MistUtil.format.ucFirst(s.type)+": "+r),i.appendChild(l);var c=document.createElement("td");c.className="timestamp",l.appendChild(c);var d=e.toLocaleTimeString().split(" ");d[0]+="."+("00"+e.getMilliseconds()).slice(-3),c.appendChild(document.createTextNode(d[0])),"currentTime"in s&&(c.title="Video playback time: "+MistUtil.format.time(s.currentTime,{ms:!0}));var u=document.createElement("td");l.appendChild(u);var p=document.createElement("span");p.className="message",u.appendChild(p),p.appendChild(document.createTextNode(r));var h=document.createElement("span");h.style.display="none",h.className="counter",u.appendChild(h);var m=document.createTextNode(a);h.appendChild(m),o&&(t.scrollTop=t.scrollHeight),n={message:r,counter:m}}for(var l in MistUtil.event.addListener(t,"scroll",function(){o=t.scrollTop+t.clientHeight>=t.scrollHeight-5}),r.logs)s(r.logs[l].time,r.logs[l].message,r.logs[l].data);return MistUtil.event.addListener(r.options.target,"log",function(e){if(e.message){var t={};r.player&&r.player.api&&"currentTime"in r.player.api&&(t.currentTime=r.player.api.currentTime),s(new Date,e.message,t)}},e),MistUtil.event.addListener(r.options.target,"error",function(e){if(e.message){var t={type:"error"};r.player&&r.player.api&&"currentTime"in r.player.api&&(t.currentTime=r.player.api.currentTime),s(new Date,e.message,t)}},e),e},decodingIssues:function(){if(this.player){var e=this,t=document.createElement("div");if(e.player.api){var i={"Playback score":function(){if("monitor"in e){if("vars"in e.monitor&&"score"in e.monitor.vars&&e.monitor.vars.values.length){var t=e.monitor.vars.values[e.monitor.vars.values.length-1];if("score"in t){Math.min(1,Math.max(0,t.score));return{x:t.clock,y:Math.min(1,Math.max(0,t.score)),options:{y:{min:0,max:1},x:{count:10}},val:Math.round(100*Math.min(1,Math.max(0,e.monitor.vars.score)))+"%"}}}return 0}},"Corrupted frames":function(){if(e.player.api&&"getVideoPlaybackQuality"in e.player.api){var t=e.player.api.getVideoPlaybackQuality();if(t)return t.corruptedVideoFrames?{val:MistUtil.format.number(t.corruptedVideoFrames),x:.001*(new Date).getTime(),y:t.corruptedVideoFrames,options:{x:{count:10}}}:0}},"Dropped frames":function(){if(e.player.api&&"getVideoPlaybackQuality"in e.player.api){var t=e.player.api.getVideoPlaybackQuality();if(t)return t.droppedVideoFrames?MistUtil.format.number(t.droppedVideoFrames):0}},"Total frames":function(){if(e.player.api&&"getVideoPlaybackQuality"in e.player.api){var t=e.player.api.getVideoPlaybackQuality();if(t)return MistUtil.format.number(t.totalVideoFrames)}},"Decoded audio":function(){if(e.player.api)return MistUtil.format.bytes(e.player.api.webkitAudioDecodedByteCount)},"Decoded video":function(){if(e.player.api)return MistUtil.format.bytes(e.player.api.webkitVideoDecodedByteCount)},"Negative acknowledgements":function(){if(e.player.api)return MistUtil.format.number(e.player.api.nackCount)},"Picture losses":function(){return MistUtil.format.number(e.player.api.pliCount)},"Packets lost":function(){return MistUtil.format.number(e.player.api.packetsLost)},"Packets received":function(){return MistUtil.format.number(e.player.api.packetsReceived)},"Bytes received":function(){if(e.player.api)return MistUtil.format.bytes(e.player.api.bytesReceived)},"Local latency [ms]":function(){if(e.player.api&&"getLatency"in e.player.api){var t=e.player.api.getLatency();return t?new Promise(function(e,i){t.then(function(t){var i=[];for(var r in t)t[r]&&i.push(r[0]+":"+Math.round(1e3*t[r]));i.length?e(i.join(" ")):e()},i)}):new Promise(function(e,t){e()},function(){})}},"Current bitrate":function(){if(e.player.monitor&&"currentBps"in e.player.monitor){var t=MistUtil.format.bits(e.player.monitor.currentBps);return t?t+"ps":t}}},r=[];for(var n in i)void 0!==i[n]()&&a({name:n,function:i[n]});t.update=function(){for(var i in r)r[i]();e.timers.start(function(){t.update()},1e3)},t.update()}return t}function a(e){var i=document.createElement("label");t.appendChild(i),i.style.display="none";var n=document.createElement("span");i.appendChild(n),n.appendChild(document.createTextNode(e.name+":")),n.className="mistvideo-description";var a=document.createElement("span");i.appendChild(a);var o=document.createTextNode(e.value?e.value:"");a.appendChild(o);var s=document.createElement("span");a.appendChild(s),i.set=function(e){if(0!==e&&(this.style.display=""),"object"==typeof e){if(e instanceof Promise)return void e.then(function(e){i.set(e)},function(){});if("val"in e&&(o.nodeValue=e.val,a.className="value"),s.children.length)return(t=s.children[0]).addData(e);var t=MistUtil.createGraph({x:[e.x],y:[e.y]},e.options);return s.style.display="",MistUtil.empty(s),s.appendChild(t)}return o.nodeValue=e},t.appendChild(i),r.push(function(){var t=e.function();i.set(t)})}},forcePlayer:function(){var e=document.createElement("label");e.title="Reload MistVideo and use the selected player";var t=this,i=document.createElement("span");e.appendChild(i),i.appendChild(document.createTextNode("Force player: "));var r=document.createElement("select");e.appendChild(r);var n=document.createElement("option");for(var a in r.appendChild(n),n.value="",n.appendChild(document.createTextNode("Automatic")),mistplayers){n=document.createElement("option");r.appendChild(n),n.value=a,n.appendChild(document.createTextNode(mistplayers[a].name))}return this.options.forcePlayer&&(r.value=this.options.forcePlayer),MistUtil.event.addListener(r,"change",function(){t.options.forcePlayer=""!=this.value&&this.value,t.options.forcePlayer!=t.playerName&&t.reload("Reloading to force player.")}),e},forceType:function(){if(this.info){var e=document.createElement("label");e.title="Reload MistVideo and use the selected protocol";var t=this,i=document.createElement("span");e.appendChild(i),i.appendChild(document.createTextNode("Force protocol: "));var r=document.createElement("select");e.appendChild(r);var n=document.createElement("option");r.appendChild(n),n.value="",n.appendChild(document.createTextNode("Automatic"));var a={};for(var o in t.info.source){var s=t.info.source[o];if(!(s.type in a)){a[s.type]=1;n=document.createElement("option");r.appendChild(n),n.value=s.type,n.appendChild(document.createTextNode(MistUtil.format.mime2human(s.type)))}}return this.options.forceType&&(r.value=this.options.forceType),MistUtil.event.addListener(r,"change",function(){t.options.forceType=""!=this.value&&this.value,t.source&&t.options.forceType==t.source.type||t.reload("Reloading to force new type.")}),e}},forceSource:function(){var e=document.createElement("label");e.title="Reload MistVideo and use the selected source";var t=this,i=document.createElement("span");e.appendChild(i),i.appendChild(document.createTextNode("Force source: "));var r=document.createElement("select");e.appendChild(r);var n=document.createElement("option");for(var a in r.appendChild(n),n.value="",n.appendChild(document.createTextNode("Automatic")),t.info.source){var o=t.info.source[a];n=document.createElement("option");r.appendChild(n),n.value=a,n.appendChild(document.createTextNode(o.url+" ("+MistUtil.format.mime2human(o.type)+")"))}return this.options.forceSource&&(r.value=this.options.forceSource),MistUtil.event.addListener(r,"change",function(){t.options.forceSource=""!=this.value&&this.value,t.options.forceSource!=t.source.index&&t.reload("Reloading to force new source.")}),e}}},MistSkins.dev.css={skin:misthost+"/skins/dev.css"},MistSkins.dev.structure.submenu=MistUtil.object.extend({},MistSkins.default.structure.submenu,!0),MistSkins.dev.structure.submenu.type="draggable",MistSkins.dev.structure.submenu.style.width="25em",MistSkins.dev.structure.submenu.children.unshift({type:"container",style:{flexShrink:1},classes:["mistvideo-column"],children:[{if:function(){return this.playerName&&this.source},then:{type:"container",classes:["mistvideo-description"],style:{display:"block"},children:[{type:"playername",style:{display:"inline"}},{type:"text",text:"is playing",style:{margin:"0 0.2em"}},{type:"mimetype"}]}},{type:"log"},{type:"decodingIssues"},{type:"container",classes:["mistvideo-column","mistvideo-devcontrols"],style:{"font-size":"0.9em"},children:[{type:"text",text:"Player control"},{type:"container",classes:["mistvideo-devbuttons"],style:{"flex-wrap":"wrap"},children:[{type:"button",title:"Build MistVideo again",label:"MistVideo.reload();",onclick:function(){this.reload("Dev-reload button clicked.")}},{type:"button",title:"Switch to the next available player and source combination",label:"MistVideo.nextCombo();",onclick:function(){this.nextCombo()}}]},{type:"forcePlayer"},{type:"forceType"}]}]});var mistplayers={};function MistPlayer(){}function mistPlay(e,t){return new MistVideo(e,t)}function MistVideo(e,t){var i=this;function r(e){if("meta"in e&&"tracks"in e.meta){var t=e.meta.tracks;for(var i in t)if("video"==t[i].type)return!0}return!1}function n(e){if(i.player&&i.player.api&&i.player.api.unload&&(i.log("Received new stream info while a player was already loaded: unloading player"),i.player.api.unload()),i.info=e,i.info.updated=new Date,MistUtil.event.send("haveStreamInfo",e,i.options.target),i.log("Stream info was loaded succesfully."),"error"in e){var n=e.error;return"on_error"in e&&(i.log(n),n=e.on_error),void i.showError(n,{reload:!0,hideTitle:!0})}if(i.calcSize=function(e){e||(e={width:!1,height:!1});var r=e.width||!!("width"in t&&t.width)&&t.width,n=e.height||!!("height"in t&&t.height)&&t.height;if(this.info&&"source"in this.info)if(this.info.hasVideo&&"audio"!=this.source.type.split("/")[1]){if(!r||!n){var a=i.info.width/i.info.height;if(r||n)r?n=r/a:r=n*a;else{var o="maxwidth"in t&&t.maxwidth?t.maxwidth:window.innerWidth,s="maxheight"in t&&t.maxheight?t.maxheight:window.innerHeight;r=i.info.width,n=i.info.height;function l(e){r/=e,n/=e}r<426&&l(r/426),n<240&&l(n/240),o&&r>o&&l(r/o),s&&n>s&&l(n/s)}}}else r||(r=480),n||(n=42);else r=640,n=480;return this.size={width:Math.round(r),height:Math.round(n)},this.size},e.hasVideo=r(e),"live"==e.type){var a=0;for(var o in i.info.meta.tracks)a=Math.max(a,i.info.meta.tracks[o].lastms);e.lastms=a}else{var s=i.resumeTime;if(s){var l=function(){i.player&&i.player.api&&(i.player.api.currentTime=s),this.removeEventListener("initialized",l)};MistUtil.event.addListener(i.options.target,"initialized",l)}}i.options.ABR_bitrate&&i.options.ABR_resize&&i.info&&!i.info.selver&&(i.options.ABR_bitrate=!1),i.choosePlayer()?(i.reporting&&i.reporting.report({player:i.playerName,sourceType:i.source.type,sourceUrl:i.source.url,pageUrl:location.href}),i.player=new mistplayers[i.playerName].player,i.player.onreadylist=[],i.player.onready=function(e){this.onreadylist.push(e)},i.player.build(i,function(e){if(i.log("Building new player"),i.container.removeAttribute("data-loading"),i.video=e,i.reporting&&i.reporting.init(),"api"in i.player){i.monitor={MistVideo:i,delay:1,averagingSteps:20,threshold:function(){return"webrtc"==this.MistVideo.source.type?.95:.75},init:function(){if(!this.vars||!this.vars.active){this.MistVideo.log("Enabling monitor"),this.vars={values:[],score:!1,active:!0};var e=this;!function t(){e.vars&&e.vars.active&&(e.vars.timer=e.MistVideo.timers.start(function(){var i=e.calcScore();!1!==i&&e.check(i)&&e.action(),t()},1e3*e.delay))}()}},destroy:function(){this.vars&&this.vars.active&&(this.MistVideo.log("Disabling monitor"),this.MistVideo.timers.stop(this.vars.timer),delete this.vars)},reset:function(){this.vars&&this.vars.active?(this.MistVideo.log("Resetting monitor"),this.vars.values=[]):this.init()},calcScore:function(){var e=this.vars.values;if(e.push(this.getValue()),e.length<=1)return!1;var t=this.valueToScore(e[0],e[e.length-1]);return e.length>this.averagingSteps&&e.shift(),t=Math.max(t,e[e.length-1].score),this.vars.score=t,i.reporting&&i.reporting.stats.set("playbackScore",Math.round(10*t)/10),t},valueToScore:function(e,t){var i=1;return"player"in this.MistVideo&&"api"in this.MistVideo.player&&"playbackRate"in this.MistVideo.player.api&&(i=this.MistVideo.player.api.playbackRate),(t.video-e.video)/(t.clock-e.clock)/i},getValue:function(){var e={clock:.001*(new Date).getTime(),video:this.MistVideo.player.api.currentTime};return this.vars.values.length&&(e.score=this.valueToScore(this.vars.values[this.vars.values.length-1],e)),e},check:function(e){return!(this.vars.values.length<.5*this.averagingSteps)&&(e3600&&(t.reloadDelay/=1e3,this.log("A reloadDelay of more than an hour was set: assuming milliseconds were intended. ReloadDelay is now "+t.reloadDelay+"s")),new MistSkin(this),this.checkCombo=function(e,t){e||(e={}),e=MistUtil.object.extend(MistUtil.object.extend({},this.options),e);var r,n,a=!1;for(var o in e.forceSource?(r=[i.info.source[e.forceSource]],i.log("Forcing source "+e.forceSource+": "+r[0].type+" @ "+r[0].url)):e.forceType?(r=i.info.source.filter(function(t){return t.type==e.forceType}),i.log("Forcing type "+e.forceType)):r=i.info.source,mistplayers)mistplayers[o].shortname=o;e.forcePlayer?(n=[mistplayers[e.forcePlayer]],i.log("Forcing player "+e.forcePlayer)):n=MistUtil.object.values(mistplayers),r=[].concat(r);var s={first:"source",source:[function(e){return"origIndex"in e?e.origIndex:(e.origIndex=i.info.source.indexOf(e),e.origIndex)}],player:[{priority:1}]},l={inner:"player",outer:"source"};if(e.forcePriority){if("source"in e.forcePriority){if(!(e.forcePriority.source instanceof Array))throw"forcePriority.source is not an array.";s.source=e.forcePriority.source.concat(s.source),MistUtil.array.multiSort(r,s.source)}if("player"in e.forcePriority){if(!(e.forcePriority.player instanceof Array))throw"forcePriority.player is not an array.";s.player=e.forcePriority.player.concat(s.player),MistUtil.array.multiSort(n,s.player)}"first"in e.forcePriority&&(s.first=e.forcePriority.first),"player"==s.first&&(l.outer="player",l.inner="source")}var c={player:{list:n,current:!1},source:{list:r,current:!1}};if(e.startCombo){e.startCombo.started={player:!1,source:!1};for(o=0;o=2))for(var p in c[l.inner].list)if(c[l.inner].current=p,!(d(l.inner)>=1)){a=c.source.list[c.source.current];var h=c.player.list[c.player.current].shortname,m=mistplayers[h];if(m.isMimeSupported(a.type)&&m.isBrowserSupported(a.type,a,i))return{player:h,source:a,source_index:c.source.current};t||i.log("Checking "+m.name+" with "+a.type+".. Nope.")}return!1},this.choosePlayer=function(){i.log("Checking available players..");var e=this.checkCombo();if(!e)return!1;var t=mistplayers[e.player],r=e.source;return i.log("Found a working combo: "+t.name+" with "+r.type+" @ "+r.url),i.playerName=e.player,(r=MistUtil.object.extend({},r)).index=e.source_index,r.url=i.urlappend(r.url),i.source=r,MistUtil.event.send("comboChosen","Player/source combination selected",i.options.target),!0},i.calcSize=function(){return{width:640,height:480}},MistUtil.empty(i.options.target),new MistSkin(i),i.container=new MistUI(i,i.skin.structure.placeholder),i.options.target.appendChild(i.container),i.container.setAttribute("data-loading",""),"WebSocket"in window){!function e(){i.log("Opening stream status stream..");var t=i.options.host.replace(/^http/i,"ws"),o=new WebSocket(i.urlappend(t+"/json_"+encodeURIComponent(i.stream)+".js"));i.socket=o,o.die=!1,o.destroy=function(){this.die=!0,i.reporting&&(i.reporting.reportStats(),i.reporting=!1),this.onclose=function(){},this.close()},o.timeOut=i.timers.start(function(){o.readyState<=1&&(o.destroy(),a())},5e3),o.onopen=function(e){this.wasConnected=!0,i.reporting||(i.reporting={stats:{set:function(e,t){this.d[e]=t},add:function(e,t){void 0===t&&(t=1),this.d[e]+=t},d:{nWaiting:0,timeWaiting:0,nStalled:0,timeStalled:0,timeUnpaused:0,nError:0,nLog:0,videoHeight:null,videoWidth:null,playerHeight:null,playerWidth:null},last:{firstPlayback:null,nWaiting:0,timeWaiting:0,nStalled:0,timeStalled:0,timeUnpaused:0,nError:0,lastError:null,playbackScore:1,nLog:0,autoplay:null,videoHeight:null,videoWidth:null,playerHeight:null,playerWidth:null}},report:function(e){1==i.socket.readyState&&i.socket.send(JSON.stringify(e))},reportStats:function(){var e={},t=!1,r=i.logs.slice(this.stats.last.nLog);for(var n in this.stats.d)this.stats.d[n]!=this.stats.last[n]&&(e[n]=this.stats.d[n],this.stats.last[n]=e[n],t=!0);if(t){if(r.length)for(var n in e.logs=[],r)e.logs.push(r[n].message);this.report(e)}i.timers.start(function(){i.reporting&&i.reporting.reportStats()},5e3)},init:function(){var e=i.video,t=MistUtil.event.addListener(e,"playing",function(){i.reporting.stats.set("firstPlayback",(new Date).getTime()-i.bootMs),MistUtil.event.removeListener(t)});if(MistUtil.event.addListener(e,"waiting",function(){i.reporting.stats.add("nWaiting")}),MistUtil.event.addListener(e,"stalled",function(){i.reporting.stats.add("nStalled")}),MistUtil.event.addListener(i.options.target,"error",function(e){i.reporting.stats.add("nError"),i.reporting.stats.set("lastError",e.message)},e),Object&&Object.defineProperty){var r=0,n=!1,a=0,o=!1,s=0,l=!1,c=i.reporting.stats.d;Object.defineProperty(c,"timeWaiting",{get:function(){return r+(n?(new Date).getTime()-n:0)}}),Object.defineProperty(c,"timeStalled",{get:function(){return a+(o?(new Date).getTime()-o:0)}}),Object.defineProperty(c,"timeUnpaused",{get:function(){return s+(l?(new Date).getTime()-l:0)}}),Object.defineProperty(c,"nLog",{get:function(){return i.logs.length}}),Object.defineProperty(c,"videoHeight",{get:function(){return i.video?i.video.videoHeight:null}}),Object.defineProperty(c,"videoWidth",{get:function(){return i.video?i.video.videoWidth:null}}),Object.defineProperty(c,"playerHeight",{get:function(){return i.video?i.video.clientHeight:null}}),Object.defineProperty(c,"playerWidth",{get:function(){return i.video?i.video.clientWidth:null}}),MistUtil.event.addListener(e,"waiting",function(){r=c.timeWaiting,n=(new Date).getTime()}),MistUtil.event.addListener(e,"stalled",function(){a=c.timeStalled,o=(new Date).getTime()});var d=["playing","pause"];for(var u in d)MistUtil.event.addListener(e,d[u],function(){r=c.timeWaiting,a=c.timeStalled,n=!1,o=!1});MistUtil.event.addListener(e,"playing",function(){s=c.timeUnpaused,l=(new Date).getTime()}),MistUtil.event.addListener(e,"pause",function(){s=c.timeUnpaused,l=!1})}this.reportStats()}})},o.onclose=function(t){if(!this.die)return this.wasConnected?(i.log("Reopening websocket.."),void e()):void a()};var s=!1;o.addEventListener("message",function(e){o.timeOut&&(i.timers.stop(o.timeOut),o.timeOut=!1);var t=JSON.parse(e.data);if(t||i.showError("Error while parsing stream status stream. Obtained: "+e.data.toString(),{reload:!0}),"error"in t){var a;switch(e=t.error,"on_error"in t&&(i.log(e),e=t.on_error),i.state=t.error,t.error){case"Stream is offline":i.info=!1,i.player&&i.player.api&&i.player.api.currentTime&&(i.resumeTime=i.player.api.currentTime);case"Stream is initializing":case"Stream is booting":case"Stream is waiting for data":case"Stream is shutting down":case"Stream status is invalid?!":if(i.player&&i.player.api&&!i.player.api.paused)return i.log(t.error,"error"),s||(s=MistUtil.event.addListener(i.video,"ended",function(){i.showError(t.error,{polling:!0})})),void(s=MistUtil.event.addListener(i.video,"waiting",function(){i.showError(t.error,{polling:!0})}));a={polling:!0};break;default:a={reload:!0}}i.showError(e,a)}else{if(i.state="Stream is online",i.clearError(),s&&MistUtil.event.removeListener(s),!i.info)return void n(t);var l=function e(t,i){if(t==i)return!1;if("object"==typeof t&&void 0!==i){var r={};for(var n in t)if(!(MistUtil.array.indexOf(["lastms","hasVideo"],n)>=0)){var a=e(t[n],i[n]);a&&(r[n]=!0===a?[t[n],i[n]]:a)}for(var n in i)MistUtil.array.indexOf(["lastms","hasVideo"],n)>=0||n in t||(r[n]=[t[n],i[n]]);return!!MistUtil.object.keys(r).length&&r}return!0}(t,i.info);if(l){if("source"in l)return void("error"in i.info&&i.reload("Reloading, stream info has error"));i.info=MistUtil.object.extend(i.info,t),i.info.updated=new Date;var c=!1;for(var d in l)switch(d){case"meta":for(var u in l[d])switch(u){case"tracks":i.info.hasVideo=r(i.info),MistUtil.event.send("metaUpdate_tracks",t,i.video)}break;case"width":case"height":c=!0}c&&i.player.resize()}else i.log("Metachange: no differences detected")}})}()}else a();return this.unload=function(e){if(!this.destroyed){for(var t in this.log("Unloading.."),this.destroyed=!0,this.timers.stop("all"),this.errorListeners){var r=this.errorListeners[t];if(r.src in MistUtil.scripts.list){var n=MistUtil.array.indexOf(MistUtil.scripts.list[r.src].subscribers);n>=0&&MistUtil.scripts.list[r.src].subscribers.splice(n,1)}}if("monitor"in i&&"destroy"in i.monitor&&i.monitor.destroy(),this.socket&&(this.reporting&&(this.reporting.reportStats(),this.reporting.report({unload:e||null})),this.socket.destroy()),this.player&&this.player.api&&("pause"in this.player.api&&this.player.api.pause(),"setSource"in this.player.api&&this.player.api.setSource(""),"unload"in this.player.api))try{this.player.api.unload()}catch(a){i.log("Error while unloading player: "+a.message)}if(this.UI&&this.UI.elements)for(var t in this.UI.elements){var a=this.UI.elements[t];if("attachedListeners"in a)for(var t in a.attachedListeners)MistUtil.event.removeListener(a.attachedListeners[t]);a.parentNode&&a.parentNode.removeChild(a)}this.video&&MistUtil.empty(this.video),"container"in this&&(MistUtil.empty(this.container),delete this.container),MistUtil.empty(this.options.target),delete this.video}},this.reload=function(e){var t="player"in this&&"api"in this.player&&this.player.api.currentTime;this.unload(e);var r=mistPlay(this.stream,this.options);if(t&&"live"!=this.info.type){var n=function(){r.player&&r.player.api&&(r.player.api.currentTime=t),this.removeEventListener("initialized",n)};MistUtil.event.addListener(this.options.target,"initialized",n)}return i},this.nextCombo=function(){var e=!1;"player"in this&&"api"in this.player&&(e=this.player.api.currentTime);var t={source:this.source.index,player:this.playerName};if(!this.checkCombo({startCombo:t},!0)){if(!this.checkCombo({startCombo:!1},!0))return;t=!1}this.unload("nextCombo");var r=this.options;if(r.startCombo=t,i=mistPlay(this.stream,r),e&&isFinite(e)&&"live"!=this.info.type){var n=function(){"player"in i&&"api"in i.player&&(i.player.api.currentTime=e),this.removeEventListener("initialized",n)};MistUtil.event.addListener(r.target,"initialized",n)}},this.onPlayerBuilt=function(){},t.MistVideoObject&&(t.MistVideoObject.reference=this),this} \ No newline at end of file +var MistUtil={format:{time:function(e,t){if(isNaN(e)||!isFinite(e))return e;t||(t={});var i=e<0?" ago":"";e=Math.abs(e);var r=Math.floor(e/86400);e-=86400*r;var n=Math.floor(e/3600);e-=3600*n;var a=Math.floor(e/60),o=Math.round(e%1*1e3);e=Math.floor(e-60*a);var s=[];return r&&(r=r+" day"+(r>1?"s":"")+", "),n||r?(s.push(n),s.push(("0"+a).slice(-2))):s.push(a),s.push(("0"+Math.floor(e)).slice(-2)),t.ms&&(s[s.length-1]+="."+("000"+o).slice(-3)),(r||"")+s.join(":")+i},ago:function(e,t){var i=t||(new Date).getTime()-e.getTime(),r="",n=i<0;return n&&(i*=-1),i<1e3?r="live":i<6e4?(r=Math.round(i/1e3)+" sec",n?r="in "+r:r+=" ago"):r=!t&&(new Date).toLocaleDateString()==e.toLocaleDateString()||t<864e5?e.toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit",second:"2-digit"}):i<5184e5?e.toLocaleString(void 0,{weekday:"short",hour:"numeric",minute:"2-digit",second:"2-digit"}):!t&&(new Date).getFullYear()==e.getFullYear()||t<316224e5?e.toLocaleString(void 0,{month:"short",day:"numeric",weekday:"short",hour:"numeric",minute:"2-digit",second:"2-digit"}):e.toLocaleString(void 0,{year:"numeric",month:"short",day:"numeric",hour:"numeric",minute:"2-digit",second:"2-digit"}),r},ucFirst:function(e){return e.charAt(0).toUpperCase()+e.slice(1)},number:function(e){if(isNaN(Number(e))||0==Number(e))return e;var t=Math.max(3,Math.ceil(Math.log(e)/Math.LN10)),i=Math.pow(10,t-Math.floor(Math.log(e)/Math.LN10)-1);if((e=Math.round(e*i)/i)>=1e4){number=e.toString().split(".");for(var r=/(\d+)(\d{3})/;r.test(number[0]);)number[0]=number[0].replace(r,"$1 $2");e=number.join(".")}return e},bytes:function(e,t){if(isNaN(Number(e)))return e;var i=t?["bits","Kb","Mb","Gb","Tb","Pb"]:["bytes","KB","MB","GB","TB","PB"];if(0==e)unit=i[0];else{var r=Math.floor(Math.log(Math.abs(e))/Math.log(1024));r<0?unit=i[0]:(e/=Math.pow(1024,r),unit=i[r])}return this.number(e)+unit},bits:function(e){return this.bytes(e,!0)},mime2human:function(e){switch(e){case"html5/video/webm":return"WebM";case"html5/application/vnd.apple.mpegurl":return"HLS (TS)";case"html5/application/vnd.apple.mpegurl;version=7":return"HLS (CMAF)";case"flash/10":return"Flash (RTMP)";case"flash/11":return"Flash (HDS)";case"flash/7":return"Flash (Progressive)";case"html5/video/mpeg":return"TS";case"html5/application/vnd.ms-sstr+xml":case"html5/application/vnd.ms-ss":return"Smooth Streaming";case"dash/video/mp4":return"DASH";case"webrtc":return"WebRTC";case"silverlight":return"Smooth streaming (Silverlight)";case"html5/text/vtt":return"VTT subtitles";case"html5/text/plain":return"SRT subtitles";default:return e.replace("html5/","").replace("video/","").replace("audio/","").toLocaleUpperCase()}}},class:{add:function(e,t){if("classList"in e)e.classList.add(t);else{var i=this.get(e);i.push(t),this.set(e,i)}},remove:function(e,t){if("classList"in e)e.classList.remove(t);else{for(var i=this.get(e),r=i.length-1;r>=0;r--)i[r]==t&&i.splice(r);this.set(e,i)}},get:function(e){var t=e.getAttribute("class");return t&&""!=t?t.split(" "):[]},set:function(e,t){e.setAttribute("class",t.join(" "))},has:function(e,t){return e.className.split(" ").indexOf(t)>=0}},object:{extend:function(e,t,i){for(var r in t)!i||"object"!=typeof t[r]||"nodeType"in t[r]?e[r]=t[r]:(r in e||(MistUtil.array.is(t[r])?e[r]=[]:e[r]={}),this.extend(e[r],t[r],!0));return e},keys:function(e,t){var i=[];for(var r in e)i.push(r);return t&&("function"!=typeof t&&(t=function(e,t){return e.localeCompare(t)}),i.sort(function(i,r){return t(i,r,e[i],e[r])})),i},values:function(e,t){var i=this.keys(e,t);for(var r in values=[],i)values.push(e[i[r]]);return values}},array:{indexOf:function(e,t){if(!(e instanceof Array))throw"Tried to use indexOf on something that is not an array";if("indexOf"in e)return e.indexOf(t);for(var i;i=0?r:i.length}if("function"==typeof e)return e(t);if("object"==typeof e){if(e instanceof Array)return i(t,e[0],e[1]);for(var r in e)return i(t,r,e[r])}if(e in t)return t[e];throw"Invalid sorting rule: "+e+". This should be a function, object or key of "+JSON.stringify(t)+"."}return e.sort(function(e,n){var a=0;for(var o in t){var s=t[o];if(0!=(a=i(r(s,e),r(s,n))))break}return a}),e}},createUnique:function(){var e="uid"+Math.random().toString().replace("0.","");return document.querySelector("."+e)?createUnique():e},http:{getpost:function(e,t,i,r,n){var a=new XMLHttpRequest;if(a.open(e,t,!0),"POST"==e&&a.setRequestHeader("Content-type","application/x-www-form-urlencoded"),n&&(a.timeout=8e3),a.onload=function(){var e=a.status;e>=200&&e<300?r(a.response):n&&n(a)},n&&(a.onerror=function(){n(a)},a.ontimeout=a.onerror),"POST"==e){var o,s=[];for(var l in i)s.push(l+"="+encodeURIComponent(i[l]));s.length&&(o=s.join("&")),a.send(o)}else a.send()},get:function(e,t,i){this.getpost("GET",e,null,t,i)},post:function(e,t,i,r){this.getpost("POST",e,t,i,r)},url:{addParam:function(e,t){var i=e.split("?"),r=[i.shift()],n=[];for(var a in i.length&&(n=i[0].split("&")),t)n.push(a+"="+t[a]);return n.length&&r.push(n.join("&")),r.join("?")},split:function(e){var t=document.createElement("a");return t.href=e,{protocol:t.protocol,host:t.hostname,hash:t.hash,port:t.port,path:t.pathname.replace(/\/*$/,"")}},sanitizeHost:function(e){var t=MistUtil.http.url.split(e);return t.protocol+"//"+t.host+(t.port&&""!=t.port?":"+t.port:"")+(t.hash&&""!=t.hash?"#"+t.hash:"")+(t.path?"/"==t.path.charAt(0)?t.path:"/"+t.path:"")}}},css:{cache:{},load:function(e,t,i){var r=document.createElement("style");r.type="text/css",r.setAttribute("data-source",e),i&&(r.callback=i);var n=this.cache;function a(e){var i=MistUtil.css.applyColors(e,t);"callback"in r?r.callback(i):r.textContent=i}if(e in n)n[e]instanceof Array?n[e].push(a):a(n[e]);else{n[e]=[a];var o=3;!function t(){MistUtil.http.get(e,function(t){for(var i in n[e])n[e][i](t);n[e]=t},function(){if(o>0)o--,setTimeout(t,2e3);else{var i="/*Failed to load*/";for(var r in n[e])n[e][r](i);n[e]=i}})}()}return r},applyColors:function(e,t){return e.replace(/\$([^\s^;^}]*)/g,function(e,i){var r=i.split("."),n=t;for(var a in r)n=n[r[a]];return n})},createStyle:function(e,t,i){var r=document.createElement("style");return r.type="text/css",e&&(t&&(e=this.prependClass(e,t,i)),r.textContent=e),r},prependClass:function(e,t,i){var r=!1;"string"!=typeof e&&("unprepended"in(r=e)||(r.unprepended=r.textContent),e=r.unprepended);var n=(e=e.replace(/\/\*.*?\*\//g,"")).match(/@[^}]*}/g);for(var a in n){e=e.replace(n[a],"@@#@@");for(var o=1;o0)o=r.bps>131072?Math.round(r.bps/1024/1024*8)+"mbps":Math.round(r.bps/1024*8)+"kbps",n[a]=o;break;case"fpks":r.fpks>0&&(n[a]=r.fpks/1e3+"fps");break;case"channels":r.channels>0&&(n[a]=1==r.channels?"Mono":2==r.channels?"Stereo":"Surround ("+r.channels+"ch)");break;case"rate":n[a]=Math.round(r.rate)+"Khz";break;case"language":"Undetermined"!=r[a]&&(n[a]=r[a]);break;case"codec":if("meta"==r.codec)continue;n[a]=r[a]}r.describe=n}for(var s in t){var l=!1;for(var i in t[s])if(l){if(MistUtil.object.keys(t[s]).length>1)for(var a in t[s][i].describe)l[a]!=t[s][i].describe[a]&&delete l[a]}else l=MistUtil.object.extend({},t[s][i].describe);for(var i in t[s]){var c={},d={};for(var a in t[s][i].describe)a in l?d[a]=t[s][i].describe[a]:c[a]=t[s][i].describe[a];t[s][i].different=c,t[s][i].same=d;var u=MistUtil.object.values(c);t[s][i].displayName=u.length?u.join(", "):MistUtil.object.values(t[s][i].describe).join(" ")}var p={};for(var i in t[s]){if(t[s][i].displayName in p){var h=1;for(var i in t[s])t[s][i].different.trackid=h+")",t[s][i].displayName="Track "+h+" ("+t[s][i].displayName+")",h++;break}p[t[s][i].displayName]=1}}return t}},isTouchDevice:function(){return"ontouchstart"in window||navigator.msMaxTouchPoints>0},getPos:function(e,t){e.currentStyle||window.getComputedStyle(e,null);for(var i=1,r=e;r;)r.style.zoom&&""!=r.style.zoom&&(i*=parseFloat(r.style.zoom,10)),r=r.parentElement;var n=e.getBoundingClientRect().left-(parseInt(e.borderLeftWidth,10)||0),a=e.getBoundingClientRect().width,o=Math.max(0,(t.clientX/i-n)/a);return o=Math.min(o,1)},createGraph:function(e,t){var i="http://www.w3.org/2000/svg",r=document.createElementNS(i,"svg");r.setAttributeNS(null,"height","100%"),r.setAttributeNS(null,"width","100%"),r.setAttributeNS(null,"class","mist icon graph"),r.setAttributeNS(null,"preserveAspectRatio","none");var n=e.x[0],a=e.y[0];if(t.differentiate)for(var o=1;ot.x.count&&(l.shift(),d()),d(e.x-n,-1*e.y),this.setAttributeNS(null,"d","M"+l.join(" L")),h()}},r.addData=function(e){m.addData(e)},r},getBrowser:function(){var e=window.navigator.userAgent;return e.indexOf("MSIE ")>=0||e.indexOf("Trident/")>=0?"ie":e.indexOf("Edge/")>=0?"edge":e.indexOf("Opera")>=0||e.indexOf("OPR")>=0?"opera":e.indexOf("Chrome")>=0?"chrome":e.indexOf("Safari")>=0?"safari":e.indexOf("Firefox")>=0&&"firefox"},getAndroid:function(){var e=navigator.userAgent.toLowerCase().match(/android\s([\d\.]*)/i);return!!e&&e[1]}};if(void 0===MistSkins)var MistSkins={};if("undefined"!=typeof mistoptions&&"host"in mistoptions)var misthost=MistUtil.http.url.sanitizeHost(mistoptions.host);else misthost="..";function MistSkin(e){e.skin=this,this.applySkinOptions=function(t){var i;return"string"==typeof t&&t in MistSkins&&(t=MistUtil.object.extend({},MistSkins[t],!0)),i="inherit"in t&&t.inherit&&t.inherit in MistSkins?this.applySkinOptions(t.inherit):MistSkins.default,this.structure=MistUtil.object.extend({},i.structure),t&&"structure"in t&&MistUtil.object.extend(this.structure,t.structure),this.blueprints=MistUtil.object.extend({},i.blueprints),t&&"blueprints"in t&&MistUtil.object.extend(this.blueprints,t.blueprints),this.icons=MistUtil.object.extend({},i.icons,!0),t&&"icons"in t&&MistUtil.object.extend(this.icons.blueprints,t.icons),this.icons.build=function(t,i,r){i||(i=22);var n,a=this.blueprints[t];n="function"==typeof a.svg?a.svg.call(e,r):a.svg,"object"!=typeof i&&(i={height:i,width:i}),"object"!=typeof a.size&&(a.size={height:a.size,width:a.size}),(!("width"in i)&&"height"in i||!("height"in i)&&"width"in i)&&("width"in i&&(i.height=i.width*a.size.height/a.size.width),"height"in i&&(i.width=i.height*a.size.width/a.size.height));var o="";o+='',o+='',o+=n,o+="",o+="";var s=document.createElement("div");return s.innerHTML=o,s.firstChild},this.colors=MistUtil.object.extend({},i.colors),t&&"colors"in t&&MistUtil.object.extend(this.colors,t.colors,!0),this.css=MistUtil.object.extend({},i.css),t&&"css"in t&&MistUtil.object.extend(this.css,t.css),this},this.applySkinOptions("skin"in e.options?e.options.skin:"default");var t=[];for(var i in this.css)if("string"==typeof this.css[i]){var r=MistUtil.css.load(e.urlappend(this.css[i]),this.colors);t.push(r)}this.css=t}function MistUI(e,t){e.UI=this,this.elements=[],this.buildStructure=function(t){if("function"==typeof t&&(t=t.call(e)),"if"in t){var i=!1;if(t.if.call(e,t)?i=t.then:"else"in t&&(i=t.else),!i)return;for(var r in t)["if","then","else"].indexOf(r)<0&&(r in i?(i[r]instanceof Array||(i[r]=[i[r]]),i[r]=i[r].concat(t[r])):i[r]=t[r]);return this.buildStructure(i)}if("type"in t&&t.type in e.skin.blueprints){var n=e.skin.blueprints[t.type].call(e,t);if(!n)return;if(MistUtil.class.add(n,"mistvideo-"+t.type),"css"in t){var a=MistUtil.createUnique();for(var r in t.css=[].concat(t.css),t.css){var o=MistUtil.css.createStyle(t.css[r],a);n.appendChild(o)}MistUtil.class.add(n,a),n.uid=a}if("classes"in t)for(var r in t.classes)MistUtil.class.add(n,t.classes[r]);if("title"in t&&(n.title=t.title),"style"in t)for(var r in t.style)n.style[r]=t.style[r];if("children"in t)for(var r in t.children){var s=this.buildStructure(t.children[r]);s&&n.appendChild(s)}return e.UI.elements.push(n),n}return!1},this.build=function(){return this.buildStructure(t||e.skin.structure.main)};var i=this.build(),r=MistUtil.createUnique(),n=0;for(var a in e.skin.css.length&&(i.style.opacity=0),e.skin.css){var o=e.skin.css[a];o.callback=function(t){"/*Failed to load*/"==t?(this.textContent=t,e.showError("Failed to load CSS from "+this.getAttribute("data-source"))):this.textContent=MistUtil.css.prependClass(t,r,!0),n++,e.skin.css.length<=n&&(i.style.opacity="")},""!=o.textContent&&o.callback(o.textContent),i.appendChild(o)}MistUtil.class.add(i,r);var s=MistUtil.getBrowser();return s&&MistUtil.class.add(i,"browser-"+s),i}MistSkins.default={structure:{main:{if:function(){return!!this.info.hasVideo&&"audio"!=this.source.type.split("/")[1]},then:{type:"placeholder",classes:["mistvideo"],children:[{type:"hoverWindow",mode:"pos",style:{position:"relative"},transition:{hide:"left: 0; right: 0; bottom: -43px;",show:"bottom: 0;",viewport:"left:0; right: 0; top: -1000px; bottom: 0;"},button:{type:"videocontainer"},children:[{type:"loading"},{type:"error"}],window:{type:"controls"}}]},else:{type:"container",classes:["mistvideo"],style:{overflow:"visible"},children:[{type:"controls",classes:["mistvideo-novideo"],style:{width:"480px"}},{type:"loading"},{type:"error"},{if:function(){return"stock"==this.options.controls},then:{type:"video",style:{position:"absolute"}},else:{type:"video",style:{position:"absolute",display:"none"}}}]}},videocontainer:{type:"container",children:[{type:"videobackground",alwaysDisplay:!1,delay:5},{type:"video"}]},controls:{if:function(){return!!(this.player&&this.player.api&&this.player.api.play)},then:{type:"container",classes:["mistvideo-column"],children:[{type:"progress",classes:["mistvideo-pointer"]},{type:"container",classes:["mistvideo-main","mistvideo-padding","mistvideo-row","mistvideo-background"],children:[{type:"play",classes:["mistvideo-pointer"]},{type:"currentTime"},{if:function(){return"size"in this&&this.size.width>300||!this.info.hasVideo||"audio"==this.source.type.split("/")[1]},then:{type:"totalTime"}},{type:"container",classes:["mistvideo-align-right"],children:[{type:"container",children:[{type:"container",classes:["mistvideo-volume_container"],children:[{type:"volume",mode:"horizontal",size:{height:22},classes:["mistvideo-pointer"]}]},{type:"speaker",classes:["mistvideo-pointer"],style:{"margin-left":"-2px"}}]},{if:function(){return"size"in this&&this.size.width>300||!this.info.hasVideo||"audio"==this.source.type.split("/")[1]},then:{type:"container",children:[{type:"loop",classes:["mistvideo-pointer"]},{type:"fullscreen",classes:["mistvideo-pointer"]}]}},{type:"hoverWindow",mode:"pos",transition:{hide:"right: -1000px; bottom: 44px;",show:"right: 5px;",viewport:"right: 0; left: 0; bottom: 0; top: -1000px"},button:{type:"settings",classes:["mistvideo-pointer"]},window:{type:"submenu"}}]}]}]},else:{if:function(){return!(!this.player||!this.player.api)},then:{type:"hoverWindow",mode:"pos",transition:{hide:"right: -1000px; bottom: 44px;",show:"right: 2.5px;",viewport:"right: 0; left: -1000px; bottom: 0; top: -1000px"},style:{right:"5px",left:"auto"},button:{type:"settings",classes:["mistvideo-background","mistvideo-padding"]},window:{type:"submenu"}}}},submenu:{type:"container",style:{width:"80%",maxWidth:"25em",zIndex:2},classes:["mistvideo-padding","mistvideo-column","mistvideo-background"],children:[{type:"tracks"},{if:function(){return"size"in this&&this.size.width<=300},then:{type:"container",classes:["mistvideo-center"],children:[{type:"loop",classes:["mistvideo-pointer"]},{type:"fullscreen",classes:["mistvideo-pointer"]}]}}]},placeholder:{type:"container",classes:["mistvideo","mistvideo-delay-display"],children:[{type:"placeholder"},{type:"loading"},{type:"error"}]},secondaryVideo:function(e){return{type:"hoverWindow",classes:["mistvideo"],mode:"pos",transition:{hide:"left: 10px; bottom: -40px;",show:"bottom: 10px;",viewport:"left: 0; right: 0; top: 0; bottom: 0"},button:{type:"container",children:[{type:"videocontainer"}]},window:{type:"switchVideo",classes:["mistvideo-controls","mistvideo-padding","mistvideo-background","mistvideo-pointer"],containers:e}}}},css:{skin:misthost+"/skins/default.css"},icons:{blueprints:{play:{size:45,svg:''},largeplay:{size:45,svg:''},pause:{size:45,svg:''},speaker:{size:45,svg:''},volume:{size:{width:100,height:45},svg:function(){var e=MistUtil.createUnique();return''}},muted:{size:45,svg:''},fullscreen:{size:45,svg:''},loop:{size:45,svg:''},settings:{size:45,svg:''},loading:{size:100,svg:''},timeout:{size:25,svg:function(e){e&&e.delay||(e={delay:10});var t=e.delay,i=MistUtil.createUnique();return''}},popout:{size:45,svg:''},switchvideo:{size:45,svg:''}}},blueprints:{container:function(){return document.createElement("div")},video:function(){var e=this;if(MistUtil.event.addListener(e.video,"contextmenu",function(t){t.preventDefault(),e.container.setAttribute("data-show-submenu",""),e.container.removeAttribute("data-hide-submenu"),e.container.removeAttribute("data-hidecursor");var i=function(){e.container.removeAttribute("data-show-submenu"),e.container.removeEventListener("mouseout",i)};MistUtil.event.addListener(e.container,"mouseout",i)}),e.video.hideTimer=!1,e.video.hideCursor=function(){this.hideTimer&&clearTimeout(this.hideTimer),this.hideTimer=e.timers.start(function(){e.container.setAttribute("data-hidecursor","");var t=e.container.querySelector(".mistvideo-controls");t&&t.parentNode.setAttribute("data-hidecursor","")},3e3)},MistUtil.event.addListener(e.video,"mousemove",function(){e.container.removeAttribute("data-hidecursor");var t=e.container.querySelector(".mistvideo-controls");t&&t.parentNode.removeAttribute("data-hidecursor"),e.video.hideCursor()}),MistUtil.event.addListener(e.video,"mouseout",function(){e.video.hideTimer&&e.timers.stop(e.video.hideTimer)}),e.options.autoplay)var t=MistUtil.event.addListener(e.video,"canplay",function(){if(e.player.api&&e.player.api.paused){var i=e.player.api.play();i&&i.catch(function(t){if(!e.destroyed)if(e.log("Autoplay failed. Retrying with muted audio.."),e.info.hasVideo){e.player.api.muted=!0,MistUtil.event.send("volumechange",null,e.video);var i=e.player.api.play();i&&i.then(function(){e.reporting&&(e.reporting.stats.d.autoplay="success")}).then(function(){if(!e.destroyed){e.log("Autoplay worked! Video will be unmuted on mouseover if the page has been interacted with."),e.reporting&&(e.reporting.stats.d.autoplay="muted");var t=e.skin.icons.build("muted",100);MistUtil.class.add(t,"mistvideo-pointer"),e.container.appendChild(t),MistUtil.event.addListener(t,"click",function(){e.player.api.muted=!1,e.container.removeChild(t)});var i=!1,r=function(){i=!0,document.body.removeEventListener("click",r)};MistUtil.event.addListener(document.body,"click",r,e.video);var n=function(){i&&(e.player.api.muted=!1,e.video.removeEventListener("mouseenter",n),e.log("Re-enabled sound"))};MistUtil.event.addListener(e.video,"mouseenter",n);var a=function(){e.video.muted||(t.parentNode&&e.container.removeChild(t),e.video.removeEventListener("volumechange",a),document.body.removeEventListener("click",r),e.video.removeEventListener("mouseenter",n))};MistUtil.event.addListener(e.video,"volumechange",a)}}).catch(function(){if(!e.destroyed){e.log("Autoplay failed even with muted video. Unmuting and showing play button."),e.timers.start(function(){e.player.api.paused&&(e.player.api.pause(),e.monitor&&e.monitor.destroy())},5e3),e.reporting&&(e.reporting.stats.d.autoplay="failed"),e.player.api.muted=!1;var t=e.skin.icons.build("largeplay",150);MistUtil.class.add(t,"mistvideo-pointer"),e.container.appendChild(t),MistUtil.event.addListener(t,"click",function(){e.player.api.paused&&e.player.api.play()});var i=function(){e.container.removeChild(t),e.video.removeEventListener("play",i)};MistUtil.event.addListener(e.video,"play",i)}})}else e.reporting&&(e.reporting.stats.d.autoplay="failed")})}else e.reporting&&(e.reporting.stats.d.autoplay="success");MistUtil.event.removeListener(t)});return this.video},videocontainer:function(){return this.UI.buildStructure(this.skin.structure.videocontainer)},secondaryVideo:function(e){e||(e={}),e.options||(e.options={});var t=this;"secondary"in t||(t.secondary=[]);var i=MistUtil.object.extend({},t.options);i=MistUtil.object.extend(i,e.options),t.secondary.push(i);var r={primary:t,secondary:!1};i.target=document.createElement("div"),delete i.container;var n={};return i.MistVideoObject=n,MistUtil.event.addListener(i.target,"initialized",function(){var e=n.reference;i.MistVideo=e,r.secondary=e,e.player.api.muted=!0,e.player.api.loop=!1;for(var a=i.target.querySelectorAll(".mistvideo-controls"),o=0;o30)e.player.api.pausedesync=!0,e.player.api.currentTime=this.currentTime,e.log("Re-syncing with main video by seeking (desync: "+t+"s)");else if(i>.01){var r=.1;i<1&&(r=.05),(r=1+r*Math.sign(t))!=e.player.api.playbackRate&&e.log("Re-syncing by changing the playback rate (desync: "+Math.round(1e3*t)+"ms, rate: "+r+")"),e.player.api.playbackRate=r}else 1!=e.player.api.playbackRate&&(e.player.api.playbackRate=1,e.log("Sync with main video achieved (desync: "+Math.round(1e3*t)+"ms)"))}},i.target),MistUtil.event.addListener(e.video,"seeked",function(){e.player.api.pausedesync=!1})}),i.skin=MistUtil.object.extend({},t.skin,!0),i.skin.structure.main=MistUtil.object.extend({},t.skin.structure.secondaryVideo(r)),mistPlay(t.stream,i),i.target},switchVideo:function(e){var t=document.createElement("div");return t.appendChild(this.skin.icons.build("switchvideo")),MistUtil.event.addListener(t,"click",function(){var t=e.containers.primary,i=e.containers.secondary;function r(e,t){if(e.video.currentTarget==t)return e.video;if(e.secondary)for(var i=0;i300&&(e.style.zoom=1.5),e}},submenu:function(){return this.UI.buildStructure(this.skin.structure.submenu)},hoverWindow:function(e){var t={type:"container",classes:"classes"in e?e.classes:[],children:"children"in e?e.children:[]};switch(t.classes.push("hover_window_container"),"classes"in e.window||(e.window.classes=[]),e.window.classes.push("inner_window"),e.window.classes.push("mistvideo-container"),e.window={type:"container",classes:["outer_window"],children:[e.window]},"classes"in e.button||(e.button.classes=[]),e.button.classes.push("pointer"),e.mode){case"left":t.classes.push("horizontal"),t.children=[e.window,e.button];break;case"right":t.classes.push("horizontal"),t.children=[e.button,e.window];break;case"top":t.classes.push("vertical"),t.children=[e.button,e.window];break;case"bottom":t.classes.push("vertical"),t.children=[e.window,e.button];break;case"pos":t.children=[e.button,e.window],"classes"in e.window||(e.window.classes=[]);break;default:throw"Unsupported mode for structure type hoverWindow"}return"transition"in e&&("css"in t||(t.css=[]),t.css.push(".hover_window_container:hover > .outer_window:not([data-hidecursor]) > .inner_window { "+e.transition.show+" }\n.hover_window_container > .outer_window { "+e.transition.viewport+" }\n.hover_window_container > .outer_window > .inner_window { "+e.transition.hide+" }")),t.classes.push(e.mode),this.UI.buildStructure(t)},draggable:function(e){var t=this.skin.blueprints.container(e),i=this,r=this.skin.icons.build("fullscreen",16);MistUtil.class.remove(r,"fullscreen"),MistUtil.class.add(r,"draggable-icon"),t.appendChild(r),r.style.alignSelf="flex-end",r.style.position="absolute",r.style.cursor="move";var n={},a=function(e){t.style.left=e.clientX-n.x+"px",t.style.top=e.clientY-n.y+"px"},o=function(e){window.removeEventListener("mousemove",a),window.removeEventListener("click",o),MistUtil.event.addListener(r,"click",s)},s=function(e){e.stopPropagation(),r.removeEventListener("click",s),n.x=i.container.getBoundingClientRect().left-(t.getBoundingClientRect().left-e.clientX),n.y=i.container.getBoundingClientRect().top-(t.getBoundingClientRect().top-e.clientY),t.style.position="absolute",t.style.right="auto",t.style.bottom="auto",i.container.appendChild(t),a(e),MistUtil.event.addListener(window,"mousemove",a,t),MistUtil.event.addListener(window,"click",o,t)};return MistUtil.event.addListener(r,"click",s),t},progress:function(){var e=document.createElement("div"),t=document.createElement("div");e.appendChild(t),t.kids={},t.kids.bar=document.createElement("div"),t.kids.bar.className="bar",t.appendChild(t.kids.bar);var i=this.video,r=this,n=1/0;if(r.info&&r.info.meta&&r.info.meta.tracks)for(var a in r.info.meta.tracks).001*r.info.meta.tracks[a].firstms1e3?(t.updateBuffers(r.player.api.buffered),l=(new Date).getTime()):c||(c=r.timers.start(function(){e(),c=!1},1e3))}()},t);var d=0,u=!1;MistUtil.event.addListener(i,"timeupdate",function(){!function e(){(new Date).getTime()-d>200&&!h?(t.updateBar(r.player.api.currentTime),d=(new Date).getTime()):u||(u=r.timers.start(function(){e(),u=!1},1e3))}()},t),MistUtil.event.addListener(i,"seeking",function(){t.updateBar(r.player.api.currentTime)},t),t.getPos=function(e){var t=MistUtil.getPos(this,e);return"live"==r.info.type?(t-1)*s()+r.player.api.duration:!!isFinite(r.player.api.duration)&&t*(r.player.api.duration-o())+o()},t.seek=function(e){var t=this.getPos(e);r.player.api.currentTime=t},MistUtil.event.addListener(e,"mouseup",function(e){1==e.which&&t.seek(e)});var p=r.UI.buildStructure({type:"tooltip"});p.style.opacity=0,t.appendChild(p),MistUtil.event.addListener(e,"mouseout",function(){h||(p.style.opacity=0)}),t.moveTooltip=function(e){var t=this.getPos(e);if(!1!==t){r.options.useDateTime&&r.info&&r.info.unixoffset?p.setText(MistUtil.format.ago(new Date(r.info.unixoffset+1e3*t))):p.setText(MistUtil.format.time(t)),p.style.opacity=1;var i=MistUtil.getPos(this,e),n={bottom:20};i>.5?(n.right=100*(1-i)+"%",p.triangle.setMode("bottom","right")):(n.left=100*i+"%",p.triangle.setMode("bottom","left")),p.setPos(n)}else p.style.opacity=0},MistUtil.event.addListener(e,"mousemove",function(e){t.moveTooltip(e)});var h=!1;return MistUtil.event.addListener(e,"mousedown",function(i){if(1==i.which){h=!0,t.updateBar(t.getPos(i));var r=MistUtil.event.addListener(document,"mousemove",function(e){t.updateBar(t.getPos(e)),t.moveTooltip(e)},t),n=MistUtil.event.addListener(document,"mouseup",function(i){1==i.which&&(h=!1,MistUtil.event.removeListener(r),MistUtil.event.removeListener(n),p.style.opacity=0,(!i.path||MistUtil.array.indexOf(i.path,e)<0)&&t.seek(i))},t)}}),e},play:function(){var e=this,t=document.createElement("div");t.appendChild(this.skin.icons.build("play")),t.appendChild(this.skin.icons.build("pause")),t.setState=function(e){this.setAttribute("data-state",e)},t.setState("paused");var i=this.video;return MistUtil.event.addListener(i,"playing",function(){t.setState("playing"),e.options.autoplay=!0},t),MistUtil.event.addListener(i,"pause",function(){t.setState("paused")},t),MistUtil.event.addListener(i,"paused",function(){t.setState("paused")},t),MistUtil.event.addListener(i,"ended",function(){t.setState("paused")},t),MistUtil.event.addListener(t,"click",function(){e.player.api.error&&e.player.api.load(),e.player.api.paused?e.player.api.play():(e.player.api.pause(),e.options.autoplay=!1)}),e.player.api&&MistUtil.event.addListener(e.video,"click",function(){e.player.api.paused?e.player.api.play():MistUtil.isTouchDevice()||(e.player.api.pause(),e.options.autoplay=!1)},t),t},speaker:function(){var e=!1,t=this.info.meta.tracks;for(var i in t)if("audio"==t[i].type){e=!0;break}if(!e)return!1;var r=this.skin.icons.build("speaker"),n=this,a=this.video;return MistUtil.event.addListener(a,"volumechange",function(){n.player.api.volume&&!n.player.api.muted?MistUtil.class.remove(r,"off"):MistUtil.class.add(r,"off")},r),MistUtil.event.addListener(r,"click",function(e){n.player.api.muted=!n.player.api.muted}),r},volume:function(e){var t=!1,i=this.info.meta.tracks;for(var r in i)if("audio"==i[r].type){t=!0;break}if(!t)return!1;var n=document.createElement("div"),a=this.skin.icons.build("volume","size"in e&&e.size);n.appendChild(a);var o=this;a.mode="mode"in e?e.mode:"vertical","vertical"==a.mode&&(a.style.transform="rotate(90deg)"),a.margin={start:.15,end:.1};var s=this.video;a.set=function(e){100!=(e=100-100*Math.pow(1-e/100,2))&&0!=e&&(e=100*this.addPadding(e/100));for(var t=a.querySelectorAll(".slider"),i=0;ii(t)?1:i(e)t[i]?1:t[e]1&&"player"in e&&"api"in e.player&&("setTrack"in e.player.api||"setTracks"in e.player.api||"setSource"in e.player.api)){var b=document.createElement("select");if(b.title="Select another "+l+" track",r[l]=b,b.trackType=l,m.appendChild(b),"subtitle"!=l){var M=document.createElement("option");b.appendChild(M),M.value="",M.appendChild(document.createTextNode("Automatic"))}var w=g(c[MistUtil.object.keys(c)[0]].same);if(w.length)(C=document.createElement("span")).className="mistvideo-description",m.appendChild(C),m.appendChild(document.createTextNode(w.join(" ")));function k(e){return""==e?-1:Number(e)}var U=MistUtil.object.keys(c,function(e,t){return k(e)-k(t)});for(var u in U){var x=c[U[u]];M=document.createElement("option");b.appendChild(M),M.value="idx"in x?x.idx:x.trackid,MistUtil.object.keys(x.different).length?M.appendChild(document.createTextNode(g(x.different).join(" "))):M.appendChild(document.createTextNode("Track "+(Number(u)+1)))}if(MistUtil.event.addListener(e.video,"playerUpdate_trackChanged",function(t){t.message.type==l&&"none"!=t.message.trackid&&(b.value=t.message.trackid,e.log("Player selected "+l+" track with id "+t.message.trackid))},b),"subtitle"==l){if(MistUtil.event.addListener(b,"change",function(){try{localStorage.mistSubtitleLanguage=c[this.value].lang}catch(e){}if(""!=this.value){var t=MistUtil.object.extend({},c[this.value]);t.label=g(t.describe).join(" "),t.src=MistUtil.http.url.addParam(d,{track:this.value}),e.player.api.setSubtitle(t)}else e.player.api.setSubtitle()}),"localStorage"in window&&null!=localStorage&&"mistSubtitleLanguage"in localStorage)for(var u in c)if(c[u].lang==localStorage.mistSubtitleLanguage){b.value=u;var T=document.createEvent("Event");T.initEvent("change"),b.dispatchEvent(T);break}}else MistUtil.event.addListener(b,"change",function(){this.trackType in n&&(n[this.trackType].checked=!0),a(this.trackType,this.value)})}else{var C;(C=document.createElement("span")).className="mistvideo-description",m.appendChild(C),C.appendChild(document.createTextNode(g(c[y[0]].same).join(" ")))}}}},text:function(e){var t=document.createElement("span");return t.appendChild(document.createTextNode(e.text)),t},placeholder:function(){var e=document.createElement("div"),t=this.calcSize();return e.style.width=t.width+"px",e.style.height=t.height+"px",this.options.poster&&(e.style.background="url('"+this.options.poster+"') no-repeat 50%/contain"),e},timeout:function(e){if(!(!1 in e)){var t="delay"in e?e.delay:5,i=this.skin.icons.build("timeout",!1,{delay:t});return i.timeout=this.timers.start(function(){e.function()},1e3*t),i}},polling:function(){var e=document.createElement("div"),t=this.skin.icons.build("loading");return e.appendChild(t),e},loading:function(){var e=this,t=this.skin.icons.build("loading",50);if("player"in e&&e.player.api){var i=!1;function r(t){e.container.setAttribute("data-loading",t.type),function t(){i||(i=e.timers.start(function(){i=!1,e.monitor.vars&&e.monitor.vars.score>=.999?n():t()},1e3))}()}function n(){e.container.removeAttribute("data-loading"),i&&e.timers.stop(i),i=!1}var a=["waiting","seeking","stalled"];for(var o in a)MistUtil.event.addListener(e.video,a[o],function(t){!this.paused&&"container"in e&&r(t)},t);a=["seeked","playing","canplay","paused","ended"];for(var o in a)MistUtil.event.addListener(e.video,a[o],function(t){"container"in e&&n()},t),MistUtil.event.addListener(e.video,"progress",function(t){"container"in e&&"monitor"in e&&"vars"in e.monitor&&"score"in e.monitor.vars&&e.monitor.vars.score>.99&&n()},t)}return t},error:function(){var e=this,t=document.createElement("div");t.message=function(t,i,r){MistUtil.empty(this);var n=document.createElement("div");if(n.className="message",this.appendChild(n),!r.polling&&!r.passive&&!r.hideTitle){var a=document.createElement("h3");n.appendChild(a),a.appendChild(document.createTextNode("The player has encountered a problem"))}var o=document.createElement("p");if(n.appendChild(o),n.update=function(e){MistUtil.empty(o),o.innerHTML=e},t){e.info.on_error&&(t=e.info.on_error.replace(/\/,t)),n.update(t);var s=document.createElement("p");if(s.className="details mistvideo-description",n.appendChild(s),i)s.appendChild(document.createTextNode(i));else if("decodingIssues"in e.skin.blueprints){if("player"in e&&"api"in e.player&&e.video){if(i=[],void 0!==e.state&&i.push(["Stream state:",e.state]),void 0!==e.player.api.currentTime&&i.push(["Current video time:",MistUtil.format.time(e.player.api.currentTime)]),"video"in e&&"getVideoPlaybackQuality"in e.video){var l=e.video.getVideoPlaybackQuality();"droppedVideoFrames"in l&&"totalVideoFrames"in l&&l.totalVideoFrames&&i.push(["Frames dropped/total:",MistUtil.format.number(l.droppedVideoFrames)+"/"+MistUtil.format.number(l.totalVideoFrames)]),"corruptedVideoFrames"in l&&l.corruptedVideoFrames&&i.push(["Corrupted frames:",MistUtil.format.number(l.corruptedVideoFrames)])}i.push({0:["NETWORK EMPTY:","not yet initialized"],1:["NETWORK IDLE:","resource selected, but not in use"],2:["NETWORK LOADING:","data is being downloaded"],3:["NETWORK NO SOURCE:","could not locate source"]}[e.video.networkState]);if(i.push({0:["HAVE NOTHING:","no information about ready state"],1:["HAVE METADATA:","metadata has been loaded"],2:["HAVE CURRENT DATA:","data for the current playback position is available, but not for the next frame"],3:["HAVE FUTURE DATA:","data for current and next frame is available"],4:["HAVE ENOUGH DATA:","can start playing"]}[e.video.readyState]),!r.passive){var c=document.createElement("table");for(var d in i){var u=document.createElement("tr");for(var p in c.appendChild(u),i[d]){var h=document.createElement("td");u.appendChild(h),h.appendChild(document.createTextNode(i[d][p]))}}s.appendChild(c)}}var m,f=document.createElement("div");f.className="mistvideo-container mistvideo-column",f.style.textAlign="left",f.style.marginBottom="1em",n.appendChild(f),(m=e.UI.buildStructure({type:"forcePlayer"}))&&f.appendChild(m),(m=e.UI.buildStructure({type:"forceType"}))&&f.appendChild(m)}}return n};var i,r=!1,n=!1,a={};if(this.showError=function(o,s){s||(s={softReload:!!(e.player&&e.player.api&&e.player.api.load),reload:!0,nextCombo:!!e.info,polling:!1,passive:!1});var l=s.type?s.type:o;if(!(l in a)){if(!0===s.reload&&(e.options.reloadDelay&&!isNaN(Number(e.options.reloadDelay))?s.reload=Number(e.options.reloadDelay):s.reload=10),s.passive){if(!0===r)return;if(r)return i.update(o),void(n=(new Date).getTime());t.setAttribute("data-passive","")}else t.removeAttribute("data-passive");r&&t.clear(),r=!s.passive||"passive",n=(new Date).getTime();var c=this.log(o,"error"),d=t.message(o,!1,s);i=d;var u=document.createElement("div");if(u.className="mistvideo-buttoncontainer",d.appendChild(u),MistUtil.empty(u),s.softReload){var p={type:"button",label:"Reload video",onclick:function(){e.player.api.load()}};isNaN(s.softReload+"")||(p.delay=s.softReload),u.appendChild(e.UI.buildStructure(p))}if(s.reload){p={type:"button",label:"Reload player",onclick:function(){e.reload("Reloading because reload button was clicked.")}};isNaN(s.reload+"")||(p.delay=s.reload),u.appendChild(e.UI.buildStructure(p))}if(s.nextCombo){p={type:"button",label:"Next source",onclick:function(){e.nextCombo()}};isNaN(s.nextCombo+"")||(p.delay=s.nextCombo),u.appendChild(e.UI.buildStructure(p))}if(s.ignore){p={type:"button",label:"Ignore",onclick:function(){this.clearError(),a[l]=!0}};isNaN(s.ignore+"")||(p.delay=s.ignore),u.appendChild(e.UI.buildStructure(p))}s.polling&&u.appendChild(e.UI.buildStructure({type:"polling"})),MistUtil.class.add(t,"show"),"container"in e&&e.container.removeAttribute("data-loading"),c.defaultPrevented&&t.clear()}},t.clear=function(){for(var i=t.querySelectorAll("svg.icon.timeout"),n=0;n=r.length&&(o=0);var a=r[o],l=a._context;a.width=i.video.videoWidth,a.height=i.video.videoHeight,l.drawImage(i.video,0,0),a.setAttribute("data-front","")}i.player.api.paused?s=!1:i.timers.start(function(){n()},1e3*e.delay)}(),s=!0)}),t}},colors:{fill:"#fff",semiFill:"rgba(255,255,255,0.5)",stroke:"#fff",strokeWidth:1.5,background:"rgba(0,0,0,0.8)",progressBackground:"#333",accent:"#0f0"}},MistSkins.dev={structure:MistUtil.object.extend({},MistSkins.default.structure,!0),blueprints:{timeout:function(){return!1!==this.options.reloadDelay&&MistSkins.default.blueprints.timeout.apply(this,arguments)},log:function(){var e=document.createElement("div");e.appendChild(document.createTextNode("Logs"));var t=document.createElement("div");t.className="logs",e.appendChild(t);var i=document.createElement("table");t.appendChild(i);var r=this,n={message:!1},a=!1,o=!0;function s(e,r,s){if(s||(s={}),n.message==r)return a++,n.counter.nodeValue=a,void(2==a&&n.counter.parentElement&&(n.counter.parentElement.style.display=""));a=1;var l=document.createElement("tr");l.className="entry",s.type&&"log"!=s.type&&(MistUtil.class.add(l,"type-"+s.type),r=MistUtil.format.ucFirst(s.type)+": "+r),i.appendChild(l);var c=document.createElement("td");c.className="timestamp",l.appendChild(c);var d=e.toLocaleTimeString().split(" ");d[0]+="."+("00"+e.getMilliseconds()).slice(-3),c.appendChild(document.createTextNode(d[0])),"currentTime"in s&&(c.title="Video playback time: "+MistUtil.format.time(s.currentTime,{ms:!0}));var u=document.createElement("td");l.appendChild(u);var p=document.createElement("span");p.className="message",u.appendChild(p),p.appendChild(document.createTextNode(r));var h=document.createElement("span");h.style.display="none",h.className="counter",u.appendChild(h);var m=document.createTextNode(a);h.appendChild(m),o&&(t.scrollTop=t.scrollHeight),n={message:r,counter:m}}for(var l in MistUtil.event.addListener(t,"scroll",function(){o=t.scrollTop+t.clientHeight>=t.scrollHeight-5}),r.logs)s(r.logs[l].time,r.logs[l].message,r.logs[l].data);return MistUtil.event.addListener(r.options.target,"log",function(e){if(e.message){var t={};r.player&&r.player.api&&"currentTime"in r.player.api&&(t.currentTime=r.player.api.currentTime),s(new Date,e.message,t)}},e),MistUtil.event.addListener(r.options.target,"error",function(e){if(e.message){var t={type:"error"};r.player&&r.player.api&&"currentTime"in r.player.api&&(t.currentTime=r.player.api.currentTime),s(new Date,e.message,t)}},e),e},decodingIssues:function(){if(this.player){var e=this,t=document.createElement("div");if(e.player.api){var i={"Playback score":function(){if("monitor"in e){if("vars"in e.monitor&&"score"in e.monitor.vars&&e.monitor.vars.values.length){var t=e.monitor.vars.values[e.monitor.vars.values.length-1];if("score"in t){Math.min(1,Math.max(0,t.score));return{x:t.clock,y:Math.min(1,Math.max(0,t.score)),options:{y:{min:0,max:1},x:{count:10}},val:Math.round(100*Math.min(1,Math.max(0,e.monitor.vars.score)))+"%"}}}return 0}},"Corrupted frames":function(){if(e.player.api&&"getVideoPlaybackQuality"in e.player.api){var t=e.player.api.getVideoPlaybackQuality();if(t)return t.corruptedVideoFrames?{val:MistUtil.format.number(t.corruptedVideoFrames),x:.001*(new Date).getTime(),y:t.corruptedVideoFrames,options:{x:{count:10}}}:0}},"Dropped frames":function(){if(e.player.api&&"getVideoPlaybackQuality"in e.player.api){var t=e.player.api.getVideoPlaybackQuality();if(t)return t.droppedVideoFrames?MistUtil.format.number(t.droppedVideoFrames):0}},"Total frames":function(){if(e.player.api&&"getVideoPlaybackQuality"in e.player.api){var t=e.player.api.getVideoPlaybackQuality();if(t)return MistUtil.format.number(t.totalVideoFrames)}},"Decoded audio":function(){if(e.player.api)return MistUtil.format.bytes(e.player.api.webkitAudioDecodedByteCount)},"Decoded video":function(){if(e.player.api)return MistUtil.format.bytes(e.player.api.webkitVideoDecodedByteCount)},"Negative acknowledgements":function(){if(e.player.api)return MistUtil.format.number(e.player.api.nackCount)},"Picture losses":function(){return MistUtil.format.number(e.player.api.pliCount)},"Packets lost":function(){return MistUtil.format.number(e.player.api.packetsLost)},"Packets received":function(){return MistUtil.format.number(e.player.api.packetsReceived)},"Bytes received":function(){if(e.player.api)return MistUtil.format.bytes(e.player.api.bytesReceived)},"Local latency [ms]":function(){if(e.player.api&&"getLatency"in e.player.api){var t=e.player.api.getLatency();return t?new Promise(function(e,i){t.then(function(t){var i=[];for(var r in t)t[r]&&i.push(r[0]+":"+Math.round(1e3*t[r]));i.length?e(i.join(" ")):e()},i)}):new Promise(function(e,t){e()},function(){})}},"Current bitrate":function(){if(e.player.monitor&&"currentBps"in e.player.monitor){var t=MistUtil.format.bits(e.player.monitor.currentBps);return t?t+"ps":t}}},r=[];for(var n in i)void 0!==i[n]()&&a({name:n,function:i[n]});t.update=function(){for(var i in r)r[i]();e.timers.start(function(){t.update()},1e3)},t.update()}return t}function a(e){var i=document.createElement("label");t.appendChild(i),i.style.display="none";var n=document.createElement("span");i.appendChild(n),n.appendChild(document.createTextNode(e.name+":")),n.className="mistvideo-description";var a=document.createElement("span");i.appendChild(a);var o=document.createTextNode(e.value?e.value:"");a.appendChild(o);var s=document.createElement("span");a.appendChild(s),i.set=function(e){if(0!==e&&(this.style.display=""),"object"==typeof e){if(e instanceof Promise)return void e.then(function(e){i.set(e)},function(){});if("val"in e&&(o.nodeValue=e.val,a.className="value"),s.children.length)return(t=s.children[0]).addData(e);var t=MistUtil.createGraph({x:[e.x],y:[e.y]},e.options);return s.style.display="",MistUtil.empty(s),s.appendChild(t)}return o.nodeValue=e},t.appendChild(i),r.push(function(){var t=e.function();i.set(t)})}},forcePlayer:function(){var e=document.createElement("label");e.title="Reload MistVideo and use the selected player";var t=this,i=document.createElement("span");e.appendChild(i),i.appendChild(document.createTextNode("Force player: "));var r=document.createElement("select");e.appendChild(r);var n=document.createElement("option");for(var a in r.appendChild(n),n.value="",n.appendChild(document.createTextNode("Automatic")),mistplayers){n=document.createElement("option");r.appendChild(n),n.value=a,n.appendChild(document.createTextNode(mistplayers[a].name))}return this.options.forcePlayer&&(r.value=this.options.forcePlayer),MistUtil.event.addListener(r,"change",function(){t.options.forcePlayer=""!=this.value&&this.value,t.options.forcePlayer!=t.playerName&&t.reload("Reloading to force player.")}),e},forceType:function(){if(this.info){var e=document.createElement("label");e.title="Reload MistVideo and use the selected protocol";var t=this,i=document.createElement("span");e.appendChild(i),i.appendChild(document.createTextNode("Force protocol: "));var r=document.createElement("select");e.appendChild(r);var n=document.createElement("option");r.appendChild(n),n.value="",n.appendChild(document.createTextNode("Automatic"));var a={};for(var o in t.info.source){var s=t.info.source[o];if(!(s.type in a)){a[s.type]=1;n=document.createElement("option");r.appendChild(n),n.value=s.type,n.appendChild(document.createTextNode(MistUtil.format.mime2human(s.type)))}}return this.options.forceType&&(r.value=this.options.forceType),MistUtil.event.addListener(r,"change",function(){t.options.forceType=""!=this.value&&this.value,t.source&&t.options.forceType==t.source.type||t.reload("Reloading to force new type.")}),e}},forceSource:function(){var e=document.createElement("label");e.title="Reload MistVideo and use the selected source";var t=this,i=document.createElement("span");e.appendChild(i),i.appendChild(document.createTextNode("Force source: "));var r=document.createElement("select");e.appendChild(r);var n=document.createElement("option");for(var a in r.appendChild(n),n.value="",n.appendChild(document.createTextNode("Automatic")),t.info.source){var o=t.info.source[a];n=document.createElement("option");r.appendChild(n),n.value=a,n.appendChild(document.createTextNode(o.url+" ("+MistUtil.format.mime2human(o.type)+")"))}return this.options.forceSource&&(r.value=this.options.forceSource),MistUtil.event.addListener(r,"change",function(){t.options.forceSource=""!=this.value&&this.value,t.options.forceSource!=t.source.index&&t.reload("Reloading to force new source.")}),e}}},MistSkins.dev.css={skin:misthost+"/skins/dev.css"},MistSkins.dev.structure.submenu=MistUtil.object.extend({},MistSkins.default.structure.submenu,!0),MistSkins.dev.structure.submenu.type="draggable",MistSkins.dev.structure.submenu.style.width="25em",MistSkins.dev.structure.submenu.children.unshift({type:"container",style:{flexShrink:1},classes:["mistvideo-column"],children:[{if:function(){return this.playerName&&this.source},then:{type:"container",classes:["mistvideo-description"],style:{display:"block"},children:[{type:"playername",style:{display:"inline"}},{type:"text",text:"is playing",style:{margin:"0 0.2em"}},{type:"mimetype"}]}},{type:"log"},{type:"decodingIssues"},{type:"container",classes:["mistvideo-column","mistvideo-devcontrols"],style:{"font-size":"0.9em"},children:[{type:"text",text:"Player control"},{type:"container",classes:["mistvideo-devbuttons"],style:{"flex-wrap":"wrap"},children:[{type:"button",title:"Build MistVideo again",label:"MistVideo.reload();",onclick:function(){this.reload("Dev-reload button clicked.")}},{type:"button",title:"Switch to the next available player and source combination",label:"MistVideo.nextCombo();",onclick:function(){this.nextCombo()}}]},{type:"forcePlayer"},{type:"forceType"}]}]});var mistplayers={};function MistPlayer(){}function mistPlay(e,t){return new MistVideo(e,t)}function MistVideo(e,t){var i=this;function r(e){if("meta"in e&&"tracks"in e.meta){var t=e.meta.tracks;for(var i in t)if("video"==t[i].type)return!0}return!1}function n(e){if(i.player&&i.player.api&&i.player.api.unload&&(i.log("Received new stream info while a player was already loaded: unloading player"),i.player.api.unload()),i.info=e,i.info.updated=new Date,MistUtil.event.send("haveStreamInfo",e,i.options.target),i.log("Stream info was loaded succesfully."),"error"in e){var n=e.error;return"on_error"in e&&(i.log(n),n=e.on_error),void i.showError(n,{reload:!0,hideTitle:!0})}if(i.calcSize=function(e){e||(e={width:!1,height:!1});var r=e.width||!!("width"in t&&t.width)&&t.width,n=e.height||!!("height"in t&&t.height)&&t.height;if(this.info&&"source"in this.info)if(this.info.hasVideo&&"audio"!=this.source.type.split("/")[1]){if(!r||!n){var a=i.info.width/i.info.height;if(r||n)r?n=r/a:r=n*a;else{var o="maxwidth"in t&&t.maxwidth?t.maxwidth:window.innerWidth,s="maxheight"in t&&t.maxheight?t.maxheight:window.innerHeight;r=i.info.width,n=i.info.height;function l(e){r/=e,n/=e}r<426&&l(r/426),n<240&&l(n/240),o&&r>o&&l(r/o),s&&n>s&&l(n/s)}}}else r||(r=480),n||(n=42);else r=640,n=480;return this.size={width:Math.round(r),height:Math.round(n)},this.size},e.hasVideo=r(e),"live"==e.type){var a=0;for(var o in i.info.meta.tracks)a=Math.max(a,i.info.meta.tracks[o].lastms);e.lastms=a}else{var s=i.resumeTime;if(s){var l=function(){i.player&&i.player.api&&(i.player.api.currentTime=s),this.removeEventListener("initialized",l)};MistUtil.event.addListener(i.options.target,"initialized",l)}}i.options.ABR_bitrate&&i.options.ABR_resize&&i.info&&!i.info.selver&&(i.options.ABR_bitrate=!1),i.choosePlayer()?(i.reporting&&i.reporting.report({player:i.playerName,sourceType:i.source.type,sourceUrl:i.source.url,pageUrl:location.href}),i.player=new mistplayers[i.playerName].player,i.player.onreadylist=[],i.player.onready=function(e){this.onreadylist.push(e)},i.player.build(i,function(e){if(i.log("Building new player"),i.container.removeAttribute("data-loading"),i.video=e,i.reporting&&i.reporting.init(),"api"in i.player){i.monitor={MistVideo:i,delay:1,averagingSteps:20,threshold:function(){return"webrtc"==this.MistVideo.source.type?.95:.75},init:function(){if(!this.vars||!this.vars.active){this.MistVideo.log("Enabling monitor"),this.vars={values:[],score:!1,active:!0};var e=this;!function t(){e.vars&&e.vars.active&&(e.vars.timer=e.MistVideo.timers.start(function(){var i=e.calcScore();!1!==i&&e.check(i)&&e.action(),t()},1e3*e.delay))}()}},destroy:function(){this.vars&&this.vars.active&&(this.MistVideo.log("Disabling monitor"),this.MistVideo.timers.stop(this.vars.timer),delete this.vars)},reset:function(){this.vars&&this.vars.active?(this.MistVideo.log("Resetting monitor"),this.vars.values=[]):this.init()},calcScore:function(){var e=this.vars.values;if(e.push(this.getValue()),e.length<=1)return!1;var t=this.valueToScore(e[0],e[e.length-1]);return e.length>this.averagingSteps&&e.shift(),t=Math.max(t,e[e.length-1].score),this.vars.score=t,i.reporting&&i.reporting.stats.set("playbackScore",Math.round(10*t)/10),t},valueToScore:function(e,t){var i=1;return"player"in this.MistVideo&&"api"in this.MistVideo.player&&"playbackRate"in this.MistVideo.player.api&&(i=this.MistVideo.player.api.playbackRate),(t.video-e.video)/(t.clock-e.clock)/i},getValue:function(){var e={clock:.001*(new Date).getTime(),video:this.MistVideo.player.api.currentTime};return this.vars.values.length&&(e.score=this.valueToScore(this.vars.values[this.vars.values.length-1],e)),e},check:function(e){return!(this.vars.values.length<.5*this.averagingSteps)&&(e3600&&(t.reloadDelay/=1e3,this.log("A reloadDelay of more than an hour was set: assuming milliseconds were intended. ReloadDelay is now "+t.reloadDelay+"s")),new MistSkin(this),this.checkCombo=function(e,t){e||(e={}),e=MistUtil.object.extend(MistUtil.object.extend({},this.options),e);var r,n,a=!1;for(var o in e.forceSource?(r=[i.info.source[e.forceSource]],i.log("Forcing source "+e.forceSource+": "+r[0].type+" @ "+r[0].url)):e.forceType?(r=i.info.source.filter(function(t){return t.type==e.forceType}),i.log("Forcing type "+e.forceType)):r=i.info.source,mistplayers)mistplayers[o].shortname=o;e.forcePlayer&&mistplayers[e.forcePlayer]?(n=[mistplayers[e.forcePlayer]],i.log("Forcing player "+e.forcePlayer)):n=MistUtil.object.values(mistplayers),r=[].concat(r);var s={first:"source",source:[function(e){return"origIndex"in e?e.origIndex:(e.origIndex=i.info.source.indexOf(e),e.origIndex)}],player:[{priority:1}]},l={inner:"player",outer:"source"};if(e.forcePriority){if("source"in e.forcePriority){if(!(e.forcePriority.source instanceof Array))throw"forcePriority.source is not an array.";s.source=e.forcePriority.source.concat(s.source),MistUtil.array.multiSort(r,s.source)}if("player"in e.forcePriority){if(!(e.forcePriority.player instanceof Array))throw"forcePriority.player is not an array.";s.player=e.forcePriority.player.concat(s.player),MistUtil.array.multiSort(n,s.player)}"first"in e.forcePriority&&(s.first=e.forcePriority.first),"player"==s.first&&(l.outer="player",l.inner="source")}var c={player:{list:n,current:!1},source:{list:r,current:!1}};if(e.startCombo){e.startCombo.started={player:!1,source:!1};for(o=0;o=2))for(var p in c[l.inner].list)if(c[l.inner].current=p,!(d(l.inner)>=1)){a=c.source.list[c.source.current];var h=c.player.list[c.player.current].shortname,m=mistplayers[h];if(m.isMimeSupported(a.type)&&m.isBrowserSupported(a.type,a,i))return{player:h,source:a,source_index:c.source.current};t||i.log("Checking "+m.name+" with "+a.type+".. Nope.")}return!1},this.choosePlayer=function(){i.log("Checking available players..");var e=this.checkCombo();if(!e)return!1;var t=mistplayers[e.player],r=e.source;return i.log("Found a working combo: "+t.name+" with "+r.type+" @ "+r.url),i.playerName=e.player,(r=MistUtil.object.extend({},r)).index=e.source_index,r.url=i.urlappend(r.url),i.source=r,MistUtil.event.send("comboChosen","Player/source combination selected",i.options.target),!0},i.calcSize=function(){return{width:640,height:480}},MistUtil.empty(i.options.target),new MistSkin(i),i.container=new MistUI(i,i.skin.structure.placeholder),i.options.target.appendChild(i.container),i.container.setAttribute("data-loading",""),"WebSocket"in window){!function e(){i.log("Opening stream status stream..");var t=i.options.host.replace(/^http/i,"ws"),o=new WebSocket(i.urlappend(t+"/json_"+encodeURIComponent(i.stream)+".js"));i.socket=o,o.die=!1,o.destroy=function(){this.die=!0,i.reporting&&(i.reporting.reportStats(),i.reporting=!1),this.onclose=function(){},this.close()},o.timeOut=i.timers.start(function(){o.readyState<=1&&(o.destroy(),a())},5e3),o.onopen=function(e){this.wasConnected=!0,i.reporting||(i.reporting={stats:{set:function(e,t){this.d[e]=t},add:function(e,t){void 0===t&&(t=1),this.d[e]+=t},d:{nWaiting:0,timeWaiting:0,nStalled:0,timeStalled:0,timeUnpaused:0,nError:0,nLog:0,videoHeight:null,videoWidth:null,playerHeight:null,playerWidth:null},last:{firstPlayback:null,nWaiting:0,timeWaiting:0,nStalled:0,timeStalled:0,timeUnpaused:0,nError:0,lastError:null,playbackScore:1,nLog:0,autoplay:null,videoHeight:null,videoWidth:null,playerHeight:null,playerWidth:null}},report:function(e){1==i.socket.readyState&&i.socket.send(JSON.stringify(e))},reportStats:function(){var e={},t=!1,r=i.logs.slice(this.stats.last.nLog);for(var n in this.stats.d)this.stats.d[n]!=this.stats.last[n]&&(e[n]=this.stats.d[n],this.stats.last[n]=e[n],t=!0);if(t){if(r.length)for(var n in e.logs=[],r)e.logs.push(r[n].message);this.report(e)}i.timers.start(function(){i.reporting&&i.reporting.reportStats()},5e3)},init:function(){var e=i.video,t=MistUtil.event.addListener(e,"playing",function(){i.reporting.stats.set("firstPlayback",(new Date).getTime()-i.bootMs),MistUtil.event.removeListener(t)});if(MistUtil.event.addListener(e,"waiting",function(){i.reporting.stats.add("nWaiting")}),MistUtil.event.addListener(e,"stalled",function(){i.reporting.stats.add("nStalled")}),MistUtil.event.addListener(i.options.target,"error",function(e){i.reporting.stats.add("nError"),i.reporting.stats.set("lastError",e.message)},e),Object&&Object.defineProperty){var r=0,n=!1,a=0,o=!1,s=0,l=!1,c=i.reporting.stats.d;Object.defineProperty(c,"timeWaiting",{get:function(){return r+(n?(new Date).getTime()-n:0)}}),Object.defineProperty(c,"timeStalled",{get:function(){return a+(o?(new Date).getTime()-o:0)}}),Object.defineProperty(c,"timeUnpaused",{get:function(){return s+(l?(new Date).getTime()-l:0)}}),Object.defineProperty(c,"nLog",{get:function(){return i.logs.length}}),Object.defineProperty(c,"videoHeight",{get:function(){return i.video?i.video.videoHeight:null}}),Object.defineProperty(c,"videoWidth",{get:function(){return i.video?i.video.videoWidth:null}}),Object.defineProperty(c,"playerHeight",{get:function(){return i.video?i.video.clientHeight:null}}),Object.defineProperty(c,"playerWidth",{get:function(){return i.video?i.video.clientWidth:null}}),MistUtil.event.addListener(e,"waiting",function(){r=c.timeWaiting,n=(new Date).getTime()}),MistUtil.event.addListener(e,"stalled",function(){a=c.timeStalled,o=(new Date).getTime()});var d=["playing","pause"];for(var u in d)MistUtil.event.addListener(e,d[u],function(){r=c.timeWaiting,a=c.timeStalled,n=!1,o=!1});MistUtil.event.addListener(e,"playing",function(){s=c.timeUnpaused,l=(new Date).getTime()}),MistUtil.event.addListener(e,"pause",function(){s=c.timeUnpaused,l=!1})}this.reportStats()}})},o.onclose=function(t){if(!this.die)return this.wasConnected?(i.log("Reopening websocket.."),void e()):void a()};var s=!1;o.addEventListener("message",function(e){o.timeOut&&(i.timers.stop(o.timeOut),o.timeOut=!1);var t=JSON.parse(e.data);if(t||i.showError("Error while parsing stream status stream. Obtained: "+e.data.toString(),{reload:!0}),"error"in t){var a;switch(e=t.error,"on_error"in t&&(i.log(e),e=t.on_error),i.state=t.error,t.error){case"Stream is offline":i.info=!1,i.player&&i.player.api&&i.player.api.currentTime&&(i.resumeTime=i.player.api.currentTime);case"Stream is initializing":case"Stream is booting":case"Stream is waiting for data":case"Stream is shutting down":case"Stream status is invalid?!":if(i.player&&i.player.api&&!i.player.api.paused)return i.log(t.error,"error"),s||(s=MistUtil.event.addListener(i.video,"ended",function(){i.showError(t.error,{polling:!0})})),void(s=MistUtil.event.addListener(i.video,"waiting",function(){i.showError(t.error,{polling:!0})}));a={polling:!0};break;default:a={reload:!0}}i.showError(e,a)}else{if(i.state="Stream is online",i.clearError(),s&&MistUtil.event.removeListener(s),!i.info)return void n(t);var l=function e(t,i){if(t==i)return!1;if("object"==typeof t&&void 0!==i){var r={};for(var n in t)if(!(MistUtil.array.indexOf(["lastms","hasVideo"],n)>=0)){var a=e(t[n],i[n]);a&&(r[n]=!0===a?[t[n],i[n]]:a)}for(var n in i)MistUtil.array.indexOf(["lastms","hasVideo"],n)>=0||n in t||(r[n]=[t[n],i[n]]);return!!MistUtil.object.keys(r).length&&r}return!0}(t,i.info);if(l){if("source"in l)return void("error"in i.info&&i.reload("Reloading, stream info has error"));i.info=MistUtil.object.extend(i.info,t),i.info.updated=new Date;var c=!1;for(var d in l)switch(d){case"meta":for(var u in l[d])switch(u){case"tracks":i.info.hasVideo=r(i.info),MistUtil.event.send("metaUpdate_tracks",t,i.video)}break;case"width":case"height":c=!0}c&&i.player.resize()}else i.log("Metachange: no differences detected")}})}()}else a();return this.unload=function(e){if(!this.destroyed){for(var t in this.log("Unloading.."),this.destroyed=!0,this.timers.stop("all"),this.errorListeners){var r=this.errorListeners[t];if(r.src in MistUtil.scripts.list){var n=MistUtil.array.indexOf(MistUtil.scripts.list[r.src].subscribers);n>=0&&MistUtil.scripts.list[r.src].subscribers.splice(n,1)}}if("monitor"in i&&"destroy"in i.monitor&&i.monitor.destroy(),this.socket&&(this.reporting&&(this.reporting.reportStats(),this.reporting.report({unload:e||null})),this.socket.destroy()),this.player&&this.player.api&&("pause"in this.player.api&&this.player.api.pause(),"setSource"in this.player.api&&this.player.api.setSource(""),"unload"in this.player.api))try{this.player.api.unload()}catch(a){i.log("Error while unloading player: "+a.message)}if(this.UI&&this.UI.elements)for(var t in this.UI.elements){var a=this.UI.elements[t];if("attachedListeners"in a)for(var t in a.attachedListeners)MistUtil.event.removeListener(a.attachedListeners[t]);a.parentNode&&a.parentNode.removeChild(a)}this.video&&MistUtil.empty(this.video),"container"in this&&(MistUtil.empty(this.container),delete this.container),MistUtil.empty(this.options.target),delete this.video}},this.reload=function(e){var t="player"in this&&"api"in this.player&&this.player.api.currentTime;this.unload(e);var r=mistPlay(this.stream,this.options);if(t&&"live"!=this.info.type){var n=function(){r.player&&r.player.api&&(r.player.api.currentTime=t),this.removeEventListener("initialized",n)};MistUtil.event.addListener(this.options.target,"initialized",n)}return i},this.nextCombo=function(){var e=!1;"player"in this&&"api"in this.player&&(e=this.player.api.currentTime);var t={source:this.source.index,player:this.playerName};if(!this.checkCombo({startCombo:t},!0)){if(!this.checkCombo({startCombo:!1},!0))return;t=!1}this.unload("nextCombo");var r=this.options;if(r.startCombo=t,i=mistPlay(this.stream,r),e&&isFinite(e)&&"live"!=this.info.type){var n=function(){"player"in i&&"api"in i.player&&(i.player.api.currentTime=e),this.removeEventListener("initialized",n)};MistUtil.event.addListener(r.target,"initialized",n)}},this.onPlayerBuilt=function(){},t.MistVideoObject&&(t.MistVideoObject.reference=this),this} \ No newline at end of file diff --git a/embed/min/wrappers/html5.js b/embed/min/wrappers/html5.js index cf1df8ac..24403a89 100644 --- a/embed/min/wrappers/html5.js +++ b/embed/min/wrappers/html5.js @@ -1 +1 @@ -mistplayers.html5={name:"HTML5 video player",mimes:["html5/application/vnd.apple.mpegurl","html5/video/mp4","html5/video/ogg","html5/video/webm","html5/audio/mp3","html5/audio/webm","html5/audio/ogg","html5/audio/wav"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(t){return MistUtil.array.indexOf(this.mimes,t)==-1?false:true},isBrowserSupported:function(t,e,i){if(location.protocol!=MistUtil.http.url.split(e.url).protocol){if(location.protocol=="file:"&&MistUtil.http.url.split(e.url).protocol=="http:"){i.log("This page was loaded over file://, the player might not behave as intended.")}else{i.log("HTTP/HTTPS mismatch for this source");return false}}if(t=="html5/application/vnd.apple.mpegurl"){var r=MistUtil.getAndroid();if(r&&parseFloat(r)<7){i.log("Skipping native HLS as videojs will do better");return false}}var a=false;var n=t.split("/");n.shift();try{n=n.join("/");function o(t){var e=document.createElement("video");if(e&&e.canPlayType(t)!=""){a=e.canPlayType(t)}return a}if(n=="video/mp4"){function s(t){function e(e){return("0"+t.init.charCodeAt(e).toString(16)).slice(-2)}switch(t.codec){case"AAC":return"mp4a.40.2";case"MP3":return"mp3";case"AC3":return"ec-3";case"H264":return"avc1."+e(1)+e(2)+e(3);case"HEVC":return"hev1."+e(1)+e(6)+e(7)+e(8)+e(9)+e(10)+e(11)+e(12);default:return t.codec.toLowerCase()}}var l={};for(var p in i.info.meta.tracks){if(i.info.meta.tracks[p].type!="meta"){l[s(i.info.meta.tracks[p])]=1}}l=MistUtil.object.keys(l);if(l.length){if(l.length>e.simul_tracks){var u=0;for(var p in l){var c=o(n+';codecs="'+l[p]+'"');if(c){u++}}return u>=e.simul_tracks}n+=';codecs="'+l.join(",")+'"'}}a=o(n)}catch(t){}return a},player:function(){this.onreadylist=[]},mistControls:true};var p=mistplayers.html5.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var i=t.source.type.split("/");i.shift();var r=document.createElement("video");r.setAttribute("crossorigin","anonymous");r.setAttribute("playsinline","");var a=document.createElement("source");a.setAttribute("src",t.source.url);r.source=a;r.appendChild(a);a.type=i.join("/");var n=["autoplay","loop","poster"];for(var o in n){var s=n[o];if(t.options[s]){r.setAttribute(s,t.options[s]===true?"":t.options[s])}}if(t.options.muted){r.muted=true}if(t.options.controls=="stock"){r.setAttribute("controls","")}if(t.info.type=="live"){r.loop=false}if("Proxy"in window&&"Reflect"in window){var l={get:{},set:{}};t.player.api=new Proxy(r,{get:function(t,e,i){if(e in l.get){return l.get[e].apply(t,arguments)}var r=t[e];if(typeof r==="function"){return function(){return r.apply(t,arguments)}}return r},set:function(t,e,i){if(e in l.set){return l.set[e].call(t,i)}return t[e]=i}});if(t.source.type=="html5/audio/mp3"){l.set.currentTime=function(){t.log("Seek attempted, but MistServer does not currently support seeking in MP3.");return false}}if(t.info.type=="live"){l.get.duration=function(){var e=0;if(this.buffered.length){e=this.buffered.end(this.buffered.length-1)}var i=((new Date).getTime()-t.player.api.lastProgress.getTime())*.001;return e+i-t.player.api.liveOffset};l.set.currentTime=function(e){var i=e-t.player.api.duration;if(i>0){i=0}t.player.api.liveOffset=i;t.log("Seeking to "+MistUtil.format.time(e)+" ("+Math.round(i*-10)/10+"s from live)");var r={startunix:i};if(i==0){r={}}t.player.api.setSource(MistUtil.http.url.addParam(t.source.url,r))};MistUtil.event.addListener(r,"progress",function(){t.player.api.lastProgress=new Date});t.player.api.lastProgress=new Date;t.player.api.liveOffset=0;MistUtil.event.addListener(r,"pause",function(){t.player.api.pausedAt=new Date});l.get.play=function(){return function(){if(t.player.api.paused&&t.player.api.pausedAt&&new Date-t.player.api.pausedAt>5e3){r.load();t.log("Reloading source..")}return r.play.apply(r,arguments)}};if(t.source.type=="html5/video/mp4"){l.get.currentTime=function(){return this.currentTime-t.player.api.liveOffset+t.info.lastms*.001}}}else{if(!isFinite(r.duration)){var p=0;for(var o in t.info.meta.tracks){p=Math.max(p,t.info.meta.tracks[o].lastms)}l.get.duration=function(){if(isFinite(this.duration)){return this.duration}return p*.001}}}}else{t.player.api=r}t.player.api.setSource=function(t){if(t!=this.source.src){this.source.src=t;this.load()}};t.player.api.setSubtitle=function(t){var e=r.getElementsByTagName("track");for(var i=e.length-1;i>=0;i--){r.removeChild(e[i])}if(t){var a=document.createElement("track");r.appendChild(a);a.kind="subtitles";a.label=t.label;a.srclang=t.lang;a.src=t.src;a.setAttribute("default","")}};t.player.setSize=function(t){this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};e(r)}; \ No newline at end of file +mistplayers.html5={name:"HTML5 video player",mimes:["html5/application/vnd.apple.mpegurl","html5/video/mp4","html5/video/ogg","html5/video/webm","html5/audio/mp3","html5/audio/webm","html5/audio/ogg","html5/audio/wav"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(t){return MistUtil.array.indexOf(this.mimes,t)==-1?false:true},isBrowserSupported:function(t,e,i){if(location.protocol!=MistUtil.http.url.split(e.url).protocol){if(location.protocol=="file:"&&MistUtil.http.url.split(e.url).protocol=="http:"){i.log("This page was loaded over file://, the player might not behave as intended.")}else{i.log("HTTP/HTTPS mismatch for this source");return false}}if(t=="html5/application/vnd.apple.mpegurl"){var r=MistUtil.getAndroid();if(r&&parseFloat(r)<7){i.log("Skipping native HLS as videojs will do better");return false}}var a=false;var n=t.split("/");n.shift();try{n=n.join("/");function o(t){var e=document.createElement("video");if(e&&e.canPlayType(t)!=""){a=e.canPlayType(t)}return a}if(n=="video/mp4"){function s(t){function e(e){return("0"+t.init.charCodeAt(e).toString(16)).slice(-2)}switch(t.codec){case"AAC":return"mp4a.40.2";case"MP3":return"mp3";case"AC3":return"ec-3";case"H264":return"avc1."+e(1)+e(2)+e(3);case"HEVC":return"hev1."+e(1)+e(6)+e(7)+e(8)+e(9)+e(10)+e(11)+e(12);default:return t.codec.toLowerCase()}}var l={};for(var p in i.info.meta.tracks){if(i.info.meta.tracks[p].type!="meta"){l[s(i.info.meta.tracks[p])]=1}}l=MistUtil.object.keys(l);if(l.length){if(l.length>e.simul_tracks){var u=0;for(var p in l){var f=o(n+';codecs="'+l[p]+'"');if(f){u++}}return u>=e.simul_tracks}n+=';codecs="'+l.join(",")+'"'}}a=o(n)}catch(t){}return a},player:function(){this.onreadylist=[]},mistControls:true};var p=mistplayers.html5.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var i=t.source.type.split("/");i.shift();var r=document.createElement("video");r.setAttribute("crossorigin","anonymous");r.setAttribute("playsinline","");var a=document.createElement("source");a.setAttribute("src",t.source.url);r.source=a;r.appendChild(a);a.type=i.join("/");var n=["autoplay","loop","poster"];for(var o in n){var s=n[o];if(t.options[s]){r.setAttribute(s,t.options[s]===true?"":t.options[s])}}if(t.options.muted){r.muted=true}if(t.options.controls=="stock"){r.setAttribute("controls","")}if(t.info.type=="live"){r.loop=false}if("Proxy"in window&&"Reflect"in window){var l={get:{},set:{}};t.player.api=new Proxy(r,{get:function(t,e,i){if(e in l.get){return l.get[e].apply(t,arguments)}var r=t[e];if(typeof r==="function"){return function(){return r.apply(t,arguments)}}return r},set:function(t,e,i){if(e in l.set){return l.set[e].call(t,i)}return t[e]=i}});if(t.source.type=="html5/audio/mp3"){l.set.currentTime=function(){t.log("Seek attempted, but MistServer does not currently support seeking in MP3.");return false}}if(t.info.type=="live"){l.get.duration=function(){var e=0;if(this.buffered.length){e=this.buffered.end(this.buffered.length-1)}var i=((new Date).getTime()-t.player.api.lastProgress.getTime())*.001;return e+i-t.player.api.liveOffset};l.set.currentTime=function(e){var i=e-t.player.api.duration;if(i>0){i=0}t.player.api.liveOffset=i;t.log("Seeking to "+MistUtil.format.time(e)+" ("+Math.round(i*-10)/10+"s from live)");var r={startunix:i};if(i==0){r={}}t.player.api.setSource(MistUtil.http.url.addParam(t.source.url,r))};MistUtil.event.addListener(r,"progress",function(){t.player.api.lastProgress=new Date});t.player.api.lastProgress=new Date;t.player.api.liveOffset=0;MistUtil.event.addListener(r,"pause",function(){t.player.api.pausedAt=new Date});l.get.play=function(){return function(){if(t.player.api.paused&&t.player.api.pausedAt&&new Date-t.player.api.pausedAt>5e3){r.load();t.log("Reloading source..")}return r.play.apply(r,arguments)}};if(t.source.type=="html5/video/mp4"){var p=l.get.duration;l.get.duration=function(){return p.apply(this,arguments)-t.player.api.liveOffset+t.info.lastms*.001};l.get.currentTime=function(){return this.currentTime-t.player.api.liveOffset+t.info.lastms*.001};l.get.buffered=function(){var e=this;return{length:e.buffered.length,start:function(i){return e.buffered.start(i)-t.player.api.liveOffset+t.info.lastms*.001},end:function(i){return e.buffered.end(i)-t.player.api.liveOffset+t.info.lastms*.001}}}}}else{if(!isFinite(r.duration)){var u=0;for(var o in t.info.meta.tracks){u=Math.max(u,t.info.meta.tracks[o].lastms)}l.get.duration=function(){if(isFinite(this.duration)){return this.duration}return u*.001}}}}else{t.player.api=r}t.player.api.setSource=function(t){if(t!=this.source.src){this.source.src=t;this.load()}};t.player.api.setSubtitle=function(t){var e=r.getElementsByTagName("track");for(var i=e.length-1;i>=0;i--){r.removeChild(e[i])}if(t){var a=document.createElement("track");r.appendChild(a);a.kind="subtitles";a.label=t.label;a.srclang=t.lang;a.src=t.src;a.setAttribute("default","")}};t.player.setSize=function(t){this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};e(r)}; \ No newline at end of file diff --git a/embed/min/wrappers/mews.js b/embed/min/wrappers/mews.js index 8b3a6b18..490a5451 100644 --- a/embed/min/wrappers/mews.js +++ b/embed/min/wrappers/mews.js @@ -1 +1 @@ -mistplayers.mews={name:"MSE websocket player",mimes:["ws/video/mp4","ws/video/webm"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return this.mimes.indexOf(e)==-1?false:true},isBrowserSupported:function(e,t,i){if(!("WebSocket"in window)||!("MediaSource"in window)){return false}if(location.protocol.replace(/^http/,"ws")!=MistUtil.http.url.split(t.url.replace(/^http/,"ws")).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}if(navigator.platform.toUpperCase().indexOf("MAC")>=0){return false}function r(e){function t(t){return("0"+e.init.charCodeAt(t).toString(16)).slice(-2)}switch(e.codec){case"AAC":return"mp4a.40.2";case"MP3":return"mp4a.40.34";case"AC3":return"ec-3";case"H264":return"avc1."+t(1)+t(2)+t(3);case"HEVC":return"hev1."+t(1)+t(6)+t(7)+t(8)+t(9)+t(10)+t(11)+t(12);default:return e.codec.toLowerCase()}}var n={};for(var s in i.info.meta.tracks){if(i.info.meta.tracks[s].type!="meta"){n[r(i.info.meta.tracks[s])]=i.info.meta.tracks[s].codec}}var a=e.split("/")[2];function o(e){return MediaSource.isTypeSupported("video/"+a+';codecs="'+e+'"')}t.supportedCodecs=[];for(var s in n){var u=o(s);if(u){t.supportedCodecs.push(n[s])}}if(!i.options.forceType&&!i.options.forcePlayer){if(t.supportedCodecs.length0},player:function(){}};var p=mistplayers.mews.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var i=document.createElement("video");i.setAttribute("playsinline","");var r=["autoplay","loop","poster"];for(var n in r){var s=r[n];if(e.options[s]){i.setAttribute(s,e.options[s]===true?"":e.options[s])}}if(e.options.muted){i.muted=true}if(e.info.type=="live"){i.loop=false}if(e.options.controls=="stock"){i.setAttribute("controls","")}i.setAttribute("crossorigin","anonymous");this.setSize=function(e){i.style.width=e.width+"px";i.style.height=e.height+"px"};var a=this;a.built=false;function o(){if(a.ws.readyState==a.ws.OPEN&&a.ms.readyState=="open"&&a.sb){if(!a.built){t(i);a.built=true}if(e.options.autoplay){a.api.play().catch(function(){})}return true}}this.msoninit=[];this.msinit=function(){return new Promise(function(e,t){a.ms=new MediaSource;i.src=URL.createObjectURL(a.ms);a.ms.onsourceopen=function(){for(var t in a.msoninit){a.msoninit[t]()}a.msoninit=[];e()};a.ms.onsourceclose=function(e){if(a.debugging)console.error("ms close",e);u({type:"stop"})};a.ms.onsourceended=function(e){if(a.debugging)console.error("ms ended",e);if(a.debugging=="dl"){function t(e,t,r){var n,s;n=new Blob([e],{type:r});s=window.URL.createObjectURL(n);i(s,t);setTimeout(function(){return window.URL.revokeObjectURL(s)},1e3)}function i(e,t){var i;i=document.createElement("a");i.href=e;i.download=t;document.body.appendChild(i);i.style="display: none";i.click();i.remove()}var r=0;for(var n=0;n=500){n=0;a.sb._clean(10)}else{n++}var t=r.slice();r=[];for(var s in t){if(!a.sb){if(a.debugging){console.warn("I was doing on_updateend but the sb was reset")}break}if(a.sb.updating){r.concat(t.slice(s));if(a.debugging){console.warn("I was doing on_updateend but was interrupted")}break}t[s](s0&&!a.sb.updating&&!i.error){a.sb._append(this.queue.shift())}});a.sb.error=function(e){console.error("sb error",e)};a.sb.abort=function(e){console.error("sb abort",e)};a.sb._doNext=function(e){r.push(e)};a.sb._do=function(e){if(this.updating||this._busy){this._doNext(e)}else{e()}};a.sb._append=function(t){if(!t){return}if(!t.buffer){return}if(a.debugging){a.sb.appending=new Uint8Array(t)}if(a.sb._busy){if(a.debugging)console.warn("I wanted to append data, but now I won't because the thingy was still busy. Putting it back in the queue.");a.sb.queue.unshift(t);return}a.sb._busy=true;try{a.sb.appendBuffer(t)}catch(n){switch(n.name){case"QuotaExceededError":{if(i.buffered.length){if(i.currentTime-i.buffered.start(0)>1){e.log("Triggered QuotaExceededError: cleaning up "+Math.round((i.currentTime-i.buffered.start(0)-1)*10)/10+"s");a.sb._clean(1)}else{var r=i.buffered.end(i.buffered.length-1);e.log("Triggered QuotaExceededError but there is nothing to clean: skipping ahead "+Math.round((r-i.currentTime)*10)/10+"s");i.currentTime=r}a.sb._busy=false;a.sb._append(t);return}break}case"InvalidStateError":{a.api.pause();if(e.video.error){return}break}}e.showError(n.message)}};if(a.msgqueue){if(a.msgqueue[0]){var s=false;if(a.msgqueue[0].length){for(var u in a.msgqueue[0]){if(a.sb.updating||a.sb.queue.length||a.sb._busy){a.sb.queue.push(a.msgqueue[0][u])}else{a.sb._append(a.msgqueue[0][u])}}}else{s=true}a.msgqueue.shift();if(a.msgqueue.length==0){a.msgqueue=false}e.log("The newly initialized source buffer was filled with data from a seperate message queue."+(a.msgqueue?" "+a.msgqueue.length+" more message queue(s) remain.":""));if(s){e.log("The seperate message queue was empty; manually triggering any onupdateend functions");a.sb.dispatchEvent(new Event("updateend"))}}}a.sb._clean=function(e){if(!e)e=180;if(i.currentTime>e){a.sb._do(function(){a.sb.remove(0,Math.max(.1,i.currentTime-e))})}};if(a.onsbinit.length){a.onsbinit.shift()()}o()};this.wsconnect=function(){return new Promise(function(t,r){this.ws=new WebSocket(e.source.url);this.ws.binaryType="arraybuffer";this.ws.s=this.ws.send;this.ws.send=function(){if(this.readyState==1){return this.s.apply(this,arguments)}return false};this.ws.onopen=function(){this.wasConnected=true;t()};this.ws.onerror=function(t){e.showError("MP4 over WS: websocket error")};this.ws.onclose=function(t){e.log("MP4 over WS: websocket closed");if(this.wasConnected&&!e.destroyed&&(!a.sb||!a.sb.paused)&&e.state=="Stream is online"&&!(e.video&&e.video.error)){e.log("MP4 over WS: reopening websocket");a.wsconnect().then(function(){if(!a.sb){var t=function(e){if(!a.sb){a.sbinit(e.data.codecs)}else{a.api.play().catch(function(){})}a.ws.removeListener("codec_data",t)};a.ws.addListener("codec_data",t);u({type:"request_codec_data",supported_codecs:e.source.supportedCodecs})}else{a.api.play()}},function(){Mistvideo.error("Lost connection to the Media Server")})}};this.ws.timeOut=e.timers.start(function(){if(a.ws.readyState==0){e.log("MP4 over WS: socket timeout - try next combo");e.nextCombo()}},5e3);this.ws.listeners={};this.ws.addListener=function(e,t){if(!(e in this.listeners)){this.listeners[e]=[]}this.listeners[e].push(t)};this.ws.removeListener=function(e,t){if(!(e in this.listeners)){return}var i=this.listeners[e].indexOf(t);if(i<0){return}this.listeners[e].splice(i,1);return true};a.msgqueue=false;var n=1;var s=[];var o=[];this.ws.onmessage=function(t){if(!t.data){throw"Received invalid data"}if(typeof t.data=="string"){var r=JSON.parse(t.data);if(a.debugging&&r.type!="on_time"){console.log("ws message",r)}switch(r.type){case"on_stop":{var s;s=MistUtil.event.addListener(i,"waiting",function(e){a.sb.paused=true;MistUtil.event.send("ended",null,i);MistUtil.event.removeListener(s)});a.ws.onclose=function(){};break}case"on_time":{var c=r.data.current-i.currentTime*1e3;var f=a.ws.serverDelay.get();var l=Math.max(100+f,f*2);var p=l+(r.data.jitter?r.data.jitter:0);if(e.info.type!="live"){l+=2e3}if(a.debugging){console.log("on_time received",r.data.current/1e3,"currtime",i.currentTime,n+"x","buffer",Math.round(c),"/",Math.round(l),e.info.type=="live"?"latency:"+Math.round(r.data.end-i.currentTime*1e3)+"ms":"",a.monitor?"bitrate:"+MistUtil.format.bits(a.monitor.currentBps)+"/s":"","listeners",a.ws.listeners&&a.ws.listeners.on_time?a.ws.listeners.on_time:0,"msgqueue",a.msgqueue?a.msgqueue.length:0,"readyState",e.video.readyState,r.data)}if(!a.sb){e.log("Received on_time, but the source buffer is being cleared right now. Ignoring.");break}if(d!=r.data.end*.001){d=r.data.end*.001;MistUtil.event.send("durationchange",null,e.video)}e.info.meta.buffer_window=r.data.end-r.data.begin;a.sb.paused=false;if(e.info.type=="live"){if(n==1){if(r.data.play_rate_curr=="auto"){if(i.currentTime>0){if(c>p*2){n=1+Math.min(1,(c-p)/p)*.08;i.playbackRate*=n;e.log("Our buffer ("+Math.round(c)+"ms) is big (>"+Math.round(p*2)+"ms), so increase the playback speed to "+Math.round(n*100)/100+" to catch up.")}else if(c<0){n=.8;i.playbackRate*=n;e.log("Our buffer ("+Math.round(c)+"ms) is negative so decrease the playback speed to "+Math.round(n*100)/100+" to let it catch up.")}else if(c1){if(cp){i.playbackRate/=n;n=1;e.log("Our buffer ("+Math.round(c)+"ms) is big enough (>"+Math.round(p)+"ms), so return to real time playback.")}}}else{if(n==1){if(r.data.play_rate_curr=="auto"){if(cl){e.log("Our buffer is big, so request a slower download rate.");n=.5;u({type:"set_speed",play_rate:n})}}}else if(n>1){if(c>l){u({type:"set_speed",play_rate:"auto"});n=1;e.log("The buffer is big enough, so ask for realtime download rate.")}}else{if(cn){n=currPos}if(!i.buffered.length||i.buffered.end(i.buffered.length-1)i.currentTime){var e=i.buffered.start(0);i.currentTime=e;if(i.currentTime!=e){r()}}}else{r()}})};r()}};t();MistUtil.event.removeListener(s)})})}else{w()}})}else{if(a.debugging){console.warn("sb not available to do clear")}a.onsbinit.push(w)}};if(!r.data.codecs||!r.data.codecs.length){e.showError("Track switch does not contain any codecs, aborting.");e.options.setTracks=false;w();break}function y(t){if(a.debugging){console.warn("reached switching point",t.data.current*.001,MistUtil.format.time(t.data.current*.001))}e.log("Track switch: reached switching point");w()}if(i.currentTime==0){y(r)}else{if(r.data.current>=i.currentTime*1e3){e.log("Track switch: waiting for playback to reach the switching point ("+MistUtil.format.time(r.data.current*.001,{ms:true})+")");var k=MistUtil.event.addListener(i,"timeupdate",function(){if(r.data.current=i.currentTime*1e3){y(e);a.ws.removeListener("on_time",k)}};a.ws.addListener("on_time",k)}}}break}case"pause":{if(a.sb){a.sb.paused=true}break}}if(r.type in this.listeners){for(var g=this.listeners[r.type].length-1;g>=0;g--){this.listeners[r.type][g](r)}}return}var T=new Uint8Array(t.data);if(T){if(a.monitor&&a.monitor.bitCounter){for(var g in a.monitor.bitCounter){a.monitor.bitCounter[g]+=t.data.byteLength*8}}if(a.sb&&!a.msgqueue){if(a.sb.updating||a.sb.queue.length||a.sb._busy){a.sb.queue.push(T)}else{a.sb._append(T)}}else{if(!a.msgqueue){a.msgqueue=[[]]}a.msgqueue[a.msgqueue.length-1].push(T)}}else{e.log("Expecting data from websocket, but received none?!")}};this.ws.serverDelay={delays:[],log:function(e){var t=false;switch(e){case"seek":case"set_speed":{t=e;break}case"request_codec_data":{t="codec_data";break}default:{return}}if(t){var i=(new Date).getTime();function r(){a.ws.serverDelay.add((new Date).getTime()-i);a.ws.removeListener(t,r)}a.ws.addListener(t,r)}},add:function(e){this.delays.unshift(e);if(this.delays.length>5){this.delays.splice(5)}},get:function(){if(this.delays.length){let e=0;let t=0;for(null;t=3){break}e+=this.delays[t]}return e/t}return 500}}}.bind(this))};this.wsconnect().then(function(){var t=function(e){if(a.ms&&a.ms.readyState=="open"){a.sbinit(e.data.codecs)}else{a.msoninit.push(function(){a.sbinit(e.data.codecs)})}a.ws.removeListener("codec_data",t)};this.ws.addListener("codec_data",t);u({type:"request_codec_data",supported_codecs:e.source.supportedCodecs})}.bind(this));function u(t){if(!a.ws){throw"No websocket to send to"}if(a.ws.readyState>=a.ws.CLOSING){e.log("MP4 over WS: reopening websocket");a.wsconnect().then(function(){if(!a.sb){var i=function(e){if(!a.sb){a.sbinit(e.data.codecs)}else{a.api.play().catch(function(){})}a.ws.removeListener("codec_data",i)};a.ws.addListener("codec_data",i);u({type:"request_codec_data",supported_codecs:e.source.supportedCodecs})}else{a.api.play()}u(t)},function(){Mistvideo.error("Lost connection to the Media Server")});return}if(a.debugging){console.log("ws send",t)}a.ws.serverDelay.log(t.type);a.ws.send(JSON.stringify(t))}a.findBuffer=function(e){var t=false;for(var r=0;r=e){t=r;break}}return t};this.api={play:function(t){return new Promise(function(r,n){if(!i.paused){r();return}if("paused"in a.sb&&!a.sb.paused){i.play().then(r).catch(n);return}var s=function(o){if(!a.sb){e.log("Attempting to play, but the source buffer is being cleared. Waiting for next on_time.");return}if(e.info.type=="live"){if(t||i.currentTime==0){var u=function(){if(i.buffered.length){var t=a.findBuffer(o.data.current*.001);if(t!==false){if(i.buffered.start(t)>i.currentTime||i.buffered.end(t)i.currentTime){a.sb.paused=false;if(i.buffered.length&&i.buffered.start(0)>i.currentTime){i.currentTime=i.buffered.start(0)}i.play().then(r).catch(n);a.ws.removeListener("on_time",s)}};a.ws.addListener("on_time",s);var o={type:"play"};if(t){o.seek_time="live"}u(o)})},pause:function(){i.pause();u({type:"hold"});if(a.sb){a.sb.paused=true}},setTracks:function(e){if(!MistUtil.object.keys(e).length){return}e.type="tracks";e=MistUtil.object.extend({type:"tracks"},e);u(e)},unload:function(){a.api.pause();a.sb._do(function(){a.sb.remove(0,Infinity);try{a.ms.endOfStream()}catch(e){}});a.ws.close()}};Object.defineProperty(this.api,"currentTime",{get:function(){return i.currentTime},set:function(t){if(isNaN(t)||t<0){e.log("Ignoring seek to "+t+" because ewww.");return}MistUtil.event.send("seeking",t,i);u({type:"seek",seek_time:Math.round(Math.max(0,t*1e3-(250+a.ws.serverDelay.get())))});var r=function(n){a.ws.removeListener("seek",r);var s=function(r){a.ws.removeListener("on_time",s);t=r.data.current*.001;t=t.toFixed(3);var n=10;var o=function(){i.currentTime=t;if(i.currentTime.toFixed(3)=0){n--;a.sb._doNext(o)}}};o()};a.ws.addListener("on_time",s)};a.ws.addListener("seek",r);i.currentTime=t;e.log("Seeking to "+MistUtil.format.time(t,{ms:true})+" ("+t+")")}});var d=1;Object.defineProperty(this.api,"duration",{get:function(){return d}});Object.defineProperty(this.api,"playbackRate",{get:function(){return i.playbackRate},set:function(e){var t=function(e){i.playbackRate=e.data.play_rate};a.ws.addListener("set_speed",t);u({type:"set_speed",play_rate:e==1?"auto":e})}});function c(e){Object.defineProperty(a.api,e,{get:function(){return i[e]},set:function(t){return i[e]=t}})}var f=["volume","buffered","muted","loop","paused",,"error","textTracks","webkitDroppedFrameCount","webkitDecodedFrameCount"];for(var n in f){c(f[n])}MistUtil.event.addListener(i,"ended",function(){if(a.api.loop){a.api.currentTime=0;a.sb._do(function(){a.sb.remove(0,Infinity)})}});var l=false;MistUtil.event.addListener(i,"seeking",function(){l=true;var e=MistUtil.event.addListener(i,"seeked",function(){l=false;MistUtil.event.removeListener(e)})});MistUtil.event.addListener(i,"waiting",function(){if(l){return}var t=a.findBuffer(i.currentTime);if(t!==false){if(t+1=i.buffered.start(r)&&i.currentTime<=i.buffered.end(r)){t=true}e.push([i.buffered.start(r),i.buffered.end(r)])}console.log("waiting","currentTime",i.currentTime,"buffers",e,t?"contained":"outside of buffer","readystate",i.readyState,"networkstate",i.networkState);if(i.readyState>=2&&i.networkState>=2){console.error("Why am I waiting?!",i.currentTime)}})}this.ABR={size:null,bitrate:null,generateString:function(e,t){switch(e){case"size":{return"~"+[t.width,t.height].join("x")}case"bitrate":{return"<"+Math.round(t)+"bps,minbps"}default:{throw"Unknown ABR type"}}},request:function(e,t){this[e]=t;var i=[];if(this.bitrate!==null){i.push(this.generateString("bitrate",this.bitrate))}if(this.size!==null){i.push(this.generateString("size",this.size))}else{i.push("maxbps")}return a.api.setTracks({video:i.join(",|")})}};this.api.ABR_resize=function(t){e.log("Requesting the video track with the resolution that best matches the player size");a.ABR.request("size",t)};this.monitor={bitCounter:[],bitsSince:[],currentBps:null,nWaiting:0,nWaitingThreshold:3,listener:e.options.ABR_bitrate?MistUtil.event.addListener(i,"waiting",function(){a.monitor.nWaiting++;if(a.monitor.nWaiting>=a.monitor.nWaitingThreshold){a.monitor.nWaiting=0;a.monitor.action()}}):null,getBitRate:function(){if(a.sb&&!a.sb.paused){this.bitCounter.push(0);this.bitsSince.push((new Date).getTime());var t,i;if(this.bitCounter.length>5){t=a.monitor.bitCounter.shift();i=this.bitsSince.shift()}else{t=a.monitor.bitCounter[0];i=this.bitsSince[0]}var r=(new Date).getTime()-i;this.currentBps=t/(r*.001)}e.timers.start(function(){a.monitor.getBitRate()},500)},action:function(){if(e.options.setTracks&&e.options.setTracks.video){return}e.log("ABR threshold triggered, requesting lower quality");a.ABR.request("bitrate",this.currentBps)}};this.monitor.getBitRate()}; \ No newline at end of file +mistplayers.mews={name:"MSE websocket player",mimes:["ws/video/mp4","ws/video/webm"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return this.mimes.indexOf(e)==-1?false:true},isBrowserSupported:function(e,t,i){if(!("WebSocket"in window)||!("MediaSource"in window)){return false}if(location.protocol.replace(/^http/,"ws")!=MistUtil.http.url.split(t.url.replace(/^http/,"ws")).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}if(navigator.platform.toUpperCase().indexOf("MAC")>=0){return false}function r(e){function t(t){return("0"+e.init.charCodeAt(t).toString(16)).slice(-2)}switch(e.codec){case"AAC":return"mp4a.40.2";case"MP3":return"mp4a.40.34";case"AC3":return"ec-3";case"H264":return"avc1."+t(1)+t(2)+t(3);case"HEVC":return"hev1."+t(1)+t(6)+t(7)+t(8)+t(9)+t(10)+t(11)+t(12);default:return e.codec.toLowerCase()}}var n={};for(var s in i.info.meta.tracks){if(i.info.meta.tracks[s].type!="meta"){n[r(i.info.meta.tracks[s])]=i.info.meta.tracks[s].codec}}var a=e.split("/")[2];function o(e){return MediaSource.isTypeSupported("video/"+a+';codecs="'+e+'"')}t.supportedCodecs=[];for(var s in n){var u=o(s);if(u){t.supportedCodecs.push(n[s])}}if(!i.options.forceType&&!i.options.forcePlayer){if(t.supportedCodecs.length0},player:function(){}};var p=mistplayers.mews.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var i=document.createElement("video");i.setAttribute("playsinline","");var r=["autoplay","loop","poster"];for(var n in r){var s=r[n];if(e.options[s]){i.setAttribute(s,e.options[s]===true?"":e.options[s])}}if(e.options.muted){i.muted=true}if(e.info.type=="live"){i.loop=false}if(e.options.controls=="stock"){i.setAttribute("controls","")}i.setAttribute("crossorigin","anonymous");this.setSize=function(e){i.style.width=e.width+"px";i.style.height=e.height+"px"};var a=this;a.built=false;function o(){if(a.ws.readyState==a.ws.OPEN&&a.ms.readyState=="open"&&a.sb){if(!a.built){t(i);a.built=true}if(e.options.autoplay){a.api.play().catch(function(){})}return true}}this.msoninit=[];this.msinit=function(){return new Promise(function(e,t){a.ms=new MediaSource;i.src=URL.createObjectURL(a.ms);a.ms.onsourceopen=function(){for(var t in a.msoninit){a.msoninit[t]()}a.msoninit=[];e()};a.ms.onsourceclose=function(e){if(a.debugging)console.error("ms close",e);u({type:"stop"})};a.ms.onsourceended=function(e){if(a.debugging)console.error("ms ended",e);if(a.debugging=="dl"){function t(e,t,r){var n,s;n=new Blob([e],{type:r});s=window.URL.createObjectURL(n);i(s,t);setTimeout(function(){return window.URL.revokeObjectURL(s)},1e3)}function i(e,t){var i;i=document.createElement("a");i.href=e;i.download=t;document.body.appendChild(i);i.style="display: none";i.click();i.remove()}var r=0;for(var n=0;n=500){n=0;a.sb._clean(10)}else{n++}var t=r.slice();r=[];for(var s in t){if(!a.sb){if(a.debugging){console.warn("I was doing on_updateend but the sb was reset")}break}if(a.sb.updating){r.concat(t.slice(s));if(a.debugging){console.warn("I was doing on_updateend but was interrupted")}break}t[s](s0&&!a.sb.updating&&!i.error){a.sb._append(this.queue.shift())}});a.sb.error=function(e){console.error("sb error",e)};a.sb.abort=function(e){console.error("sb abort",e)};a.sb._doNext=function(e){r.push(e)};a.sb._do=function(e){if(this.updating||this._busy){this._doNext(e)}else{e()}};a.sb._append=function(t){if(!t){return}if(!t.buffer){return}if(a.debugging){a.sb.appending=new Uint8Array(t)}if(a.sb._busy){if(a.debugging)console.warn("I wanted to append data, but now I won't because the thingy was still busy. Putting it back in the queue.");a.sb.queue.unshift(t);return}a.sb._busy=true;try{a.sb.appendBuffer(t)}catch(n){switch(n.name){case"QuotaExceededError":{if(i.buffered.length){if(i.currentTime-i.buffered.start(0)>1){e.log("Triggered QuotaExceededError: cleaning up "+Math.round((i.currentTime-i.buffered.start(0)-1)*10)/10+"s");a.sb._clean(1)}else{var r=i.buffered.end(i.buffered.length-1);e.log("Triggered QuotaExceededError but there is nothing to clean: skipping ahead "+Math.round((r-i.currentTime)*10)/10+"s");i.currentTime=r}a.sb._busy=false;a.sb._append(t);return}break}case"InvalidStateError":{a.api.pause();if(e.video.error){return}break}}e.showError(n.message)}};if(a.msgqueue){if(a.msgqueue[0]){var s=false;if(a.msgqueue[0].length){for(var u in a.msgqueue[0]){if(a.sb.updating||a.sb.queue.length||a.sb._busy){a.sb.queue.push(a.msgqueue[0][u])}else{a.sb._append(a.msgqueue[0][u])}}}else{s=true}a.msgqueue.shift();if(a.msgqueue.length==0){a.msgqueue=false}e.log("The newly initialized source buffer was filled with data from a seperate message queue."+(a.msgqueue?" "+a.msgqueue.length+" more message queue(s) remain.":""));if(s){e.log("The seperate message queue was empty; manually triggering any onupdateend functions");a.sb.dispatchEvent(new Event("updateend"))}}}a.sb._clean=function(e){if(!e)e=180;if(i.currentTime>e){a.sb._do(function(){a.sb.remove(0,Math.max(.1,i.currentTime-e))})}};if(a.onsbinit.length){a.onsbinit.shift()()}o()};this.wsconnect=function(){return new Promise(function(t,r){this.ws=new WebSocket(e.source.url);this.ws.binaryType="arraybuffer";this.ws.s=this.ws.send;this.ws.send=function(){if(this.readyState==1){return this.s.apply(this,arguments)}return false};this.ws.onopen=function(){this.wasConnected=true;t()};this.ws.onerror=function(t){e.showError("MP4 over WS: websocket error")};this.ws.onclose=function(t){e.log("MP4 over WS: websocket closed");if(this.wasConnected&&!e.destroyed&&(!a.sb||!a.sb.paused)&&e.state=="Stream is online"&&!(e.video&&e.video.error)){e.log("MP4 over WS: reopening websocket");a.wsconnect().then(function(){if(!a.sb){var t=function(e){if(!a.sb){a.sbinit(e.data.codecs)}else{a.api.play().catch(function(){})}a.ws.removeListener("codec_data",t)};a.ws.addListener("codec_data",t);u({type:"request_codec_data",supported_codecs:e.source.supportedCodecs})}else{a.api.play()}},function(){Mistvideo.error("Lost connection to the Media Server")})}};this.ws.timeOut=e.timers.start(function(){if(a.ws.readyState==0){e.log("MP4 over WS: socket timeout - try next combo");e.nextCombo()}},5e3);this.ws.listeners={};this.ws.addListener=function(e,t){if(!(e in this.listeners)){this.listeners[e]=[]}this.listeners[e].push(t)};this.ws.removeListener=function(e,t){if(!(e in this.listeners)){return}var i=this.listeners[e].indexOf(t);if(i<0){return}this.listeners[e].splice(i,1);return true};a.msgqueue=false;var n=1;var s=[];var o=[];this.ws.onmessage=function(t){if(!t.data){throw"Received invalid data"}if(typeof t.data=="string"){var r=JSON.parse(t.data);if(a.debugging&&r.type!="on_time"){console.log("ws message",r)}switch(r.type){case"on_stop":{var s;s=MistUtil.event.addListener(i,"waiting",function(e){a.sb.paused=true;MistUtil.event.send("ended",null,i);MistUtil.event.removeListener(s)});a.ws.onclose=function(){};break}case"on_time":{var c=r.data.current-i.currentTime*1e3;var f=a.ws.serverDelay.get();var l=Math.max(100+f,f*2);var p=l+(r.data.jitter?r.data.jitter:0);if(e.info.type!="live"){l+=2e3}if(a.debugging){console.log("on_time received",r.data.current/1e3,"currtime",i.currentTime,n+"x","buffer",Math.round(c),"/",Math.round(l),e.info.type=="live"?"latency:"+Math.round(r.data.end-i.currentTime*1e3)+"ms":"",a.monitor?"bitrate:"+MistUtil.format.bits(a.monitor.currentBps)+"/s":"","listeners",a.ws.listeners&&a.ws.listeners.on_time?a.ws.listeners.on_time:0,"msgqueue",a.msgqueue?a.msgqueue.length:0,"readyState",e.video.readyState,r.data)}if(!a.sb){e.log("Received on_time, but the source buffer is being cleared right now. Ignoring.");break}if(d!=r.data.end*.001){d=r.data.end*.001;MistUtil.event.send("durationchange",null,e.video)}e.info.meta.buffer_window=r.data.end-r.data.begin;a.sb.paused=false;if(e.info.type=="live"){if(n==1){if(r.data.play_rate_curr=="auto"){if(i.currentTime>0){if(c>p*2){n=1+Math.min(1,(c-p)/p)*.08;i.playbackRate*=n;e.log("Our buffer ("+Math.round(c)+"ms) is big (>"+Math.round(p*2)+"ms), so increase the playback speed to "+Math.round(n*100)/100+" to catch up.")}else if(c<0){n=.8;i.playbackRate*=n;e.log("Our buffer ("+Math.round(c)+"ms) is negative so decrease the playback speed to "+Math.round(n*100)/100+" to let it catch up.")}else if(c1){if(cp){i.playbackRate/=n;n=1;e.log("Our buffer ("+Math.round(c)+"ms) is big enough (>"+Math.round(p)+"ms), so return to real time playback.")}}}else{if(n==1){if(r.data.play_rate_curr=="auto"){if(cl){e.log("Our buffer is big, so request a slower download rate.");n=.5;u({type:"set_speed",play_rate:n})}}}else if(n>1){if(c>l){u({type:"set_speed",play_rate:"auto"});n=1;e.log("The buffer is big enough, so ask for realtime download rate.")}}else{if(cn){n=currPos}if(!i.buffered.length||i.buffered.end(i.buffered.length-1)i.currentTime){var e=i.buffered.start(0);i.currentTime=e;if(i.currentTime!=e){r()}}}else{r()}})};r()}};t();MistUtil.event.removeListener(s)})})}else{w()}})}else{if(a.debugging){console.warn("sb not available to do clear")}a.onsbinit.push(w)}};if(!r.data.codecs||!r.data.codecs.length){e.showError("Track switch does not contain any codecs, aborting.");e.options.setTracks=false;w();break}function y(t){if(a.debugging){console.warn("reached switching point",t.data.current*.001,MistUtil.format.time(t.data.current*.001))}e.log("Track switch: reached switching point");w()}if(i.currentTime==0){y(r)}else{if(r.data.current>=i.currentTime*1e3){e.log("Track switch: waiting for playback to reach the switching point ("+MistUtil.format.time(r.data.current*.001,{ms:true})+")");var k=MistUtil.event.addListener(i,"timeupdate",function(){if(r.data.current=i.currentTime*1e3){y(e);a.ws.removeListener("on_time",k)}};a.ws.addListener("on_time",k)}}}break}case"pause":{if(a.sb){a.sb.paused=true}break}}if(r.type in this.listeners){for(var g=this.listeners[r.type].length-1;g>=0;g--){this.listeners[r.type][g](r)}}return}var T=new Uint8Array(t.data);if(T){if(a.monitor&&a.monitor.bitCounter){for(var g in a.monitor.bitCounter){a.monitor.bitCounter[g]+=t.data.byteLength*8}}if(a.sb&&!a.msgqueue){if(a.sb.updating||a.sb.queue.length||a.sb._busy){a.sb.queue.push(T)}else{a.sb._append(T)}}else{if(!a.msgqueue){a.msgqueue=[[]]}a.msgqueue[a.msgqueue.length-1].push(T)}}else{e.log("Expecting data from websocket, but received none?!")}};this.ws.serverDelay={delays:[],log:function(e){var t=false;switch(e){case"seek":case"set_speed":{t=e;break}case"request_codec_data":{t="codec_data";break}default:{return}}if(t){var i=(new Date).getTime();function r(){a.ws.serverDelay.add((new Date).getTime()-i);a.ws.removeListener(t,r)}a.ws.addListener(t,r)}},add:function(e){this.delays.unshift(e);if(this.delays.length>5){this.delays.splice(5)}},get:function(){if(this.delays.length){let e=0;let t=0;for(null;t=3){break}e+=this.delays[t]}return e/t}return 500}}}.bind(this))};this.wsconnect().then(function(){var t=function(e){if(a.ms&&a.ms.readyState=="open"){a.sbinit(e.data.codecs)}else{a.msoninit.push(function(){a.sbinit(e.data.codecs)})}a.ws.removeListener("codec_data",t)};this.ws.addListener("codec_data",t);u({type:"request_codec_data",supported_codecs:e.source.supportedCodecs})}.bind(this));function u(t){if(!a.ws){throw"No websocket to send to"}if(a.ws.readyState>=a.ws.CLOSING){e.log("MP4 over WS: reopening websocket");a.wsconnect().then(function(){if(!a.sb){var i=function(e){if(!a.sb){a.sbinit(e.data.codecs)}else{a.api.play().catch(function(){})}a.ws.removeListener("codec_data",i)};a.ws.addListener("codec_data",i);u({type:"request_codec_data",supported_codecs:e.source.supportedCodecs})}else{a.api.play()}u(t)},function(){Mistvideo.error("Lost connection to the Media Server")});return}if(a.debugging){console.log("ws send",t)}a.ws.serverDelay.log(t.type);a.ws.send(JSON.stringify(t))}a.findBuffer=function(e){var t=false;for(var r=0;r=e){t=r;break}}return t};this.api={play:function(t){return new Promise(function(r,n){if(!i.paused){r();return}if("paused"in a.sb&&!a.sb.paused){i.play().then(r).catch(n);return}var s=function(o){if(!a.sb){e.log("Attempting to play, but the source buffer is being cleared. Waiting for next on_time.");return}if(e.info.type=="live"){if(t||i.currentTime==0){var u=function(){if(i.buffered.length){var t=a.findBuffer(o.data.current*.001);if(t!==false){if(i.buffered.start(t)>i.currentTime||i.buffered.end(t)i.currentTime){a.sb.paused=false;if(i.buffered.length&&i.buffered.start(0)>i.currentTime){i.currentTime=i.buffered.start(0)}i.play().then(r).catch(n);a.ws.removeListener("on_time",s)}};a.ws.addListener("on_time",s);var o={type:"play"};if(t){o.seek_time="live"}u(o)})},pause:function(){i.pause();u({type:"hold"});if(a.sb){a.sb.paused=true}},setTracks:function(e){if(!MistUtil.object.keys(e).length){return}e.type="tracks";e=MistUtil.object.extend({type:"tracks"},e);u(e)},unload:function(){a.api.pause();a.sb._do(function(){a.sb.remove(0,Infinity);try{a.ms.endOfStream()}catch(e){}});a.ws.close()}};Object.defineProperty(this.api,"currentTime",{get:function(){return i.currentTime},set:function(t){if(isNaN(t)||t<0){e.log("Ignoring seek to "+t+" because ewww.");return}MistUtil.event.send("seeking",t,i);u({type:"seek",seek_time:Math.round(Math.max(0,t*1e3-(250+a.ws.serverDelay.get())))});var r=function(n){a.ws.removeListener("seek",r);var s=function(r){a.ws.removeListener("on_time",s);t=r.data.current*.001;t=t.toFixed(3);var n=10;var o=function(){i.currentTime=t;if(i.currentTime.toFixed(3)=0){n--;a.sb._doNext(o)}}};o()};a.ws.addListener("on_time",s)};a.ws.addListener("seek",r);i.currentTime=t;e.log("Seeking to "+MistUtil.format.time(t,{ms:true})+" ("+t+")")}});var d=Infinity;Object.defineProperty(this.api,"duration",{get:function(){return d}});Object.defineProperty(this.api,"playbackRate",{get:function(){return i.playbackRate},set:function(e){var t=function(e){i.playbackRate=e.data.play_rate_curr};a.ws.addListener("set_speed",t);u({type:"set_speed",play_rate:e==1?"auto":e})}});function c(e){Object.defineProperty(a.api,e,{get:function(){return i[e]},set:function(t){return i[e]=t}})}var f=["volume","buffered","muted","loop","paused",,"error","textTracks","webkitDroppedFrameCount","webkitDecodedFrameCount"];for(var n in f){c(f[n])}MistUtil.event.addListener(i,"ended",function(){if(a.api.loop){a.api.currentTime=0;a.sb._do(function(){a.sb.remove(0,Infinity)})}});var l=false;MistUtil.event.addListener(i,"seeking",function(){l=true;var e=MistUtil.event.addListener(i,"seeked",function(){l=false;MistUtil.event.removeListener(e)})});MistUtil.event.addListener(i,"waiting",function(){if(l){return}var t=a.findBuffer(i.currentTime);if(t!==false){if(t+1=i.buffered.start(r)&&i.currentTime<=i.buffered.end(r)){t=true}e.push([i.buffered.start(r),i.buffered.end(r)])}console.log("waiting","currentTime",i.currentTime,"buffers",e,t?"contained":"outside of buffer","readystate",i.readyState,"networkstate",i.networkState);if(i.readyState>=2&&i.networkState>=2){console.error("Why am I waiting?!",i.currentTime)}})}this.ABR={size:null,bitrate:null,generateString:function(e,t){switch(e){case"size":{return"~"+[t.width,t.height].join("x")}case"bitrate":{return"<"+Math.round(t)+"bps,minbps"}default:{throw"Unknown ABR type"}}},request:function(e,t){this[e]=t;var i=[];if(this.bitrate!==null){i.push(this.generateString("bitrate",this.bitrate))}if(this.size!==null){i.push(this.generateString("size",this.size))}else{i.push("maxbps")}return a.api.setTracks({video:i.join(",|")})}};this.api.ABR_resize=function(t){e.log("Requesting the video track with the resolution that best matches the player size");a.ABR.request("size",t)};this.monitor={bitCounter:[],bitsSince:[],currentBps:null,nWaiting:0,nWaitingThreshold:3,listener:e.options.ABR_bitrate?MistUtil.event.addListener(i,"waiting",function(){a.monitor.nWaiting++;if(a.monitor.nWaiting>=a.monitor.nWaitingThreshold){a.monitor.nWaiting=0;a.monitor.action()}}):null,getBitRate:function(){if(a.sb&&!a.sb.paused){this.bitCounter.push(0);this.bitsSince.push((new Date).getTime());var t,i;if(this.bitCounter.length>5){t=a.monitor.bitCounter.shift();i=this.bitsSince.shift()}else{t=a.monitor.bitCounter[0];i=this.bitsSince[0]}var r=(new Date).getTime()-i;this.currentBps=t/(r*.001)}e.timers.start(function(){a.monitor.getBitRate()},500)},action:function(){if(e.options.setTracks&&e.options.setTracks.video){return}e.log("ABR threshold triggered, requesting lower quality");a.ABR.request("bitrate",this.currentBps)}};this.monitor.getBitRate()}; \ No newline at end of file diff --git a/embed/min/wrappers/videojs.js b/embed/min/wrappers/videojs.js index 8995fe5a..7c29b85f 100644 --- a/embed/min/wrappers/videojs.js +++ b/embed/min/wrappers/videojs.js @@ -1 +1 @@ -mistplayers.videojs={name:"VideoJS player",mimes:["html5/application/vnd.apple.mpegurl","html5/application/vnd.apple.mpegurl;version=7"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return this.mimes.indexOf(e)==-1?false:true},isBrowserSupported:function(e,t,i){if(location.protocol!=MistUtil.http.url.split(t.url).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}if(location.protocol=="file:"&&e=="html5/application/vnd.apple"){i.log("This source ("+e+") won't load if the page is run via file://");return false}return"MediaSource"in window},player:function(){},scriptsrc:function(e){return e+"/videojs.js"}};var p=mistplayers.videojs.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var i=this;var r;function o(){if(e.destroyed){return}e.log("Building VideoJS player..");r=document.createElement("video");if(e.source.type!="html5/video/ogg"){r.crossOrigin="anonymous"}r.setAttribute("playsinline","");var o=e.source.type.split("/");if(o[0]=="html5"){o.shift()}var s=document.createElement("source");s.setAttribute("src",e.source.url);i.source=s;r.appendChild(s);s.type=o.join("/");e.log("Adding "+s.type+" source @ "+e.source.url);MistUtil.class.add(r,"video-js");var n={};if(e.options.autoplay){n.autoplay=true}if(e.options.loop&&e.info.type!="live"){r.setAttribute("loop","")}if(e.options.muted){r.setAttribute("muted","")}if(e.options.poster){n.poster=e.options.poster}if(e.options.controls=="stock"){r.setAttribute("controls","");if(!document.getElementById("videojs-css")){var a=document.createElement("link");a.rel="stylesheet";a.href=e.options.host+"/skins/videojs.css";a.id="videojs-css";document.head.appendChild(a)}}else{n.controls=false}function l(){var e=navigator.userAgent.toLowerCase().match(/android\s([\d\.]*)/i);return e?e[1]:false}var d=MistUtil.getAndroid();if(d&&parseFloat(d)<7){e.log("Detected android < 7: instructing videojs to override native playback");n.html5={hls:{overrideNative:true}};n.nativeAudioTracks=false;n.nativeVideoTracks=false}i.onready(function(){e.log("Building videojs");i.videojs=videojs(r,n,function(){e.log("Videojs initialized")});MistUtil.event.addListener(r,"error",function(t){if(t.target.error.message.indexOf("NS_ERROR_DOM_MEDIA_OVERFLOW_ERR")>=0){e.timers.start(function(){e.log("Reloading player because of NS_ERROR_DOM_MEDIA_OVERFLOW_ERR");e.reload()},1e3)}});i.api.unload=function(){if(i.videojs){i.videojs.autoplay(false);i.videojs.pause();i.videojs.dispose();i.videojs=false;e.log("Videojs instance disposed")}}});e.log("Built html");if("Proxy"in window&&"Reflect"in window){var p={get:{},set:{}};e.player.api=new Proxy(r,{get:function(e,t,i){if(t in p.get){return p.get[t].apply(e,arguments)}var r=e[t];if(typeof r==="function"){return function(){return r.apply(e,arguments)}}return r},set:function(e,t,i){if(t in p.set){return p.set[t].call(e,i)}return e[t]=i}});e.player.api.load=function(){};p.set.currentTime=function(t){e.player.videojs.currentTime(t)};if(e.info.type=="live"){function u(e){var t=0;if(e.buffered.length){t=e.buffered.end(e.buffered.length-1)}return t}var f=0;p.get.duration=function(){if(e.info){var t=(e.info.lastms+(new Date).getTime()-e.info.updated.getTime())*.001;return t}return 0};e.player.api.lastProgress=new Date;e.player.api.liveOffset=0;MistUtil.event.addListener(r,"progress",function(){e.player.api.lastProgress=new Date});p.set.currentTime=function(t){var i=e.player.api.currentTime-t;var r=t-e.player.api.duration;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(r*-10)/10+"s from live)");e.player.videojs.currentTime(e.video.currentTime-i)};var c=0;p.get.currentTime=function(){if(e.info){c=e.info.lastms*.001}var t=this.currentTime+c-e.player.api.liveOffset-f;if(isNaN(t)){return 0}return t}}}else{i.api=r}e.player.setSize=function(t){if("videojs"in e.player){e.player.videojs.dimensions(t.width,t.height);r.parentNode.style.width=t.width+"px";r.parentNode.style.height=t.height+"px"}this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};e.player.api.setSource=function(t){if(!e.player.videojs){return}if(e.player.videojs.src()!=t){e.player.videojs.src({type:e.player.videojs.currentSource().type,src:t})}};e.player.api.setSubtitle=function(e){var t=r.getElementsByTagName("track");for(var i=t.length-1;i>=0;i--){r.removeChild(t[i])}if(e){var o=document.createElement("track");r.appendChild(o);o.kind="subtitles";o.label=e.label;o.srclang=e.lang;o.src=e.src;o.setAttribute("default","")}};if(e.info.type=="live"){var v=MistUtil.event.addListener(r,"loadstart",function(e){MistUtil.event.removeListener(v);MistUtil.event.send("canplay",false,this)});var y=MistUtil.event.addListener(r,"canplay",function(e){if(v){MistUtil.event.removeListener(v)}MistUtil.event.removeListener(y)})}t(r)}if("videojs"in window){o()}else{var s=false;function n(){try{e.video.pause()}catch(e){}e.showError("Error in videojs player");if(!window.mistplayer_videojs_failures){window.mistplayer_videojs_failures=1;e.reload()}else{if(!s){var t=.05*Math.pow(2,window.mistplayer_videojs_failures);e.log("Rate limiter activated: MistPlayer reload delayed by "+Math.round(t*10)/10+" seconds.","error");s=e.timers.start(function(){s=false;delete window.videojs;e.reload()},t*1e3);window.mistplayer_videojs_failures++}}}var a=e.urlappend(mistplayers.videojs.scriptsrc(e.options.host));var l;var d=function(e,t,i,r,o){if(!l){return}if(t==l.src){window.removeEventListener("error",d);n()}return false};window.addEventListener("error",d);l=MistUtil.scripts.insert(a,{onerror:function(t){var i="Failed to load videojs.js";if(t.message){i+=": "+t.message}e.showError(i)},onload:o},e)}}; \ No newline at end of file +mistplayers.videojs={name:"VideoJS player",mimes:["html5/application/vnd.apple.mpegurl","html5/application/vnd.apple.mpegurl;version=7"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return this.mimes.indexOf(e)==-1?false:true},isBrowserSupported:function(e,t,i){if(location.protocol!=MistUtil.http.url.split(t.url).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}if(location.protocol=="file:"&&e=="html5/application/vnd.apple"){i.log("This source ("+e+") won't load if the page is run via file://");return false}return"MediaSource"in window},player:function(){},scriptsrc:function(e){return e+"/videojs.js"}};var p=mistplayers.videojs.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var i=this;var r;function o(){if(e.destroyed){return}e.log("Building VideoJS player..");r=document.createElement("video");if(e.source.type!="html5/video/ogg"){r.crossOrigin="anonymous"}r.setAttribute("playsinline","");var o=e.source.type.split("/");if(o[0]=="html5"){o.shift()}var n=document.createElement("source");n.setAttribute("src",e.source.url);i.source=n;r.appendChild(n);n.type=o.join("/");e.log("Adding "+n.type+" source @ "+e.source.url);MistUtil.class.add(r,"video-js");var s={};if(e.options.autoplay){s.autoplay=true}if(e.options.loop&&e.info.type!="live"){r.setAttribute("loop","")}if(e.options.muted){r.setAttribute("muted","")}if(e.options.poster){s.poster=e.options.poster}if(e.options.controls=="stock"){r.setAttribute("controls","");if(!document.getElementById("videojs-css")){var a=document.createElement("link");a.rel="stylesheet";a.href=e.options.host+"/skins/videojs.css";a.id="videojs-css";document.head.appendChild(a)}}else{s.controls=false}function l(){var e=navigator.userAgent.toLowerCase().match(/android\s([\d\.]*)/i);return e?e[1]:false}var d=MistUtil.getAndroid();if(d&&parseFloat(d)<7){e.log("Detected android < 7: instructing videojs to override native playback");s.html5={hls:{overrideNative:true}};s.nativeAudioTracks=false;s.nativeVideoTracks=false}i.onready(function(){e.log("Building videojs");i.videojs=videojs(r,s,function(){e.log("Videojs initialized");if(e.info.type=="live"){MistUtil.event.addListener(r,"progress",function(t){var i=e.player.videojs.seekable().length-1;e.info.meta.buffer_window=(Math.max(e.player.videojs.seekable().end(i),r.duration)-e.player.videojs.seekable().start(i))*1e3})}});MistUtil.event.addListener(r,"error",function(t){if(t.target.error.message.indexOf("NS_ERROR_DOM_MEDIA_OVERFLOW_ERR")>=0){e.timers.start(function(){e.log("Reloading player because of NS_ERROR_DOM_MEDIA_OVERFLOW_ERR");e.reload()},1e3)}});i.api.unload=function(){if(i.videojs){i.videojs.autoplay(false);i.videojs.pause();i.videojs.dispose();i.videojs=false;e.log("Videojs instance disposed")}}});e.log("Built html");if("Proxy"in window&&"Reflect"in window){var p={get:{},set:{}};e.player.api=new Proxy(r,{get:function(e,t,i){if(t in p.get){return p.get[t].apply(e,arguments)}var r=e[t];if(typeof r==="function"){return function(){return r.apply(e,arguments)}}return r},set:function(e,t,i){if(t in p.set){return p.set[t].call(e,i)}return e[t]=i}});e.player.api.load=function(){};p.set.currentTime=function(t){e.player.videojs.currentTime(t)};if(e.info.type=="live"){function u(e){var t=0;if(e.buffered.length){t=e.buffered.end(e.buffered.length-1)}return t}var f=0;p.get.duration=function(){if(e.info){var t=r.duration;return t}return 0};e.player.api.lastProgress=new Date;e.player.api.liveOffset=0;MistUtil.event.addListener(r,"progress",function(){e.player.api.lastProgress=new Date});p.set.currentTime=function(t){var i=e.player.api.currentTime-t;var r=t-e.player.api.duration;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(r*-10)/10+"s from live)");e.player.videojs.currentTime(e.video.currentTime-i)};var c=0;p.get.currentTime=function(){if(e.info){c=e.info.lastms*.001}var t=e.player.videojs?e.player.videojs.currentTime():r.currentTime;if(isNaN(t)){return 0}return t};p.get.buffered=function(){var t=e.player.videojs?e.player.videojs.buffered():r.buffered;return{length:t.length,start:function(e){return t.start(e)},end:function(e){return t.end(e);e}}}}}else{i.api=r}e.player.setSize=function(t){if("videojs"in e.player){e.player.videojs.dimensions(t.width,t.height);r.parentNode.style.width=t.width+"px";r.parentNode.style.height=t.height+"px"}this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};e.player.api.setSource=function(t){if(!e.player.videojs){return}if(e.player.videojs.src()!=t){e.player.videojs.src({type:e.player.videojs.currentSource().type,src:t})}};e.player.api.setSubtitle=function(e){var t=r.getElementsByTagName("track");for(var i=t.length-1;i>=0;i--){r.removeChild(t[i])}if(e){var o=document.createElement("track");r.appendChild(o);o.kind="subtitles";o.label=e.label;o.srclang=e.lang;o.src=e.src;o.setAttribute("default","")}};if(e.info.type=="live"){var v=MistUtil.event.addListener(r,"loadstart",function(e){MistUtil.event.removeListener(v);MistUtil.event.send("canplay",false,this)});var y=MistUtil.event.addListener(r,"canplay",function(e){if(v){MistUtil.event.removeListener(v)}MistUtil.event.removeListener(y)})}t(r)}if("videojs"in window){o()}else{var n=false;function s(){try{e.video.pause()}catch(e){}e.showError("Error in videojs player");if(!window.mistplayer_videojs_failures){window.mistplayer_videojs_failures=1;e.reload()}else{if(!n){var t=.05*Math.pow(2,window.mistplayer_videojs_failures);e.log("Rate limiter activated: MistPlayer reload delayed by "+Math.round(t*10)/10+" seconds.","error");n=e.timers.start(function(){n=false;delete window.videojs;e.reload()},t*1e3);window.mistplayer_videojs_failures++}}}var a=e.urlappend(mistplayers.videojs.scriptsrc(e.options.host));var l;var d=function(e,t,i,r,o){if(!l){return}if(t==l.src){window.removeEventListener("error",d);s()}return false};window.addEventListener("error",d);l=MistUtil.scripts.insert(a,{onerror:function(t){var i="Failed to load videojs.js";if(t.message){i+=": "+t.message}e.showError(i)},onload:o},e)}}; \ No newline at end of file diff --git a/embed/min/wrappers/webrtc.js b/embed/min/wrappers/webrtc.js index d91a456d..1949924e 100644 --- a/embed/min/wrappers/webrtc.js +++ b/embed/min/wrappers/webrtc.js @@ -1 +1 @@ -mistplayers.webrtc={name:"WebRTC player",mimes:["webrtc"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return this.mimes.indexOf(e)==-1?false:true},isBrowserSupported:function(e,t,n){if(!("WebSocket"in window)||!("RTCPeerConnection"in window)){return false}if(location.protocol.replace(/^http/,"ws")!=MistUtil.http.url.split(t.url.replace(/^http/,"ws")).protocol){n.log("HTTP/HTTPS mismatch for this source");return false}return true},player:function(){}};var p=mistplayers.webrtc.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var n=this;if(typeof WebRTCBrowserEqualizerLoaded=="undefined"||!WebRTCBrowserEqualizerLoaded){var i=document.createElement("script");i.src=e.urlappend(e.options.host+"/webrtc.js");e.log("Retrieving webRTC browser equalizer code from "+i.src);document.head.appendChild(i);i.onerror=function(){e.showError("Failed to load webrtc browser equalizer",{nextCombo:5})};i.onload=function(){n.build(e,t)};return}var r=document.createElement("video");r.setAttribute("playsinline","");var o=["autoplay","loop","poster"];for(var s in o){var c=o[s];if(e.options[c]){r.setAttribute(c,e.options[c]===true?"":e.options[c])}}if(e.options.muted){r.muted=true}if(e.info.type=="live"){r.loop=false}if(e.options.controls=="stock"){r.setAttribute("controls","")}r.setAttribute("crossorigin","anonymous");this.setSize=function(e){r.style.width=e.width+"px";r.style.height=e.height+"px"};MistUtil.event.addListener(r,"loadeddata",b);MistUtil.event.addListener(r,"seeked",b);if(!e.options.autoplay){MistUtil.event.addListener(r,"canplay",function(){var t=MistUtil.event.addListener(r,"play",function(){e.log("Pausing because autoplay is disabled");var i=MistUtil.event.addListener(r,"pause",function(){e.options.autoplay=false;MistUtil.event.removeListener(i)});n.api.pause();MistUtil.event.removeListener(t)})})}var a=0;var l=false;var u=[];this.listeners={on_connected:function(){a=0;l=false;this.webrtc.play();MistUtil.event.send("webrtc_connected",null,r)},on_disconnected:function(){MistUtil.event.send("webrtc_disconnected",null,r);e.log("Websocket sent on_disconnect");if(!l){r.pause()}},on_answer_sdp:function(t){if(!t.result){e.showError("Failed to open stream.");this.on_disconnected();return}e.log("SDP answer received")},on_time:function(t){var n=a;a=t.current*.001-r.currentTime;if(Math.abs(n-a)>1){b()}if((!("paused"in t)||!t.paused)&&r.paused){r.play()}var i=t.end==0?Infinity:t.end*.001;if(i!=p){p=i;MistUtil.event.send("durationchange",i,r)}if(t.tracks&&u!=t.tracks){var o=e.info?MistUtil.tracks.parse(e.info.meta.tracks):[];for(var s in t.tracks){if(u.indexOf(t.tracks[s])<0){var c;for(var l in o){if(t.tracks[s]in o[l]){c=l;break}}if(!c){continue}MistUtil.event.send("playerUpdate_trackChanged",{type:c,trackid:t.tracks[s]},e.video)}}u=t.tracks}if(e.reporting&&t.tracks){e.reporting.stats.d.tracks=t.tracks.join(",")}},on_seek:function(e){var t=this;MistUtil.event.send("seeked",a,r);if(e.live_point){t.webrtc.playbackrate("auto")}if("seekPromise"in this.webrtc.signaling){r.play().then(function(){if("seekPromise"in t.webrtc.signaling){t.webrtc.signaling.seekPromise.resolve("Play promise resolved")}}).catch(function(){if("seekPromise"in t.webrtc.signaling){t.webrtc.signaling.seekPromise.reject("Play promise rejected")}})}else{r.play()}},on_speed:function(e){this.webrtc.play_rate=e.play_rate_curr;MistUtil.event.send("ratechange",e,r)},on_stop:function(){e.log("Websocket sent on_stop");r.pause();MistUtil.event.send("ended",null,r);l=true}};function f(){this.peerConn=null;this.localOffer=null;this.isConnected=false;this.isConnecting=false;this.play_rate="auto";var t=this;this.on_event=function(i){switch(i.type){case"on_connected":{t.isConnected=true;t.isConnecting=false;break}case"on_answer_sdp":{t.peerConn.setRemoteDescription({type:"answer",sdp:i.answer_sdp}).then(function(){},function(e){console.error(e)});break}case"on_disconnected":{t.isConnected=false;break}}if(i.type in n.listeners){return n.listeners[i.type].call(n,i)}e.log("Unhandled WebRTC event "+i.type+": "+JSON.stringify(i));return false};this.connect=function(n){t.isConnecting=true;e.container.setAttribute("data-loading","connecting");function i(e){var t=new Promise(function(t,n){function i(e){try{var r=RTCRtpReceiver.getCapabilities("video");for(var o=0;o0){setTimeout(function(){i(e-1)},100)}else{n("H264 not found :(")}}catch(e){t("Checker unavailable")}}i(e)});return t}i(5).catch(function(){e.log("Beware: this device does not seem to be able to play H264.")}).finally(function(){t.signaling=new d(t.on_event);var i={};if(e.options.RTCIceServers){i.iceServers=e.options.RTCIceServers}else if(e.source.RTCIceServers){i.iceServers=e.source.RTCIceServers}t.peerConn=new RTCPeerConnection(i);t.peerConn.ontrack=function(e){r.srcObject=e.streams[0];if(n){n()}};t.peerConn.onconnectionstatechange=function(t){if(e.destroyed){return}switch(this.connectionState){case"failed":{e.log("UDP connection failed, trying next combo.","error");e.nextCombo();break}case"connected":{e.container.removeAttribute("data-loading")}case"disconnected":case"closed":case"new":case"connecting":default:{e.log("WebRTC connection state changed to "+this.connectionState);break}}};t.peerConn.oniceconnectionstatechange=function(t){if(e.destroyed){return}switch(this.iceConnectionState){case"failed":{e.showError("ICE connection "+this.iceConnectionState);break}case"disconnected":case"closed":case"new":case"checking":case"connected":case"completed":default:{e.log("WebRTC ICE connection state changed to "+this.iceConnectionState);break}}}})};this.play=function(){if(!this.isConnected){throw"Not connected, cannot play"}this.peerConn.createOffer({offerToReceiveAudio:true,offerToReceiveVideo:true}).then(function(e){t.localOffer=e;t.peerConn.setLocalDescription(e).then(function(){t.signaling.sendOfferSDP(t.localOffer.sdp)},function(e){console.error(e)})},function(e){throw e})};this.stop=function(){if(!this.isConnected){throw"Not connected, cannot stop."}this.signaling.send({type:"stop"})};this.seek=function(n){var i=new Promise(function(i,r){if(!t.isConnected||!t.signaling){if(t.isConnecting){var o=MistUtil.event.addListener(e.video,"loadstart",function(){t.seek(n);MistUtil.event.removeListener(o)});return r("Not connected yet, will seek once connected")}else{return r("Failed seek: not connected")}}t.signaling.send({type:"seek",seek_time:n=="live"?"live":n*1e3});if("seekPromise"in t.signaling){t.signaling.seekPromise.reject("Doing new seek")}t.signaling.seekPromise={resolve:function(e){i("seeked");delete t.signaling.seekPromise},reject:function(e){r("Failed to seek: "+e);delete t.signaling.seekPromise}}});return i};this.pause=function(){if(!this.isConnected){throw"Not connected, cannot pause."}this.signaling.send({type:"hold"})};this.setTrack=function(e){if(!this.isConnected){throw"Not connected, cannot set track."}e.type="tracks";this.signaling.send(e)};this.playbackrate=function(e){if(typeof e=="undefined"){return n.webrtc.play_rate=="auto"?1:n.webrtc.play_rate}if(!this.isConnected){throw"Not connected, cannot change playback rate."}this.signaling.send({type:"set_speed",play_rate:e})};this.getStats=function(e){this.peerConn.getStats().then(function(t){var n={};var i=Array.from(t.entries());for(var r in i){var o=i[r];if(o[1].type=="inbound-rtp"){n[o[0]]=o[1]}}e(n)})};this.connect()}function d(t){this.ws=null;this.ws=new WebSocket(e.source.url.replace(/^http/,"ws"));var n=false;this.ws.onopen=function(){t({type:"on_connected"})};this.ws.timeOut=e.timers.start(function(){if(e.player.webrtc.signaling.ws.readyState==0){e.log("WebRTC: socket timeout - try next combo");e.nextCombo()}},5e3);this.ws.onmessage=function(e){try{var n=JSON.parse(e.data);t(n)}catch(t){console.error("Failed to parse a response from MistServer",t,e.data)}};this.ws.onclose=function(e){switch(e.code){case 1006:{}default:{t({type:"on_disconnected",code:e.code});break}}};this.sendOfferSDP=function(e){this.send({type:"offer_sdp",offer_sdp:e})};this.send=function(e){if(!this.ws){throw"Not initialized, cannot send "+JSON.stringify(e)}this.ws.send(JSON.stringify(e))}}this.webrtc=new f;this.api={};var p;Object.defineProperty(this.api,"duration",{get:function(){return p}});Object.defineProperty(this.api,"currentTime",{get:function(){return a+r.currentTime},set:function(e){a=e-r.currentTime;r.pause();var t=n.webrtc.seek(e);MistUtil.event.send("seeking",e,r);if(t){t.catch(function(e){})}}});Object.defineProperty(this.api,"playbackRate",{get:function(){return n.webrtc.playbackrate()},set:function(e){return n.webrtc.playbackrate(e)}});function h(e){Object.defineProperty(n.api,e,{get:function(){return r[e]},set:function(t){return r[e]=t}})}var v=["volume","muted","loop","paused",,"error","textTracks","webkitDroppedFrameCount","webkitDecodedFrameCount"];for(var s in v){h(v[s])}function g(e){if(e in r){n.api[e]=function(){return r[e].call(r,arguments)}}}var v=["load","getVideoPlaybackQuality"];for(var s in v){g(v[s])}n.api.play=function(){var t;if(n.api.currentTime){t=n.api.currentTime}if(e.info&&e.info.type=="live"){t="live"}if(t){var i=new Promise(function(i,r){if(!n.webrtc.isConnected&&n.webrtc.peerConn.iceConnectionState!="completed"){if(!n.webrtc.isConnecting){e.log("Received call to play while not connected, connecting "+n.webrtc.peerConn.iceConnectionState);n.webrtc.connect(function(){n.webrtc.seek(t).then(function(e){i("played "+e)}).catch(function(e){r(e)})})}else{r("Still connecting")}}else{n.webrtc.seek(t).then(function(e){i("played "+e)}).catch(function(e){r(e)})}});return i}else{return r.play()}};n.api.getStats=function(){if(n.webrtc&&n.webrtc.isConnected){return new Promise(function(e,t){n.webrtc.peerConn.getStats().then(t=>{var n={audio:null,video:null};for(let e of t.values()){if(e.type=="track"){n[e.kind]=e}}e(n)})})}};n.api.getLatency=function(){var t=e.player.api.getStats();if(t){return new Promise(function(e,i){t.then(function(t){setTimeout(function(){var r=n.api.getStats();if(!r){i();return}r.then(function(n){var i={};for(var r in t){i[r]=t[r]&&n[r]?(n[r].jitterBufferDelay-t[r].jitterBufferDelay)/(n[r].jitterBufferEmittedCount-t[r].jitterBufferEmittedCount):null}e(i)},i)},1e3)},i)})}};n.api.pause=function(){r.pause();try{n.webrtc.pause()}catch(e){}MistUtil.event.send("paused",null,r)};n.api.setTracks=function(e){if(n.webrtc.isConnected){n.webrtc.setTrack(e)}else{var t=function(){n.webrtc.setTrack(e);MistUtil.event.removeListener({type:"webrtc_connected",callback:t,element:r})};MistUtil.event.addListener(r,"webrtc_connected",t)}};function b(){if(!n.api.textTracks[0]){return}var e=n.api.textTracks[0].currentOffset||0;if(Math.abs(a-e)<1){return}var t=[];for(var i=n.api.textTracks[0].cues.length-1;i>=0;i--){var r=n.api.textTracks[0].cues[i];n.api.textTracks[0].removeCue(r);if(!("orig"in r)){r.orig={start:r.startTime,end:r.endTime}}r.startTime=r.orig.start-a;r.endTime=r.orig.end-a;t.push(r)}for(var i in t){n.api.textTracks[0].addCue(t[i])}n.api.textTracks[0].currentOffset=a}n.api.setSubtitle=function(e){var t=r.getElementsByTagName("track");for(var n=t.length-1;n>=0;n--){r.removeChild(t[n])}if(e){var i=document.createElement("track");r.appendChild(i);i.kind="subtitles";i.label=e.label;i.srclang=e.lang;i.src=e.src;i.setAttribute("default","");i.onload=b}};MistUtil.event.addListener(r,"ended",function(){if(n.api.loop){if(e.state=="Stream is online"){n.webrtc.connect()}}});if("decodingIssues"in e.skin.blueprints){var w=["nackCount","pliCount","packetsLost","packetsReceived","bytesReceived"];for(var y in w){n.api[w[y]]=0}var k=function(){e.timers.start(function(){n.webrtc.getStats(function(e){for(var t in e){for(var i in w){if(w[i]in e[t]){n.api[w[i]]=e[t][w[i]]}}break}});k()},1e3)};k()}n.api.ABR_resize=function(t){e.log("Requesting the video track with the resolution that best matches the player size");n.api.setTracks({video:"~"+[t.width,t.height].join("x")})};n.api.unload=function(){try{n.webrtc.stop();n.webrtc.signaling.ws.close();n.webrtc.peerConn.close()}catch(e){}};t(r)}; \ No newline at end of file +mistplayers.webrtc={name:"WebRTC player",mimes:["webrtc"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return this.mimes.indexOf(e)==-1?false:true},isBrowserSupported:function(e,t,n){if(!("WebSocket"in window)||!("RTCPeerConnection"in window)){return false}if(location.protocol.replace(/^http/,"ws")!=MistUtil.http.url.split(t.url.replace(/^http/,"ws")).protocol){n.log("HTTP/HTTPS mismatch for this source");return false}return true},player:function(){}};var p=mistplayers.webrtc.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var n=this;if(typeof WebRTCBrowserEqualizerLoaded=="undefined"||!WebRTCBrowserEqualizerLoaded){var i=document.createElement("script");i.src=e.urlappend(e.options.host+"/webrtc.js");e.log("Retrieving webRTC browser equalizer code from "+i.src);document.head.appendChild(i);i.onerror=function(){e.showError("Failed to load webrtc browser equalizer",{nextCombo:5})};i.onload=function(){n.build(e,t)};return}var r=document.createElement("video");r.setAttribute("playsinline","");var o=["autoplay","loop","poster"];for(var s in o){var c=o[s];if(e.options[c]){r.setAttribute(c,e.options[c]===true?"":e.options[c])}}if(e.options.muted){r.muted=true}if(e.info.type=="live"){r.loop=false}if(e.options.controls=="stock"){r.setAttribute("controls","")}r.setAttribute("crossorigin","anonymous");this.setSize=function(e){r.style.width=e.width+"px";r.style.height=e.height+"px"};MistUtil.event.addListener(r,"loadeddata",b);MistUtil.event.addListener(r,"seeked",b);if(!e.options.autoplay){MistUtil.event.addListener(r,"canplay",function(){var t=MistUtil.event.addListener(r,"play",function(){e.log("Pausing because autoplay is disabled");var i=MistUtil.event.addListener(r,"pause",function(){e.options.autoplay=false;MistUtil.event.removeListener(i)});n.api.pause();MistUtil.event.removeListener(t)})})}var a=0;var l=false;var u=[];this.listeners={on_connected:function(){a=0;l=false;this.webrtc.play();MistUtil.event.send("webrtc_connected",null,r)},on_disconnected:function(){MistUtil.event.send("webrtc_disconnected",null,r);e.log("Websocket sent on_disconnect");if(!l){r.pause()}},on_answer_sdp:function(t){if(!t.result){e.showError("Failed to open stream.");this.on_disconnected();return}e.log("SDP answer received")},on_time:function(t){var n=a;a=t.current*.001-r.currentTime;if(Math.abs(n-a)>1){b()}if((!("paused"in t)||!t.paused)&&r.paused){r.play()}var i=t.end==0?Infinity:t.end*.001;if(i!=p){p=i;MistUtil.event.send("durationchange",i,r)}e.info.meta.buffer_window=t.end-t.begin;if(t.tracks&&u!=t.tracks){var o=e.info?MistUtil.tracks.parse(e.info.meta.tracks):[];for(var s in t.tracks){if(u.indexOf(t.tracks[s])<0){var c;for(var l in o){if(t.tracks[s]in o[l]){c=l;break}}if(!c){continue}MistUtil.event.send("playerUpdate_trackChanged",{type:c,trackid:t.tracks[s]},e.video)}}u=t.tracks}if(e.reporting&&t.tracks){e.reporting.stats.d.tracks=t.tracks.join(",")}},on_seek:function(e){var t=this;MistUtil.event.send("seeked",a,r);if(e.live_point){t.webrtc.playbackrate("auto")}if("seekPromise"in this.webrtc.signaling){r.play().then(function(){if("seekPromise"in t.webrtc.signaling){t.webrtc.signaling.seekPromise.resolve("Play promise resolved")}}).catch(function(){if("seekPromise"in t.webrtc.signaling){t.webrtc.signaling.seekPromise.reject("Play promise rejected")}})}else{r.play()}},on_speed:function(e){this.webrtc.play_rate=e.play_rate_curr;MistUtil.event.send("ratechange",e,r)},on_stop:function(){e.log("Websocket sent on_stop");r.pause();MistUtil.event.send("ended",null,r);l=true}};function f(){this.peerConn=null;this.localOffer=null;this.isConnected=false;this.isConnecting=false;this.play_rate="auto";var t=this;this.on_event=function(i){switch(i.type){case"on_connected":{t.isConnected=true;t.isConnecting=false;break}case"on_answer_sdp":{t.peerConn.setRemoteDescription({type:"answer",sdp:i.answer_sdp}).then(function(){},function(e){console.error(e)});break}case"on_disconnected":{t.isConnected=false;break}}if(i.type in n.listeners){return n.listeners[i.type].call(n,i)}e.log("Unhandled WebRTC event "+i.type+": "+JSON.stringify(i));return false};this.connect=function(n){t.isConnecting=true;e.container.setAttribute("data-loading","connecting");function i(e){var t=new Promise(function(t,n){function i(e){try{var r=RTCRtpReceiver.getCapabilities("video");for(var o=0;o0){setTimeout(function(){i(e-1)},100)}else{n("H264 not found :(")}}catch(e){t("Checker unavailable")}}i(e)});return t}i(5).catch(function(){e.log("Beware: this device does not seem to be able to play H264.")}).finally(function(){t.signaling=new d(t.on_event);var i={};if(e.options.RTCIceServers){i.iceServers=e.options.RTCIceServers}else if(e.source.RTCIceServers){i.iceServers=e.source.RTCIceServers}t.peerConn=new RTCPeerConnection(i);t.peerConn.ontrack=function(e){r.srcObject=e.streams[0];if(n){n()}};t.peerConn.onconnectionstatechange=function(t){if(e.destroyed){return}switch(this.connectionState){case"failed":{e.log("UDP connection failed, trying next combo.","error");e.nextCombo();break}case"connected":{e.container.removeAttribute("data-loading")}case"disconnected":case"closed":case"new":case"connecting":default:{e.log("WebRTC connection state changed to "+this.connectionState);break}}};t.peerConn.oniceconnectionstatechange=function(t){if(e.destroyed){return}switch(this.iceConnectionState){case"failed":{e.showError("ICE connection "+this.iceConnectionState);break}case"disconnected":case"closed":case"new":case"checking":case"connected":case"completed":default:{e.log("WebRTC ICE connection state changed to "+this.iceConnectionState);break}}}})};this.play=function(){if(!this.isConnected){throw"Not connected, cannot play"}this.peerConn.createOffer({offerToReceiveAudio:true,offerToReceiveVideo:true}).then(function(e){t.localOffer=e;t.peerConn.setLocalDescription(e).then(function(){t.signaling.sendOfferSDP(t.localOffer.sdp)},function(e){console.error(e)})},function(e){throw e})};this.stop=function(){if(!this.isConnected){throw"Not connected, cannot stop."}this.signaling.send({type:"stop"})};this.seek=function(n){var i=new Promise(function(i,r){if(!t.isConnected||!t.signaling){if(t.isConnecting){var o=MistUtil.event.addListener(e.video,"loadstart",function(){t.seek(n);MistUtil.event.removeListener(o)});return r("Not connected yet, will seek once connected")}else{return r("Failed seek: not connected")}}t.signaling.send({type:"seek",seek_time:n=="live"?"live":n*1e3});if("seekPromise"in t.signaling){t.signaling.seekPromise.reject("Doing new seek")}t.signaling.seekPromise={resolve:function(e){i("seeked");delete t.signaling.seekPromise},reject:function(e){r("Failed to seek: "+e);delete t.signaling.seekPromise}}});return i};this.pause=function(){if(!this.isConnected){throw"Not connected, cannot pause."}this.signaling.send({type:"hold"})};this.setTrack=function(e){if(!this.isConnected){throw"Not connected, cannot set track."}e.type="tracks";this.signaling.send(e)};this.playbackrate=function(e){if(typeof e=="undefined"){return n.webrtc.play_rate=="auto"?1:n.webrtc.play_rate}if(!this.isConnected){throw"Not connected, cannot change playback rate."}this.signaling.send({type:"set_speed",play_rate:e})};this.getStats=function(e){this.peerConn.getStats().then(function(t){var n={};var i=Array.from(t.entries());for(var r in i){var o=i[r];if(o[1].type=="inbound-rtp"){n[o[0]]=o[1]}}e(n)})};this.connect()}function d(t){this.ws=null;this.ws=new WebSocket(e.source.url.replace(/^http/,"ws"));var n=false;this.ws.onopen=function(){t({type:"on_connected"})};this.ws.timeOut=e.timers.start(function(){if(e.player.webrtc.signaling.ws.readyState==0){e.log("WebRTC: socket timeout - try next combo");e.nextCombo()}},5e3);this.ws.onmessage=function(e){try{var n=JSON.parse(e.data);t(n)}catch(t){console.error("Failed to parse a response from MistServer",t,e.data)}};this.ws.onclose=function(e){switch(e.code){case 1006:{}default:{t({type:"on_disconnected",code:e.code});break}}};this.sendOfferSDP=function(e){this.send({type:"offer_sdp",offer_sdp:e})};this.send=function(e){if(!this.ws){throw"Not initialized, cannot send "+JSON.stringify(e)}this.ws.send(JSON.stringify(e))}}this.webrtc=new f;this.api={};var p;Object.defineProperty(this.api,"duration",{get:function(){return p}});Object.defineProperty(this.api,"currentTime",{get:function(){return a+r.currentTime},set:function(e){a=e-r.currentTime;r.pause();var t=n.webrtc.seek(e);MistUtil.event.send("seeking",e,r);if(t){t.catch(function(e){})}}});Object.defineProperty(this.api,"playbackRate",{get:function(){return n.webrtc.playbackrate()},set:function(e){return n.webrtc.playbackrate(e)}});function h(e){Object.defineProperty(n.api,e,{get:function(){return r[e]},set:function(t){return r[e]=t}})}var v=["volume","muted","loop","paused",,"error","textTracks","webkitDroppedFrameCount","webkitDecodedFrameCount"];for(var s in v){h(v[s])}function g(e){if(e in r){n.api[e]=function(){return r[e].call(r,arguments)}}}var v=["load","getVideoPlaybackQuality"];for(var s in v){g(v[s])}n.api.play=function(){var t;if(n.api.currentTime){t=n.api.currentTime}if(e.info&&e.info.type=="live"){t="live"}if(t){var i=new Promise(function(i,r){if(!n.webrtc.isConnected&&n.webrtc.peerConn.iceConnectionState!="completed"){if(!n.webrtc.isConnecting){e.log("Received call to play while not connected, connecting "+n.webrtc.peerConn.iceConnectionState);n.webrtc.connect(function(){n.webrtc.seek(t).then(function(e){i("played "+e)}).catch(function(e){r(e)})})}else{r("Still connecting")}}else{n.webrtc.seek(t).then(function(e){i("played "+e)}).catch(function(e){r(e)})}});return i}else{return r.play()}};n.api.getStats=function(){if(n.webrtc&&n.webrtc.isConnected){return new Promise(function(e,t){n.webrtc.peerConn.getStats().then(t=>{var n={audio:null,video:null};for(let e of t.values()){if(e.type=="track"){n[e.kind]=e}}e(n)})})}};n.api.getLatency=function(){var t=e.player.api.getStats();if(t){return new Promise(function(e,i){t.then(function(t){setTimeout(function(){var r=n.api.getStats();if(!r){i();return}r.then(function(n){var i={};for(var r in t){i[r]=t[r]&&n[r]?(n[r].jitterBufferDelay-t[r].jitterBufferDelay)/(n[r].jitterBufferEmittedCount-t[r].jitterBufferEmittedCount):null}e(i)},i)},1e3)},i)})}};n.api.pause=function(){r.pause();try{n.webrtc.pause()}catch(e){}MistUtil.event.send("paused",null,r)};n.api.setTracks=function(e){if(n.webrtc.isConnected){n.webrtc.setTrack(e)}else{var t=function(){n.webrtc.setTrack(e);MistUtil.event.removeListener({type:"webrtc_connected",callback:t,element:r})};MistUtil.event.addListener(r,"webrtc_connected",t)}};function b(){if(!n.api.textTracks[0]){return}var e=n.api.textTracks[0].currentOffset||0;if(Math.abs(a-e)<1){return}var t=[];for(var i=n.api.textTracks[0].cues.length-1;i>=0;i--){var r=n.api.textTracks[0].cues[i];n.api.textTracks[0].removeCue(r);if(!("orig"in r)){r.orig={start:r.startTime,end:r.endTime}}r.startTime=r.orig.start-a;r.endTime=r.orig.end-a;t.push(r)}for(var i in t){n.api.textTracks[0].addCue(t[i])}n.api.textTracks[0].currentOffset=a}n.api.setSubtitle=function(e){var t=r.getElementsByTagName("track");for(var n=t.length-1;n>=0;n--){r.removeChild(t[n])}if(e){var i=document.createElement("track");r.appendChild(i);i.kind="subtitles";i.label=e.label;i.srclang=e.lang;i.src=e.src;i.setAttribute("default","");i.onload=b}};MistUtil.event.addListener(r,"ended",function(){if(n.api.loop){if(e.state=="Stream is online"){n.webrtc.connect()}}});if("decodingIssues"in e.skin.blueprints){var w=["nackCount","pliCount","packetsLost","packetsReceived","bytesReceived"];for(var y in w){n.api[w[y]]=0}var k=function(){e.timers.start(function(){n.webrtc.getStats(function(e){for(var t in e){for(var i in w){if(w[i]in e[t]){n.api[w[i]]=e[t][w[i]]}}break}});k()},1e3)};k()}n.api.ABR_resize=function(t){e.log("Requesting the video track with the resolution that best matches the player size");n.api.setTracks({video:"~"+[t.width,t.height].join("x")})};n.api.unload=function(){try{n.webrtc.stop();n.webrtc.signaling.ws.close();n.webrtc.peerConn.close()}catch(e){}};t(r)}; \ No newline at end of file diff --git a/embed/player.js b/embed/player.js index ca6cb0d6..47343c33 100644 --- a/embed/player.js +++ b/embed/player.js @@ -35,6 +35,7 @@ function MistVideo(streamName,options) { maxheight: false, //no max height (apart from targets dimensions) ABR_resize: true, //for supporting wrappers: when the player resizes, request a video track that matches the resolution best ABR_bitrate: true, //for supporting wrappers: when there are playback issues, request a lower bitrate video track + useDateTime: true, //when the unix timestamp of the stream is known, display the date/time MistVideoObject: false//no reference object is passed },options); if (options.host) { options.host = MistUtil.http.url.sanitizeHost(options.host); } @@ -144,7 +145,7 @@ function MistVideo(streamName,options) { for (var i in mistplayers) { mistplayers[i].shortname = i; } - if (options.forcePlayer) { + if (options.forcePlayer && mistplayers[options.forcePlayer]) { players = [mistplayers[options.forcePlayer]]; MistVideo.log("Forcing player "+options.forcePlayer); } diff --git a/embed/skins.js b/embed/skins.js index 9cb9c2d7..88c752b1 100644 --- a/embed/skins.js +++ b/embed/skins.js @@ -770,6 +770,38 @@ MistSkins["default"] = { var video = this.video; var MistVideo = this; + + var first = Infinity; + if (MistVideo.info && MistVideo.info.meta && MistVideo.info.meta.tracks) { + for (var i in MistVideo.info.meta.tracks) { + if (MistVideo.info.meta.tracks[i].firstms*1e-3 < first) { + first = MistVideo.info.meta.tracks[i].firstms*1e-3; + } + } + } + if (first == Infinity) { + first = 0; + } + function firsts() { + if (MistVideo.player.api.duration < first) { return 0; } + return first; + } + + function getBufferWindow() { + var buffer_window = MistVideo.info.meta.buffer_window; + if (typeof buffer_window == "undefined") { + //for some reason, buffer_window is not defined (liveDVR?) + //just assume we can seek in our own buffer + if (MistVideo.player && MistVideo.player.api && MistVideo.player.api.buffered && MistVideo.player.api.buffered.length) { + buffer_window = (MistVideo.player.api.duration - MistVideo.player.api.buffered.start(0))*1e3; + } + else { + //no buffer of our own either? we'll just assume we have a minute + buffer_window = 60e3; + } + } + return buffer_window *= 1e-3; + } //these functions update the states container.updateBar = function(currentTime){ @@ -785,11 +817,11 @@ MistSkins["default"] = { if (!isFinite(MistVideo.player.api.duration)) { return 0; } var result = 0; if (MistVideo.info.type == "live") { - var buffer_window = MistVideo.info.meta.buffer_window * 1e-3; + var buffer_window = getBufferWindow(); result = (time - MistVideo.player.api.duration + buffer_window) / buffer_window; } else { - result = time / MistVideo.player.api.duration; + result = (time - firsts()) / (MistVideo.player.api.duration - firsts()); } return Math.min(1,Math.max(0,result)); } @@ -865,14 +897,14 @@ MistSkins["default"] = { var perc = MistUtil.getPos(this,e); if (MistVideo.info.type == "live") { //live mode: seek in DVR window - var bufferWindow = MistVideo.info.meta.buffer_window * 1e-3; //buffer window in seconds + var bufferWindow = getBufferWindow(); //assuming the "right" part or the progressbar is at true live return (perc-1) * bufferWindow + MistVideo.player.api.duration; } else { //VOD mode if (!isFinite(MistVideo.player.api.duration)) { return false; } - return perc * MistVideo.player.api.duration; + return perc * (MistVideo.player.api.duration - firsts()) + firsts(); } }; //seeking @@ -887,6 +919,7 @@ MistSkins["default"] = { //hovering var tooltip = MistVideo.UI.buildStructure({type:"tooltip"}); + tooltip.style.opacity = 0; container.appendChild(tooltip); MistUtil.event.addListener(margincontainer,"mouseout",function(){ @@ -899,8 +932,15 @@ MistSkins["default"] = { tooltip.style.opacity = 0; return; } - tooltip.setText(MistUtil.format.time(secs)); + + if (MistVideo.options.useDateTime && MistVideo.info && MistVideo.info.unixoffset) { + tooltip.setText(MistUtil.format.ago(new Date(MistVideo.info.unixoffset + secs*1e3))); + } + else { + tooltip.setText(MistUtil.format.time(secs)); + } tooltip.style.opacity = 1; + var perc = MistUtil.getPos(this,e);// e.clientX - this.getBoundingClientRect().left; var pos = {bottom:20}; @@ -1193,8 +1233,18 @@ MistSkins["default"] = { var formatTime = MistUtil.format.time; container.set = function(){ var v = MistVideo.player.api.currentTime; - text.nodeValue = formatTime(v); - container.setAttribute("title",text.nodeValue); + var t; + if (MistVideo.options.useDateTime && MistVideo.info && MistVideo.info.unixoffset) { + var d = new Date(MistVideo.info.unixoffset + v*1e3); + t = MistUtil.format.ago(d); + container.setAttribute("title",MistUtil.format.ago(d,34560e6)); + } + else { + t = formatTime(v); + container.setAttribute("title",t); + } + + text.nodeValue = t; }; container.set(); @@ -1226,7 +1276,16 @@ MistSkins["default"] = { return; } this.style.display = ""; - text.nodeValue = MistUtil.format.time(duration); + + if (MistVideo.options.useDateTime && MistVideo.info && MistVideo.info.unixoffset) { + var t = new Date(duration*1e3 + MistVideo.info.unixoffset) + text.nodeValue = MistUtil.format.ago(t); + container.setAttribute("title",MistUtil.format.ago(t,34560e6)); //format as if more than a year ago + } + else { + text.nodeValue = MistUtil.format.time(duration); + container.setAttribute("title",text.nodeValue); + } }; MistUtil.event.addListener(MistVideo.video,"durationchange",function(){ diff --git a/embed/util.js b/embed/util.js index 3fc5395e..7414b0c3 100644 --- a/embed/util.js +++ b/embed/util.js @@ -33,6 +33,73 @@ var MistUtil = { return (days ? days : "")+str.join(":")+ago; }, + ago: function(date,range){ + //format a date nicely depending on how long ago it was + //if the range param [ms] is specified, use that to choose how to format the date string + + var ago = range ? range : new Date().getTime() - date.getTime(); + var out = ""; + var negative = (ago < 0); + + if (negative) { ago *= -1; } + + if (ago < 1000) { + //less than a second ago + out = "live"; + } + else if (ago < 60e3) { + //less than a minute ago + out = Math.round(ago/1e3)+" sec"; + if (negative) { + out = "in "+out; + } + else { + out += " ago"; + } + + } + else if ((!range && (new Date().toLocaleDateString() == date.toLocaleDateString())) || (range < 86400e3)) { + //today + out = date.toLocaleTimeString(undefined,{ + hour: "numeric", + minute: "2-digit", + second: "2-digit" + }); + } + else if (ago < 518400e3) { + //less than 6 days ago + out = date.toLocaleString(undefined,{ + weekday: "short", + hour: "numeric", + minute: "2-digit", + second: "2-digit" + }); + } + else if ((!range && (new Date().getFullYear() == date.getFullYear())) || (range < 31622400e3)) { + //this year + out = date.toLocaleString(undefined,{ + month: "short", + day: "numeric", + weekday: "short", + hour: "numeric", + minute: "2-digit", + second: "2-digit" + }); + } + else { + //before this year + out = date.toLocaleString(undefined,{ + year: "numeric", + month: "short", + day: "numeric", + hour: "numeric", + minute: "2-digit", + second: "2-digit" + }); + } + + return out; + }, ucFirst: function(string){ return string.charAt(0).toUpperCase()+string.slice(1); }, diff --git a/embed/wrappers/html5.js b/embed/wrappers/html5.js index be89c3bb..7693a368 100644 --- a/embed/wrappers/html5.js +++ b/embed/wrappers/html5.js @@ -195,6 +195,7 @@ p.prototype.build = function (MistVideo,callback) { MistVideo.player.api.setSource(MistUtil.http.url.addParam(MistVideo.source.url,params)); } + MistUtil.event.addListener(video,"progress",function(){ MistVideo.player.api.lastProgress = new Date(); }); @@ -217,9 +218,21 @@ p.prototype.build = function (MistVideo,callback) { }; if (MistVideo.source.type == "html5/video/mp4") { + var otherdurationoverride = overrides.get.duration; + overrides.get.duration = function(){ + return otherdurationoverride.apply(this,arguments) - MistVideo.player.api.liveOffset + MistVideo.info.lastms * 1e-3; + } overrides.get.currentTime = function(){ return this.currentTime - MistVideo.player.api.liveOffset + MistVideo.info.lastms * 1e-3; } + overrides.get.buffered = function(){ + var video = this; + return { + length: video.buffered.length, + start: function(i) { return video.buffered.start(i) - MistVideo.player.api.liveOffset + MistVideo.info.lastms * 1e-3; }, + end: function(i) { return video.buffered.end(i) - MistVideo.player.api.liveOffset + MistVideo.info.lastms * 1e-3; } + } + }; } } else { diff --git a/embed/wrappers/mews.js b/embed/wrappers/mews.js index 14ca364b..227b3868 100644 --- a/embed/wrappers/mews.js +++ b/embed/wrappers/mews.js @@ -1067,7 +1067,7 @@ p.prototype.build = function (MistVideo,callback) { } }); //override duration - var lastduration = 1; + var lastduration = Infinity; Object.defineProperty(this.api,"duration",{ get: function(){ return lastduration; @@ -1079,7 +1079,7 @@ p.prototype.build = function (MistVideo,callback) { }, set: function(value){ var f = function(msg){ - video.playbackRate = msg.data.play_rate; + video.playbackRate = msg.data.play_rate_curr; }; player.ws.addListener("set_speed",f); send({type: "set_speed", play_rate: (value == 1 ? "auto" : value)}); diff --git a/embed/wrappers/videojs.js b/embed/wrappers/videojs.js index 6ec8f0cc..2ef7a479 100644 --- a/embed/wrappers/videojs.js +++ b/embed/wrappers/videojs.js @@ -100,6 +100,14 @@ p.prototype.build = function (MistVideo,callback) { MistVideo.log("Building videojs"); me.videojs = videojs(ele,vjsopts,function(){ MistVideo.log("Videojs initialized"); + + if (MistVideo.info.type == "live") { + //overwrite the stream info's buffer window to the seekable range as indicated by the m3u8 + MistUtil.event.addListener(ele,"progress",function(e){ + var i = MistVideo.player.videojs.seekable().length-1; + MistVideo.info.meta.buffer_window = (Math.max(MistVideo.player.videojs.seekable().end(i),ele.duration) - MistVideo.player.videojs.seekable().start(i))*1e3; + }); + } }); MistUtil.event.addListener(ele,"error",function(e){ @@ -160,6 +168,7 @@ p.prototype.build = function (MistVideo,callback) { }; if (MistVideo.info.type == "live") { + function getLastBuffer(video) { var buffer_end = 0; if (video.buffered.length) { @@ -171,8 +180,7 @@ p.prototype.build = function (MistVideo,callback) { overrides.get.duration = function(){ if (MistVideo.info) { - var duration = (MistVideo.info.lastms + (new Date()).getTime() - MistVideo.info.updated.getTime())*1e-3; - //if (isNaN(duration)) { return 1e9; } + var duration = ele.duration; return duration; } return 0; @@ -186,19 +194,25 @@ p.prototype.build = function (MistVideo,callback) { overrides.set.currentTime = function(value){ var diff = MistVideo.player.api.currentTime - value; var offset = value - MistVideo.player.api.duration; - //MistVideo.player.api.liveOffset = offset; MistVideo.log("Seeking to "+MistUtil.format.time(value)+" ("+Math.round(offset*-10)/10+"s from live)"); - //MistVideo.video.currentTime -= diff; - MistVideo.player.videojs.currentTime(MistVideo.video.currentTime - diff); //seeking backwards does not work if we set it on the video directly + MistVideo.player.videojs.currentTime(MistVideo.video.currentTime - diff); } var lastms = 0; overrides.get.currentTime = function(){ if (MistVideo.info) { lastms = MistVideo.info.lastms*1e-3; } - var time = this.currentTime + lastms - MistVideo.player.api.liveOffset - HLSlatency; + var time = MistVideo.player.videojs ? MistVideo.player.videojs.currentTime() : ele.currentTime; if (isNaN(time)) { return 0; } return time; } + overrides.get.buffered = function(){ + var buffered = MistVideo.player.videojs ? MistVideo.player.videojs.buffered() : ele.buffered; + return { + length: buffered.length, + start: function(i) { return buffered.start(i); }, + end: function(i) { return buffered.end(i); i} + } + }; } } else { diff --git a/embed/wrappers/webrtc.js b/embed/wrappers/webrtc.js index cd679137..b303af60 100644 --- a/embed/wrappers/webrtc.js +++ b/embed/wrappers/webrtc.js @@ -129,6 +129,8 @@ p.prototype.build = function (MistVideo,callback) { duration = d; MistUtil.event.send("durationchange",d,video); } + + MistVideo.info.meta.buffer_window = ev.end - ev.begin; if ((ev.tracks) && (currenttracks != ev.tracks)) { var tracks = MistVideo.info ? MistUtil.tracks.parse(MistVideo.info.meta.tracks) : [];