diff --git a/embed/min/player.js b/embed/min/player.js index c5ea48bd..a26da177 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),s=Math.round(e%1*1e3);e=Math.floor(e-60*a);var o=[];return r&&(r=r+" day"+(r>1?"s":"")+", "),n||r?(o.push(n),o.push(("0"+a).slice(-2))):o.push(a),o.push(("0"+Math.floor(e)).slice(-2)),t.ms&&(o[o.length-1]+="."+("000"+s).slice(-3)),(r||"")+o.join(":")+i},ago:function(e,t){if(isNaN(e.getTime()))return"";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 (WS)";case"whep":return"WebRTC (WHEP)";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<e.length;i++)if(e[i]==t)return i;return-1},is:function(e){return"isArray"in Array?Array.isArray(e):"[object Array]"===Object.prototype.toString.call(e)},multiSort:function(e,t){var i=function(e,t){return isNaN(e)||isNaN(t)?e.localeCompare(t):e>t?1:e<t?-1:0};if(!t.length)return e.sort(i);function r(e,t){function i(e,t,i){if(!(t in e))throw"Invalid sorting rule: "+JSON.stringify([t,i])+'. "'+t+'" is not a key of '+JSON.stringify(e);if("number"==typeof i&&t in e)return e[t]*i;var r=i.indexOf(e[t]);return r>=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 s in t){var o=t[s];if(0!=(a=i(r(o,e),r(o,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 s,o=[];for(var l in i)o.push(l+"="+encodeURIComponent(i[l]));o.length&&(s=o.join("&")),a.send(s)}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("?")},append:function(e,t){var i=document.createElement("a");return i.href=e,"?"==t[0]?""==i.search?i.search=t:i.search+="&"+t.slice(1):"&"==t[0]?""==i.search?i.search="?"+t.slice(1):i.search+=t:i.href+=t,i.href},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 s=3;!function t(){MistUtil.http.get(e,function(t){for(var i in n[e])n[e][i](t);n[e]=t},function(){if(s>0)s--,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 s=1;s<n[a].match(/{/g).length;){var o=e.match(/@@#@@([^}]*})/);e=e.replace(o[0],"@@#@@"),n[a]+=o[1],s++}e=e.replace("@@#@@","@@@@")}for(var a in e=e.replace(/[^@]*?{[^]*?}/g,function(e){var r=e.split("{"),n=r[0].split(","),a="{"+r.slice(1).join("}");for(var s in n){n[s]=n[s].trim();var o="."+t+n[s];i&&(o+=",\n."+t+" "+n[s]),n[s]=o}return"\n"+n+" "+a}),n)e=e.replace(/@@@@/,n[a]);if(!r)return e;r.textContent=e}},empty:function(e){for(;e.lastChild;){if(e.lastChild.lastChild&&this.empty(e.lastChild),"attachedListeners"in e.lastChild)for(var t in e.lastChild.attachedListeners)MistUtil.event.removeListener(e.lastChild.attachedListeners[t]);e.removeChild(e.lastChild)}},event:{send:function(e,t,i){try{return(r=new Event(e,{bubbles:!0,cancelable:!0})).message=t,i.dispatchEvent(r),r}catch(n){try{var r;return(r=document.createEvent("Event")).initEvent(e,!0,!0),r.message=t,i.dispatchEvent(r),r}catch(e){return!1}}return!0},addListener:function(e,t,i,r){e.addEventListener(t,i),r||(r=e),"attachedListeners"in r||(r.attachedListeners=[]);var n={element:e,type:t,callback:i};return r.attachedListeners.push(n),n},removeListener:function(e){e.element.removeEventListener(e.type,e.callback)}},scripts:{list:{},insert:function(e,t,i){var r=this;if(i&&i.errorListeners.push({src:e,onevent:t}),e in this.list)return this.list[e].subscribers.push(t.onerror),void("onload"in t&&(this.list[e].tag.hasLoaded?t.onload():MistUtil.event.addListener(this.list[e].tag,"load",t.onload)));var n=document.createElement("script");n.hasLoaded=!1,n.setAttribute("src",e),n.setAttribute("crossorigin","anonymous"),document.head.appendChild(n),n.onerror=function(e){t.onerror(e)},n.onload=function(e){this.hasLoaded=!0,i.destroyed||t.onload(e)},n.addEventListener("error",function(e){t.onerror(e)});var a=!1;return window.onerror&&(a=window.onerror),window.onerror=function(i,n,s,o,l){if(a&&a.apply(this,arguments),n==e)for(var c in t.onerror(l),r.list[e].subscribers)r.list[e].subscribers[c](l)},this.list[e]={subscribers:[t.onerror],tag:n},n}},tracks:{parse:function(e){var t={};for(var i in e){var r=MistUtil.object.extend({},e[i]);"meta"==r.type&&(r.type=r.codec,r.codec="meta"),r.type in t||(t[r.type]={}),t[r.type]["idx"in r?r.idx:r.trackid]=r;var n={};for(var a in r)switch(a){case"width":n[a]=r.width+"×"+r.height;break;case"bps":if("meta"==r.codec)continue;var s;if(r.bps>0)s=r.bps>131072?Math.round(r.bps/1024/1024*8)+"mbps":Math.round(r.bps/1024*8)+"kbps",n[a]=s;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(.001*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 o in t){var l=!1;for(var i in t[o])if(l){if(MistUtil.object.keys(t[o]).length>1)for(var a in t[o][i].describe)l[a]!=t[o][i].describe[a]&&delete l[a]}else l=MistUtil.object.extend({},t[o][i].describe);for(var i in t[o]){var c={},d={};for(var a in t[o][i].describe)a in l?d[a]=t[o][i].describe[a]:c[a]=t[o][i].describe[a];t[o][i].different=c,t[o][i].same=d;var u=MistUtil.object.values(c);t[o][i].displayName=u.length?u.join(", "):MistUtil.object.values(t[o][i].describe).join(" ")}var p={};for(var i in t[o]){if(t[o][i].displayName in p){var h=1;for(var i in t[o])t[o][i].different.trackid=h+")",t[o][i].displayName="Track "+h+" ("+t[o][i].displayName+")",h++;break}p[t[o][i].displayName]=1}}return t},translateCodec:function(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"mp3";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()}}},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,s=Math.max(0,(t.clientX/i-n)/a);return s=Math.min(s,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 s=1;s<e.y.length;s++){var o=e.y[s]-a;a=e.y[s],e.y[s]=o}var l=[],c={x:{min:e.x[0]-n,max:e.x[0]-n},y:{min:-1*e.y[0],max:-1*e.y[0]}};function d(e,t){if(arguments.length)c.x.min=Math.min(c.x.min,e),c.x.max=Math.max(c.x.max,e),c.y.min=Math.min(c.y.min,-1*t),c.y.max=Math.max(c.y.max,-1*t);else{var i=l[0].split(",");c={x:{min:i[0],max:i[0]},y:{min:i[1],max:i[1]}};for(var r=1;r<l.length;r++){d((i=l[r].split(","))[0],-1*i[1])}}}l.push([e.x[0]-n,-1*e.y[0]].join(","));for(s=1;s<e.y.length;s++)d(e.x[s]-n,-1*e.y[s]),l.push("L "+[e.x[s]-n,-1*e.y[s]].join(","));var u=document.createElementNS(i,"defs");r.appendChild(u);var p=document.createElementNS(i,"linearGradient");function h(){"x"in t&&("min"in t.x&&(c.x.min=t.x.min),"max"in t.x&&(c.x.max=t.x.max),"count"in t.x&&(c.x.min=c.x.max-t.x.count)),"y"in t&&("min"in t.y&&(c.y.min=-1*t.y.max),"max"in t.y&&(c.y.max=-1*t.y.min)),r.setAttributeNS(null,"viewBox",[c.x.min,c.y.min,c.x.max-c.x.min,c.y.max-c.y.min].join(" ")),p.setAttributeNS(null,"x1",0),p.setAttributeNS(null,"x2",0),t.reverseGradient?(p.setAttributeNS(null,"y1",c.y.max),p.setAttributeNS(null,"y2",c.y.min)):(p.setAttributeNS(null,"y1",c.y.min),p.setAttributeNS(null,"y2",c.y.max))}u.appendChild(p),p.setAttributeNS(null,"id",MistUtil.createUnique()),p.setAttributeNS(null,"gradientUnits","userSpaceOnUse"),p.innerHTML+='<stop offset="0" stop-color="green"/>',p.innerHTML+='<stop offset="0.33" stop-color="yellow"/>',p.innerHTML+='<stop offset="0.66" stop-color="orange"/>',p.innerHTML+='<stop offset="1" stop-color="red"/>',h();var m=document.createElementNS(i,"path");return r.appendChild(m),m.setAttributeNS(null,"stroke-width","0.1"),m.setAttributeNS(null,"fill","none"),m.setAttributeNS(null,"stroke","url(#"+p.getAttribute("id")+")"),m.setAttributeNS(null,"d","M"+l.join(" L")),m.addData=function(e){if(!isNaN(e.y)){if(t.differentiate){var i=e.y-a;a=e.y,e.y=i}l.push([e.x-n,-1*e.y].join(",")),t.x&&t.x.count&&l.length>t.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]},sources:{find:function(e,t){e:for(var i in e){for(var r in t)if("protocol"==r){if(e[i].url.slice(0,t.protocol.length)!=t.protocol)continue e}else if(e[i][r]!=t[r])continue e;return e[i]}return!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 s="";s+='<svg viewBox="0 0 '+a.size.width+" "+a.size.height+'"'+("width"in i?' width="'+i.width+'"':"")+("height"in i?' height="'+i.height+'"':"")+' class="mist icon '+t+'">',s+='<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="100%" width="100%">',s+=n,s+="</svg>",s+="</svg>";var o=document.createElement("div");return o.innerHTML=s,o.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 s=MistUtil.css.createStyle(t.css[r],a);n.appendChild(s)}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 o=this.buildStructure(t.children[r]);o&&n.appendChild(o)}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 s=e.skin.css[a];s.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="")},""!=s.textContent&&s.callback(s.textContent),i.appendChild(s)}MistUtil.class.add(i,r);var o=MistUtil.getBrowser();return o&&MistUtil.class.add(i,"browser-"+o),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",classes:["mistvideo-maincontainer"],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"},{type:"subtitles"}]},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:"chromecast",classes:["mistvideo-pointer"]},{type:"loop",classes:["mistvideo-pointer"]},{type:"fullscreen",classes:["mistvideo-pointer"]},{type:"picture-in-picture",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:"chromecast",classes:["mistvideo-pointer"]},{type:"loop",classes:["mistvideo-pointer"]},{type:"fullscreen",classes:["mistvideo-pointer"]},{type:"picture-in-picture",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:'<path d="M6.26004984594 3.0550109625C5.27445051914 3.68940862462 4.67905105702 4.78142391497 4.67968264562 5.95354422781C4.67968264562 5.95354422781 4.70004942312 39.0717540916 4.70004942312 39.0717540916C4.70302341604 40.3033886636 5.36331656075 41.439734231 6.43188211452 42.0521884912C7.50044766829 42.6646427515 8.81469531629 42.6600161659 9.87892235656 42.0400537716C9.87892235656 42.0400537716 38.5612768409 25.4802882606 38.5612768409 25.4802882606C39.6181165777 24.8606067582 40.2663250096 23.7262617523 40.2636734301 22.5011460995C40.2610218505 21.2760304467 39.6079092743 20.1445019555 38.5483970356 19.5294009803C38.5483970356 19.5294009803 9.84567577375 2.9709566275 9.84567577375 2.9709566275C8.72898008118 2.32550764609 7.34527425735 2.35794451351 6.26004984594 3.0550109625C6.26004984594 3.0550109625 6.26004984594 3.0550109625 6.26004984594 3.0550109625" class="fill" />'},largeplay:{size:45,svg:'<path d="M6.26004984594 3.0550109625C5.27445051914 3.68940862462 4.67905105702 4.78142391497 4.67968264562 5.95354422781C4.67968264562 5.95354422781 4.70004942312 39.0717540916 4.70004942312 39.0717540916C4.70302341604 40.3033886636 5.36331656075 41.439734231 6.43188211452 42.0521884912C7.50044766829 42.6646427515 8.81469531629 42.6600161659 9.87892235656 42.0400537716C9.87892235656 42.0400537716 38.5612768409 25.4802882606 38.5612768409 25.4802882606C39.6181165777 24.8606067582 40.2663250096 23.7262617523 40.2636734301 22.5011460995C40.2610218505 21.2760304467 39.6079092743 20.1445019555 38.5483970356 19.5294009803C38.5483970356 19.5294009803 9.84567577375 2.9709566275 9.84567577375 2.9709566275C8.72898008118 2.32550764609 7.34527425735 2.35794451351 6.26004984594 3.0550109625C6.26004984594 3.0550109625 6.26004984594 3.0550109625 6.26004984594 3.0550109625" class="stroke" />'},pause:{size:45,svg:'<g><path d="m 7.5,38.531275 a 4.0011916,4.0011916 0 0 0 3.749999,3.96873 l 2.2812501,0 a 4.0011916,4.0011916 0 0 0 3.96875,-3.75003 l 0,-32.28123 a 4.0011916,4.0011916 0 0 0 -3.75,-3.96875 l -2.2812501,0 a 4.0011916,4.0011916 0 0 0 -3.968749,3.75 l 0,32.28128 z" class="fill" /><path d="m 27.5,38.531275 a 4.0011916,4.0011916 0 0 0 3.75,3.9687 l 2.28125,0 a 4.0011916,4.0011916 0 0 0 3.96875,-3.75 l 0,-32.28126 a 4.0011916,4.0011916 0 0 0 -3.75,-3.96875 l -2.28125,0 a 4.0011916,4.0011916 0 0 0 -3.96875,3.75 l 0,32.28131 z" class="fill" /></g>'},speaker:{size:45,svg:'<path d="m 32.737813,5.2037363 c -1.832447,-1.10124 -4.200687,-0.8622 -5.771871,0.77112 0,0 -7.738819,8.0443797 -7.738819,8.0443797 0,0 -3.417976,0 -3.417976,0 -1.953668,0 -3.54696,1.65618 -3.54696,3.68694 0,0 0,9.58644 0,9.58644 0,2.03094 1.593292,3.68712 3.54696,3.68712 0,0 3.417976,0 3.417976,0 0,0 7.738819,8.04474 7.738819,8.04474 1.572104,1.63404 3.938942,1.8747 5.771871,0.77076 0,0 0,-34.5914997 0,-34.5914997 z" class="stroke semiFill toggle" />'},volume:{size:{width:100,height:45},svg:function(){var e=MistUtil.createUnique();return'<defs><mask id="'+e+'"><path d="m6.202 33.254 86.029-28.394c2.6348-0.86966 4.7433 0.77359 4.7433 3.3092v28.617c0 1.9819-1.6122 3.5773-3.6147 3.5773h-86.75c-4.3249 0-5.0634-5.5287-0.40598-7.1098" fill="#fff" /></mask></defs><rect mask="url(#'+e+')" class="slider horizontal semiFill" width="100%" height="100%" /><path d="m6.202 33.254 86.029-28.394c2.6348-0.86966 4.7433 0.77359 4.7433 3.3092v28.617c0 1.9819-1.6122 3.5773-3.6147 3.5773h-86.75c-4.3249 0-5.0634-5.5287-0.40598-7.1098" class="stroke" /><rect x="0" y="0" width="100%" height="100%" fill="rgba(0,0,0,0.001)"/>'}},muted:{size:45,svg:'<g class="stroke" stroke-linecap="round" vector-effect="none" stroke-width="2"><path d="m25.587 5.2036c-1.8324-1.1012-4.2007-0.8622-5.7719 0.77112 0 0-7.7388 8.0444-7.7388 8.0444h-3.418c-1.9537 0-3.547 1.6562-3.547 3.6869v9.5864c0 2.0309 1.5933 3.6871 3.547 3.6871h3.418s7.7388 8.0447 7.7388 8.0447c1.5721 1.634 3.9389 1.8747 5.7719 0.77076v-34.591 z" /><path d="m30.032 27.86 9.8517-9.8517"/><path d="m30.032 18.008 9.8517 9.8517"/></g>'},fullscreen:{size:45,svg:'<path d="m2.5 10.928v8.5898l4.9023-2.8008 9.6172 5.7832-9.6172 5.7832-4.9023-2.8008v8.5898h15.031l-4.9004-2.8008 9.8691-5.6387 9.8691 5.6387-4.9004 2.8008h15.031v-8.5898l-4.9023 2.8008-9.6172-5.7832 9.6172-5.7832 4.9023 2.8008v-8.5898h-15.033l4.9023 2.8008-9.8691 5.6387-9.8691-5.6387 4.9023-2.8008z" class="fill">'},pip:{size:45,svg:'<rect x="5.25" y="12.25" width="34.5" height="19.5" ry="2" class="stroke semiFill toggle"/><rect x="20" y="21" width="17" height="8" rx="2" ry="2" class="semiFill toggle stroke"/>'},loop:{size:45,svg:'<path d="M 21.279283,3.749797 A 18.750203,18.750203 0 0 0 8.0304417,9.2511582 L 12.740779,13.961496 A 12.083464,12.083464 0 0 1 21.279283,10.416536 12.083464,12.083464 0 0 1 33.362748,22.5 12.083464,12.083464 0 0 1 21.279283,34.583464 12.083464,12.083464 0 0 1 12.740779,31.038504 l 3.063185,-3.063185 H 4.9705135 V 38.80877 L 8.0304417,35.748842 A 18.750203,18.750203 0 0 0 21.279283,41.250203 18.750203,18.750203 0 0 0 40.029486,22.5 18.750203,18.750203 0 0 0 21.279283,3.749797 Z" class="stroke semiFill toggle" />'},settings:{size:45,svg:'<path d="m24.139 3.834-1.4785 4.3223c-1.1018 0.0088-2.2727 0.13204-3.2031 0.33594l-2.3281-3.9473c-1.4974 0.45304-2.9327 1.091-4.2715 1.9004l1.3457 4.3672c-0.87808 0.62225-1.685 1.3403-2.4023 2.1426l-4.1953-1.8223c-0.9476 1.2456-1.7358 2.6055-2.3457 4.0469l3.6523 2.7383c-0.34895 1.0215-0.58154 2.0787-0.69336 3.1523l-4.4531 0.98828c-0.00716 0.14696-0.011931 0.29432-0.015625 0.44141 0.00628 1.4179 0.17336 2.8307 0.49805 4.2109l4.5703 0.070312c0.32171 1.0271 0.75826 2.0138 1.3008 2.9434l-3.0391 3.4355c0.89502 1.2828 1.9464 2.4492 3.1309 3.4707l3.7363-2.6289c0.86307 0.64582 1.7958 1.192 2.7812 1.6289l-0.43555 4.541c1.4754 0.52082 3.0099 0.85458 4.5684 0.99414l1.4766-4.3223c0.05369 3e-3 0.10838 0.005313 0.16211 0.007812 1.024-0.0061 2.0436-0.12048 3.043-0.34375l2.3281 3.9473c1.4974-0.45304 2.9327-1.091 4.2715-1.9004l-1.3457-4.3672c0.87808-0.62225 1.685-1.3403 2.4023-2.1426l4.1953 1.8223c0.9476-1.2456 1.7358-2.6055 2.3457-4.0469l-3.6523-2.7383c0.34895-1.0215 0.58154-2.0787 0.69336-3.1523l4.4531-0.98828c0.0072-0.14698 0.011925-0.29432 0.015625-0.44141-0.0062-1.4179-0.17336-2.8307-0.49805-4.2109l-4.5703-0.070312c-0.32171-1.0271-0.75826-2.0138-1.3008-2.9434l3.0391-3.4355c-0.89502-1.2828-1.9464-2.4492-3.1309-3.4707l-3.7363 2.6289c-0.86307-0.64582-1.7958-1.192-2.7812-1.6289l0.43555-4.541c-1.4754-0.52082-3.0099-0.85457-4.5684-0.99414zm-1.6387 7.8789a10.786 10.786 0 0 1 10.787 10.787 10.786 10.786 0 0 1-10.787 10.787 10.786 10.786 0 0 1-10.787-10.787 10.786 10.786 0 0 1 10.787-10.787z" class="fill"/>'},loading:{size:100,svg:'<path d="m49.998 8.7797e-4c-0.060547 0.0018431-0.12109 0.0037961-0.18164 0.0058593-0.1251 0.0015881-0.25012 0.0061465-0.375 0.013672h-0.001954c-27.388 0.30599-49.432 22.59-49.439 49.98 0.020074 2.6488 0.25061 5.292 0.68945 7.904 3.8792-24.231 24.77-42.065 49.311-42.096v-0.0058582h0.001954c4.3638 3.0803e-4 7.9013-3.5366 7.9021-7.9002 1.474e-4 -2.0958-0.83235-4.106-2.3144-5.5879-1.482-1.482-3.492-2.3145-5.5879-2.3144-6.5007e-4 -7.9369e-8 -0.0013001-7.9369e-8 -0.001954 0" class="semiFill spin"></path>'},timeout:{size:25,svg:function(e){e&&e.delay||(e={delay:10});var t=e.delay,i=MistUtil.createUnique();return'<defs><mask id="'+i+'"><rect x="0" y="0" width="25" height="25" fill="#fff"/><rect x="-5" y="-5" width="17.5" height="35" fill="#000" transform="rotate(180,12.5,12.5)"><animateTransform attributeName="transform" type="rotate" from="0,12.5,12.5" to="180,12.5,12.5" begin="DOMNodeInsertedIntoDocument" dur="'+t/2+'s" repeatCount="1"/></rect><rect x="0" y="0" width="12.5" height="25" fill="#fff"/><rect x="-5" y="-5" width="17.5" height="35" fill="#000" transform="rotate(360,12.5,12.5)"><animate attributeType="CSS" attributeName="opacity" from="0" to="1" begin="DOMNodeInsertedIntoDocument" dur="'+t+'s" calcMode="discrete" repeatCount="1" /><animateTransform attributeName="transform" type="rotate" from="180,12.5,12.5" to="360,12.5,12.5" begin="DOMNodeInsertedIntoDocument+'+t/2+'s" dur="'+t/2+'s" repeatCount="1"/></rect><circle cx="12.5" cy="12.5" r="8" fill="#000"/></mask></defs><circle cx="12.5" cy="12.5" r="12.5" class="fill" mask="url(#'+i+')"/>'}},popout:{size:45,svg:'<path d="m24.721 11.075c-12.96 0.049575-32.113 15.432-10.336 28.834-7.6763-7.9825-2.4795-21.824 10.336-22.19v5.5368l15.276-8.862-15.276-8.86v5.5419z" class="stroke fill"/>'},switchvideo:{size:45,svg:'<path d="m8.4925 18.786c-3.9578 1.504-6.4432 3.632-6.4434 5.9982 2.183e-4 4.1354 7.5562 7.5509 17.399 8.1467v4.7777l10.718-6.2573-10.718-6.2529v4.5717c-6.9764-0.4712-12.229-2.5226-12.227-4.9859 6.693e-4 -0.72127 0.45868-1.4051 1.2714-2.0267zm28.015 0v3.9715c0.81164 0.62126 1.2685 1.3059 1.2692 2.0267-0.0014 1.4217-1.791 2.75-4.8021 3.6968-2.0515 0.82484-0.93693 3.7696 1.2249 2.9659 5.3088-1.8593 8.7426-3.8616 8.7514-6.6627-1.26e-4 -2.3662-2.4856-4.4942-6.4434-5.9982z" class="fill"/><rect rect x="10.166" y="7.7911" width="24.668" height="15.432" class="stroke"/>'}}},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.player.api.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"),s=0;s<a.length;s++)MistUtil.event.addListener(a[s],"click",function(e){e.stopPropagation()});MistUtil.event.addListener(t.video,"play",function(){e.player.api.paused&&e.player.api.play()},i.target),MistUtil.event.addListener(t.video,"pause",function(t){e.player.api.paused||e.player.api.pause()},i.target),MistUtil.event.addListener(t.video,"seeking",function(){e.player.api.currentTime=this.currentTime},i.target),MistUtil.event.addListener(t.video,"timeupdate",function(){if(!e.player.api.pausedesync){var t=this.currentTime-e.player.api.currentTime,i=Math.abs(t);if(i>30)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;i<e.secondary.length;i++){var n=r(e.secondary[i].MistVideo,t);if(n)return n}return!1}var n=r(t,t.options.target),a=r(t,i.options.target),s=!n.paused,o=document.createElement("div");if(a.parentElement.insertBefore(o,a),n.parentElement.insertBefore(a,n),o.parentElement.insertBefore(n,o),o.parentElement.removeChild(o),s)try{n.play(),a.play()}catch(e){}var l={width:n.style.width,height:n.style.height,currentTarget:n.currentTarget};n.currentTarget=a.currentTarget,a.currentTarget=l.currentTarget,t.player.resizeAll()}),t},controls:function(){if(this.options.controls&&"stock"!=this.options.controls){MistUtil.class.add(this.container,"hasControls");var e=this.UI.buildStructure(this.skin.structure.controls);return MistUtil.isTouchDevice()&&this.size&&this.size.width>300&&(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"},s=function(e){window.removeEventListener("mousemove",a),window.removeEventListener("click",s),MistUtil.event.addListener(r,"click",o)},o=function(e){e.stopPropagation(),r.removeEventListener("click",o),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",s,t)};return MistUtil.event.addListener(r,"click",o),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].firstms<n&&(n=.001*r.info.meta.tracks[a].firstms);function s(){return r.player.api.duration<n?0:n}function o(){var e=r.info.meta.buffer_window;return void 0===e&&(e=r.player&&r.player.api&&r.player.api.buffered&&r.player.api.buffered.length?1e3*(r.player.api.duration-r.player.api.buffered.start(0)):6e4),.001*e}n==1/0&&(n=0),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=o();t=(e-r.player.api.duration+i)/i}else t=(e-s())/(r.player.api.duration-s());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;i<t.length;i++)this.removeChild(t[i]);if(e)for(i=0;i<e.length;i++)this.appendChild(this.buildBuffer(e.start(i),e.end(i)))};var l=0,c=!1;MistUtil.event.addListener(i,"progress",function(){!function e(){(new Date).getTime()-l>1e3?(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&&!f?(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=isNaN(e)?MistUtil.getPos(this,e):e;return"live"==r.info.type?(t-1)*o()+r.player.api.duration:!!isFinite(r.player.api.duration)&&t*(r.player.api.duration-s())+s()},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(){f||(p.style.opacity=0)}),t.moveTooltip=function(e){var t=this.getPos(e);if(!1!==t){p.setDisplay(t),p.style.opacity=1;var i=MistUtil.getPos(this,e),r={bottom:20};i>.5?(r.right=100*(1-i)+"%",p.triangle.setMode("bottom","right")):(r.left=100*i+"%",p.triangle.setMode("bottom","left")),p.setPos(r)}else p.style.opacity=0};var h=document.createElement("span");h.setAttribute("class","mistvideo-realtime");var m=document.createTextNode("");h.appendChild(m),p.setDisplay=function(e){if(r.options.useDateTime&&r.info&&r.info.unixoffset){var i=t.getPos(1)-t.getPos(0),n=.001*(new Date).getTime()-(.001*r.info.unixoffset+t.getPos(1)),a=Math.max(i,n),s="";if("live"==r.info.type)if(a<60)s=MistUtil.format.ago(new Date(r.info.unixoffset+1e3*e));else{var o=.001*(new Date).getTime()-(.001*r.info.unixoffset+e);o<172800&&(s+=" - "+MistUtil.format.time(o))}else s+=MistUtil.format.time(e);if(a>=60){m.nodeValue=" at "+MistUtil.format.ago(new Date(r.info.unixoffset+1e3*e),1e3*a);var l=document.createDocumentFragment();l.appendChild(document.createTextNode(s)),l.appendChild(h),p.setHtml(l)}else m.nodeValue="",p.setText(s)}else p.setText(MistUtil.format.time(e))},MistUtil.event.addListener(e,"mousemove",function(e){t.moveTooltip(e)});var f=!1;return MistUtil.event.addListener(e,"mousedown",function(i){if(1==i.which){f=!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&&(f=!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(){if(!(this.player.api&&"muted"in this.player.api))return!1;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 n.player.api.volume&&!n.player.api.muted||MistUtil.class.add(r,"off"),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){if(!(this.player.api&&"volume"in this.player.api))return!1;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 s=this;a.mode="mode"in e?e.mode:"vertical","vertical"==a.mode&&(a.style.transform="rotate(90deg)"),a.margin={start:.15,end:.1};var o=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;i<t.length;i++)t[i].setAttribute("vertical"==a.mode?"height":"width",e+"%")},MistUtil.event.addListener(o,"volumechange",function(){a.set(s.player.api.muted?0:100*s.player.api.volume)},a),a.set(s.player.api.muted?0:100*s.player.api.volume);var l=MistUtil.event.addListener(o,"loadedmetadata",function(){"localStorage"in window&&null!=localStorage&&"mistVolume"in localStorage&&(s.player.api.volume=localStorage.mistVolume),MistUtil.event.removeListener(l)});a.addPadding=function(e){return e*(1-(this.margin.start+this.margin.end))+this.margin.start},a.removePadding=function(e){var t=(e-this.margin.start)/(1-(this.margin.start+this.margin.end));return t=Math.max(t,0),t=Math.min(t,1)},a.getPos=function(e){return this.addPadding(MistUtil.getPos(this,e))},a.setVolume=function(e){s.player.api.muted=!1;var t=this.removePadding(MistUtil.getPos(this,e));t=1-Math.pow(1-t,.5),s.player.api.volume=t;try{localStorage.mistVolume=s.player.api.volume}catch(e){}},MistUtil.event.addListener(a,"mouseup",function(e){1==e.which&&a.setVolume(e)});var c=s.UI.buildStructure({type:"tooltip"});c.style.opacity=0,c.triangle.setMode("bottom","right"),n.style.position="relative",n.appendChild(c),MistUtil.event.addListener(a,"mouseover",function(){c.style.opacity=1}),MistUtil.event.addListener(a,"mouseout",function(){d||(c.style.opacity=0)}),a.moveTooltip=function(e){c.style.opacity=1;var t=MistUtil.getPos(this,e);c.setText(Math.round(100*this.removePadding(t))+"%"),c.setPos({bottom:46,right:100*(1-t)+"%"})},MistUtil.event.addListener(a,"mousemove",function(e){a.moveTooltip(e)});var d=!1;return MistUtil.event.addListener(a,"mousedown",function(e){if(1==e.which){d=!0,a.setVolume(e),c.style.opacity=1;var t=MistUtil.event.addListener(document,"mousemove",function(e){a.setVolume(e),a.moveTooltip(e)},a),i=MistUtil.event.addListener(document,"mouseup",function(e){1==e.which&&(d=!1,MistUtil.event.removeListener(t),MistUtil.event.removeListener(i),c.style.opacity=0,(!e.path||MistUtil.array.indexOf(e.path,a)<0)&&a.setVolume(e))},a)}}),n},currentTime:function(){var e=this,t=document.createElement("div"),i=document.createTextNode(""),r=document.createElement("span");r.setAttribute("class","mistvideo-realtime"),t.appendChild(i),t.appendChild(r);var n=document.createTextNode("");r.appendChild(n);e.player.api;var a=MistUtil.format.time;return t.set=function(){var r,s=e.player.api.currentTime;if(e.options.useDateTime&&e.info&&e.info.unixoffset){var o=new Date(e.info.unixoffset+1e3*s),l=new Date-o;n.nodeValue="","live"==e.info.type?r=l<6e4?MistUtil.format.ago(o):l<432e5?"- "+MistUtil.format.time(.001*l):MistUtil.format.ago(o):(r=a(s),l>6e4&&e.size.width>=600&&(n.nodeValue=" (at "+MistUtil.format.ago(o)+")")),t.setAttribute("title",MistUtil.format.ago(o,3456e7))}else r=a(s),t.setAttribute("title",r);i.nodeValue=r},t.set(),MistUtil.event.addListener(e.video,"timeupdate",function(){t.set()},t),MistUtil.event.addListener(e.video,"seeking",function(){t.set()},t),t},totalTime:function(){var e=this,t=document.createElement("div"),i=document.createTextNode("");t.appendChild(i);this.player.api;return"live"==e.info.type?(i.nodeValue="live",t.className="live"):(t.set=function(r){if(!isNaN(r)&&isFinite(r))if(this.style.display="",e.options.useDateTime&&e.info&&"live"==e.info.type&&e.info.unixoffset){var n=new Date(1e3*r+e.info.unixoffset);i.nodeValue=MistUtil.format.ago(n),t.setAttribute("title",MistUtil.format.ago(n,3456e7))}else i.nodeValue=MistUtil.format.time(r),t.setAttribute("title",i.nodeValue);else this.style.display="none"},MistUtil.event.addListener(e.video,"durationchange",function(){var i=e.player.api.duration;t.set(i)},t)),t},playername:function(){if(this.playerName&&this.playerName in mistplayers){var e=document.createElement("span");return e.appendChild(document.createTextNode(mistplayers[this.playerName].name)),e}},mimetype:function(){if(this.source){var e=document.createElement("a");return e.href=this.source.url,e.target="_blank",e.title=e.href+" ("+this.source.type+")",e.appendChild(document.createTextNode(MistUtil.format.mime2human(this.source.type))),e}},logo:function(e){if("element"in e)return e.element;if("src"in e){var t=document.createElement("img");return t.src=e.src,t}},settings:function(){var e=this,t=this.skin.icons.build("settings"),i=void 0!==document.ontouchstart;return MistUtil.event.addListener(t,"click",function(){e.container.hasAttribute("data-show-submenu")?(i&&e.container.setAttribute("data-hide-submenu",""),e.container.removeAttribute("data-show-submenu")):(e.container.setAttribute("data-show-submenu",""),e.container.removeAttribute("data-hide-submenu"))}),t},loop:function(){if("loop"in this.player.api&&"live"!=this.info.type){var e=this,t=this.skin.icons.build("loop");this.video;return t.set=function(){e.player.api.loop?MistUtil.class.remove(this,"off"):MistUtil.class.add(this,"off")},MistUtil.event.addListener(t,"click",function(t){e.player.api.loop=!e.player.api.loop,this.set()}),t.set(),t}},fullscreen:function(){if("setSize"in this.player&&this.info.hasVideo&&"audio"!=this.source.type.split("/")[1]){var e=this,t=["requestFullscreen","webkitRequestFullscreen","mozRequestFullScreen","msRequestFullscreen","webkitEnterFullscreen"],i=[function(){return e.container},function(){return e.video}],r=!1;e:for(var n in i)for(var a in t)if(t[a]in i[n]()){(r={}).request=function(){return r.fullscreenableElement()[t[a]]()};var s=["exitFullscreen","webkitCancelFullScreen","mozCancelFullScreen","msExitFullscreen","webkitExitFullscreen"],o=["fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","webkitFullscreenElement"];r.cancel=function(){return document[s[a]]()},r.element=function(){return document[o[a]]},r.event=["fullscreenchange","webkitfullscreenchange","mozfullscreenchange","MSFullscreenChange","webkitfullscreenchange"][a],r.fullscreenableElement=i[n];break e}if(!r){var l=function(e){switch(e.key){case"Escape":r.cancel()}};(r={event:"fakefullscreenchange",fullscreenableElement:function(){return e.container}}).request=function(){return r.element=function(){return e.container},MistUtil.event.send(r.event,null,document),document.addEventListener("keydown",l),!0},r.cancel=function(){return r.element=function(){return null},document.removeEventListener("keydown",l),MistUtil.event.send(r.event,null,document),!0},r.element=function(){return null}}var c=this.skin.icons.build("fullscreen");return MistUtil.event.addListener(c,"click",d),MistUtil.event.addListener(e.video,"dblclick",d),MistUtil.event.addListener(document,r.event,function(){r.element()==r.fullscreenableElement()?e.container.setAttribute("data-fullscreen",""):e.container.hasAttribute("data-fullscreen")&&e.container.removeAttribute("data-fullscreen"),e.player.resizeAll()},c),c}function d(){r.element()?r.cancel():r.request()}},"picture-in-picture":function(){if("setSize"in this.player&&this.info.hasVideo&&"audio"!=this.source.type.split("/")[1]&&document.pictureInPictureEnabled){var e=this;if("requestPictureInPicture"in e.video){var t=this.skin.icons.build("pip");return t.set=function(){document.pictureInPictureElement?MistUtil.class.remove(this,"off"):MistUtil.class.add(this,"off")},MistUtil.event.addListener(t,"click",function(){var i;(i=document.pictureInPictureElement?document.exitPictureInPicture():e.video.requestPictureInPicture())?i.then(function(){t.set()}):t.set()}),t.set(),t}}},tracks:function(){if(this.info&&this.video){var e=this,t=document.createElement("table");return i(this.info.meta.tracks),MistUtil.event.addListener(e.video,"metaUpdate_tracks",function(e){i(e.message.meta.tracks)},t),t}function i(i){MistUtil.empty(t),i=MistUtil.tracks.parse(i);var r={},n={};function a(t,i){if(i?e.log("User selected "+t+" track with id "+i):(e.log("User selected automatic track selection for "+t),MistUtil.event.send("trackSetToAuto",t,e.video)),e.options.setTracks||(e.options.setTracks={}),e.options.setTracks[t]=i,!0===i&&r[t]&&MistUtil.event.send("change",null,r[t]),"setTrack"in e.player.api)return e.player.api.setTrack(t,i);var n={};for(var a in r)"subtitle"!=a&&""!=r[a].value&&(n[a]=r[a].value);return""!=i&&(n[t]=i),"setTracks"in e.player.api?e.player.api.setTracks(n):"setSource"in e.player.api?e.player.api.setSource(MistUtil.http.url.addParam(e.source.url,n)):void 0}var s=MistUtil.object.keys(i,function(e,t){function i(e){switch(e){case"audio":return"aaaaaaa";case"video":return"aaaaaab";default:return e}}return i(e)>i(t)?1:i(e)<i(t)?-1:0});for(var o in s){var l=s[o],c=i[l];if(!(MistUtil.array.indexOf(["video","audio","subtitle"],l)<=-1)){if("subtitle"==l){if(!("player"in e&&"api"in e.player&&("setWSSubtitle"in e.player.api||"setSubtitle"in e.player.api))){e.log("Subtitle selection was disabled as this player does not support it.");continue}var d="html5/text/vtt";"setWSSubtitle"in e.player.api&&(d="html5/text/javascript");var u=!1;for(var p in e.info.source){var h=e.info.source[p];if(h.type==d&&MistUtil.http.url.split(h.url).protocol==MistUtil.http.url.split(e.source.url).protocol.replace(/^ws/,"http")){u=h.url.replace(/.srt$/,".vtt");break}}if(!u){e.log("Subtitle selection was disabled as a source could not be found.");continue}c[""]={trackid:"",different:{none:"None"}}}var m=document.createElement("tr");if(m.title="The current "+l+" track",t.appendChild(m),"decodingIssues"in e.skin.blueprints){var f=document.createElement("td");if(m.appendChild(f),"subtitle"!=l){var v=document.createElement("input");v.setAttribute("type","checkbox"),v.setAttribute("checked",""),v.setAttribute("title","Whether or not to play "+l),v.trackType=l,f.appendChild(v),n[l]=v,e.options.setTracks&&e.options.setTracks[l]&&("none"==e.options.setTracks[l]?v.checked=!1:v.checked=!0),MistUtil.event.addListener(v,"change",function(){var e=0;for(var t in n)n[t].checked&&e++;if(0==e)for(var t in n)if(t!=this.trackType&&!n[t].checked){n[t].checked=!0,a(t,!0);break}var i="none";i=this.checked?this.trackType in r?r[this.trackType].value:"auto":"none",a(this.trackType,this.checked?i:"none")}),MistUtil.event.addListener(e.video,"playerUpdate_trackChanged",function(e){e.message.type==l&&("none"==e.message.value?this.checked=!1:this.checked=!0)},b)}}var y=document.createElement("td");m.appendChild(y),y.appendChild(document.createTextNode(MistUtil.format.ucFirst(l)+":"));f=document.createElement("td");m.appendChild(f);var g=MistUtil.object.keys(c);if(g.length>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,f.appendChild(b),"subtitle"!=l){var k=document.createElement("option");b.appendChild(k),k.value="",k.appendChild(document.createTextNode("Automatic"))}var M=S(c[MistUtil.object.keys(c)[0]].same);if(M.length)(x=document.createElement("span")).className="mistvideo-description",f.appendChild(x),f.appendChild(document.createTextNode(M.join(" ")));function w(e){return""==e?-1:Number(e)}var U=MistUtil.object.keys(c,function(e,t){return w(e)-w(t)});for(var p in U){var C=c[U[p]];k=document.createElement("option");b.appendChild(k),k.value="idx"in C?C.idx:C.trackid,MistUtil.object.keys(C.different).length?k.appendChild(document.createTextNode(S(C.different).join(" "))):k.appendChild(document.createTextNode("Track "+(Number(p)+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("setWSSubtitle"in e.player.api)e.player.api.setWSSubtitle(""==this.value?void 0:this.value);else if(""!=this.value){var t=MistUtil.object.extend({},c[this.value]);t.label=S(t.describe).join(" "),t.src=MistUtil.http.url.addParam(u,{track:this.value}),e.player.api.setSubtitle(t)}else e.player.api.setSubtitle()}),"localStorage"in window&&null!=localStorage&&"mistSubtitleLanguage"in localStorage)for(var p in c)if(c[p].lang==localStorage.mistSubtitleLanguage){b.value=p;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 x;(x=document.createElement("span")).className="mistvideo-description",f.appendChild(x),x.appendChild(document.createTextNode(S(c[g[0]].same).join(" ")))}}function S(e){var t={trackid:0,language:1,width:2,bps:3,fpks:4,channels:5,codec:6,rate:7};return MistUtil.object.values(e,function(e,i,r,n){return t[e]>t[i]?1:t[e]<t[i]?-1:0})}}}},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 s in a)MistUtil.event.addListener(e.video,a[s],function(t){e.player.api&&!e.player.api.paused&&"container"in e&&r(t)},t);a=["seeked","playing","canplay","paused","ended"];for(var s in a)MistUtil.event.addListener(e.video,a[s],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 "+(e.casting?"chromecast":"player")+" has encountered a problem"))}var s=document.createElement("p");if(n.appendChild(s),n.update=function(e){MistUtil.empty(s),s.innerHTML=e},t){e.info.on_error&&(t=e.info.on_error.replace(/\<error>/,t)),n.update(t);var o=document.createElement("p");if(o.className="details mistvideo-description",n.appendChild(o),i)o.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]))}}o.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(s,o){o||(o={softReload:!!(e.player&&e.player.api&&e.player.api.load),reload:!0,nextCombo:!!e.info,polling:!1,passive:!1});var l=o.type?o.type:s;if(!(l in a)){if(!0===o.reload&&(e.options.reloadDelay&&!isNaN(Number(e.options.reloadDelay))?o.reload=Number(e.options.reloadDelay):o.reload=10),o.passive){if(!0===r)return;if(r)return i.update(s),void(n=(new Date).getTime());t.setAttribute("data-passive","")}else t.removeAttribute("data-passive");var c;r&&t.clear(),r=!o.passive||"passive",n=(new Date).getTime(),e.casting||(c=this.log(s,"error"));var d=t.message(s,!1,o);i=d;var u=document.createElement("div");if(u.className="mistvideo-buttoncontainer",d.appendChild(u),MistUtil.empty(u),e.casting&&!o.passive){var p={type:"button",label:"Stop casting",onclick:function(){e.detachFromCast()}};isNaN(o.softReload+"")||(p.delay=o.softReload),u.appendChild(e.UI.buildStructure(p))}if(o.softReload&&!e.casting){p={type:"button",label:"Reload video",onclick:function(){e.player.api.load()}};isNaN(o.softReload+"")||(p.delay=o.softReload),u.appendChild(e.UI.buildStructure(p))}if(o.reload){p={type:"button",label:"Reload player",onclick:function(){e.reload("Reloading because reload button was clicked.")}};isNaN(o.reload+"")||(p.delay=o.reload),u.appendChild(e.UI.buildStructure(p))}if(o.nextCombo){p={type:"button",label:"Next source",onclick:function(){e.nextCombo()}};isNaN(o.nextCombo+"")||(p.delay=o.nextCombo),u.appendChild(e.UI.buildStructure(p))}if(o.ignore){p={type:"button",label:"Ignore",onclick:function(){this.clearError(),a[l]=!0}};isNaN(o.ignore+"")||(p.delay=o.ignore),u.appendChild(e.UI.buildStructure(p))}o.polling&&u.appendChild(e.UI.buildStructure({type:"polling"})),MistUtil.class.add(t,"show"),"container"in e&&e.container.removeAttribute("data-loading"),c&&c.defaultPrevented&&(e.log("Error event was defaultPrevented, not showing."),t.clear())}},t.clear=function(){for(var i=t.querySelectorAll("svg.icon.timeout"),n=0;n<i.length;n++)e.timers.stop(i[n].timeout);MistUtil.empty(t),MistUtil.class.remove(t,"show"),r=!1},this.clearError=t.clear,"video"in e){var s=["timeupdate","playing","canplay"];for(var o in s)MistUtil.event.addListener(e.video,s[o],function(i){if(r){if("timeupdate"==i.type){if(0==e.player.api.currentTime)return;if((new Date).getTime()-n<2e3)return}e.log("Removing error window because of "+i.type+" event"),t.clear()}},t)}return t},tooltip:function(){var e=document.createElement("div"),t="text",i=document.createTextNode("");e.appendChild(i),e.setText=function(n){i.nodeValue=n,"text"!=t&&(e.removeChild(r),e.appendChild(i),t="text")};var r=document.createElement("div");r.empty=function(){r.innerText="";for(var e=r.children.length-1;e>=0;e--)r.removeChild(r.children[e])},e.setHtml=function(n){r.empty(),r.appendChild(n),"html"!=t&&(e.removeChild(i),e.appendChild(r),t="html")};var n=document.createElement("div");return e.triangle=n,n.className="triangle",e.appendChild(n),n.setMode=function(e,t){e||(e="bottom"),t||(t="left");var i=["bottom","top","right","left"];for(var r in i){this.style[i[r]]="";var n=MistUtil.format.ucFirst(i[r]);this.style["border"+n]="",this.style["border"+n+"Color"]=""}var a={top:"bottom",bottom:"top",left:"right",right:"left"};this.style[e]="-10px",this.style["border"+MistUtil.format.ucFirst(a[e])]="none",this.style["border"+MistUtil.format.ucFirst(e)+"Color"]="transparent",this.style[t]=0,this.style["border"+MistUtil.format.ucFirst(a[t])]="none"},e.setPos=function(e){var t={left:"auto",right:"auto",top:"auto",bottom:"auto"};for(var i in MistUtil.object.extend(t,e),t)isNaN(t[i])||(t[i]+="px"),this.style[i]=t[i]},e},button:function(e){var t=document.createElement("button"),i=this;if(e.onclick&&(MistUtil.event.addListener(t,"click",function(){e.onclick.call(i,arguments)}),e.delay)){var r=this.UI.buildStructure({type:"timeout",delay:e.delay,function:e.onclick});r&&t.appendChild(r)}return t.appendChild(document.createTextNode(e.label)),t},videobackground:function(e){e||(e={}),e.delay||(e.delay=5);for(var t=document.createElement("div"),i=this,r=[],n=0;n<2;n++){var a=document.createElement("canvas");a._context=a.getContext("2d"),t.appendChild(a),r.push(a)}var s=0,o=!1;return MistUtil.event.addListener(i.video,"playing",function(){o||(!function n(){if(e.alwaysDisplay||i.video.videoWidth/i.video.videoHeight!=t.clientWidth/t.clientHeight){r[s].removeAttribute("data-front"),++s>=r.length&&(s=0);var a=r[s],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?o=!1:i.timers.start(function(){n()},1e3*e.delay)}(),o=!0)}),t},subtitles:function(e){if(!("WebSocket"in window))return!1;var t=this;if(!("player"in t&&"api"in t.player&&"currentTime"in t.player.api))return!1;if(!("metaTrackSubscriptions"in t))return!1;var i=document.createElement("div"),r=document.createElement("span");i.appendChild(r);var n=document.createTextNode("");r.appendChild(n);var a=!1;function s(e){n.nodeValue=e.data.replace(/\<\/?[bui]\>/gi,"").replace(/{\/?[bui]}/gi,"").replace(/{\\a\d+}/gi,"").replace(/\<\/?font[^>]*?\>/gi,""),a&&(t.timers.stop(a),a=null),function i(r){a=t.timers.start(function(){if(t.player.api.paused)var r=MistUtil.event.addListener(t.video,"playing",function(){i(e.time+("duration"in e?e.duration:5e3)-1e3*t.player.api.currentTime),MistUtil.event.removeListener(r)});else n.nodeValue=""},r)}("duration"in e?e.duration:5e3)}if(MistUtil.event.addListener(t.video,"seeked",function(){n.nodeValue="",a&&t.timers.stop(a),a=null}),!("setWSSubtitle"in t.player.api)){var o=!1;t.player.api.setWSSubtitle=function(e){e!=o&&(void 0!==e&&t.metaTrackSubscriptions.add(e,s),e!=o&&t.metaTrackSubscriptions.remove(o,s),o="undefined"!=e&&e)}}return i},chromecast:function(){var e=this;if(!(!"".indexOf||e.options.host.indexOf("localhost")>-1||e.options.host.indexOf("::1")>-1)){var t,i,r,n,a=document.createElement("div"),s=document.createElement("div");s.className="mistvideo-casting";var o={},l={currentTime:!1,paused:!0,volume:1,muted:!1,buffer:[],loop:e.player.api?e.player.api.loop:e.options.loop};if(e.casting=!1,window.chrome&&window.chrome.cast||window.loadedCastApi)"loading"==window.loadedCastApi?(e.log("Not appending chromecast script - still loading"),e.timers.start(function(){d()},200)):(e.log("Not appending chromecast script - already loaded"),d());else{window.__onGCastApiAvailable=function(t,i){t||e.log("Error while loading chromecast API: "+i),d()},window.loadedCastApi="loading";var c=document.createElement("script");c.setAttribute("src","//www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"),document.head.appendChild(c),e.log("Appending chromecast script")}return a}function d(c){if(!window.chrome||!window.chrome.cast||!window.chrome.cast.isAvailable||c>5)return a.parentNode&&a.parentNode.removeChild(a),e.log("Chromecast is not supported"),void console.warn(chrome,chrome.cast,chrome.cast?chrome.cast.isAvailable:void 0,cast);if(!window.cast)return c||(c=0),e.log("Casting api loaded but cast function not yet available, retrying.."),void e.timers.start(function(){d(c++)},200);e.log("Chromecast API loaded"),window.loadedCastApi&&"loading"!=window.loadedCastApi||(window.loadedCastApi=!0);var u=document.createElement("google-cast-launcher");function p(a){MistUtil.class.remove(u,"active"),MistUtil.class.remove(e.container,"casting"),s.parentNode&&s.parentNode.removeChild(s),!a&&cast.framework.CastContext.getInstance().getCurrentSession()&&cast.framework.CastContext.getInstance().getCurrentSession().endSession(!0),t?(e.player.api=t,t.currentTime=l.currentTime,t.play(),e.reload=i,e.nextCombo=r,e.unload=n):e.player.api.play(),e.player.api&&e.player.api.setTracks&&MistUtil.object.keys(o).length&&e.player.api.setTracks(o),e.casting=!1,e.log("Detached chromecast session")}a.appendChild(u),cast.framework.CastContext.getInstance().setOptions({receiverApplicationId:"E5F1558C",autoJoinPolicy:chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED}),e.detachFromCast=p,u.addEventListener("click",function(a){if(a.stopPropagation(),MistUtil.class.has(u,"active"))p();else{function c(){cast.framework.CastContext.getInstance().getCurrentSession().addMessageListener("urn:x-cast:mistcaster",function(t,i){if(e.destroyed&&p(),(i=JSON.parse(i)).type)switch(i.type){case"log":case"error":e.log("[Chromecast] "+i.message,i.type);break;case"showError":e.showError.apply(e,i.args);break;case"event":switch(i.event){case"timeupdate":l.currentTime=i.currentTime,MistUtil.event.send(i.event,"chromecast",e.video);break;case"progress":l.buffer=i.buffer,MistUtil.event.send(i.event,"chromecast",e.video);break;case"pause":case"paused":case"ended":case"play":case"playing":l.paused=i.paused,MistUtil.event.send(i.event,"chromecast",e.video);break;case"volumechange":l.volume=i.volume,l.muted=i.muted,MistUtil.event.send(i.event,"chromecast",e.video);break;default:MistUtil.event.send(i.event,"chromecast",e.video)}break;case"detach":i.n==e.n&&p(!0);break;default:console.log("Unknown chromecast message type",i)}});var a={type:"load",n:e.n,options:{host:e.options.host,loop:e.options.loop,poster:e.options.poster,streaminfo:e.options.streaminfo,urlappend:e.options.urlappend,forcePriority:e.options.forcePriority,setTracks:e.options.setTracks,controls:!1,skin:"default"},stream:e.stream};e.info&&"live"!=e.info.type&&(a.time=e.player.api.currentTime),"dev"==e.options.skin&&(a.options.skin=e.options.skin),e.player&&e.player.api&&(a.volume=e.player.api.volume,a.muted=e.player.api.muted,a.options.loop=e.player.api.loop),MistCast.send(a),t=e.player.api,i=e.reload,r=e.nextCombo,n=e.unload,o=e.options.setTracks?e.options.setTracks:{},e.player.api=new Proxy(t,{get:function(e,t,i){var r=e[t];switch(t){case"muted":case"volume":case"currentTime":case"paused":case"loop":return l[t];case"buffered":return new function(){this.length=l.buffer.length,this.start=function(e){return l.buffer[e][0]},this.end=function(e){return l.buffer[e][1]}};case"setTracks":case"play":case"pause":return function(){for(var e=[],i=0;i<arguments.length;i++)e.push(arguments[i]);"setTracks"==t&&MistUtil.object.extend(o,arguments[0]),MistCast.send({type:"cmd",cmd:t,args:e})}}return r},set:function(e,t,i){"loop"==t&&(l[t]=i),MistCast.send({type:"set",cmd:t,value:i})}}),t.pause(),e.reload=function(){MistCast.send({type:"reload"})},e.nextCombo=function(){MistCast.send({type:"nextCombo"})},e.unload=function(){return p(),n.apply(this,arguments)},(a=cast.framework.CastContext.getInstance().getCurrentSession().getCastDevice())&&a.friendlyName&&(s.innerHTML="Casting to "+a.friendlyName);var c=function(){"SESSION_ENDED"==cast.framework.CastContext.getInstance().getSessionState()&&(MistUtil.class.has(u,"active")&&p(),cast.framework.CastContext.getInstance().removeEventListener(cast.framework.CastContextEventType.SESSION_STATE_CHANGED,c))};cast.framework.CastContext.getInstance().addEventListener(cast.framework.CastContextEventType.SESSION_STATE_CHANGED,c),e.log("Attached chromecast session")}MistUtil.class.add(u,"active"),s.innerHTML="Select a device to cast to",e.container.appendChild(s),MistUtil.class.add(e.container,"casting"),e.log("chromecast: pausing player"),e.player.api.pause(),e.container.setAttribute("data-loading","waiting for cast"),e.casting=!0,window.MistCast||(window.MistCast={send:function(e){cast.framework.CastContext.getInstance().getCurrentSession().sendMessage("urn:x-cast:mistcaster",JSON.stringify(e))}}),cast.framework.CastContext.getInstance().getCurrentSession()?c():cast.framework.CastContext.getInstance().requestSession().then(function(){if(!cast.framework.CastContext.getInstance().getCurrentSession())throw"Could not connect to the cast device";c()},function(t){e.log("Chromecast session ended: "+t),p()})}},!0)}}},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,s=!0;function o(e,r,o){if(o||(o={}),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",o.type&&"log"!=o.type&&(MistUtil.class.add(l,"type-"+o.type),r=MistUtil.format.ucFirst(o.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 o&&(c.title="Video playback time: "+MistUtil.format.time(o.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),s&&(t.scrollTop=t.scrollHeight),n={message:r,counter:m}}for(var l in MistUtil.event.addListener(t,"scroll",function(){s=t.scrollTop+t.clientHeight>=t.scrollHeight-5}),r.logs)o(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),o(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),o(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){if("getVideoPlaybackQuality"in e.player.api){var t=e.player.api.getVideoPlaybackQuality();if(t)return t.droppedVideoFrames?MistUtil.format.number(t.droppedVideoFrames):0}if("webkitDroppedFrameCount"in e.player.api)return e.player.api.webkitDroppedFrameCount}},"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(){var t;return e.player.monitor&&"currentBps"in e.player.monitor?(t=MistUtil.format.bits(e.player.monitor.currentBps))?t+"ps":t:e.player.api&&"currentBps"in e.player.api?(t=MistUtil.format.bits(e.player.api.currentBps()))?t+"ps":t:void 0},"Framerate in":function(){if(e.player.api&&"framerate_in"in e.player.api)return MistUtil.format.number(e.player.api.framerate_in())},"Framerate out":function(){if(e.player.api&&"framerate_out"in e.player.api)return MistUtil.format.number(e.player.api.framerate_out())}},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 s=document.createTextNode(e.value?e.value:"");a.appendChild(s);var o=document.createElement("span");a.appendChild(o),i.set=function(e){if(0!==e&&(this.style.display=""),"object"==typeof e){try{if(e instanceof Promise)return void e.then(function(e){i.set(e)},function(){})}catch(e){}if("val"in e&&(s.nodeValue=e.val,a.className="value"),o.children.length)return(t=o.children[0]).addData(e);var t=MistUtil.createGraph({x:[e.x],y:[e.y]},e.options);return o.style.display="",MistUtil.empty(o),o.appendChild(t)}return s.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 s in t.info.source){var o=t.info.source[s];if(!(o.type in a)){a[o.type]=1;n=document.createElement("option");r.appendChild(n),n.value=o.type,n.appendChild(document.createTextNode(MistUtil.format.mime2human(o.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 s=t.info.source[a];n=document.createElement("option");r.appendChild(n),n.value=a,n.appendChild(document.createTextNode(s.url+" ("+MistUtil.format.mime2human(s.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","mistvideo-displayCombo"],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):"perc"in e&&(n+=" ("+Math.round(10*e.perc)/10+"%)"),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 s="maxwidth"in t&&t.maxwidth?t.maxwidth:window.innerWidth,o="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),s&&r>s&&l(r/s),o&&n>o&&l(n/o)}}}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 s in i.info.meta.tracks)a=Math.max(a,i.info.meta.tracks[s].lastms);e.lastms=a}else{var o=i.resumeTime;if(o){var l=function(){i.player&&i.player.api&&(i.player.api.currentTime=o),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)&&(e<this.threshold()||void 0)},action:function(){var e=this.vars.score;this.MistVideo.showError("Poor playback: "+Math.max(0,Math.round(100*e))+"%",{passive:!0,reload:!0,nextCombo:!0,ignore:!0,type:"poor_playback"})}},"monitor"in i.options&&(i.monitor.default=MistUtil.object.extend({},i.monitor),MistUtil.object.extend(i.monitor,i.options.monitor));var r=["loadstart","play","playing"];for(var n in r)MistUtil.event.addListener(i.video,r[n],function(){i.monitor.init()});r=["loadeddata","pause","abort","emptied","ended"];for(var n in r)MistUtil.event.addListener(i.video,r[n],function(){i.monitor&&i.monitor.destroy()});r=["seeking","seeked","ratechange"];for(var n in r)MistUtil.event.addListener(i.video,r[n],function(){i.monitor&&i.monitor.reset()});if("currentTime"in i.player.api){var a=MistUtil.sources.find(i.info.source,{type:"html5/text/javascript",protocol:"ws"+("s"==location.protocol.charAt(location.protocol.length-2)?"s":"")+":"});if(a&&(i.metaTrackSubscriptions={subscriptions:{},socket:null,listeners:{},init:function(){var e=this;i.player.api.metaTrackSocket?this.socket=new i.player.api.metaTrackSocket:this.socket=new WebSocket(MistUtil.http.url.addParam(i.urlappend(a.url),{rate:1})),e.send_queue=[],e.checktimer=null,e.s=function(t){if(e.socket.readyState==e.socket.OPEN)return e.socket.send(JSON.stringify(t)),!0;e.socket.readyState>=e.socket.CLOSING&&e.init(),this.send_queue.push(t)};var t=!1;if(e.socket.setTracks=function(){e.s({type:"tracks",meta:MistUtil.object.keys(e.subscriptions).join(",")})},e.socket.onopen=function(){for(i.log("Metadata socket opened"),e.socket.setTracks(),1!=i.player.api.playbackRate&&e.s({type:"set_speed",play_rate:i.player.api.playbackRate}),e.s({type:"seek",seek_time:Math.round(1e3*i.player.api.currentTime),ff_to:Math.round(1e3*(i.player.api.currentTime+5))}),e.socket.addEventListener("message",function(r){if(r.data){var n=JSON.parse(r.data);if(n){if("time"in n&&"track"in n&&"data"in n){var a=!1;if("all"in e.subscriptions&&(e.subscriptions.all.buffer.push(n),a=!0),n.track in e.subscriptions&&(e.subscriptions[n.track].buffer.push(n),a=!0),a)if(e.checktimer){var s=i.timers.list[e.checktimer];if(s)s>(new Date).getTime()+n.time-1e3*i.player.api.currentTime&&(i.log("The metadata socket received a message that should be displayed sooner than the current check time; resetting"),i.timers.stop(e.checktimer),e.checktimer=null,e.check())}else e.check()}if("type"in n)switch(n.type){case"on_time":!t&&n.data.current>1e3*(i.player.api.currentTime+30)&&(t=!0,e.s({type:"hold"}),i.log("Pausing metadata buffer because it is very far ahead, checking again in 5 seconds: "+n.data.current+" > "+1e3*i.player.api.currentTime),i.timers.start(function(){i.player.api.paused||e.s({type:"play"}),e.s({type:"fast_forward",ff_to:Math.round(1e3*(i.player.api.currentTime+5))})},5e3));break;case"seek":for(var o in e.subscriptions)e.subscriptions[o].buffer=[];i.log("Cleared metadata buffer after completed seek"),e.checktimer&&(i.timers.stop(e.checktimer),e.checktimer=null)}}else i.log("Subtitle websocket received invalid message.")}else i.log("Subtitle websocket received empty message.")}),e.socket.onclose=function(){i.log("Metadata socket closed")};e.send_queue.length&&e.socket.readyState==e.socket.OPEN;)e.s(e.send_queue.shift())},!("seeked"in this.listeners)){var r=(new Date).getTime();e.check=function(){if(e.checktimer&&(i.timers.stop(e.checktimer),e.checktimer=null),!i.player.api.paused){var t=null;for(var n in e.subscriptions){for(var a=e.subscriptions[n].buffer;a.length&&a[0].time<=1e3*i.player.api.currentTime;){var s=a.shift();if(!(s.time<1e3*(i.player.api.currentTime-5)))for(var o in e.subscriptions[n].callbacks)e.subscriptions[n].callbacks[o].call(i,s)}a.length&&(t=Math.min(null===t?1e9:t,a[0].time))}var l=(new Date).getTime();if(l>r+5e3&&(e.s({type:"fast_forward",ff_to:Math.round(1e3*(i.player.api.currentTime+5))}),r=l),t){var c=t-1e3*i.player.api.currentTime;e.checktimer=i.timers.start(function(){e.check()},c)}}},this.listeners.seeked=MistUtil.event.addListener(i.video,"seeked",function(){for(var t in e.subscriptions)e.subscriptions[t].buffer=[];e.s({type:"seek",seek_time:Math.round(1e3*i.player.api.currentTime),ff_to:Math.round(1e3*(i.player.api.currentTime+5))}),r=(new Date).getTime()}),this.listeners.pause=MistUtil.event.addListener(i.video,"pause",function(){e.s({type:"hold"}),i.timers.stop(e.checktimer),e.checktimer=null}),this.listeners.playing=MistUtil.event.addListener(i.video,"playing",function(){e.s({type:"play"}),e.checktimer||e.check()}),this.listeners.ratechange=MistUtil.event.addListener(i.video,"ratechange",function(){e.s({type:"set_speed",play_rate:i.player.api.playbackRate})})}e.socket.readyState==e.socket.OPEN&&e.socket.onopen()},destroy:function(){for(var e in i.log("Closing metadata socket.."),this.socket.close(),this.socket=null,this.subscriptions={},this.listeners)MistUtil.event.removeListener(this.listeners[e]);this.listeners={}},add:function(e,t){"function"!=typeof e||t||(t=e,e="all"),"function"==typeof t&&(e in this.subscriptions||(this.subscriptions[e]={buffer:[],callbacks:[]}),this.subscriptions[e].callbacks.push(t),null===this.socket?this.init():this.socket.setTracks())},remove:function(e,t){if(e in this.subscriptions){for(var i in this.subscriptions[e].callbacks)if(t==this.subscriptions[e].callbacks[i]){this.subscriptions[e].callbacks.splice(i,1);break}0==this.subscriptions[e].callbacks.length&&(delete this.subscriptions[e],MistUtil.object.keys(this.subscriptions).length?this.socket.setTracks():this.destroy())}}},"function"==typeof t.subscribeToMetaTrack&&(t.subscribeToMetaTrack=[["all",t.subscribeToMetaTrack]]),t.subscribeToMetaTrack.length))for(var n in"object"!=typeof t.subscribeToMetaTrack[0]&&(t.subscribeToMetaTrack=[t.subscribeToMetaTrack]),t.subscribeToMetaTrack)i.metaTrackSubscriptions.add.apply(i.metaTrackSubscriptions,t.subscribeToMetaTrack[n])}}MistUtil.empty(i.options.target),new MistSkin(i),i.container=new MistUI(i),i.options.target.appendChild(i.container),i.container.setAttribute("data-loading",""),i.video.p=i.player;r=["abort","canplay","canplaythrough",,"emptied","ended","loadeddata","loadedmetadata","loadstart","pause","play","playing","ratechange","seeked","seeking","stalled","volumechange","waiting","metaUpdate_tracks","resizing"];for(var n in r)MistUtil.event.addListener(i.video,r[n],function(e){e.message&&"chromecast"==e.message||i.log("Player event fired: "+e.type)});if(MistUtil.event.addListener(i.video,"error",function(e){var t;if("player"in i&&"api"in i.player&&"error"in i.player.api&&i.player.api.error)if("message"in i.player.api.error)t=i.player.api.error.message;else if("code"in i.player.api.error&&i.player.api.error instanceof MediaError){var r={1:"MEDIA_ERR_ABORTED: The fetching of the associated resource was aborted by the user's request.",2:"MEDIA_ERR_NETWORK: Some kind of network error occurred which prevented the media from being successfully fetched, despite having previously been available.",3:"MEDIA_ERR_DECODE: Despite having previously been determined to be usable, an error occurred while trying to decode the media resource, resulting in an error.",4:"MEDIA_ERR_SRC_NOT_SUPPORTED: The associated resource or media provider object (such as a MediaStream) has been found to be unsuitable."};t=i.player.api.error.code in r?r[i.player.api.error.code]:"MediaError code "+i.player.api.error.code}else"string"!=typeof(t=i.player.api.error)&&(t=JSON.stringify(t));else t="An error was encountered.";"Stream is online"==i.state?i.showError(t):(i.log(t,"error"),i.showError(i.state,{polling:!0}))}),"setSize"in i.player&&(i.player.videocontainer=i.video.parentNode,i.video.currentTarget=i.options.target,MistUtil.class.has(i.options.target,"mistvideo-secondaryVideo")||(i.player.resizeAll=function(){function e(t,i){if(t.video.currentTarget==i)return t.video;if(t.secondary)for(var r=0;r<t.secondary.length;r++){var n=e(t.secondary[r].MistVideo,i);if(n)return n}return!1}var t=e(i,i.options.target);if(!t)throw"Main video not found";if(t.p.resize(),"secondary"in i){function r(t){if(t.MistVideo){if("player"in t.MistVideo){var n=e(i,t.MistVideo.options.target);if(!n)throw"Secondary video not found";n.p.resize()}}else i.timers.start(function(){r(t)},100)}for(var n in i.secondary)r(i.secondary[n])}}),i.player.resize=function(e,t){var r=i.video.currentTarget.querySelector(".mistvideo");if(t||(t={width:i.video.clientWidth,height:i.video.clientHeight}),r.hasAttribute("data-fullscreen"))size={width:window.innerWidth,height:window.innerHeight},this.setSize(size);else{if(size=i.calcSize(e),this.setSize(size),r.style.width=size.width+"px",r.style.height=size.height+"px",i.options.fillSpace&&(!e||!e.reiterating))return this.resize({width:window.innerWidth,height:!1,reiterating:!0},t);if(i.video.currentTarget.clientHeight&&i.video.currentTarget.clientHeight<size.height)return this.resize({width:!1,height:i.video.currentTarget.clientHeight,reiterating:!0},t);if(i.video.currentTarget.clientWidth&&i.video.currentTarget.clientWidth<size.width)return this.resize({width:i.video.currentTarget.clientWidth,height:!1,reiterating:!0},t)}return size.width==t.width&&size.height==t.height||(i.log("Player size calculated: "+size.width+" x "+size.height+" px"),MistUtil.event.send("player_resize",size,i.video)),!0},MistUtil.class.has(i.options.target,"mistvideo-secondaryVideo")||(MistUtil.event.addListener(window,"resize",function(){i.destroyed||i.player.resizeAll()},i.video),MistUtil.event.addListener(i.options.target,"resize",function(){i.player.resizeAll()},i.video),i.player.resizeAll())),i.player.api){if("setSource"in i.player.api&&(i.sourceParams={},i.player.api.setSourceParams=function(e,t){MistUtil.object.extend(i.sourceParams,t),i.player.api.setSource(MistUtil.http.url.addParam(e,t))},"setTracks"in i.player.api||(i.player.api.setTracks=function(e){var t=MistUtil.tracks.parse(i.info.meta.tracks);for(var r in e)r in t&&(e[r]in t[r]||"none"==e[r])||(i.log("Skipping trackselection of "+r+" track "+e[r]+" because it does not exist"),delete e[r]);var n=i.source.url,a=i.player.api.currentTime;if(this.setSourceParams(n,e),"live"!=i.info.type){var s=function(){i.player.api.currentTime=a,this.removeEventListener("loadedmetadata",s)};MistUtil.event.addListener(i.video,"loadedmetadata",s)}})),!("setTracks"in i.player.api)&&"setTrack"in i.player.api&&(i.player.api.setTracks=function(e){for(var t in e)i.player.api.setTrack(t,e[t])}),t.setTracks){var s=MistUtil.object.extend({},t.setTracks);if("subtitle"in t.setTracks&&"setSubtitle"in i.player.api&&i.player.onready(function(){var e=!1;for(var t in i.info.source){var r=i.info.source[t];if("html5/text/vtt"==r.type&&MistUtil.http.url.split(r.url).protocol==MistUtil.http.url.split(i.source.url).protocol){e=r.url.replace(/.srt$/,".vtt");break}}if(e){var n=MistUtil.tracks.parse(i.info.meta.tracks);"subtitle"in n&&s.subtitle in n.subtitle&&(meta=n.subtitle[s.subtitle],meta.src=MistUtil.http.url.addParam(e,{track:s.subtitle}),meta.label="automatic",meta.lang="unknown",i.player.api.setSubtitle(meta),MistUtil.event.send("playerUpdate_trackChanged",{type:"subtitle",trackid:s.subtitle},i.video),delete s.subtitle)}}),"setTrack"in i.player.api)i.player.onready(function(){for(var e in s)i.player.api.setTrack(e,s[e]),MistUtil.event.send("playerUpdate_trackChanged",{type:e,trackid:s[e]},i.video)});else if("setTracks"in i.player.api)for(var n in i.player.onready(function(){i.player.api.setTracks(s)}),s)MistUtil.event.send("playerUpdate_trackChanged",{type:n,trackid:s[n]},i.video)}if(i.player.api.ABR_resize&&i.options.ABR_resize){var o=!1;MistUtil.event.addListener(i.video,"player_resize",function(e){i.options.setTracks&&i.options.setTracks.video||(o&&i.timers.stop(o),o=i.timers.start(function(){i.player.api.ABR_resize(e.message),o=!1},1e3))}),MistUtil.event.addListener(i.video,"trackSetToAuto",function(e){"video"==e.message&&i.player.api.ABR_resize({width:i.video.clientWidth,height:i.video.clientHeight})}),i.player.api.ABR_resize({width:i.video.clientWidth,height:i.video.clientHeight})}}for(var n in i.player.onreadylist)i.player.onreadylist[n]();MistUtil.event.send("initialized",null,t.target),i.log("Initialized"),i.options.callback&&t.callback(i)})):i.options.startCombo?(delete i.options.startCombo,i.unload("No compatible players found - retrying without startCombo."),mistPlay(i.stream,i.options)):(i.showError("No compatible player/source combo found.",{reload:!0}),MistUtil.event.send("initializeFailed",null,t.target),i.log("Initialization failed"))}function a(){var e=MistUtil.http.url.addParam(i.urlappend(t.host+"/json_"+encodeURIComponent(i.stream)+".js"),{metaeverywhere:1,inclzero:1});i.log("Requesting stream info from "+e),MistUtil.http.get(e,function(e){i.destroyed||n(JSON.parse(e))},function(e){var r="Connection failed: the media server at "+i.options.host+" may be offline";i.showError(r,{reload:30}),i.info||(MistUtil.event.send("initializeFailed",null,t.target),i.log("Initialization failed"))})}if(t||(t={}),"undefined"!=typeof mistoptions&&(t=MistUtil.object.extend(MistUtil.object.extend({},mistoptions),t)),(t=MistUtil.object.extend({host:null,autoplay:!0,controls:!0,loop:!1,poster:!1,muted:!1,callback:!1,streaminfo:!1,startCombo:!1,forceType:!1,forcePlayer:!1,forceSource:!1,forcePriority:!1,monitor:!1,reloadDelay:!1,urlappend:!1,setTracks:!1,fillSpace:!1,width:!1,height:!1,maxwidth:!1,maxheight:!1,ABR_resize:!0,ABR_bitrate:!0,useDateTime:!0,subscribeToMetaTrack:!1,MistVideoObject:!1},t)).host&&(t.host=MistUtil.http.url.sanitizeHost(t.host)),this.options=t,this.stream=e,this.info=!1,window.MistInstances||(window.MistInstances=0),window.MistInstances++,this.n=window.MistInstances,this.logs=[],this.log=function(e,r){r||(r="log");var n=MistUtil.event.send(r,e,t.target),a={type:r};if(this.logs.push({time:new Date,message:e,data:a}),"dev"==this.options.skin)try{var s="["+(r||"log")+"] "+(i.destroyed?"[DESTROYED] ":"")+"[#"+i.n+"] "+(this.player&&this.player.api?MistUtil.format.time(this.player.api.currentTime,{ms:!0})+" ":"")+e;r&&"log"!=r?console.warn(s):console.log(s)}catch(e){}return n},this.log("Initializing.."),this.bootMs=(new Date).getTime(),this.timers={list:{},start:function(e,t){var r=setTimeout(function(){delete i.timers.list[r],i.destroyed||e()},t);return this.list[r]=new Date((new Date).getTime()+t),r},stop:function(e){var t;for(var i in"all"==e?t=this.list:(t={})[e]=1,t)clearTimeout(i),delete this.list[i]}},this.errorListeners=[],this.resumeTime=!1,this.urlappend=function(e){return this.options.urlappend&&(e=MistUtil.http.url.append(e,this.options.urlappend)),e},t.reloadDelay&&t.reloadDelay>3600&&(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 s 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[s].shortname=s;e.forcePlayer&&mistplayers[e.forcePlayer]?(n=[mistplayers[e.forcePlayer]],i.log("Forcing player "+e.forcePlayer)):n=MistUtil.object.values(mistplayers),r=[].concat(r);var o={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.";o.source=e.forcePriority.source.concat(o.source),MistUtil.array.multiSort(r,o.source)}if("player"in e.forcePriority){if(!(e.forcePriority.player instanceof Array))throw"forcePriority.player is not an array.";o.player=e.forcePriority.player.concat(o.player),MistUtil.array.multiSort(n,o.player)}"first"in e.forcePriority&&(o.first=e.forcePriority.first),"player"==o.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(s=0;s<n.length;s++)if(n[s].shortname==e.startCombo.player){e.startCombo.player=s;break}}function d(t){return e.startCombo&&!e.startCombo.started[t]?e.startCombo[t]==c[t].current||e.startCombo[t]==c[t].list[c[t].current]?(e.startCombo.started[t]=!0,1):2:0}var u={score:0,source_index:null,player:null};function p(e){if(!0===e)return 1.9;var t={video:2,audio:1,subtitle:.5},i=0;for(var r in e)i+=t[e[r]];return i}var h={};for(var s in i.info.meta.tracks)"meta"==i.info.meta.tracks[s].type?h[i.info.meta.tracks[s].codec]=1:h[i.info.meta.tracks[s].type]=1;var m=p(MistUtil.object.keys(h));for(var f in c[l.outer].list)if(c[l.outer].current=f,!(d(l.outer)>=2))for(var v in c[l.inner].list)if(c[l.inner].current=v,!(d(l.inner)>=1)){a=c.source.list[c.source.current];var y=c.player.list[c.player.current].shortname,g=mistplayers[y];if(g.isMimeSupported(a.type)){var b=g.isBrowserSupported(a.type,a,i);if(b){var k=p(b);if(k>u.score&&(t||i.log("Found a "+(u.score?"better":"working")+" combo: "+g.name+" with "+a.url+" (Score: "+k+")"),(u={score:k,player:y,source:a,source_index:c.source.current}).score==m))return u}}}return!!u.score&&u},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("Selected: "+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 through websocket..");var t,s=i.options.host.replace(/^http/i,"ws");s=MistUtil.http.url.addParam(i.urlappend(s+"/json_"+encodeURIComponent(i.stream)+".js"),{metaeverywhere:1,inclzero:1});try{t=new WebSocket(s)}catch(e){return i.log("Error while attempting to open WebSocket to "+s),void a()}i.socket=t,t.die=!1,t.destroy=function(){this.die=!0,i.reporting&&(i.reporting.reportStats(),i.reporting=!1),this.onclose=function(){},this.close()},t.timeOut=i.timers.start(function(){t.readyState<=1&&(t.destroy(),a())},5e3),t.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&&i.reporting&&i.reporting.stats.add("nWaiting")}),MistUtil.event.addListener(e,"stalled",function(){i&&i.reporting&&i.reporting.stats.add("nStalled")}),MistUtil.event.addListener(i.options.target,"error",function(e){i&&i.reporting&&(i.reporting.stats.add("nError"),i.reporting.stats.set("lastError",e.message))},e),Object&&Object.defineProperty){var r=0,n=!1,a=0,s=!1,o=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+(s?(new Date).getTime()-s:0)}}),Object.defineProperty(c,"timeUnpaused",{get:function(){return o+(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,s=(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,s=!1});MistUtil.event.addListener(e,"playing",function(){o=c.timeUnpaused,l=(new Date).getTime()}),MistUtil.event.addListener(e,"pause",function(){o=c.timeUnpaused,l=!1})}this.reportStats()}})},t.onclose=function(t){if(!this.die)return this.wasConnected?(i.log("Reopening websocket.."),void e()):void a()};var o=!1;t.addEventListener("message",function(e){t.timeOut&&(i.timers.stop(t.timeOut),t.timeOut=!1);var a=JSON.parse(e.data);if(a||i.showError("Error while parsing stream status stream. Obtained: "+e.data.toString(),{reload:!0}),"error"in a){var s;switch(e=a.error,"on_error"in a?(i.log(e),e=a.on_error):"perc"in a&&(e+=" ("+Math.round(10*a.perc)/10+"%)"),i.state=a.error,a.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(a.error,"error"),o||(o=MistUtil.event.addListener(i.video,"ended",function(){i.showError(a.error,{polling:!0})})),void(o=MistUtil.event.addListener(i.video,"waiting",function(){i.showError(a.error,{polling:!0})}));s={polling:!0};break;default:s={reload:!0}}i.showError(e,s)}else{if(i.state="Stream is online",i.clearError(),o&&MistUtil.event.removeListener(o),!i.info)return void n(a);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}(a,i.info);if(l){if("source"in l&&"error"in i.info)return void i.reload("Reloading, stream info has error");i.info=MistUtil.object.extend(i.info,a),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",a,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.metaTrackSubscriptions&&this.metaTrackSubscriptions.socket&&this.metaTrackSubscriptions.destroy(),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),s=Math.round(e%1*1e3);e=Math.floor(e-60*a);var o=[];return r&&(r=r+" day"+(r>1?"s":"")+", "),n||r?(o.push(n),o.push(("0"+a).slice(-2))):o.push(a),o.push(("0"+Math.floor(e)).slice(-2)),t.ms&&(o[o.length-1]+="."+("000"+s).slice(-3)),(r||"")+o.join(":")+i},ago:function(e,t){if(isNaN(e.getTime()))return"";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 (WS)";case"whep":return"WebRTC (WHEP)";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])?(r in e||(MistUtil.array.is(t[r])?e[r]=[]:e[r]={}),this.extend(e[r],t[r],!0)):e[r]=t[r];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<e.length;i++)if(e[i]==t)return i;return-1},is:function(e){return"isArray"in Array?Array.isArray(e):"[object Array]"===Object.prototype.toString.call(e)},multiSort:function(e,t){var i=function(e,t){return isNaN(e)||isNaN(t)?e.localeCompare(t):e>t?1:e<t?-1:0};if(!t.length)return e.sort(i);function r(e,t){function i(e,t,i){if(!(t in e))throw"Invalid sorting rule: "+JSON.stringify([t,i])+'. "'+t+'" is not a key of '+JSON.stringify(e);if("number"==typeof i&&t in e)return e[t]*i;var r=i.indexOf(e[t]);return r>=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 s in t){var o=t[s];if(0!=(a=i(r(o,e),r(o,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 s,o=[];for(var l in i)o.push(l+"="+encodeURIComponent(i[l]));o.length&&(s=o.join("&")),a.send(s)}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("?")},append:function(e,t){var i=document.createElement("a");return i.href=e,"?"==t[0]?""==i.search?i.search=t:i.search+="&"+t.slice(1):"&"==t[0]?""==i.search?i.search="?"+t.slice(1):i.search+=t:i.href+=t,i.href},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 s=3;!function t(){MistUtil.http.get(e,(function(t){for(var i in n[e])n[e][i](t);n[e]=t}),(function(){if(s>0)s--,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 s=1;s<n[a].match(/{/g).length;){var o=e.match(/@@#@@([^}]*})/);e=e.replace(o[0],"@@#@@"),n[a]+=o[1],s++}e=e.replace("@@#@@","@@@@")}for(var a in e=e.replace(/[^@]*?{[^]*?}/g,(function(e){var r=e.split("{"),n=r[0].split(","),a="{"+r.slice(1).join("}");for(var s in n){n[s]=n[s].trim();var o="."+t+n[s];i&&(o+=",\n."+t+" "+n[s]),n[s]=o}return"\n"+n+" "+a})),n)e=e.replace(/@@@@/,n[a]);if(!r)return e;r.textContent=e}},empty:function(e){for(;e.lastChild;){if(e.lastChild.lastChild&&this.empty(e.lastChild),"attachedListeners"in e.lastChild)for(var t in e.lastChild.attachedListeners)MistUtil.event.removeListener(e.lastChild.attachedListeners[t]);e.removeChild(e.lastChild)}},event:{send:function(e,t,i){try{return(r=new Event(e,{bubbles:!0,cancelable:!0})).message=t,i.dispatchEvent(r),r}catch(n){try{var r;return(r=document.createEvent("Event")).initEvent(e,!0,!0),r.message=t,i.dispatchEvent(r),r}catch(e){return!1}}return!0},addListener:function(e,t,i,r){e.addEventListener(t,i),r||(r=e),"attachedListeners"in r||(r.attachedListeners=[]);var n={element:e,type:t,callback:i};return r.attachedListeners.push(n),n},removeListener:function(e){e.element.removeEventListener(e.type,e.callback)}},scripts:{list:{},insert:function(e,t,i){var r=this;if(i&&i.errorListeners.push({src:e,onevent:t}),e in this.list)return this.list[e].subscribers.push(t.onerror),void("onload"in t&&(this.list[e].tag.hasLoaded?t.onload():MistUtil.event.addListener(this.list[e].tag,"load",t.onload)));var n=document.createElement("script");n.hasLoaded=!1,n.setAttribute("src",e),n.setAttribute("crossorigin","anonymous"),document.head.appendChild(n),n.onerror=function(e){t.onerror(e)},n.onload=function(e){this.hasLoaded=!0,i.destroyed||t.onload(e)},n.addEventListener("error",(function(e){t.onerror(e)}));var a=!1;return window.onerror&&(a=window.onerror),window.onerror=function(i,n,s,o,l){if(a&&a.apply(this,arguments),n==e)for(var c in t.onerror(l),r.list[e].subscribers)r.list[e].subscribers[c](l)},this.list[e]={subscribers:[t.onerror],tag:n},n}},tracks:{parse:function(e){var t={};for(var i in e){var r=MistUtil.object.extend({},e[i]);"meta"==r.type&&(r.type=r.codec,r.codec="meta"),r.type in t||(t[r.type]={}),t[r.type]["idx"in r?r.idx:r.trackid]=r;var n={};for(var a in r)switch(a){case"width":n[a]=r.width+"×"+r.height;break;case"bps":if("meta"==r.codec)continue;var s;if(r.bps>0)s=r.bps>131072?Math.round(r.bps/1024/1024*8)+"mbps":Math.round(r.bps/1024*8)+"kbps",n[a]=s;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(.001*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 o in t){var l=!1;for(var i in t[o])if(l){if(MistUtil.object.keys(t[o]).length>1)for(var a in t[o][i].describe)l[a]!=t[o][i].describe[a]&&delete l[a]}else l=MistUtil.object.extend({},t[o][i].describe);for(var i in t[o]){var c={},d={};for(var a in t[o][i].describe)a in l?d[a]=t[o][i].describe[a]:c[a]=t[o][i].describe[a];t[o][i].different=c,t[o][i].same=d;var u=MistUtil.object.values(c);t[o][i].displayName=u.length?u.join(", "):MistUtil.object.values(t[o][i].describe).join(" ")}var p={};for(var i in t[o]){if(t[o][i].displayName in p){var h=1;for(var i in t[o])t[o][i].different.trackid=h+")",t[o][i].displayName="Track "+h+" ("+t[o][i].displayName+")",h++;break}p[t[o][i].displayName]=1}}return t},translateCodec:function(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"mp3";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()}}},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,s=Math.max(0,(t.clientX/i-n)/a);return s=Math.min(s,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 s=1;s<e.y.length;s++){var o=e.y[s]-a;a=e.y[s],e.y[s]=o}var l=[],c={x:{min:e.x[0]-n,max:e.x[0]-n},y:{min:-1*e.y[0],max:-1*e.y[0]}};function d(e,t){if(arguments.length)c.x.min=Math.min(c.x.min,e),c.x.max=Math.max(c.x.max,e),c.y.min=Math.min(c.y.min,-1*t),c.y.max=Math.max(c.y.max,-1*t);else{var i=l[0].split(",");c={x:{min:i[0],max:i[0]},y:{min:i[1],max:i[1]}};for(var r=1;r<l.length;r++){d((i=l[r].split(","))[0],-1*i[1])}}}l.push([e.x[0]-n,-1*e.y[0]].join(","));for(s=1;s<e.y.length;s++)d(e.x[s]-n,-1*e.y[s]),l.push("L "+[e.x[s]-n,-1*e.y[s]].join(","));var u=document.createElementNS(i,"defs");r.appendChild(u);var p=document.createElementNS(i,"linearGradient");function h(){"x"in t&&("min"in t.x&&(c.x.min=t.x.min),"max"in t.x&&(c.x.max=t.x.max),"count"in t.x&&(c.x.min=c.x.max-t.x.count)),"y"in t&&("min"in t.y&&(c.y.min=-1*t.y.max),"max"in t.y&&(c.y.max=-1*t.y.min)),r.setAttributeNS(null,"viewBox",[c.x.min,c.y.min,c.x.max-c.x.min,c.y.max-c.y.min].join(" ")),p.setAttributeNS(null,"x1",0),p.setAttributeNS(null,"x2",0),t.reverseGradient?(p.setAttributeNS(null,"y1",c.y.max),p.setAttributeNS(null,"y2",c.y.min)):(p.setAttributeNS(null,"y1",c.y.min),p.setAttributeNS(null,"y2",c.y.max))}u.appendChild(p),p.setAttributeNS(null,"id",MistUtil.createUnique()),p.setAttributeNS(null,"gradientUnits","userSpaceOnUse"),p.innerHTML+='<stop offset="0" stop-color="green"/>',p.innerHTML+='<stop offset="0.33" stop-color="yellow"/>',p.innerHTML+='<stop offset="0.66" stop-color="orange"/>',p.innerHTML+='<stop offset="1" stop-color="red"/>',h();var m=document.createElementNS(i,"path");return r.appendChild(m),m.setAttributeNS(null,"stroke-width","0.1"),m.setAttributeNS(null,"fill","none"),m.setAttributeNS(null,"stroke","url(#"+p.getAttribute("id")+")"),m.setAttributeNS(null,"d","M"+l.join(" L")),m.addData=function(e){if(!isNaN(e.y)){if(t.differentiate){var i=e.y-a;a=e.y,e.y=i}l.push([e.x-n,-1*e.y].join(",")),t.x&&t.x.count&&l.length>t.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]},sources:{find:function(e,t){e:for(var i in e){for(var r in t)if("protocol"==r){if(e[i].url.slice(0,t.protocol.length)!=t.protocol)continue e}else if(e[i][r]!=t[r])continue e;return e[i]}return!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 s="";s+='<svg viewBox="0 0 '+a.size.width+" "+a.size.height+'"'+("width"in i?' width="'+i.width+'"':"")+("height"in i?' height="'+i.height+'"':"")+' class="mist icon '+t+'">',s+='<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="100%" width="100%">',s+=n,s+="</svg>",s+="</svg>";var o=document.createElement("div");return o.innerHTML=s,o.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 s=MistUtil.css.createStyle(t.css[r],a);n.appendChild(s)}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 o=this.buildStructure(t.children[r]);o&&n.appendChild(o)}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 s=e.skin.css[a];s.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="")},""!=s.textContent&&s.callback(s.textContent),i.appendChild(s)}MistUtil.class.add(i,r);var o=MistUtil.getBrowser();return o&&MistUtil.class.add(i,"browser-"+o),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",classes:["mistvideo-maincontainer"],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"},{type:"subtitles"}]},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:"chromecast",classes:["mistvideo-pointer"]},{type:"loop",classes:["mistvideo-pointer"]},{type:"fullscreen",classes:["mistvideo-pointer"]},{type:"picture-in-picture",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:"chromecast",classes:["mistvideo-pointer"]},{type:"loop",classes:["mistvideo-pointer"]},{type:"fullscreen",classes:["mistvideo-pointer"]},{type:"picture-in-picture",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:'<path d="M6.26004984594 3.0550109625C5.27445051914 3.68940862462 4.67905105702 4.78142391497 4.67968264562 5.95354422781C4.67968264562 5.95354422781 4.70004942312 39.0717540916 4.70004942312 39.0717540916C4.70302341604 40.3033886636 5.36331656075 41.439734231 6.43188211452 42.0521884912C7.50044766829 42.6646427515 8.81469531629 42.6600161659 9.87892235656 42.0400537716C9.87892235656 42.0400537716 38.5612768409 25.4802882606 38.5612768409 25.4802882606C39.6181165777 24.8606067582 40.2663250096 23.7262617523 40.2636734301 22.5011460995C40.2610218505 21.2760304467 39.6079092743 20.1445019555 38.5483970356 19.5294009803C38.5483970356 19.5294009803 9.84567577375 2.9709566275 9.84567577375 2.9709566275C8.72898008118 2.32550764609 7.34527425735 2.35794451351 6.26004984594 3.0550109625C6.26004984594 3.0550109625 6.26004984594 3.0550109625 6.26004984594 3.0550109625" class="fill" />'},largeplay:{size:45,svg:'<path d="M6.26004984594 3.0550109625C5.27445051914 3.68940862462 4.67905105702 4.78142391497 4.67968264562 5.95354422781C4.67968264562 5.95354422781 4.70004942312 39.0717540916 4.70004942312 39.0717540916C4.70302341604 40.3033886636 5.36331656075 41.439734231 6.43188211452 42.0521884912C7.50044766829 42.6646427515 8.81469531629 42.6600161659 9.87892235656 42.0400537716C9.87892235656 42.0400537716 38.5612768409 25.4802882606 38.5612768409 25.4802882606C39.6181165777 24.8606067582 40.2663250096 23.7262617523 40.2636734301 22.5011460995C40.2610218505 21.2760304467 39.6079092743 20.1445019555 38.5483970356 19.5294009803C38.5483970356 19.5294009803 9.84567577375 2.9709566275 9.84567577375 2.9709566275C8.72898008118 2.32550764609 7.34527425735 2.35794451351 6.26004984594 3.0550109625C6.26004984594 3.0550109625 6.26004984594 3.0550109625 6.26004984594 3.0550109625" class="stroke" />'},pause:{size:45,svg:'<g><path d="m 7.5,38.531275 a 4.0011916,4.0011916 0 0 0 3.749999,3.96873 l 2.2812501,0 a 4.0011916,4.0011916 0 0 0 3.96875,-3.75003 l 0,-32.28123 a 4.0011916,4.0011916 0 0 0 -3.75,-3.96875 l -2.2812501,0 a 4.0011916,4.0011916 0 0 0 -3.968749,3.75 l 0,32.28128 z" class="fill" /><path d="m 27.5,38.531275 a 4.0011916,4.0011916 0 0 0 3.75,3.9687 l 2.28125,0 a 4.0011916,4.0011916 0 0 0 3.96875,-3.75 l 0,-32.28126 a 4.0011916,4.0011916 0 0 0 -3.75,-3.96875 l -2.28125,0 a 4.0011916,4.0011916 0 0 0 -3.96875,3.75 l 0,32.28131 z" class="fill" /></g>'},speaker:{size:45,svg:'<path d="m 32.737813,5.2037363 c -1.832447,-1.10124 -4.200687,-0.8622 -5.771871,0.77112 0,0 -7.738819,8.0443797 -7.738819,8.0443797 0,0 -3.417976,0 -3.417976,0 -1.953668,0 -3.54696,1.65618 -3.54696,3.68694 0,0 0,9.58644 0,9.58644 0,2.03094 1.593292,3.68712 3.54696,3.68712 0,0 3.417976,0 3.417976,0 0,0 7.738819,8.04474 7.738819,8.04474 1.572104,1.63404 3.938942,1.8747 5.771871,0.77076 0,0 0,-34.5914997 0,-34.5914997 z" class="stroke semiFill toggle" />'},volume:{size:{width:100,height:45},svg:function(){var e=MistUtil.createUnique();return'<defs><mask id="'+e+'"><path d="m6.202 33.254 86.029-28.394c2.6348-0.86966 4.7433 0.77359 4.7433 3.3092v28.617c0 1.9819-1.6122 3.5773-3.6147 3.5773h-86.75c-4.3249 0-5.0634-5.5287-0.40598-7.1098" fill="#fff" /></mask></defs><rect mask="url(#'+e+')" class="slider horizontal semiFill" width="100%" height="100%" /><path d="m6.202 33.254 86.029-28.394c2.6348-0.86966 4.7433 0.77359 4.7433 3.3092v28.617c0 1.9819-1.6122 3.5773-3.6147 3.5773h-86.75c-4.3249 0-5.0634-5.5287-0.40598-7.1098" class="stroke" /><rect x="0" y="0" width="100%" height="100%" fill="rgba(0,0,0,0.001)"/>'}},muted:{size:45,svg:'<g class="stroke" stroke-linecap="round" vector-effect="none" stroke-width="2"><path d="m25.587 5.2036c-1.8324-1.1012-4.2007-0.8622-5.7719 0.77112 0 0-7.7388 8.0444-7.7388 8.0444h-3.418c-1.9537 0-3.547 1.6562-3.547 3.6869v9.5864c0 2.0309 1.5933 3.6871 3.547 3.6871h3.418s7.7388 8.0447 7.7388 8.0447c1.5721 1.634 3.9389 1.8747 5.7719 0.77076v-34.591 z" /><path d="m30.032 27.86 9.8517-9.8517"/><path d="m30.032 18.008 9.8517 9.8517"/></g>'},fullscreen:{size:45,svg:'<path d="m2.5 10.928v8.5898l4.9023-2.8008 9.6172 5.7832-9.6172 5.7832-4.9023-2.8008v8.5898h15.031l-4.9004-2.8008 9.8691-5.6387 9.8691 5.6387-4.9004 2.8008h15.031v-8.5898l-4.9023 2.8008-9.6172-5.7832 9.6172-5.7832 4.9023 2.8008v-8.5898h-15.033l4.9023 2.8008-9.8691 5.6387-9.8691-5.6387 4.9023-2.8008z" class="fill">'},pip:{size:45,svg:'<rect x="5.25" y="12.25" width="34.5" height="19.5" ry="2" class="stroke semiFill toggle"/><rect x="20" y="21" width="17" height="8" rx="2" ry="2" class="semiFill toggle stroke"/>'},loop:{size:45,svg:'<path d="M 21.279283,3.749797 A 18.750203,18.750203 0 0 0 8.0304417,9.2511582 L 12.740779,13.961496 A 12.083464,12.083464 0 0 1 21.279283,10.416536 12.083464,12.083464 0 0 1 33.362748,22.5 12.083464,12.083464 0 0 1 21.279283,34.583464 12.083464,12.083464 0 0 1 12.740779,31.038504 l 3.063185,-3.063185 H 4.9705135 V 38.80877 L 8.0304417,35.748842 A 18.750203,18.750203 0 0 0 21.279283,41.250203 18.750203,18.750203 0 0 0 40.029486,22.5 18.750203,18.750203 0 0 0 21.279283,3.749797 Z" class="stroke semiFill toggle" />'},settings:{size:45,svg:'<path d="m24.139 3.834-1.4785 4.3223c-1.1018 0.0088-2.2727 0.13204-3.2031 0.33594l-2.3281-3.9473c-1.4974 0.45304-2.9327 1.091-4.2715 1.9004l1.3457 4.3672c-0.87808 0.62225-1.685 1.3403-2.4023 2.1426l-4.1953-1.8223c-0.9476 1.2456-1.7358 2.6055-2.3457 4.0469l3.6523 2.7383c-0.34895 1.0215-0.58154 2.0787-0.69336 3.1523l-4.4531 0.98828c-0.00716 0.14696-0.011931 0.29432-0.015625 0.44141 0.00628 1.4179 0.17336 2.8307 0.49805 4.2109l4.5703 0.070312c0.32171 1.0271 0.75826 2.0138 1.3008 2.9434l-3.0391 3.4355c0.89502 1.2828 1.9464 2.4492 3.1309 3.4707l3.7363-2.6289c0.86307 0.64582 1.7958 1.192 2.7812 1.6289l-0.43555 4.541c1.4754 0.52082 3.0099 0.85458 4.5684 0.99414l1.4766-4.3223c0.05369 3e-3 0.10838 0.005313 0.16211 0.007812 1.024-0.0061 2.0436-0.12048 3.043-0.34375l2.3281 3.9473c1.4974-0.45304 2.9327-1.091 4.2715-1.9004l-1.3457-4.3672c0.87808-0.62225 1.685-1.3403 2.4023-2.1426l4.1953 1.8223c0.9476-1.2456 1.7358-2.6055 2.3457-4.0469l-3.6523-2.7383c0.34895-1.0215 0.58154-2.0787 0.69336-3.1523l4.4531-0.98828c0.0072-0.14698 0.011925-0.29432 0.015625-0.44141-0.0062-1.4179-0.17336-2.8307-0.49805-4.2109l-4.5703-0.070312c-0.32171-1.0271-0.75826-2.0138-1.3008-2.9434l3.0391-3.4355c-0.89502-1.2828-1.9464-2.4492-3.1309-3.4707l-3.7363 2.6289c-0.86307-0.64582-1.7958-1.192-2.7812-1.6289l0.43555-4.541c-1.4754-0.52082-3.0099-0.85457-4.5684-0.99414zm-1.6387 7.8789a10.786 10.786 0 0 1 10.787 10.787 10.786 10.786 0 0 1-10.787 10.787 10.786 10.786 0 0 1-10.787-10.787 10.786 10.786 0 0 1 10.787-10.787z" class="fill"/>'},loading:{size:100,svg:'<path d="m49.998 8.7797e-4c-0.060547 0.0018431-0.12109 0.0037961-0.18164 0.0058593-0.1251 0.0015881-0.25012 0.0061465-0.375 0.013672h-0.001954c-27.388 0.30599-49.432 22.59-49.439 49.98 0.020074 2.6488 0.25061 5.292 0.68945 7.904 3.8792-24.231 24.77-42.065 49.311-42.096v-0.0058582h0.001954c4.3638 3.0803e-4 7.9013-3.5366 7.9021-7.9002 1.474e-4 -2.0958-0.83235-4.106-2.3144-5.5879-1.482-1.482-3.492-2.3145-5.5879-2.3144-6.5007e-4 -7.9369e-8 -0.0013001-7.9369e-8 -0.001954 0" class="semiFill spin"></path>'},timeout:{size:25,svg:function(e){e&&e.delay||(e={delay:10});var t=e.delay,i=MistUtil.createUnique();return'<defs><mask id="'+i+'"><rect x="0" y="0" width="25" height="25" fill="#fff"/><rect x="-5" y="-5" width="17.5" height="35" fill="#000" transform="rotate(180,12.5,12.5)"><animateTransform attributeName="transform" type="rotate" from="0,12.5,12.5" to="180,12.5,12.5" begin="DOMNodeInsertedIntoDocument" dur="'+t/2+'s" repeatCount="1"/></rect><rect x="0" y="0" width="12.5" height="25" fill="#fff"/><rect x="-5" y="-5" width="17.5" height="35" fill="#000" transform="rotate(360,12.5,12.5)"><animate attributeType="CSS" attributeName="opacity" from="0" to="1" begin="DOMNodeInsertedIntoDocument" dur="'+t+'s" calcMode="discrete" repeatCount="1" /><animateTransform attributeName="transform" type="rotate" from="180,12.5,12.5" to="360,12.5,12.5" begin="DOMNodeInsertedIntoDocument+'+t/2+'s" dur="'+t/2+'s" repeatCount="1"/></rect><circle cx="12.5" cy="12.5" r="8" fill="#000"/></mask></defs><circle cx="12.5" cy="12.5" r="12.5" class="fill" mask="url(#'+i+')"/>'}},popout:{size:45,svg:'<path d="m24.721 11.075c-12.96 0.049575-32.113 15.432-10.336 28.834-7.6763-7.9825-2.4795-21.824 10.336-22.19v5.5368l15.276-8.862-15.276-8.86v5.5419z" class="stroke fill"/>'},switchvideo:{size:45,svg:'<path d="m8.4925 18.786c-3.9578 1.504-6.4432 3.632-6.4434 5.9982 2.183e-4 4.1354 7.5562 7.5509 17.399 8.1467v4.7777l10.718-6.2573-10.718-6.2529v4.5717c-6.9764-0.4712-12.229-2.5226-12.227-4.9859 6.693e-4 -0.72127 0.45868-1.4051 1.2714-2.0267zm28.015 0v3.9715c0.81164 0.62126 1.2685 1.3059 1.2692 2.0267-0.0014 1.4217-1.791 2.75-4.8021 3.6968-2.0515 0.82484-0.93693 3.7696 1.2249 2.9659 5.3088-1.8593 8.7426-3.8616 8.7514-6.6627-1.26e-4 -2.3662-2.4856-4.4942-6.4434-5.9982z" class="fill"/><rect rect x="10.166" y="7.7911" width="24.668" height="15.432" class="stroke"/>'}}},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.player.api.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"),s=0;s<a.length;s++)MistUtil.event.addListener(a[s],"click",(function(e){e.stopPropagation()}));MistUtil.event.addListener(t.video,"play",(function(){e.player.api.paused&&e.player.api.play()}),i.target),MistUtil.event.addListener(t.video,"pause",(function(t){e.player.api.paused||e.player.api.pause()}),i.target),MistUtil.event.addListener(t.video,"seeking",(function(){e.player.api.currentTime=this.currentTime}),i.target),MistUtil.event.addListener(t.video,"timeupdate",(function(){if(!e.player.api.pausedesync){var t=this.currentTime-e.player.api.currentTime,i=Math.abs(t);if(i>30)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;i<e.secondary.length;i++){var n=r(e.secondary[i].MistVideo,t);if(n)return n}return!1}var n=r(t,t.options.target),a=r(t,i.options.target),s=!n.paused,o=document.createElement("div");if(a.parentElement.insertBefore(o,a),n.parentElement.insertBefore(a,n),o.parentElement.insertBefore(n,o),o.parentElement.removeChild(o),s)try{n.play(),a.play()}catch(e){}var l={width:n.style.width,height:n.style.height,currentTarget:n.currentTarget};n.currentTarget=a.currentTarget,a.currentTarget=l.currentTarget,t.player.resizeAll()})),t},controls:function(){if(this.options.controls&&"stock"!=this.options.controls){MistUtil.class.add(this.container,"hasControls");var e=this.UI.buildStructure(this.skin.structure.controls);return MistUtil.isTouchDevice()&&this.size&&this.size.width>300&&(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"},s=function(e){window.removeEventListener("mousemove",a),window.removeEventListener("click",s),MistUtil.event.addListener(r,"click",o)},o=function(e){e.stopPropagation(),r.removeEventListener("click",o),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",s,t)};return MistUtil.event.addListener(r,"click",o),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].firstms<n&&(n=.001*r.info.meta.tracks[a].firstms);function s(){return r.player.api.duration<n?0:n}function o(){var e=r.info.meta.buffer_window;return void 0===e&&(e=r.player&&r.player.api&&r.player.api.buffered&&r.player.api.buffered.length?1e3*(r.player.api.duration-r.player.api.buffered.start(0)):6e4),.001*e}n==1/0&&(n=0),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=o();t=(e-r.player.api.duration+i)/i}else t=(e-s())/(r.player.api.duration-s());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;i<t.length;i++)this.removeChild(t[i]);if(e)for(i=0;i<e.length;i++)this.appendChild(this.buildBuffer(e.start(i),e.end(i)))};var l=0,c=!1;MistUtil.event.addListener(i,"progress",(function(){!function e(){(new Date).getTime()-l>1e3?(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&&!f?(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=isNaN(e)?MistUtil.getPos(this,e):e;return"live"==r.info.type?(t-1)*o()+r.player.api.duration:!!isFinite(r.player.api.duration)&&t*(r.player.api.duration-s())+s()},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(){f||(p.style.opacity=0)})),t.moveTooltip=function(e){var t=this.getPos(e);if(!1!==t){p.setDisplay(t),p.style.opacity=1;var i=MistUtil.getPos(this,e),r={bottom:20};i>.5?(r.right=100*(1-i)+"%",p.triangle.setMode("bottom","right")):(r.left=100*i+"%",p.triangle.setMode("bottom","left")),p.setPos(r)}else p.style.opacity=0};var h=document.createElement("span");h.setAttribute("class","mistvideo-realtime");var m=document.createTextNode("");h.appendChild(m),p.setDisplay=function(e){if(r.options.useDateTime&&r.info&&r.info.unixoffset){var i=t.getPos(1)-t.getPos(0),n=.001*(new Date).getTime()-(.001*r.info.unixoffset+t.getPos(1)),a=Math.max(i,n),s="";if("live"==r.info.type)if(a<60)s=MistUtil.format.ago(new Date(r.info.unixoffset+1e3*e));else{var o=.001*(new Date).getTime()-(.001*r.info.unixoffset+e);o<172800&&(s+=" - "+MistUtil.format.time(o))}else s+=MistUtil.format.time(e);if(a>=60){m.nodeValue=" at "+MistUtil.format.ago(new Date(r.info.unixoffset+1e3*e),1e3*a);var l=document.createDocumentFragment();l.appendChild(document.createTextNode(s)),l.appendChild(h),p.setHtml(l)}else m.nodeValue="",p.setText(s)}else p.setText(MistUtil.format.time(e))},MistUtil.event.addListener(e,"mousemove",(function(e){t.moveTooltip(e)}));var f=!1;return MistUtil.event.addListener(e,"mousedown",(function(i){if(1==i.which){f=!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&&(f=!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(){if(!this.player.api||!("muted"in this.player.api))return!1;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 n.player.api.volume&&!n.player.api.muted||MistUtil.class.add(r,"off"),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){if(!this.player.api||!("volume"in this.player.api))return!1;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 s=this;a.mode="mode"in e?e.mode:"vertical","vertical"==a.mode&&(a.style.transform="rotate(90deg)"),a.margin={start:.15,end:.1};var o=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;i<t.length;i++)t[i].setAttribute("vertical"==a.mode?"height":"width",e+"%")},MistUtil.event.addListener(o,"volumechange",(function(){a.set(s.player.api.muted?0:100*s.player.api.volume)}),a),a.set(s.player.api.muted?0:100*s.player.api.volume);var l=MistUtil.event.addListener(o,"loadedmetadata",(function(){"localStorage"in window&&null!=localStorage&&"mistVolume"in localStorage&&(s.player.api.volume=localStorage.mistVolume),MistUtil.event.removeListener(l)}));a.addPadding=function(e){return e*(1-(this.margin.start+this.margin.end))+this.margin.start},a.removePadding=function(e){var t=(e-this.margin.start)/(1-(this.margin.start+this.margin.end));return t=Math.max(t,0),t=Math.min(t,1)},a.getPos=function(e){return this.addPadding(MistUtil.getPos(this,e))},a.setVolume=function(e){s.player.api.muted=!1;var t=this.removePadding(MistUtil.getPos(this,e));t=1-Math.pow(1-t,.5),s.player.api.volume=t;try{localStorage.mistVolume=s.player.api.volume}catch(e){}},MistUtil.event.addListener(a,"mouseup",(function(e){1==e.which&&a.setVolume(e)}));var c=s.UI.buildStructure({type:"tooltip"});c.style.opacity=0,c.triangle.setMode("bottom","right"),n.style.position="relative",n.appendChild(c),MistUtil.event.addListener(a,"mouseover",(function(){c.style.opacity=1})),MistUtil.event.addListener(a,"mouseout",(function(){d||(c.style.opacity=0)})),a.moveTooltip=function(e){c.style.opacity=1;var t=MistUtil.getPos(this,e);c.setText(Math.round(100*this.removePadding(t))+"%"),c.setPos({bottom:46,right:100*(1-t)+"%"})},MistUtil.event.addListener(a,"mousemove",(function(e){a.moveTooltip(e)}));var d=!1;return MistUtil.event.addListener(a,"mousedown",(function(e){if(1==e.which){d=!0,a.setVolume(e),c.style.opacity=1;var t=MistUtil.event.addListener(document,"mousemove",(function(e){a.setVolume(e),a.moveTooltip(e)}),a),i=MistUtil.event.addListener(document,"mouseup",(function(e){1==e.which&&(d=!1,MistUtil.event.removeListener(t),MistUtil.event.removeListener(i),c.style.opacity=0,(!e.path||MistUtil.array.indexOf(e.path,a)<0)&&a.setVolume(e))}),a)}})),n},currentTime:function(){var e=this,t=document.createElement("div"),i=document.createTextNode(""),r=document.createElement("span");r.setAttribute("class","mistvideo-realtime"),t.appendChild(i),t.appendChild(r);var n=document.createTextNode("");r.appendChild(n);e.player.api;var a=MistUtil.format.time;return t.set=function(){var r,s=e.player.api.currentTime;if(e.options.useDateTime&&e.info&&e.info.unixoffset){var o=new Date(e.info.unixoffset+1e3*s),l=new Date-o;n.nodeValue="","live"==e.info.type?r=l<6e4?MistUtil.format.ago(o):l<432e5?"- "+MistUtil.format.time(.001*l):MistUtil.format.ago(o):(r=a(s),l>6e4&&e.size.width>=600&&(n.nodeValue=" (at "+MistUtil.format.ago(o)+")")),t.setAttribute("title",MistUtil.format.ago(o,3456e7))}else r=a(s),t.setAttribute("title",r);i.nodeValue=r},t.set(),MistUtil.event.addListener(e.video,"timeupdate",(function(){t.set()}),t),MistUtil.event.addListener(e.video,"seeking",(function(){t.set()}),t),t},totalTime:function(){var e=this,t=document.createElement("div"),i=document.createTextNode("");t.appendChild(i);this.player.api;return"live"==e.info.type?(i.nodeValue="live",t.className="live"):(t.set=function(r){if(!isNaN(r)&&isFinite(r))if(this.style.display="",e.options.useDateTime&&e.info&&"live"==e.info.type&&e.info.unixoffset){var n=new Date(1e3*r+e.info.unixoffset);i.nodeValue=MistUtil.format.ago(n),t.setAttribute("title",MistUtil.format.ago(n,3456e7))}else i.nodeValue=MistUtil.format.time(r),t.setAttribute("title",i.nodeValue);else this.style.display="none"},MistUtil.event.addListener(e.video,"durationchange",(function(){var i=e.player.api.duration;t.set(i)}),t)),t},playername:function(){if(this.playerName&&this.playerName in mistplayers){var e=document.createElement("span");return e.appendChild(document.createTextNode(mistplayers[this.playerName].name)),e}},mimetype:function(){if(this.source){var e=document.createElement("a");return e.href=this.source.url,e.target="_blank",e.title=e.href+" ("+this.source.type+")",e.appendChild(document.createTextNode(MistUtil.format.mime2human(this.source.type))),e}},logo:function(e){if("element"in e)return e.element;if("src"in e){var t=document.createElement("img");return t.src=e.src,t}},settings:function(){var e=this,t=this.skin.icons.build("settings"),i=void 0!==document.ontouchstart;return MistUtil.event.addListener(t,"click",(function(){e.container.hasAttribute("data-show-submenu")?(i&&e.container.setAttribute("data-hide-submenu",""),e.container.removeAttribute("data-show-submenu")):(e.container.setAttribute("data-show-submenu",""),e.container.removeAttribute("data-hide-submenu"))})),t},loop:function(){if("loop"in this.player.api&&"live"!=this.info.type){var e=this,t=this.skin.icons.build("loop");this.video;return t.set=function(){e.player.api.loop?MistUtil.class.remove(this,"off"):MistUtil.class.add(this,"off")},MistUtil.event.addListener(t,"click",(function(t){e.player.api.loop=!e.player.api.loop,this.set()})),t.set(),t}},fullscreen:function(){if("setSize"in this.player&&this.info.hasVideo&&"audio"!=this.source.type.split("/")[1]){var e=this,t=["requestFullscreen","webkitRequestFullscreen","mozRequestFullScreen","msRequestFullscreen","webkitEnterFullscreen"],i=[function(){return e.container},function(){return e.video}],r=!1;e:for(var n in i)for(var a in t)if(t[a]in i[n]()){(r={}).request=function(){return r.fullscreenableElement()[t[a]]()};var s=["exitFullscreen","webkitCancelFullScreen","mozCancelFullScreen","msExitFullscreen","webkitExitFullscreen"],o=["fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","webkitFullscreenElement"];r.cancel=function(){return document[s[a]]()},r.element=function(){return document[o[a]]},r.event=["fullscreenchange","webkitfullscreenchange","mozfullscreenchange","MSFullscreenChange","webkitfullscreenchange"][a],r.fullscreenableElement=i[n];break e}if(!r){var l=function(e){if("Escape"===e.key)r.cancel()};(r={event:"fakefullscreenchange",fullscreenableElement:function(){return e.container}}).request=function(){return r.element=function(){return e.container},MistUtil.event.send(r.event,null,document),document.addEventListener("keydown",l),!0},r.cancel=function(){return r.element=function(){return null},document.removeEventListener("keydown",l),MistUtil.event.send(r.event,null,document),!0},r.element=function(){return null}}var c=this.skin.icons.build("fullscreen");return MistUtil.event.addListener(c,"click",d),MistUtil.event.addListener(e.video,"dblclick",d),MistUtil.event.addListener(document,r.event,(function(){r.element()==r.fullscreenableElement()?e.container.setAttribute("data-fullscreen",""):e.container.hasAttribute("data-fullscreen")&&e.container.removeAttribute("data-fullscreen"),e.player.resizeAll()}),c),c}function d(){r.element()?r.cancel():r.request()}},"picture-in-picture":function(){if("setSize"in this.player&&this.info.hasVideo&&"audio"!=this.source.type.split("/")[1]&&document.pictureInPictureEnabled){var e=this;if("requestPictureInPicture"in e.video){var t=this.skin.icons.build("pip");return t.set=function(){document.pictureInPictureElement?MistUtil.class.remove(this,"off"):MistUtil.class.add(this,"off")},MistUtil.event.addListener(t,"click",(function(){var i;(i=document.pictureInPictureElement?document.exitPictureInPicture():e.video.requestPictureInPicture())?i.then((function(){t.set()})):t.set()})),t.set(),t}}},tracks:function(){if(this.info&&this.video){var e=this,t=document.createElement("table");return i(this.info.meta.tracks),MistUtil.event.addListener(e.video,"metaUpdate_tracks",(function(e){i(e.message.meta.tracks)}),t),t}function i(i){MistUtil.empty(t),i=MistUtil.tracks.parse(i);var r={},n={};function a(t,i){if(i?e.log("User selected "+t+" track with id "+i):(e.log("User selected automatic track selection for "+t),MistUtil.event.send("trackSetToAuto",t,e.video)),e.options.setTracks||(e.options.setTracks={}),e.options.setTracks[t]=i,!0===i&&r[t]&&MistUtil.event.send("change",null,r[t]),"setTrack"in e.player.api)return e.player.api.setTrack(t,i);var n={};for(var a in r)"subtitle"!=a&&""!=r[a].value&&(n[a]=r[a].value);return""!=i&&(n[t]=i),"setTracks"in e.player.api?e.player.api.setTracks(n):"setSource"in e.player.api?e.player.api.setSource(MistUtil.http.url.addParam(e.source.url,n)):void 0}var s=MistUtil.object.keys(i,(function(e,t){function i(e){switch(e){case"audio":return"aaaaaaa";case"video":return"aaaaaab";default:return e}}return i(e)>i(t)?1:i(e)<i(t)?-1:0}));for(var o in s){var l=s[o],c=i[l];if(!(MistUtil.array.indexOf(["video","audio","subtitle"],l)<=-1)){if("subtitle"==l){if(!("player"in e)||!("api"in e.player)||!("setWSSubtitle"in e.player.api)&&!("setSubtitle"in e.player.api)){e.log("Subtitle selection was disabled as this player does not support it.");continue}var d="html5/text/vtt";"setWSSubtitle"in e.player.api&&(d="html5/text/javascript");var u=!1;for(var p in e.info.source){var h=e.info.source[p];if(h.type==d&&MistUtil.http.url.split(h.url).protocol==MistUtil.http.url.split(e.source.url).protocol.replace(/^ws/,"http")){u=h.url.replace(/.srt$/,".vtt");break}}if(!u){e.log("Subtitle selection was disabled as a source could not be found.");continue}c[""]={trackid:"",different:{none:"None"}}}var m=document.createElement("tr");if(m.title="The current "+l+" track",t.appendChild(m),"decodingIssues"in e.skin.blueprints){var f=document.createElement("td");if(m.appendChild(f),"subtitle"!=l){var v=document.createElement("input");v.setAttribute("type","checkbox"),v.setAttribute("checked",""),v.setAttribute("title","Whether or not to play "+l),v.trackType=l,f.appendChild(v),n[l]=v,e.options.setTracks&&e.options.setTracks[l]&&("none"==e.options.setTracks[l]?v.checked=!1:v.checked=!0),MistUtil.event.addListener(v,"change",(function(){var e=0;for(var t in n)n[t].checked&&e++;if(0==e)for(var t in n)if(t!=this.trackType&&!n[t].checked){n[t].checked=!0,a(t,!0);break}var i="none";i=this.checked?this.trackType in r?r[this.trackType].value:"auto":"none",a(this.trackType,this.checked?i:"none")})),MistUtil.event.addListener(e.video,"playerUpdate_trackChanged",(function(e){e.message.type==l&&("none"==e.message.value?this.checked=!1:this.checked=!0)}),b)}}var y=document.createElement("td");m.appendChild(y),y.appendChild(document.createTextNode(MistUtil.format.ucFirst(l)+":"));f=document.createElement("td");m.appendChild(f);var g=MistUtil.object.keys(c);if(g.length>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,f.appendChild(b),"subtitle"!=l){var k=document.createElement("option");b.appendChild(k),k.value="",k.appendChild(document.createTextNode("Automatic"))}var M=S(c[MistUtil.object.keys(c)[0]].same);if(M.length)(x=document.createElement("span")).className="mistvideo-description",f.appendChild(x),f.appendChild(document.createTextNode(M.join(" ")));function w(e){return""==e?-1:Number(e)}var U=MistUtil.object.keys(c,(function(e,t){return w(e)-w(t)}));for(var p in U){var C=c[U[p]];k=document.createElement("option");b.appendChild(k),k.value="idx"in C?C.idx:C.trackid,MistUtil.object.keys(C.different).length?k.appendChild(document.createTextNode(S(C.different).join(" "))):k.appendChild(document.createTextNode("Track "+(Number(p)+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("setWSSubtitle"in e.player.api)e.player.api.setWSSubtitle(""==this.value?void 0:this.value);else if(""!=this.value){var t=MistUtil.object.extend({},c[this.value]);t.label=S(t.describe).join(" "),t.src=MistUtil.http.url.addParam(u,{track:this.value}),e.player.api.setSubtitle(t)}else e.player.api.setSubtitle()})),"localStorage"in window&&null!=localStorage&&"mistSubtitleLanguage"in localStorage)for(var p in c)if(c[p].lang==localStorage.mistSubtitleLanguage){b.value=p;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 x;(x=document.createElement("span")).className="mistvideo-description",f.appendChild(x),x.appendChild(document.createTextNode(S(c[g[0]].same).join(" ")))}}function S(e){var t={trackid:0,language:1,width:2,bps:3,fpks:4,channels:5,codec:6,rate:7};return MistUtil.object.values(e,(function(e,i,r,n){return t[e]>t[i]?1:t[e]<t[i]?-1:0}))}}}},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),a()}function n(){e.container.removeAttribute("data-loading"),i&&e.timers.stop(i),i=!1}function a(){i||(i=e.timers.start((function(){i=!1,e.monitor.vars&&e.monitor.vars.score>=.999?n():a()}),1e3))}var s=["waiting","seeking","stalled"];for(var o in s)MistUtil.event.addListener(e.video,s[o],(function(t){e.player.api&&!e.player.api.paused&&"container"in e&&r(t)}),t);s=["seeked","playing","canplay","paused","ended"];for(var o in s)MistUtil.event.addListener(e.video,s[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 "+(e.casting?"chromecast":"player")+" has encountered a problem"))}var s=document.createElement("p");if(n.appendChild(s),n.update=function(e){MistUtil.empty(s),s.innerHTML=e},t){e.info.on_error&&(t=e.info.on_error.replace(/\<error>/,t)),n.update(t);var o=document.createElement("p");if(o.className="details mistvideo-description",n.appendChild(o),i)o.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]))}}o.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(s,o){o||(o={softReload:!!(e.player&&e.player.api&&e.player.api.load),reload:!0,nextCombo:!!e.info,polling:!1,passive:!1});var l=o.type?o.type:s;if(!(l in a)){if(!0===o.reload&&(e.options.reloadDelay&&!isNaN(Number(e.options.reloadDelay))?o.reload=Number(e.options.reloadDelay):o.reload=10),o.passive){if(!0===r)return;if(r)return i.update(s),void(n=(new Date).getTime());t.setAttribute("data-passive","")}else t.removeAttribute("data-passive");var c;r&&t.clear(),r=!o.passive||"passive",n=(new Date).getTime(),e.casting||(c=this.log(s,"error"));var d=t.message(s,!1,o);i=d;var u=document.createElement("div");if(u.className="mistvideo-buttoncontainer",d.appendChild(u),MistUtil.empty(u),e.casting&&!o.passive){var p={type:"button",label:"Stop casting",onclick:function(){e.detachFromCast()}};isNaN(o.softReload+"")||(p.delay=o.softReload),u.appendChild(e.UI.buildStructure(p))}if(o.softReload&&!e.casting){p={type:"button",label:"Reload video",onclick:function(){e.player.api.load()}};isNaN(o.softReload+"")||(p.delay=o.softReload),u.appendChild(e.UI.buildStructure(p))}if(o.reload){p={type:"button",label:"Reload player",onclick:function(){e.reload("Reloading because reload button was clicked.")}};isNaN(o.reload+"")||(p.delay=o.reload),u.appendChild(e.UI.buildStructure(p))}if(o.nextCombo){p={type:"button",label:"Next source",onclick:function(){e.nextCombo()}};isNaN(o.nextCombo+"")||(p.delay=o.nextCombo),u.appendChild(e.UI.buildStructure(p))}if(o.ignore){p={type:"button",label:"Ignore",onclick:function(){this.clearError(),a[l]=!0}};isNaN(o.ignore+"")||(p.delay=o.ignore),u.appendChild(e.UI.buildStructure(p))}o.polling&&u.appendChild(e.UI.buildStructure({type:"polling"})),MistUtil.class.add(t,"show"),"container"in e&&e.container.removeAttribute("data-loading"),c&&c.defaultPrevented&&(e.log("Error event was defaultPrevented, not showing."),t.clear())}},t.clear=function(){for(var i=t.querySelectorAll("svg.icon.timeout"),n=0;n<i.length;n++)e.timers.stop(i[n].timeout);MistUtil.empty(t),MistUtil.class.remove(t,"show"),r=!1},this.clearError=t.clear,"video"in e){var s=["timeupdate","playing","canplay"];for(var o in s)MistUtil.event.addListener(e.video,s[o],(function(i){if(r){if("timeupdate"==i.type){if(0==e.player.api.currentTime)return;if((new Date).getTime()-n<2e3)return}e.log("Removing error window because of "+i.type+" event"),t.clear()}}),t)}return t},tooltip:function(){var e=document.createElement("div"),t="text",i=document.createTextNode("");e.appendChild(i),e.setText=function(n){i.nodeValue=n,"text"!=t&&(e.removeChild(r),e.appendChild(i),t="text")};var r=document.createElement("div");r.empty=function(){r.innerText="";for(var e=r.children.length-1;e>=0;e--)r.removeChild(r.children[e])},e.setHtml=function(n){r.empty(),r.appendChild(n),"html"!=t&&(e.removeChild(i),e.appendChild(r),t="html")};var n=document.createElement("div");return e.triangle=n,n.className="triangle",e.appendChild(n),n.setMode=function(e,t){e||(e="bottom"),t||(t="left");var i=["bottom","top","right","left"];for(var r in i){this.style[i[r]]="";var n=MistUtil.format.ucFirst(i[r]);this.style["border"+n]="",this.style["border"+n+"Color"]=""}var a={top:"bottom",bottom:"top",left:"right",right:"left"};this.style[e]="-10px",this.style["border"+MistUtil.format.ucFirst(a[e])]="none",this.style["border"+MistUtil.format.ucFirst(e)+"Color"]="transparent",this.style[t]=0,this.style["border"+MistUtil.format.ucFirst(a[t])]="none"},e.setPos=function(e){var t={left:"auto",right:"auto",top:"auto",bottom:"auto"};for(var i in MistUtil.object.extend(t,e),t)isNaN(t[i])||(t[i]+="px"),this.style[i]=t[i]},e},button:function(e){var t=document.createElement("button"),i=this;if(e.onclick&&(MistUtil.event.addListener(t,"click",(function(){e.onclick.call(i,arguments)})),e.delay)){var r=this.UI.buildStructure({type:"timeout",delay:e.delay,function:e.onclick});r&&t.appendChild(r)}return t.appendChild(document.createTextNode(e.label)),t},videobackground:function(e){e||(e={}),e.delay||(e.delay=5);for(var t=document.createElement("div"),i=this,r=[],n=0;n<2;n++){var a=document.createElement("canvas");a._context=a.getContext("2d"),t.appendChild(a),r.push(a)}var s=0,o=!1;function l(){if(e.alwaysDisplay||i.video.videoWidth/i.video.videoHeight!=t.clientWidth/t.clientHeight){r[s].removeAttribute("data-front"),++s>=r.length&&(s=0);var n=r[s],a=n._context;n.width=i.video.videoWidth,n.height=i.video.videoHeight,a.drawImage(i.video,0,0),n.setAttribute("data-front","")}i.player.api.paused?o=!1:i.timers.start((function(){l()}),1e3*e.delay)}return MistUtil.event.addListener(i.video,"playing",(function(){o||(l(),o=!0)})),t},subtitles:function(e){if(!("WebSocket"in window))return!1;var t=this;if(!("player"in t)||!("api"in t.player)||!("currentTime"in t.player.api))return!1;if(!("metaTrackSubscriptions"in t))return!1;var i=document.createElement("div"),r=document.createElement("span");i.appendChild(r);var n=document.createTextNode("");r.appendChild(n);var a=!1;function s(e){n.nodeValue=e.data.replace(/\<\/?[bui]\>/gi,"").replace(/{\/?[bui]}/gi,"").replace(/{\\a\d+}/gi,"").replace(/\<\/?font[^>]*?\>/gi,""),a&&(t.timers.stop(a),a=null),function i(r){a=t.timers.start((function(){if(t.player.api.paused)var r=MistUtil.event.addListener(t.video,"playing",(function(){i(e.time+("duration"in e?e.duration:5e3)-1e3*t.player.api.currentTime),MistUtil.event.removeListener(r)}));else n.nodeValue=""}),r)}("duration"in e?e.duration:5e3)}if(MistUtil.event.addListener(t.video,"seeked",(function(){n.nodeValue="",a&&t.timers.stop(a),a=null})),!("setWSSubtitle"in t.player.api)){var o=!1;t.player.api.setWSSubtitle=function(e){e!=o&&(void 0!==e&&t.metaTrackSubscriptions.add(e,s),e!=o&&t.metaTrackSubscriptions.remove(o,s),o="undefined"!=e&&e)}}return i},chromecast:function(){var e=this;if(!(!"".indexOf||e.options.host.indexOf("localhost")>-1||e.options.host.indexOf("::1")>-1)){var t,i,r,n,a=document.createElement("div"),s=document.createElement("div");s.className="mistvideo-casting";var o={},l={currentTime:!1,paused:!0,volume:1,muted:!1,buffer:[],loop:e.player.api?e.player.api.loop:e.options.loop};if(e.casting=!1,window.chrome&&window.chrome.cast||window.loadedCastApi)"loading"==window.loadedCastApi?(e.log("Not appending chromecast script - still loading"),e.timers.start((function(){d()}),200)):(e.log("Not appending chromecast script - already loaded"),d());else{window.__onGCastApiAvailable=function(t,i){t||e.log("Error while loading chromecast API: "+i),d()},window.loadedCastApi="loading";var c=document.createElement("script");c.setAttribute("src","//www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"),document.head.appendChild(c),e.log("Appending chromecast script")}return a}function d(c){if(!window.chrome||!window.chrome.cast||!window.chrome.cast.isAvailable||c>5)return a.parentNode&&a.parentNode.removeChild(a),e.log("Chromecast is not supported"),void console.warn(chrome,chrome.cast,chrome.cast?chrome.cast.isAvailable:void 0,cast);if(!window.cast)return c||(c=0),e.log("Casting api loaded but cast function not yet available, retrying.."),void e.timers.start((function(){d(c++)}),200);e.log("Chromecast API loaded"),window.loadedCastApi&&"loading"!=window.loadedCastApi||(window.loadedCastApi=!0);var u=document.createElement("google-cast-launcher");function p(a){MistUtil.class.remove(u,"active"),MistUtil.class.remove(e.container,"casting"),s.parentNode&&s.parentNode.removeChild(s),!a&&cast.framework.CastContext.getInstance().getCurrentSession()&&cast.framework.CastContext.getInstance().getCurrentSession().endSession(!0),t?(e.player.api=t,t.currentTime=l.currentTime,t.play(),e.reload=i,e.nextCombo=r,e.unload=n):e.player.api.play(),e.player.api&&e.player.api.setTracks&&MistUtil.object.keys(o).length&&e.player.api.setTracks(o),e.casting=!1,e.log("Detached chromecast session")}a.appendChild(u),cast.framework.CastContext.getInstance().setOptions({receiverApplicationId:"E5F1558C",autoJoinPolicy:chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED}),e.detachFromCast=p,u.addEventListener("click",(function(a){if(a.stopPropagation(),MistUtil.class.has(u,"active"))p();else{function c(){cast.framework.CastContext.getInstance().getCurrentSession().addMessageListener("urn:x-cast:mistcaster",(function(t,i){if(e.destroyed&&p(),(i=JSON.parse(i)).type)switch(i.type){case"log":case"error":e.log("[Chromecast] "+i.message,i.type);break;case"showError":e.showError.apply(e,i.args);break;case"event":switch(i.event){case"timeupdate":l.currentTime=i.currentTime,MistUtil.event.send(i.event,"chromecast",e.video);break;case"progress":l.buffer=i.buffer,MistUtil.event.send(i.event,"chromecast",e.video);break;case"pause":case"paused":case"ended":case"play":case"playing":l.paused=i.paused,MistUtil.event.send(i.event,"chromecast",e.video);break;case"volumechange":l.volume=i.volume,l.muted=i.muted,MistUtil.event.send(i.event,"chromecast",e.video);break;default:MistUtil.event.send(i.event,"chromecast",e.video)}break;case"detach":i.n==e.n&&p(!0);break;default:console.log("Unknown chromecast message type",i)}}));var a={type:"load",n:e.n,options:{host:e.options.host,loop:e.options.loop,poster:e.options.poster,streaminfo:e.options.streaminfo,urlappend:e.options.urlappend,forcePriority:e.options.forcePriority,setTracks:e.options.setTracks,controls:!1,skin:"default"},stream:e.stream};e.info&&"live"!=e.info.type&&(a.time=e.player.api.currentTime),"dev"==e.options.skin&&(a.options.skin=e.options.skin),e.player&&e.player.api&&(a.volume=e.player.api.volume,a.muted=e.player.api.muted,a.options.loop=e.player.api.loop),MistCast.send(a),t=e.player.api,i=e.reload,r=e.nextCombo,n=e.unload,o=e.options.setTracks?e.options.setTracks:{},e.player.api=new Proxy(t,{get:function(e,t,i){var r=e[t];switch(t){case"muted":case"volume":case"currentTime":case"paused":case"loop":return l[t];case"buffered":return new function(){this.length=l.buffer.length,this.start=function(e){return l.buffer[e][0]},this.end=function(e){return l.buffer[e][1]}};case"setTracks":case"play":case"pause":return function(){for(var e=[],i=0;i<arguments.length;i++)e.push(arguments[i]);"setTracks"==t&&MistUtil.object.extend(o,arguments[0]),MistCast.send({type:"cmd",cmd:t,args:e})}}return r},set:function(e,t,i){"loop"==t&&(l[t]=i),MistCast.send({type:"set",cmd:t,value:i})}}),t.pause(),e.reload=function(){MistCast.send({type:"reload"})},e.nextCombo=function(){MistCast.send({type:"nextCombo"})},e.unload=function(){return p(),n.apply(this,arguments)},(a=cast.framework.CastContext.getInstance().getCurrentSession().getCastDevice())&&a.friendlyName&&(s.innerHTML="Casting to "+a.friendlyName);var c=function(){"SESSION_ENDED"==cast.framework.CastContext.getInstance().getSessionState()&&(MistUtil.class.has(u,"active")&&p(),cast.framework.CastContext.getInstance().removeEventListener(cast.framework.CastContextEventType.SESSION_STATE_CHANGED,c))};cast.framework.CastContext.getInstance().addEventListener(cast.framework.CastContextEventType.SESSION_STATE_CHANGED,c),e.log("Attached chromecast session")}MistUtil.class.add(u,"active"),s.innerHTML="Select a device to cast to",e.container.appendChild(s),MistUtil.class.add(e.container,"casting"),e.log("chromecast: pausing player"),e.player.api.pause(),e.container.setAttribute("data-loading","waiting for cast"),e.casting=!0,window.MistCast||(window.MistCast={send:function(e){cast.framework.CastContext.getInstance().getCurrentSession().sendMessage("urn:x-cast:mistcaster",JSON.stringify(e))}}),cast.framework.CastContext.getInstance().getCurrentSession()?c():cast.framework.CastContext.getInstance().requestSession().then((function(){if(!cast.framework.CastContext.getInstance().getCurrentSession())throw"Could not connect to the cast device";c()}),(function(t){e.log("Chromecast session ended: "+t),p()}))}}),!0)}}},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,s=!0;function o(e,r,o){if(o||(o={}),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",o.type&&"log"!=o.type&&(MistUtil.class.add(l,"type-"+o.type),r=MistUtil.format.ucFirst(o.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 o&&(c.title="Video playback time: "+MistUtil.format.time(o.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),s&&(t.scrollTop=t.scrollHeight),n={message:r,counter:m}}for(var l in MistUtil.event.addListener(t,"scroll",(function(){s=t.scrollTop+t.clientHeight>=t.scrollHeight-5})),r.logs)o(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),o(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),o(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){if("getVideoPlaybackQuality"in e.player.api){var t=e.player.api.getVideoPlaybackQuality();if(t)return t.droppedVideoFrames?MistUtil.format.number(t.droppedVideoFrames):0}if("webkitDroppedFrameCount"in e.player.api)return e.player.api.webkitDroppedFrameCount}},"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(){var t;return e.player.monitor&&"currentBps"in e.player.monitor?(t=MistUtil.format.bits(e.player.monitor.currentBps))?t+"ps":t:e.player.api&&"currentBps"in e.player.api?(t=MistUtil.format.bits(e.player.api.currentBps()))?t+"ps":t:void 0},"Framerate in":function(){if(e.player.api&&"framerate_in"in e.player.api)return MistUtil.format.number(e.player.api.framerate_in())},"Framerate out":function(){if(e.player.api&&"framerate_out"in e.player.api)return MistUtil.format.number(e.player.api.framerate_out())}},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 s=document.createTextNode(e.value?e.value:"");a.appendChild(s);var o=document.createElement("span");a.appendChild(o),i.set=function(e){if(0!==e&&(this.style.display=""),"object"==typeof e){try{if(e instanceof Promise)return void e.then((function(e){i.set(e)}),(function(){}))}catch(e){}if("val"in e&&(s.nodeValue=e.val,a.className="value"),o.children.length)return(t=o.children[0]).addData(e);var t=MistUtil.createGraph({x:[e.x],y:[e.y]},e.options);return o.style.display="",MistUtil.empty(o),o.appendChild(t)}return s.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 s in t.info.source){var o=t.info.source[s];if(!(o.type in a)){a[o.type]=1;n=document.createElement("option");r.appendChild(n),n.value=o.type,n.appendChild(document.createTextNode(MistUtil.format.mime2human(o.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 s=t.info.source[a];n=document.createElement("option");r.appendChild(n),n.value=a,n.appendChild(document.createTextNode(s.url+" ("+MistUtil.format.mime2human(s.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","mistvideo-displayCombo"],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):"perc"in e&&(n+=" ("+Math.round(10*e.perc)/10+"%)"),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 s="maxwidth"in t&&t.maxwidth?t.maxwidth:window.innerWidth,o="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),s&&r>s&&l(r/s),o&&n>o&&l(n/o)}}}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 s in i.info.meta.tracks)a=Math.max(a,i.info.meta.tracks[s].lastms);e.lastms=a}else{var o=i.resumeTime;if(o){var l=function(){i.player&&i.player.api&&(i.player.api.currentTime=o),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)&&(e<this.threshold()||void 0)},action:function(){var e=this.vars.score;this.MistVideo.showError("Poor playback: "+Math.max(0,Math.round(100*e))+"%",{passive:!0,reload:!0,nextCombo:!0,ignore:!0,type:"poor_playback"})}},"monitor"in i.options&&(i.monitor.default=MistUtil.object.extend({},i.monitor),MistUtil.object.extend(i.monitor,i.options.monitor));var r=["loadstart","play","playing"];for(var n in r)MistUtil.event.addListener(i.video,r[n],(function(){i.monitor.init()}));r=["loadeddata","pause","abort","emptied","ended"];for(var n in r)MistUtil.event.addListener(i.video,r[n],(function(){i.monitor&&i.monitor.destroy()}));r=["seeking","seeked","ratechange"];for(var n in r)MistUtil.event.addListener(i.video,r[n],(function(){i.monitor&&i.monitor.reset()}));if("currentTime"in i.player.api){var a=MistUtil.sources.find(i.info.source,{type:"html5/text/javascript",protocol:"ws"+("s"==location.protocol.charAt(location.protocol.length-2)?"s":"")+":"});if(a&&(i.metaTrackSubscriptions={subscriptions:{},socket:null,listeners:{},init:function(){var e=this;i.player.api.metaTrackSocket?this.socket=new i.player.api.metaTrackSocket:this.socket=new WebSocket(MistUtil.http.url.addParam(i.urlappend(a.url),{rate:1})),e.send_queue=[],e.checktimer=null,e.s=function(t){if(e.socket.readyState==e.socket.OPEN)return e.socket.send(JSON.stringify(t)),!0;e.socket.readyState>=e.socket.CLOSING&&e.init(),this.send_queue.push(t)};var t=!1;if(e.socket.setTracks=function(){e.s({type:"tracks",meta:MistUtil.object.keys(e.subscriptions).join(",")})},e.socket.onopen=function(){for(i.log("Metadata socket opened"),e.socket.setTracks(),1!=i.player.api.playbackRate&&e.s({type:"set_speed",play_rate:i.player.api.playbackRate}),e.s({type:"seek",seek_time:Math.round(1e3*i.player.api.currentTime),ff_to:Math.round(1e3*(i.player.api.currentTime+5))}),e.socket.addEventListener("message",(function(r){if(r.data){var n=JSON.parse(r.data);if(n){if("time"in n&&"track"in n&&"data"in n){var a=!1;if("all"in e.subscriptions&&(e.subscriptions.all.buffer.push(n),a=!0),n.track in e.subscriptions&&(e.subscriptions[n.track].buffer.push(n),a=!0),a)if(e.checktimer){var s=i.timers.list[e.checktimer];if(s)s>(new Date).getTime()+n.time-1e3*i.player.api.currentTime&&(i.log("The metadata socket received a message that should be displayed sooner than the current check time; resetting"),i.timers.stop(e.checktimer),e.checktimer=null,e.check())}else e.check()}if("type"in n)switch(n.type){case"on_time":!t&&n.data.current>1e3*(i.player.api.currentTime+30)&&(t=!0,e.s({type:"hold"}),i.log("Pausing metadata buffer because it is very far ahead, checking again in 5 seconds: "+n.data.current+" > "+1e3*i.player.api.currentTime),i.timers.start((function(){i.player.api.paused||e.s({type:"play"}),e.s({type:"fast_forward",ff_to:Math.round(1e3*(i.player.api.currentTime+5))})}),5e3));break;case"seek":for(var o in e.subscriptions)e.subscriptions[o].buffer=[];i.log("Cleared metadata buffer after completed seek"),e.checktimer&&(i.timers.stop(e.checktimer),e.checktimer=null)}}else i.log("Subtitle websocket received invalid message.")}else i.log("Subtitle websocket received empty message.")})),e.socket.onclose=function(){i.log("Metadata socket closed")};e.send_queue.length&&e.socket.readyState==e.socket.OPEN;)e.s(e.send_queue.shift())},!("seeked"in this.listeners)){var r=(new Date).getTime();e.check=function(){if(e.checktimer&&(i.timers.stop(e.checktimer),e.checktimer=null),!i.player.api.paused){var t=null;for(var n in e.subscriptions){for(var a=e.subscriptions[n].buffer;a.length&&a[0].time<=1e3*i.player.api.currentTime;){var s=a.shift();if(!(s.time<1e3*(i.player.api.currentTime-5)))for(var o in e.subscriptions[n].callbacks)e.subscriptions[n].callbacks[o].call(i,s)}a.length&&(t=Math.min(null===t?1e9:t,a[0].time))}var l=(new Date).getTime();if(l>r+5e3&&(e.s({type:"fast_forward",ff_to:Math.round(1e3*(i.player.api.currentTime+5))}),r=l),t){var c=t-1e3*i.player.api.currentTime;e.checktimer=i.timers.start((function(){e.check()}),c)}}},this.listeners.seeked=MistUtil.event.addListener(i.video,"seeked",(function(){for(var t in e.subscriptions)e.subscriptions[t].buffer=[];e.s({type:"seek",seek_time:Math.round(1e3*i.player.api.currentTime),ff_to:Math.round(1e3*(i.player.api.currentTime+5))}),r=(new Date).getTime()})),this.listeners.pause=MistUtil.event.addListener(i.video,"pause",(function(){e.s({type:"hold"}),i.timers.stop(e.checktimer),e.checktimer=null})),this.listeners.playing=MistUtil.event.addListener(i.video,"playing",(function(){e.s({type:"play"}),e.checktimer||e.check()})),this.listeners.ratechange=MistUtil.event.addListener(i.video,"ratechange",(function(){e.s({type:"set_speed",play_rate:i.player.api.playbackRate})}))}e.socket.readyState==e.socket.OPEN&&e.socket.onopen()},destroy:function(){for(var e in i.log("Closing metadata socket.."),this.socket.close(),this.socket=null,this.subscriptions={},this.listeners)MistUtil.event.removeListener(this.listeners[e]);this.listeners={}},add:function(e,t){"function"!=typeof e||t||(t=e,e="all"),"function"==typeof t&&(e in this.subscriptions||(this.subscriptions[e]={buffer:[],callbacks:[]}),this.subscriptions[e].callbacks.push(t),null===this.socket?this.init():this.socket.setTracks())},remove:function(e,t){if(e in this.subscriptions){for(var i in this.subscriptions[e].callbacks)if(t==this.subscriptions[e].callbacks[i]){this.subscriptions[e].callbacks.splice(i,1);break}0==this.subscriptions[e].callbacks.length&&(delete this.subscriptions[e],MistUtil.object.keys(this.subscriptions).length?this.socket.setTracks():this.destroy())}}},"function"==typeof t.subscribeToMetaTrack&&(t.subscribeToMetaTrack=[["all",t.subscribeToMetaTrack]]),t.subscribeToMetaTrack.length))for(var n in"object"!=typeof t.subscribeToMetaTrack[0]&&(t.subscribeToMetaTrack=[t.subscribeToMetaTrack]),t.subscribeToMetaTrack)i.metaTrackSubscriptions.add.apply(i.metaTrackSubscriptions,t.subscribeToMetaTrack[n])}}MistUtil.empty(i.options.target),new MistSkin(i),i.container=new MistUI(i),i.options.target.appendChild(i.container),i.container.setAttribute("data-loading",""),i.video.p=i.player;r=["abort","canplay","canplaythrough",,"emptied","ended","loadeddata","loadedmetadata","loadstart","pause","play","playing","ratechange","seeked","seeking","stalled","volumechange","waiting","metaUpdate_tracks","resizing"];for(var n in r)MistUtil.event.addListener(i.video,r[n],(function(e){e.message&&"chromecast"==e.message||i.log("Player event fired: "+e.type)}));if(MistUtil.event.addListener(i.video,"error",(function(e){var t;if("player"in i&&"api"in i.player&&"error"in i.player.api&&i.player.api.error)if("message"in i.player.api.error)t=i.player.api.error.message;else if("code"in i.player.api.error&&i.player.api.error instanceof MediaError){var r={1:"MEDIA_ERR_ABORTED: The fetching of the associated resource was aborted by the user's request.",2:"MEDIA_ERR_NETWORK: Some kind of network error occurred which prevented the media from being successfully fetched, despite having previously been available.",3:"MEDIA_ERR_DECODE: Despite having previously been determined to be usable, an error occurred while trying to decode the media resource, resulting in an error.",4:"MEDIA_ERR_SRC_NOT_SUPPORTED: The associated resource or media provider object (such as a MediaStream) has been found to be unsuitable."};t=i.player.api.error.code in r?r[i.player.api.error.code]:"MediaError code "+i.player.api.error.code}else"string"!=typeof(t=i.player.api.error)&&(t=JSON.stringify(t));else t="An error was encountered.";"Stream is online"==i.state?i.showError(t):(i.log(t,"error"),i.showError(i.state,{polling:!0}))})),"setSize"in i.player&&(i.player.videocontainer=i.video.parentNode,i.video.currentTarget=i.options.target,MistUtil.class.has(i.options.target,"mistvideo-secondaryVideo")||(i.player.resizeAll=function(){function e(t,i){if(t.video.currentTarget==i)return t.video;if(t.secondary)for(var r=0;r<t.secondary.length;r++){var n=e(t.secondary[r].MistVideo,i);if(n)return n}return!1}var t=e(i,i.options.target);if(!t)throw"Main video not found";if(t.p.resize(),"secondary"in i){function r(t){if(t.MistVideo){if("player"in t.MistVideo){var n=e(i,t.MistVideo.options.target);if(!n)throw"Secondary video not found";n.p.resize()}}else i.timers.start((function(){r(t)}),100)}for(var n in i.secondary)r(i.secondary[n])}}),i.player.resize=function(e,t){var r=i.video.currentTarget.querySelector(".mistvideo");if(t||(t={width:i.video.clientWidth,height:i.video.clientHeight}),r.hasAttribute("data-fullscreen"))size={width:window.innerWidth,height:window.innerHeight},this.setSize(size);else{if(size=i.calcSize(e),this.setSize(size),r.style.width=size.width+"px",r.style.height=size.height+"px",i.options.fillSpace&&(!e||!e.reiterating))return this.resize({width:window.innerWidth,height:!1,reiterating:!0},t);if(i.video.currentTarget.clientHeight&&i.video.currentTarget.clientHeight<size.height)return this.resize({width:!1,height:i.video.currentTarget.clientHeight,reiterating:!0},t);if(i.video.currentTarget.clientWidth&&i.video.currentTarget.clientWidth<size.width)return this.resize({width:i.video.currentTarget.clientWidth,height:!1,reiterating:!0},t)}return size.width==t.width&&size.height==t.height||(i.log("Player size calculated: "+size.width+" x "+size.height+" px"),MistUtil.event.send("player_resize",size,i.video)),!0},MistUtil.class.has(i.options.target,"mistvideo-secondaryVideo")||(MistUtil.event.addListener(window,"resize",(function(){i.destroyed||i.player.resizeAll()}),i.video),MistUtil.event.addListener(i.options.target,"resize",(function(){i.player.resizeAll()}),i.video),i.player.resizeAll())),i.player.api){if("setSource"in i.player.api&&(i.sourceParams={},i.player.api.setSourceParams=function(e,t){MistUtil.object.extend(i.sourceParams,t),i.player.api.setSource(MistUtil.http.url.addParam(e,t))},"setTracks"in i.player.api||(i.player.api.setTracks=function(e){var t=MistUtil.tracks.parse(i.info.meta.tracks);for(var r in e)r in t&&(e[r]in t[r]||"none"==e[r])||(i.log("Skipping trackselection of "+r+" track "+e[r]+" because it does not exist"),delete e[r]);var n=i.source.url,a=i.player.api.currentTime;if(this.setSourceParams(n,e),"live"!=i.info.type){var s=function(){i.player.api.currentTime=a,this.removeEventListener("loadedmetadata",s)};MistUtil.event.addListener(i.video,"loadedmetadata",s)}})),!("setTracks"in i.player.api)&&"setTrack"in i.player.api&&(i.player.api.setTracks=function(e){for(var t in e)i.player.api.setTrack(t,e[t])}),t.setTracks){var s=MistUtil.object.extend({},t.setTracks);if("subtitle"in t.setTracks&&"setSubtitle"in i.player.api&&i.player.onready((function(){var e=!1;for(var t in i.info.source){var r=i.info.source[t];if("html5/text/vtt"==r.type&&MistUtil.http.url.split(r.url).protocol==MistUtil.http.url.split(i.source.url).protocol){e=r.url.replace(/.srt$/,".vtt");break}}if(e){var n=MistUtil.tracks.parse(i.info.meta.tracks);"subtitle"in n&&s.subtitle in n.subtitle&&(meta=n.subtitle[s.subtitle],meta.src=MistUtil.http.url.addParam(e,{track:s.subtitle}),meta.label="automatic",meta.lang="unknown",i.player.api.setSubtitle(meta),MistUtil.event.send("playerUpdate_trackChanged",{type:"subtitle",trackid:s.subtitle},i.video),delete s.subtitle)}})),"setTrack"in i.player.api)i.player.onready((function(){for(var e in s)i.player.api.setTrack(e,s[e]),MistUtil.event.send("playerUpdate_trackChanged",{type:e,trackid:s[e]},i.video)}));else if("setTracks"in i.player.api)for(var n in i.player.onready((function(){i.player.api.setTracks(s)})),s)MistUtil.event.send("playerUpdate_trackChanged",{type:n,trackid:s[n]},i.video)}if(i.player.api.ABR_resize&&i.options.ABR_resize){var o=!1;MistUtil.event.addListener(i.video,"player_resize",(function(e){i.options.setTracks&&i.options.setTracks.video||(o&&i.timers.stop(o),o=i.timers.start((function(){i.player.api.ABR_resize(e.message),o=!1}),1e3))})),MistUtil.event.addListener(i.video,"trackSetToAuto",(function(e){"video"==e.message&&i.player.api.ABR_resize({width:i.video.clientWidth,height:i.video.clientHeight})})),i.player.api.ABR_resize({width:i.video.clientWidth,height:i.video.clientHeight})}}for(var n in i.player.onreadylist)i.player.onreadylist[n]();MistUtil.event.send("initialized",null,t.target),i.log("Initialized"),i.options.callback&&t.callback(i)}))):i.options.startCombo?(delete i.options.startCombo,i.unload("No compatible players found - retrying without startCombo."),mistPlay(i.stream,i.options)):(i.showError("No compatible player/source combo found.",{reload:!0}),MistUtil.event.send("initializeFailed",null,t.target),i.log("Initialization failed"))}function a(){var e=MistUtil.http.url.addParam(i.urlappend(t.host+"/json_"+encodeURIComponent(i.stream)+".js"),{metaeverywhere:1,inclzero:1});i.log("Requesting stream info from "+e),MistUtil.http.get(e,(function(e){i.destroyed||n(JSON.parse(e))}),(function(e){var r="Connection failed: the media server at "+i.options.host+" may be offline";i.showError(r,{reload:30}),i.info||(MistUtil.event.send("initializeFailed",null,t.target),i.log("Initialization failed"))}))}if(t||(t={}),"undefined"!=typeof mistoptions&&(t=MistUtil.object.extend(MistUtil.object.extend({},mistoptions),t)),(t=MistUtil.object.extend({host:null,autoplay:!0,controls:!0,loop:!1,poster:!1,muted:!1,callback:!1,streaminfo:!1,startCombo:!1,forceType:!1,forcePlayer:!1,forceSource:!1,forcePriority:!1,monitor:!1,reloadDelay:!1,urlappend:!1,setTracks:!1,fillSpace:!1,width:!1,height:!1,maxwidth:!1,maxheight:!1,ABR_resize:!0,ABR_bitrate:!0,useDateTime:!0,subscribeToMetaTrack:!1,MistVideoObject:!1},t)).host&&(t.host=MistUtil.http.url.sanitizeHost(t.host)),this.options=t,this.stream=e,this.info=!1,window.MistInstances||(window.MistInstances=0),window.MistInstances++,this.n=window.MistInstances,this.logs=[],this.log=function(e,r){r||(r="log");var n=MistUtil.event.send(r,e,t.target),a={type:r};if(this.logs.push({time:new Date,message:e,data:a}),"dev"==this.options.skin)try{var s="["+(r||"log")+"] "+(i.destroyed?"[DESTROYED] ":"")+"[#"+i.n+"] "+(this.player&&this.player.api?MistUtil.format.time(this.player.api.currentTime,{ms:!0})+" ":"")+e;r&&"log"!=r?console.warn(s):console.log(s)}catch(e){}return n},this.log("Initializing.."),this.bootMs=(new Date).getTime(),this.timers={list:{},start:function(e,t){var r=setTimeout((function(){delete i.timers.list[r],i.destroyed||e()}),t);return this.list[r]=new Date((new Date).getTime()+t),r},stop:function(e){var t;for(var i in"all"==e?t=this.list:(t={})[e]=1,t)clearTimeout(i),delete this.list[i]}},this.errorListeners=[],this.resumeTime=!1,this.urlappend=function(e){return this.options.urlappend&&(e=MistUtil.http.url.append(e,this.options.urlappend)),e},t.reloadDelay&&t.reloadDelay>3600&&(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 s 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[s].shortname=s;e.forcePlayer&&mistplayers[e.forcePlayer]?(n=[mistplayers[e.forcePlayer]],i.log("Forcing player "+e.forcePlayer)):n=MistUtil.object.values(mistplayers),r=[].concat(r);var o={first:"source",source:[function(e){return"origIndex"in e||(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.";o.source=e.forcePriority.source.concat(o.source),MistUtil.array.multiSort(r,o.source)}if("player"in e.forcePriority){if(!(e.forcePriority.player instanceof Array))throw"forcePriority.player is not an array.";o.player=e.forcePriority.player.concat(o.player),MistUtil.array.multiSort(n,o.player)}"first"in e.forcePriority&&(o.first=e.forcePriority.first),"player"==o.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(s=0;s<n.length;s++)if(n[s].shortname==e.startCombo.player){e.startCombo.player=s;break}}function d(t){return e.startCombo&&!e.startCombo.started[t]?e.startCombo[t]==c[t].current||e.startCombo[t]==c[t].list[c[t].current]?(e.startCombo.started[t]=!0,1):2:0}var u={score:0,source_index:null,player:null};function p(e){if(!0===e)return 1.9;var t={video:2,audio:1,subtitle:.5},i=0;for(var r in e)i+=t[e[r]];return i}var h={};for(var s in i.info.meta.tracks)"meta"==i.info.meta.tracks[s].type?h[i.info.meta.tracks[s].codec]=1:h[i.info.meta.tracks[s].type]=1;var m=p(MistUtil.object.keys(h));for(var f in c[l.outer].list)if(c[l.outer].current=f,!(d(l.outer)>=2))for(var v in c[l.inner].list)if(c[l.inner].current=v,!(d(l.inner)>=1)){a=c.source.list[c.source.current];var y=c.player.list[c.player.current].shortname,g=mistplayers[y];if(g.isMimeSupported(a.type)){var b=g.isBrowserSupported(a.type,a,i);if(b){var k=p(b);if(k>u.score&&(t||i.log("Found a "+(u.score?"better":"working")+" combo: "+g.name+" with "+a.url+" (Score: "+k+")"),(u={score:k,player:y,source:a,source_index:c.source.current}).score==m))return u}}}return!!u.score&&u},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("Selected: "+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 through websocket..");var t,s=i.options.host.replace(/^http/i,"ws");s=MistUtil.http.url.addParam(i.urlappend(s+"/json_"+encodeURIComponent(i.stream)+".js"),{metaeverywhere:1,inclzero:1});try{t=new WebSocket(s)}catch(e){return i.log("Error while attempting to open WebSocket to "+s),void a()}i.socket=t,t.die=!1,t.destroy=function(){this.die=!0,i.reporting&&(i.reporting.reportStats(),i.reporting=!1),this.onclose=function(){},this.close()},t.timeOut=i.timers.start((function(){t.readyState<=1&&(t.destroy(),a())}),5e3),t.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&&i.reporting&&i.reporting.stats.add("nWaiting")})),MistUtil.event.addListener(e,"stalled",(function(){i&&i.reporting&&i.reporting.stats.add("nStalled")})),MistUtil.event.addListener(i.options.target,"error",(function(e){i&&i.reporting&&(i.reporting.stats.add("nError"),i.reporting.stats.set("lastError",e.message))}),e),Object&&Object.defineProperty){var r=0,n=!1,a=0,s=!1,o=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+(s?(new Date).getTime()-s:0)}}),Object.defineProperty(c,"timeUnpaused",{get:function(){return o+(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,s=(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,s=!1}));MistUtil.event.addListener(e,"playing",(function(){o=c.timeUnpaused,l=(new Date).getTime()})),MistUtil.event.addListener(e,"pause",(function(){o=c.timeUnpaused,l=!1}))}this.reportStats()}})},t.onclose=function(t){if(!this.die)return this.wasConnected?(i.log("Reopening websocket.."),void e()):void a()};var o=!1;t.addEventListener("message",(function(e){t.timeOut&&(i.timers.stop(t.timeOut),t.timeOut=!1);var a=JSON.parse(e.data);if(a||i.showError("Error while parsing stream status stream. Obtained: "+e.data.toString(),{reload:!0}),"error"in a){var s;e=a.error;switch("on_error"in a?(i.log(e),e=a.on_error):"perc"in a&&(e+=" ("+Math.round(10*a.perc)/10+"%)"),i.state=a.error,a.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(a.error,"error"),o||(o=MistUtil.event.addListener(i.video,"ended",(function(){i.showError(a.error,{polling:!0})}))),void(o=MistUtil.event.addListener(i.video,"waiting",(function(){i.showError(a.error,{polling:!0})})));s={polling:!0};break;default:s={reload:!0}}i.showError(e,s)}else{if(i.state="Stream is online",i.clearError(),o&&MistUtil.event.removeListener(o),!i.info)return void n(a);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}(a,i.info);if(l){if("source"in l&&"error"in i.info)return void i.reload("Reloading, stream info has error");i.info=MistUtil.object.extend(i.info,a),i.info.updated=new Date;var c=!1;for(var d in l)switch(d){case"meta":for(var u in l[d])if("tracks"===u)i.info.hasVideo=r(i.info),MistUtil.event.send("metaUpdate_tracks",a,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.metaTrackSubscriptions&&this.metaTrackSubscriptions.socket&&this.metaTrackSubscriptions.destroy(),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/dashjs.js b/embed/min/wrappers/dashjs.js index 59281cf0..2c68ce73 100644 --- a/embed/min/wrappers/dashjs.js +++ b/embed/min/wrappers/dashjs.js @@ -1 +1 @@ -mistplayers.dashjs={name:"Dash.js player",mimes:["dash/video/mp4"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return MistUtil.array.indexOf(this.mimes,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:"){i.log("This source ("+e+") won't load if the page is run via file://");return false}if(!("MediaSource"in window)){return false}if(!MediaSource.isTypeSupported){return true}var r={};var a=false;for(var s in i.info.meta.tracks){if(i.info.meta.tracks[s].type=="meta"){if(i.info.meta.tracks[s].codec=="subtitle"){a=true}continue}if(!(i.info.meta.tracks[s].type in r)){r[i.info.meta.tracks[s].type]={}}r[i.info.meta.tracks[s].type][MistUtil.tracks.translateCodec(i.info.meta.tracks[s])]=1}var o=[];for(var n in r){var l=false;for(var f in r[n]){if(MediaSource.isTypeSupported('video/mp4;codecs="'+f+'"')){l=true;break}}if(l){o.push(n)}}if(a){for(var s in i.info.source){if(i.info.source[s].type=="html5/text/vtt"){o.push("subtitle");break}}}return o.length?o:false},player:function(){this.onreadylist=[]},scriptsrc:function(e){return e+"/dashjs.js"}};var p=mistplayers.dashjs.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var i=this;this.onDashLoad=function(){if(e.destroyed){return}e.log("Building DashJS player..");var r=document.createElement("video");if("Proxy"in window){var a={get:{},set:{}};e.player.api=new Proxy(r,{get:function(e,t,i){if(t in a.get){return a.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 a.set){return a.set[t].call(e,i)}return e[t]=i}});if(e.info.type=="live"){a.get.duration=function(){var t=0;if(this.buffered.length){t=this.buffered.end(this.buffered.length-1)}var i=((new Date).getTime()-e.player.api.lastProgress.getTime())*.001;return t+i+-1*e.player.api.liveOffset+45};a.set.currentTime=function(t){var i=t-e.player.api.duration;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(i*-10)/10+"s from live)");e.video.currentTime=t};MistUtil.event.addListener(r,"progress",function(){e.player.api.lastProgress=new Date});e.player.api.lastProgress=new Date;e.player.api.liveOffset=0}}else{i.api=r}if(e.options.autoplay){r.setAttribute("autoplay","")}if(e.options.loop&&e.info.type!="live"){r.setAttribute("loop","")}if(e.options.poster){r.setAttribute("poster",e.options.poster)}if(e.options.muted){r.muted=true}if(e.options.controls=="stock"){r.setAttribute("controls","")}var s=dashjs.MediaPlayer().create();s.initialize(r,e.source.url,e.options.autoplay);i.dash=s;var o=["METRIC_ADDED","METRIC_UPDATED","METRIC_CHANGED","METRICS_CHANGED","FRAGMENT_LOADING_STARTED","FRAGMENT_LOADING_COMPLETED","LOG","PLAYBACK_TIME_UPDATED","PLAYBACK_PROGRESS"];for(var n in dashjs.MediaPlayer.events){if(o.indexOf(n)<0){i.dash.on(dashjs.MediaPlayer.events[n],function(t){e.log("Player event fired: "+t.type)})}}e.player.setSize=function(e){this.api.style.width=e.width+"px";this.api.style.height=e.height+"px"};e.player.api.setSource=function(t){e.player.dash.attachSource(t)};if(e.options.controls!="stock"){i.dash.updateSettings({streaming:{text:{defaultEnabled:false}}})}var l=false;i.dash.on("allTextTracksAdded",function(){l=true});e.player.api.setSubtitle=function(t){if(!l){var r=function(){e.player.api.setSubtitle(t);i.dash.off("allTextTracksAdded",r)};i.dash.on("allTextTracksAdded",r);return}if(!t){i.dash.enableText(false);return}var a=i.dash.getTracksFor("text");for(var s in a){var o="idx"in t?t.idx:t.trackid;if(a[s].id==o){i.dash.setTextTrack(s);if(!i.dash.isTextEnabled()){i.dash.enableText()}return true}}return false};MistUtil.event.addListener(r,"progress",function(t){if(e.container.getAttribute("data-loading")=="stalled"){e.container.removeAttribute("data-loading")}});i.api.unload=function(){i.dash.reset()};e.log("Built html");t(r)};if("dashjs"in window){this.onDashLoad()}else{var r=MistUtil.scripts.insert(e.urlappend(mistplayers.dashjs.scriptsrc(e.options.host)),{onerror:function(t){var i="Failed to load dashjs.js";if(t.message){i+=": "+t.message}e.showError(i)},onload:i.onDashLoad},e)}}; \ No newline at end of file +mistplayers.dashjs={name:"Dash.js player",mimes:["dash/video/mp4"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return MistUtil.array.indexOf(this.mimes,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:"){i.log("This source ("+e+") won't load if the page is run via file://");return false}if(!("MediaSource"in window)){return false}if(!MediaSource.isTypeSupported){return true}var r={};var a=false;for(var s in i.info.meta.tracks){if(i.info.meta.tracks[s].type=="meta"){if(i.info.meta.tracks[s].codec=="subtitle"){a=true}continue}if(!(i.info.meta.tracks[s].type in r)){r[i.info.meta.tracks[s].type]={}}r[i.info.meta.tracks[s].type][MistUtil.tracks.translateCodec(i.info.meta.tracks[s])]=1}var o=[];for(var n in r){var l=false;for(var f in r[n]){if(MediaSource.isTypeSupported('video/mp4;codecs="'+f+'"')){l=true;break}}if(l){o.push(n)}}if(a){for(var s in i.info.source){if(i.info.source[s].type=="html5/text/vtt"){o.push("subtitle");break}}}return o.length?o:false},player:function(){this.onreadylist=[]},scriptsrc:function(e){return e+"/dashjs.js"}};var p=mistplayers.dashjs.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var i=this;this.onDashLoad=function(){if(e.destroyed){return}e.log("Building DashJS player..");var r=document.createElement("video");if("Proxy"in window){var a={get:{},set:{}};e.player.api=new Proxy(r,{get:function(e,t,i){if(t in a.get){return a.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 a.set){return a.set[t].call(e,i)}return e[t]=i}});if(e.info.type=="live"){a.get.duration=function(){var t=0;if(this.buffered.length){t=this.buffered.end(this.buffered.length-1)}var i=((new Date).getTime()-e.player.api.lastProgress.getTime())*.001;return t+i+-1*e.player.api.liveOffset+45};a.set.currentTime=function(t){var i=t-e.player.api.duration;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(i*-10)/10+"s from live)");e.video.currentTime=t};MistUtil.event.addListener(r,"progress",(function(){e.player.api.lastProgress=new Date}));e.player.api.lastProgress=new Date;e.player.api.liveOffset=0}}else{i.api=r}if(e.options.autoplay){r.setAttribute("autoplay","")}if(e.options.loop&&e.info.type!="live"){r.setAttribute("loop","")}if(e.options.poster){r.setAttribute("poster",e.options.poster)}if(e.options.muted){r.muted=true}if(e.options.controls=="stock"){r.setAttribute("controls","")}var s=dashjs.MediaPlayer().create();s.initialize(r,e.source.url,e.options.autoplay);i.dash=s;var o=["METRIC_ADDED","METRIC_UPDATED","METRIC_CHANGED","METRICS_CHANGED","FRAGMENT_LOADING_STARTED","FRAGMENT_LOADING_COMPLETED","LOG","PLAYBACK_TIME_UPDATED","PLAYBACK_PROGRESS"];for(var n in dashjs.MediaPlayer.events){if(o.indexOf(n)<0){i.dash.on(dashjs.MediaPlayer.events[n],(function(t){e.log("Player event fired: "+t.type)}))}}e.player.setSize=function(e){this.api.style.width=e.width+"px";this.api.style.height=e.height+"px"};e.player.api.setSource=function(t){e.player.dash.attachSource(t)};if(e.options.controls!="stock"){i.dash.updateSettings({streaming:{text:{defaultEnabled:false}}})}var l=false;i.dash.on("allTextTracksAdded",(function(){l=true}));e.player.api.setSubtitle=function(t){if(!l){var r=function(){e.player.api.setSubtitle(t);i.dash.off("allTextTracksAdded",r)};i.dash.on("allTextTracksAdded",r);return}if(!t){i.dash.enableText(false);return}var a=i.dash.getTracksFor("text");for(var s in a){var o="idx"in t?t.idx:t.trackid;if(a[s].id==o){i.dash.setTextTrack(s);if(!i.dash.isTextEnabled()){i.dash.enableText()}return true}}return false};MistUtil.event.addListener(r,"progress",(function(t){if(e.container.getAttribute("data-loading")=="stalled"){e.container.removeAttribute("data-loading")}}));i.api.unload=function(){i.dash.reset()};e.log("Built html");t(r)};if("dashjs"in window){this.onDashLoad()}else{var r=MistUtil.scripts.insert(e.urlappend(mistplayers.dashjs.scriptsrc(e.options.host)),{onerror:function(t){var i="Failed to load dashjs.js";if(t.message){i+=": "+t.message}e.showError(i)},onload:i.onDashLoad},e)}}; \ No newline at end of file diff --git a/embed/min/wrappers/flash_strobe.js b/embed/min/wrappers/flash_strobe.js index 8248445d..09013d5d 100644 --- a/embed/min/wrappers/flash_strobe.js +++ b/embed/min/wrappers/flash_strobe.js @@ -1 +1 @@ -mistplayers.flash_strobe={name:"Strobe Flash media playback",mimes:["flash/10","flash/11","flash/7"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(t){return this.mimes.indexOf(t)==-1?false:true},isBrowserSupported:function(t,e,i){if(MistUtil.http.url.split(e.url).protocol.slice(0,4)=="http"&&location.protocol!=MistUtil.http.url.split(e.url).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}var r=0;try{var a=navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin;if(a.version){r=a.version.split(".")[0]}else{r=a.description.replace(/([^0-9\.])/g,"").split(".")[0]}}catch(t){}try{r=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version").replace(/([^0-9\,])/g,"").split(",")[0]}catch(t){}if(!r){return false}var l=t.split("/");return Number(r)>=Number(l[l.length-1])},player:function(){this.onreadylist=[]}};var p=mistplayers.flash_strobe.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var i=document.createElement("object");var r=document.createElement("embed");i.appendChild(r);function a(e){var a=t.options;function l(t,e){var i=document.createElement("param");i.setAttribute("name",t);i.setAttribute("value",e);return i}MistUtil.empty(i);i.appendChild(l("movie",t.urlappend(a.host+t.source.player_url)));var o="src="+encodeURIComponent(e)+"&controlBarMode="+(a.controls?"floating":"none")+"&initialBufferTime=0.5&expandedBufferTime=5&minContinuousPlaybackTime=3"+(a.live?"&streamType=live":"")+(a.autoplay?"&autoPlay=true":"")+(a.loop?"&loop=true":"")+(a.poster?"&poster="+a.poster:"")+(a.muted?"&muted=true":"");i.appendChild(l("flashvars",o));i.appendChild(l("allowFullScreen","true"));i.appendChild(l("wmode","direct"));if(a.autoplay){i.appendChild(l("autoPlay","true"))}if(a.loop){i.appendChild(l("loop","true"))}if(a.poster){i.appendChild(l("poster",a.poster))}if(a.muted){i.appendChild(l("muted","true"))}r.setAttribute("src",t.urlappend(t.source.player_url));r.setAttribute("type","application/x-shockwave-flash");r.setAttribute("allowfullscreen","true");r.setAttribute("flashvars",o)}a(t.source.url);this.api={};this.setSize=function(t){i.setAttribute("width",t.width);i.setAttribute("height",t.height);r.setAttribute("width",t.width);r.setAttribute("height",t.height)};this.setSize(t.calcSize());this.onready(function(){if(t.container){t.container.removeAttribute("data-loading")}});this.api.setSource=function(t){a(t)};t.log("Built html");e(i)}; \ No newline at end of file +mistplayers.flash_strobe={name:"Strobe Flash media playback",mimes:["flash/10","flash/11","flash/7"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(t){return this.mimes.indexOf(t)==-1?false:true},isBrowserSupported:function(t,e,i){if(MistUtil.http.url.split(e.url).protocol.slice(0,4)=="http"&&location.protocol!=MistUtil.http.url.split(e.url).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}var r=0;try{var a=navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin;if(a.version){r=a.version.split(".")[0]}else{r=a.description.replace(/([^0-9\.])/g,"").split(".")[0]}}catch(t){}try{r=new ActiveXObject("ShockwaveFlash.ShockwaveFlash").GetVariable("$version").replace(/([^0-9\,])/g,"").split(",")[0]}catch(t){}if(!r){return false}var l=t.split("/");return Number(r)>=Number(l[l.length-1])},player:function(){this.onreadylist=[]}};var p=mistplayers.flash_strobe.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var i=document.createElement("object");var r=document.createElement("embed");i.appendChild(r);function a(e){var a=t.options;function l(t,e){var i=document.createElement("param");i.setAttribute("name",t);i.setAttribute("value",e);return i}MistUtil.empty(i);i.appendChild(l("movie",t.urlappend(a.host+t.source.player_url)));var o="src="+encodeURIComponent(e)+"&controlBarMode="+(a.controls?"floating":"none")+"&initialBufferTime=0.5&expandedBufferTime=5&minContinuousPlaybackTime=3"+(a.live?"&streamType=live":"")+(a.autoplay?"&autoPlay=true":"")+(a.loop?"&loop=true":"")+(a.poster?"&poster="+a.poster:"")+(a.muted?"&muted=true":"");i.appendChild(l("flashvars",o));i.appendChild(l("allowFullScreen","true"));i.appendChild(l("wmode","direct"));if(a.autoplay){i.appendChild(l("autoPlay","true"))}if(a.loop){i.appendChild(l("loop","true"))}if(a.poster){i.appendChild(l("poster",a.poster))}if(a.muted){i.appendChild(l("muted","true"))}r.setAttribute("src",t.urlappend(t.source.player_url));r.setAttribute("type","application/x-shockwave-flash");r.setAttribute("allowfullscreen","true");r.setAttribute("flashvars",o)}a(t.source.url);this.api={};this.setSize=function(t){i.setAttribute("width",t.width);i.setAttribute("height",t.height);r.setAttribute("width",t.width);r.setAttribute("height",t.height)};this.setSize(t.calcSize());this.onready((function(){if(t.container){t.container.removeAttribute("data-loading")}}));this.api.setSource=function(t){a(t)};t.log("Built html");e(i)}; \ No newline at end of file diff --git a/embed/min/wrappers/flv.js b/embed/min/wrappers/flv.js index 72c2db72..9e980613 100644 --- a/embed/min/wrappers/flv.js +++ b/embed/min/wrappers/flv.js @@ -1 +1 @@ -mistplayers.flv={name:"HTML5 FLV Player",mimes:["flash/7"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return MistUtil.array.indexOf(this.mimes,e)==-1?false:true},isBrowserSupported:function(e,t,r){if(location.protocol!=MistUtil.http.url.split(t.url).protocol){if(location.protocol=="file:"&&MistUtil.http.url.split(t.url).protocol=="http:"){r.log("This page was loaded over file://, the player might not behave as intended.")}else{r.log("HTTP/HTTPS mismatch for this source");return false}}if(!window.MediaSource){return false}if(!MediaSource.isTypeSupported){return true}try{var o={};for(var a in r.info.meta.tracks){if(r.info.meta.tracks[a].type=="meta"){continue}if(!(r.info.meta.tracks[a].type in o)){o[r.info.meta.tracks[a].type]={}}o[r.info.meta.tracks[a].type][MistUtil.tracks.translateCodec(r.info.meta.tracks[a])]=1}var i=[];for(var l in o){var n=false;for(var s in o[l]){if(MediaSource.isTypeSupported('video/mp4;codecs="'+s+'"')){n=true;break}}if(n){i.push(l)}}t.supportedCodecs=i;return i.length?i:false}catch(e){}return false},player:function(){this.onreadylist=[]},scriptsrc:function(e){return e+"/flv.js"}};var p=mistplayers.flv.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){this.onFLVLoad=function(){if(e.destroyed){return}e.log("Building flv.js player..");var r=document.createElement("video");r.setAttribute("playsinline","");var o=["autoplay","loop","poster"];for(var a in o){var i=o[a];if(e.options[i]){r.setAttribute(i,e.options[i]===true?"":e.options[i])}}if(e.options.muted){r.muted=true}if(e.options.controls=="stock"){r.setAttribute("controls","")}if(e.info.type=="live"){r.loop=false}flvjs.LoggingControl.applyConfig({enableVerbose:false});flvjs.LoggingControl.addLogListener(function(t,r){e.log("[flvjs] "+r)});var l={type:"flv",url:e.source.url,hasAudio:false,hasVideo:false};for(var a in e.source.supportedCodecs){l["has"+e.source.supportedCodecs[a].charAt(0).toUpperCase()+e.source.supportedCodecs[a].slice(1)]=true}e.player.create=function(t){t=MistUtil.object.extend({},t);e.player.flvPlayer=flvjs.createPlayer(t,{lazyLoad:false});e.player.flvPlayer.attachMediaElement(r);e.player.flvPlayer.load();e.player.flvPlayer.play();if(!e.options.autoplay){r.pause()}};e.player.create(l);e.player.api={};function n(t){Object.defineProperty(e.player.api,t,{get:function(){return r[t]},set:function(e){return r[t]=e}})}var s=["volume","buffered","muted","loop","paused",,"error","textTracks","webkitDroppedFrameCount","webkitDecodedFrameCount"];if(e.info.type!="live"){s.push("duration")}else{Object.defineProperty(e.player.api,"duration",{get:function(){if(!r.buffered.length){return 0}return r.buffered.end(r.buffered.length-1)}})}for(var a in s){n(s[a])}function f(t){if(t in r){e.player.api[t]=function(){return r[t].call(r,arguments)}}}var s=["load","getVideoPlaybackQuality","play","pause"];for(var a in s){f(s[a])}e.player.api.setSource=function(t){if(t!=l.url&&t!=""){e.player.flvPlayer.unload();e.player.flvPlayer.detachMediaElement();e.player.flvPlayer.destroy();l.url=t;e.player.create(l)}};e.player.api.unload=function(){e.player.flvPlayer.unload();e.player.flvPlayer.detachMediaElement();e.player.flvPlayer.destroy()};e.player.setSize=function(e){r.style.width=e.width+"px";r.style.height=e.height+"px"};Object.defineProperty(e.player.api,"currentTime",{get:function(){return r.currentTime},set:function(t){var o=.5;for(var a=0;a<r.buffered.length;a++){if(t>=r.buffered.start(a)&&t<=r.buffered.end(a)-o){return r.currentTime=t}}e.log("Seek attempted outside of buffer, but MistServer does not support seeking in progressive flash. Setting to closest available instead");return r.currentTime=r.buffered.length?r.buffered.end(r.buffered.length-1)-o:0}});t(r)};if("flvjs"in window){this.onFLVLoad()}else{var r=MistUtil.scripts.insert(e.urlappend(mistplayers.flv.scriptsrc(e.options.host)),{onerror:function(t){var r="Failed to load flv.js";if(t.message){r+=": "+t.message}e.showError(r)},onload:e.player.onFLVLoad},e)}}; \ No newline at end of file +mistplayers.flv={name:"HTML5 FLV Player",mimes:["flash/7"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return MistUtil.array.indexOf(this.mimes,e)==-1?false:true},isBrowserSupported:function(e,t,r){if(location.protocol!=MistUtil.http.url.split(t.url).protocol){if(location.protocol=="file:"&&MistUtil.http.url.split(t.url).protocol=="http:"){r.log("This page was loaded over file://, the player might not behave as intended.")}else{r.log("HTTP/HTTPS mismatch for this source");return false}}if(!window.MediaSource){return false}if(!MediaSource.isTypeSupported){return true}try{var o={};for(var a in r.info.meta.tracks){if(r.info.meta.tracks[a].type=="meta"){continue}if(!(r.info.meta.tracks[a].type in o)){o[r.info.meta.tracks[a].type]={}}o[r.info.meta.tracks[a].type][MistUtil.tracks.translateCodec(r.info.meta.tracks[a])]=1}var i=[];for(var l in o){var n=false;for(var s in o[l]){if(MediaSource.isTypeSupported('video/mp4;codecs="'+s+'"')){n=true;break}}if(n){i.push(l)}}t.supportedCodecs=i;return i.length?i:false}catch(e){}return false},player:function(){this.onreadylist=[]},scriptsrc:function(e){return e+"/flv.js"}};var p=mistplayers.flv.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){this.onFLVLoad=function(){if(e.destroyed){return}e.log("Building flv.js player..");var r=document.createElement("video");r.setAttribute("playsinline","");var o=["autoplay","loop","poster"];for(var a in o){var i=o[a];if(e.options[i]){r.setAttribute(i,e.options[i]===true?"":e.options[i])}}if(e.options.muted){r.muted=true}if(e.options.controls=="stock"){r.setAttribute("controls","")}if(e.info.type=="live"){r.loop=false}flvjs.LoggingControl.applyConfig({enableVerbose:false});flvjs.LoggingControl.addLogListener((function(t,r){e.log("[flvjs] "+r)}));var l={type:"flv",url:e.source.url,hasAudio:false,hasVideo:false};for(var a in e.source.supportedCodecs){l["has"+e.source.supportedCodecs[a].charAt(0).toUpperCase()+e.source.supportedCodecs[a].slice(1)]=true}e.player.create=function(t){t=MistUtil.object.extend({},t);e.player.flvPlayer=flvjs.createPlayer(t,{lazyLoad:false});e.player.flvPlayer.attachMediaElement(r);e.player.flvPlayer.load();e.player.flvPlayer.play();if(!e.options.autoplay){r.pause()}};e.player.create(l);e.player.api={};function n(t){Object.defineProperty(e.player.api,t,{get:function(){return r[t]},set:function(e){return r[t]=e}})}var s=["volume","buffered","muted","loop","paused",,"error","textTracks","webkitDroppedFrameCount","webkitDecodedFrameCount"];if(e.info.type!="live"){s.push("duration")}else{Object.defineProperty(e.player.api,"duration",{get:function(){if(!r.buffered.length){return 0}return r.buffered.end(r.buffered.length-1)}})}for(var a in s){n(s[a])}function f(t){if(t in r){e.player.api[t]=function(){return r[t].call(r,arguments)}}}var s=["load","getVideoPlaybackQuality","play","pause"];for(var a in s){f(s[a])}e.player.api.setSource=function(t){if(t!=l.url&&t!=""){e.player.flvPlayer.unload();e.player.flvPlayer.detachMediaElement();e.player.flvPlayer.destroy();l.url=t;e.player.create(l)}};e.player.api.unload=function(){e.player.flvPlayer.unload();e.player.flvPlayer.detachMediaElement();e.player.flvPlayer.destroy()};e.player.setSize=function(e){r.style.width=e.width+"px";r.style.height=e.height+"px"};Object.defineProperty(e.player.api,"currentTime",{get:function(){return r.currentTime},set:function(t){var o=.5;for(var a=0;a<r.buffered.length;a++){if(t>=r.buffered.start(a)&&t<=r.buffered.end(a)-o){return r.currentTime=t}}e.log("Seek attempted outside of buffer, but MistServer does not support seeking in progressive flash. Setting to closest available instead");return r.currentTime=r.buffered.length?r.buffered.end(r.buffered.length-1)-o:0}});t(r)};if("flvjs"in window){this.onFLVLoad()}else{var r=MistUtil.scripts.insert(e.urlappend(mistplayers.flv.scriptsrc(e.options.host)),{onerror:function(t){var r="Failed to load flv.js";if(t.message){r+=": "+t.message}e.showError(r)},onload:e.player.onFLVLoad},e)}}; \ No newline at end of file diff --git a/embed/min/wrappers/hlsjs.js b/embed/min/wrappers/hlsjs.js index 195c5883..d13425e7 100644 --- a/embed/min/wrappers/hlsjs.js +++ b/embed/min/wrappers/hlsjs.js @@ -1 +1 @@ -mistplayers.hlsjs={name:"HLS.js player",mimes:["html5/application/vnd.apple.mpegurl","html5/application/vnd.apple.mpegurl;version=7"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(t){return this.mimes.indexOf(t)==-1?false:true},isBrowserSupported:function(t,e,r){if(location.protocol!=MistUtil.http.url.split(e.url).protocol){r.log("HTTP/HTTPS mismatch for this source");return false}if(!("MediaSource"in window)){return false}if(!MediaSource.isTypeSupported){return true}var i={};var s=false;for(var o in r.info.meta.tracks){if(r.info.meta.tracks[o].type=="meta"){if(r.info.meta.tracks[o].codec=="subtitle"){s=true}continue}if(!(r.info.meta.tracks[o].type in i)){i[r.info.meta.tracks[o].type]={}}i[r.info.meta.tracks[o].type][MistUtil.tracks.translateCodec(r.info.meta.tracks[o])]=1}var a=[];for(var l in i){var n=false;for(var p in i[l]){if(MediaSource.isTypeSupported('video/mp4;codecs="'+p+'"')){n=true;break}}if(n){a.push(l)}}if(s){for(var o in r.info.source){if(r.info.source[o].type=="html5/text/vtt"){a.push("subtitle");break}}}return a.length?a:false},player:function(){},scriptsrc:function(t){return t+"/hlsjs.js"}};var p=mistplayers.hlsjs.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var r=this;var i=document.createElement("video");i.setAttribute("playsinline","");var s=["autoplay","loop","poster"];for(var o in s){var a=s[o];if(t.options[a]){i.setAttribute(a,t.options[a]===true?"":t.options[a])}}if(t.options.muted){i.muted=true}if(t.info.type=="live"){i.loop=false}if(t.options.controls=="stock"){i.setAttribute("controls","")}i.setAttribute("crossorigin","anonymous");this.setSize=function(t){i.style.width=t.width+"px";i.style.height=t.height+"px"};this.api=i;t.player.api.unload=function(){if(t.player.hls){t.player.hls.destroy();t.player.hls=false;t.log("hls.js instance disposed")}};function l(e){t.player.hls=new Hls({maxBufferLength:15,maxMaxBufferLength:60});t.player.hls.attachMedia(i);t.player.hls.on(Hls.Events.MEDIA_ATTACHED,function(){t.player.hls.loadSource(e)})}t.player.api.setSource=function(e){if(!t.player.hls){return}if(t.player.hls.url!=e){t.player.hls.destroy();l(e)}};t.player.api.setSubtitle=function(t){var e=i.getElementsByTagName("track");for(var r=e.length-1;r>=0;r--){i.removeChild(e[r])}if(t){var s=document.createElement("track");i.appendChild(s);s.kind="subtitles";s.label=t.label;s.srclang=t.lang;s.src=t.src;s.setAttribute("default","")}};function n(){l(t.source.url)}if("Hls"in window){n()}else{var p=t.urlappend(mistplayers.hlsjs.scriptsrc(t.options.host));MistUtil.scripts.insert(p,{onerror:function(e){var r="Failed to load hlsjs.js";if(e.message){r+=": "+e.message}t.showError(r)},onload:n},t)}e(i)}; \ No newline at end of file +mistplayers.hlsjs={name:"HLS.js player",mimes:["html5/application/vnd.apple.mpegurl","html5/application/vnd.apple.mpegurl;version=7"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(t){return this.mimes.indexOf(t)==-1?false:true},isBrowserSupported:function(t,e,r){if(location.protocol!=MistUtil.http.url.split(e.url).protocol){r.log("HTTP/HTTPS mismatch for this source");return false}if(!("MediaSource"in window)){return false}if(!MediaSource.isTypeSupported){return true}var i={};var s=false;for(var o in r.info.meta.tracks){if(r.info.meta.tracks[o].type=="meta"){if(r.info.meta.tracks[o].codec=="subtitle"){s=true}continue}if(!(r.info.meta.tracks[o].type in i)){i[r.info.meta.tracks[o].type]={}}i[r.info.meta.tracks[o].type][MistUtil.tracks.translateCodec(r.info.meta.tracks[o])]=1}var a=[];for(var l in i){var n=false;for(var p in i[l]){if(MediaSource.isTypeSupported('video/mp4;codecs="'+p+'"')){n=true;break}}if(n){a.push(l)}}if(s){for(var o in r.info.source){if(r.info.source[o].type=="html5/text/vtt"){a.push("subtitle");break}}}return a.length?a:false},player:function(){},scriptsrc:function(t){return t+"/hlsjs.js"}};var p=mistplayers.hlsjs.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var r=this;var i=document.createElement("video");i.setAttribute("playsinline","");var s=["autoplay","loop","poster"];for(var o in s){var a=s[o];if(t.options[a]){i.setAttribute(a,t.options[a]===true?"":t.options[a])}}if(t.options.muted){i.muted=true}if(t.info.type=="live"){i.loop=false}if(t.options.controls=="stock"){i.setAttribute("controls","")}i.setAttribute("crossorigin","anonymous");this.setSize=function(t){i.style.width=t.width+"px";i.style.height=t.height+"px"};this.api=i;t.player.api.unload=function(){if(t.player.hls){t.player.hls.destroy();t.player.hls=false;t.log("hls.js instance disposed")}};function l(e){t.player.hls=new Hls({maxBufferLength:15,maxMaxBufferLength:60});t.player.hls.attachMedia(i);t.player.hls.on(Hls.Events.MEDIA_ATTACHED,(function(){t.player.hls.loadSource(e)}))}t.player.api.setSource=function(e){if(!t.player.hls){return}if(t.player.hls.url!=e){t.player.hls.destroy();l(e)}};t.player.api.setSubtitle=function(t){var e=i.getElementsByTagName("track");for(var r=e.length-1;r>=0;r--){i.removeChild(e[r])}if(t){var s=document.createElement("track");i.appendChild(s);s.kind="subtitles";s.label=t.label;s.srclang=t.lang;s.src=t.src;s.setAttribute("default","")}};function n(){l(t.source.url)}if("Hls"in window){n()}else{var p=t.urlappend(mistplayers.hlsjs.scriptsrc(t.options.host));MistUtil.scripts.insert(p,{onerror:function(e){var r="Failed to load hlsjs.js";if(e.message){r+=": "+e.message}t.showError(r)},onload:n},t)}e(i)}; \ No newline at end of file diff --git a/embed/min/wrappers/html5.js b/embed/min/wrappers/html5.js index ac29029f..aa8de371 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/application/vnd.apple.mpegurl;version=7","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(e){return MistUtil.array.indexOf(this.mimes,e)==-1?false:true},isBrowserSupported:function(e,t,i){if(location.protocol!=MistUtil.http.url.split(t.url).protocol){if(location.protocol=="file:"&&MistUtil.http.url.split(t.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(e=="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=e.split("/");n.shift();try{n=n.join("/");function o(e){if(e.codecstring){return e.codecstring}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 s={};var l={};var p=false;for(var u in i.info.meta.tracks){if(i.info.meta.tracks[u].type!="meta"){s[o(i.info.meta.tracks[u])]=i.info.meta.tracks[u]}else if(i.info.meta.tracks[u].codec=="subtitle"){p=true}}var f=e.split("/")[2];t.supportedCodecs=[];for(var u in s){var c=d(u);if(c){t.supportedCodecs.push(s[u].codec);l[s[u].type]=1}}function d(e){var t=document.createElement("video");if(t&&typeof t.canPlayType=="function"){var i;switch(n){case"video/webm":{i=t.canPlayType(n);break}case"video/mp4":case"html5/application/vnd.apple.mpegurl":default:{i=t.canPlayType(n+';codecs="'+e+'"');break}}if(i!=""){return i}}return false}if(p){for(var u in i.info.source){if(i.info.source[u].type=="html5/text/vtt"){l.subtitle=1;break}}}a=MistUtil.object.keys(l)}catch(e){}return a},player:function(){this.onreadylist=[]},mistControls:true};var p=mistplayers.html5.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var i=e.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",e.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(e.options[s]){r.setAttribute(s,e.options[s]===true?"":e.options[s])}}if(e.options.muted){r.muted=true}if(e.options.controls=="stock"){r.setAttribute("controls","")}if(e.info.type=="live"){r.loop=false}if("Proxy"in window&&"Reflect"in window){var l={get:{},set:{}};e.player.api=new Proxy(r,{get:function(e,t,i){if(t in l.get){return l.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 l.set){return l.set[t].call(e,i)}return e[t]=i}});if(e.source.type=="html5/audio/mp3"){l.set.currentTime=function(){e.log("Seek attempted, but MistServer does not currently support seeking in MP3.");return false}}if(e.info.type=="live"){l.get.duration=function(){var t=0;if(this.buffered.length){t=this.buffered.end(this.buffered.length-1)}var i=((new Date).getTime()-e.player.api.lastProgress.getTime())*.001;return t+i-e.player.api.liveOffset};l.set.currentTime=function(t){var i=t-e.player.api.duration;if(i>0){i=0}e.player.api.liveOffset=i;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(i*-10)/10+"s from live)");var r={startunix:i};if(i==0){r={}}e.player.api.setSource(MistUtil.http.url.addParam(e.source.url,r))};MistUtil.event.addListener(r,"progress",function(){e.player.api.lastProgress=new Date});e.player.api.lastProgress=new Date;e.player.api.liveOffset=0;MistUtil.event.addListener(r,"pause",function(){e.player.api.pausedAt=new Date});l.get.play=function(){return function(){if(e.player.api.paused&&e.player.api.pausedAt&&new Date-e.player.api.pausedAt>5e3){r.load();e.log("Reloading source..")}return r.play.apply(r,arguments)}};if(e.source.type=="html5/video/mp4"){var p=l.get.duration;l.get.duration=function(){return p.apply(this,arguments)-e.player.api.liveOffset+e.info.lastms*.001};l.get.currentTime=function(){return this.currentTime-e.player.api.liveOffset+e.info.lastms*.001};l.get.buffered=function(){var t=this;return{length:t.buffered.length,start:function(i){return t.buffered.start(i)-e.player.api.liveOffset+e.info.lastms*.001},end:function(i){return t.buffered.end(i)-e.player.api.liveOffset+e.info.lastms*.001}}}}}else{if(!isFinite(r.duration)){var u=0;for(var o in e.info.meta.tracks){u=Math.max(u,e.info.meta.tracks[o].lastms)}l.get.duration=function(){if(isFinite(this.duration)){return this.duration}return u*.001}}}}else{e.player.api=r}e.player.api.setSource=function(e){if(e!=this.source.src){this.source.src=e;this.load()}};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 a=document.createElement("track");r.appendChild(a);a.kind="subtitles";a.label=e.label;a.srclang=e.lang;a.src=e.src;a.setAttribute("default","")}};e.player.setSize=function(e){this.api.style.width=e.width+"px";this.api.style.height=e.height+"px"};t(r)}; \ No newline at end of file +mistplayers.html5={name:"HTML5 video player",mimes:["html5/application/vnd.apple.mpegurl","html5/application/vnd.apple.mpegurl;version=7","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(e){return MistUtil.array.indexOf(this.mimes,e)==-1?false:true},isBrowserSupported:function(e,t,i){if(location.protocol!=MistUtil.http.url.split(t.url).protocol){if(location.protocol=="file:"&&MistUtil.http.url.split(t.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(e=="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=e.split("/");n.shift();try{n=n.join("/");function o(e){if(e.codecstring){return e.codecstring}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 s={};var l={};var p=false;for(var u in i.info.meta.tracks){if(i.info.meta.tracks[u].type!="meta"){s[o(i.info.meta.tracks[u])]=i.info.meta.tracks[u]}else if(i.info.meta.tracks[u].codec=="subtitle"){p=true}}var f=e.split("/")[2];t.supportedCodecs=[];for(var u in s){var c=d(u);if(c){t.supportedCodecs.push(s[u].codec);l[s[u].type]=1}}function d(e){var t=document.createElement("video");if(t&&typeof t.canPlayType=="function"){var i;switch(n){case"video/webm":{i=t.canPlayType(n);break}case"video/mp4":case"html5/application/vnd.apple.mpegurl":default:{i=t.canPlayType(n+';codecs="'+e+'"');break}}if(i!=""){return i}}return false}if(p){for(var u in i.info.source){if(i.info.source[u].type=="html5/text/vtt"){l.subtitle=1;break}}}a=MistUtil.object.keys(l)}catch(m){}return a},player:function(){this.onreadylist=[]},mistControls:true};var p=mistplayers.html5.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var i=e.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",e.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(e.options[s]){r.setAttribute(s,e.options[s]===true?"":e.options[s])}}if(e.options.muted){r.muted=true}if(e.options.controls=="stock"){r.setAttribute("controls","")}if(e.info.type=="live"){r.loop=false}if("Proxy"in window&&"Reflect"in window){var l={get:{},set:{}};e.player.api=new Proxy(r,{get:function(e,t,i){if(t in l.get){return l.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 l.set){return l.set[t].call(e,i)}return e[t]=i}});if(e.source.type=="html5/audio/mp3"){l.set.currentTime=function(){e.log("Seek attempted, but MistServer does not currently support seeking in MP3.");return false}}if(e.info.type=="live"){l.get.duration=function(){var t=0;if(this.buffered.length){t=this.buffered.end(this.buffered.length-1)}var i=((new Date).getTime()-e.player.api.lastProgress.getTime())*.001;return t+i-e.player.api.liveOffset};l.set.currentTime=function(t){var i=t-e.player.api.duration;if(i>0){i=0}e.player.api.liveOffset=i;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(i*-10)/10+"s from live)");var r={startunix:i};if(i==0){r={}}e.player.api.setSource(MistUtil.http.url.addParam(e.source.url,r))};MistUtil.event.addListener(r,"progress",(function(){e.player.api.lastProgress=new Date}));e.player.api.lastProgress=new Date;e.player.api.liveOffset=0;MistUtil.event.addListener(r,"pause",(function(){e.player.api.pausedAt=new Date}));l.get.play=function(){return function(){if(e.player.api.paused&&e.player.api.pausedAt&&new Date-e.player.api.pausedAt>5e3){r.load();e.log("Reloading source..")}return r.play.apply(r,arguments)}};if(e.source.type=="html5/video/mp4"){var p=l.get.duration;l.get.duration=function(){return p.apply(this,arguments)-e.player.api.liveOffset+e.info.lastms*.001};l.get.currentTime=function(){return this.currentTime-e.player.api.liveOffset+e.info.lastms*.001};l.get.buffered=function(){var t=this;return{length:t.buffered.length,start:function(i){return t.buffered.start(i)-e.player.api.liveOffset+e.info.lastms*.001},end:function(i){return t.buffered.end(i)-e.player.api.liveOffset+e.info.lastms*.001}}}}}else{if(!isFinite(r.duration)){var u=0;for(var o in e.info.meta.tracks){u=Math.max(u,e.info.meta.tracks[o].lastms)}l.get.duration=function(){if(isFinite(this.duration)){return this.duration}return u*.001}}}}else{e.player.api=r}e.player.api.setSource=function(e){if(e!=this.source.src){this.source.src=e;this.load()}};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 a=document.createElement("track");r.appendChild(a);a.kind="subtitles";a.label=e.label;a.srclang=e.lang;a.src=e.src;a.setAttribute("default","")}};e.player.setSize=function(e){this.api.style.width=e.width+"px";this.api.style.height=e.height+"px"};t(r)}; \ No newline at end of file diff --git a/embed/min/wrappers/mews.js b/embed/min/wrappers/mews.js index 194b355b..ff57a3e5 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)||!("Promise"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){if(e.codecstring){return e.codecstring}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={};var s={};var a=false;for(var o in i.info.meta.tracks){if(i.info.meta.tracks[o].type!="meta"){n[r(i.info.meta.tracks[o])]=i.info.meta.tracks[o]}else if(i.info.meta.tracks[o].codec=="subtitle"){a=true}}var u=e.split("/")[2];function d(e){return MediaSource.isTypeSupported("video/"+u+';codecs="'+e+'"')}t.supportedCodecs=[];for(var o in n){var c=d(o);if(c){t.supportedCodecs.push(n[o].codec);s[n[o].type]=1}}if(a){for(var o in i.info.source){if(i.info.source[o].type=="html5/text/vtt"){s.subtitle=1;break}}}return MistUtil.object.keys(s)},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<a.sb.appended.length;n++){r+=a.sb.appended[n].length}var s=new Uint8Array(r);var r=0;for(var n=0;n<a.sb.appended.length;n++){s.set(a.sb.appended[n],r);r+=a.sb.appended[n].length}t(s,"appended.mp4.bin","application/octet-stream")}u({type:"stop"})}})};this.msinit().then(function(){if(a.sb){e.log("Not creating source buffer as one already exists.");o();return}});this.onsbinit=[];this.sbinit=function(t){if(!t){e.showError("Did not receive any codec: nothing to initialize.");return}a.sb=a.ms.addSourceBuffer("video/"+e.source.type.split("/")[2]+';codecs="'+t.join(",")+'"');a.sb.mode="segments";a.sb._codecs=t;a.sb._size=0;a.sb.queue=[];var r=[];a.sb.do_on_updateend=r;a.sb.appending=null;a.sb.appended=[];var n=0;a.sb.addEventListener("updateend",function(){if(!a.sb){e.log("Reached updateend but the source buffer is "+JSON.stringify(a.sb)+". ");return}if(a.debugging){if(a.sb.appending)a.sb.appended.push(a.sb.appending);a.sb.appending=null}if(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](s<t.length-1?t.slice(s):[])}if(!a.sb){return}a.sb._busy=false;if(a.sb&&a.sb.queue.length>0&&!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 separate message queue."+(a.msgqueue?" "+a.msgqueue.length+" more message queue(s) remain.":""));if(s){e.log("The separate 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){this.s.apply(this,arguments);return true}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(c<l/2){n=1+Math.min(1,(c-l)/l)*.08;i.playbackRate*=n;e.log("Our buffer ("+Math.round(c)+"ms) is small (<"+Math.round(l/2)+"ms), so decrease the playback speed to "+Math.round(n*100)/100+" to catch up.")}}}}else if(n>1){if(c<p){i.playbackRate/=n;n=1;e.log("Our buffer ("+Math.round(c)+"ms) is small enough (<"+Math.round(p)+"ms), so return to real time playback.")}}else{if(c>p){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(c<l/2){if(c<-1e4){u({type:"seek",seek_time:Math.round(i.currentTime*1e3)})}else{n=2;e.log("Our buffer is negative, so request a faster download rate.");u({type:"set_speed",play_rate:n})}}else if(c-l>l){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(c<l){u({type:"set_speed",play_rate:"auto"});n=1;e.log("The buffer is small enough, so ask for realtime download rate.")}}}if(e.reporting&&r.data.tracks){e.reporting.stats.d.tracks=r.data.tracks.join(",")}if(r.data.tracks&&o!=r.data.tracks){var b=e.info?MistUtil.tracks.parse(e.info.meta.tracks):[];for(var g in r.data.tracks){if(o.indexOf(r.data.tracks[g])<0){var h;for(var m in b){if(r.data.tracks[g]in b[m]){h=m;break}}if(!h){continue}MistUtil.event.send("playerUpdate_trackChanged",{type:h,trackid:r.data.tracks[g]},e.video)}}o=r.data.tracks}break}case"tracks":{function v(e,t){if(!t){return false}if(e.length!=t.length){return false}for(var i in e){if(t.indexOf(e[i])<0){return false}}return true}function w(t){var r=i.currentTime.toFixed(3);if(r>t){t=r}if(!i.buffered.length||i.buffered.end(i.buffered.length-1)<t){if(a.debugging){console.log("Desired seeking position ("+MistUtil.format.time(t,{ms:true})+") not yet in buffer ("+(i.buffered.length?MistUtil.format.time(i.buffered.end(i.buffered.length-1),{ms:true}):"null")+")")}a.sb._doNext(function(){w(t)});return}i.currentTime=t;e.log("Setting playback position to "+MistUtil.format.time(t,{ms:true}));if(i.currentTime.toFixed(3)<t){a.sb._doNext(function(){w(t)});if(a.debugging){console.log("Could not set playback position")}}else{if(a.debugging){console.log("Set playback position to "+MistUtil.format.time(t,{ms:true}))}var n=function(){a.sb._doNext(function(){if(i.buffered.length){if(i.buffered.start(0)>i.currentTime){var e=i.buffered.start(0);i.currentTime=e;if(i.currentTime!=e){n()}}}else{n()}})};n()}}if(v(a.last_codecs?a.last_codecs:a.sb._codecs,r.data.codecs)){e.log("Player switched tracks, keeping source buffer as codecs are the same as before.");if(i.currentTime==0&&r.data.current!=0){w((r.data.current*.001).toFixed(3))}}else{if(a.debugging){console.warn("Different codecs!");console.warn("video time",i.currentTime,"switch startpoint",r.data.current*.001)}a.last_codecs=r.data.codecs;if(a.msgqueue){a.msgqueue.push([])}else{a.msgqueue=[[]]}var y=function(){if(a&&a.sb){a.sb._do(function(t){if(!a.sb.updating){if(!isNaN(a.ms.duration))a.sb.remove(0,Infinity);a.sb.queue=[];a.ms.removeSourceBuffer(a.sb);a.sb=null;i.src="";a.ms.onsourceclose=null;a.ms.onsourceended=null;if(a.debugging&&t&&t.length){console.warn("There are do_on_updateend functions queued, which I will re-apply after clearing the sb.")}a.msinit().then(function(){a.sbinit(r.data.codecs);a.sb.do_on_updateend=t;var n=MistUtil.event.addListener(i,"loadedmetadata",function(){e.log("Buffer cleared");w((r.data.current*.001).toFixed(3));MistUtil.event.removeListener(n)})})}else{y()}})}else{if(a.debugging){console.warn("sb not available to do clear")}a.onsbinit.push(y)}};if(!r.data.codecs||!r.data.codecs.length){e.showError("Track switch does not contain any codecs, aborting.");e.options.setTracks=false;y();break}function k(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");y()}if(i.currentTime==0){k(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 _=MistUtil.event.addListener(i,"timeupdate",function(){if(r.data.current<i.currentTime*1e3){if(a.debugging){console.log("Track switch: video.currentTime has reached switching point.")}k(r);MistUtil.event.removeListener(_);MistUtil.event.removeListener(M)}});var M=MistUtil.event.addListener(i,"waiting",function(){if(a.debugging){console.log("Track switch: video has reached end of buffer.","Gap:",Math.round(r.data.current-i.currentTime*1e3),"ms")}k(r);MistUtil.event.removeListener(_);MistUtil.event.removeListener(M)})}else{e.log("Track switch: waiting for the received data to reach the current playback point");var _=function(e){if(e.data.current>=i.currentTime*1e3){k(e);a.ws.removeListener("on_time",_)}};a.ws.addListener("on_time",_)}}}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(){if(!a.ws||!a.ws.serverDelay){return}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<this.delays.length;t++){if(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,i){if(!a.ws){throw"No websocket to send to"}if(i>5){throw"Too many retries, giving up"}if(a.ws.readyState<a.ws.OPEN){e.timers.start(function(){u(t,++i)},500);return}if(a.ws.readyState>=a.ws.CLOSING){if(e.destroyed){return}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);if(!a.ws.send(JSON.stringify(t))){return u(t,++i)}}a.findBuffer=function(e){var t=false;for(var r=0;r<i.buffered.length;r++){if(i.buffered.start(r)<=e&&i.buffered.end(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){i.currentTime=o.data.current*.001;e.log("Setting live playback position to "+MistUtil.format.time(i.currentTime))}i.play().then(r).catch(function(){return n.apply(this,arguments)});a.sb.paused=false;a.sb.removeEventListener("updateend",u)}}};a.sb.addEventListener("updateend",u)}else{a.sb.paused=false;i.play().then(r).catch(function(){a.api.pause();return n.apply(this,arguments)})}a.ws.removeListener("on_time",s)}else if(o.data.current>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()},setSubtitle:function(e){var t=i.getElementsByTagName("track");for(var r=t.length-1;r>=0;r--){i.removeChild(t[r])}if(e){var n=document.createElement("track");i.appendChild(n);n.kind="subtitles";n.label=e.label;n.srclang=e.lang;n.src=e.src;n.setAttribute("default","")}}};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)<t){e.log("Failed to seek, wanted: "+t+" got: "+i.currentTime.toFixed(3));if(n>=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(){try{a.sb.remove(0,Infinity)}catch(e){}})}});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.length&&i.buffered.start(t+1)-i.currentTime<1e4){e.log("Skipped over buffer gap (from "+MistUtil.format.time(i.currentTime)+" to "+MistUtil.format.time(i.buffered.start(t+1))+")");i.currentTime=i.buffered.start(t+1)}}});MistUtil.event.addListener(i,"pause",function(){if(a.sb&&!a.sb.paused){e.log("The browser paused the vid - probably because it has no audio and the tab is no longer visible. Pausing download.");u({type:"hold"});a.sb.paused=true;var t=MistUtil.event.addListener(i,"play",function(){if(a.sb&&a.sb.paused){u({type:"play"})}MistUtil.event.removeListener(t)})}});if(a.debugging){MistUtil.event.addListener(i,"waiting",function(){var e=[];var t=false;for(var r=0;r<i.buffered.length;r++){if(i.currentTime>=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)||!("Promise"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){if(e.codecstring){return e.codecstring}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={};var s={};var a=false;for(var o in i.info.meta.tracks){if(i.info.meta.tracks[o].type!="meta"){n[r(i.info.meta.tracks[o])]=i.info.meta.tracks[o]}else if(i.info.meta.tracks[o].codec=="subtitle"){a=true}}var u=e.split("/")[2];function d(e){return MediaSource.isTypeSupported("video/"+u+';codecs="'+e+'"')}t.supportedCodecs=[];for(var o in n){var c=d(o);if(c){t.supportedCodecs.push(n[o].codec);s[n[o].type]=1}}if(a){for(var o in i.info.source){if(i.info.source[o].type=="html5/text/vtt"){s.subtitle=1;break}}}return MistUtil.object.keys(s)},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<a.sb.appended.length;n++){r+=a.sb.appended[n].length}var s=new Uint8Array(r);var r=0;for(var n=0;n<a.sb.appended.length;n++){s.set(a.sb.appended[n],r);r+=a.sb.appended[n].length}t(s,"appended.mp4.bin","application/octet-stream")}u({type:"stop"})}}))};this.msinit().then((function(){if(a.sb){e.log("Not creating source buffer as one already exists.");o();return}}));this.onsbinit=[];this.sbinit=function(t){if(!t){e.showError("Did not receive any codec: nothing to initialize.");return}a.sb=a.ms.addSourceBuffer("video/"+e.source.type.split("/")[2]+';codecs="'+t.join(",")+'"');a.sb.mode="segments";a.sb._codecs=t;a.sb._size=0;a.sb.queue=[];var r=[];a.sb.do_on_updateend=r;a.sb.appending=null;a.sb.appended=[];var n=0;a.sb.addEventListener("updateend",(function(){if(!a.sb){e.log("Reached updateend but the source buffer is "+JSON.stringify(a.sb)+". ");return}if(a.debugging){if(a.sb.appending)a.sb.appended.push(a.sb.appending);a.sb.appending=null}if(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](s<t.length-1?t.slice(s):[])}if(!a.sb){return}a.sb._busy=false;if(a.sb&&a.sb.queue.length>0&&!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 separate message queue."+(a.msgqueue?" "+a.msgqueue.length+" more message queue(s) remain.":""));if(s){e.log("The separate 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){this.s.apply(this,arguments);return true}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(c<l/2){n=1+Math.min(1,(c-l)/l)*.08;i.playbackRate*=n;e.log("Our buffer ("+Math.round(c)+"ms) is small (<"+Math.round(l/2)+"ms), so decrease the playback speed to "+Math.round(n*100)/100+" to catch up.")}}}}else if(n>1){if(c<p){i.playbackRate/=n;n=1;e.log("Our buffer ("+Math.round(c)+"ms) is small enough (<"+Math.round(p)+"ms), so return to real time playback.")}}else{if(c>p){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(c<l/2){if(c<-1e4){u({type:"seek",seek_time:Math.round(i.currentTime*1e3)})}else{n=2;e.log("Our buffer is negative, so request a faster download rate.");u({type:"set_speed",play_rate:n})}}else if(c-l>l){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(c<l){u({type:"set_speed",play_rate:"auto"});n=1;e.log("The buffer is small enough, so ask for realtime download rate.")}}}if(e.reporting&&r.data.tracks){e.reporting.stats.d.tracks=r.data.tracks.join(",")}if(r.data.tracks&&o!=r.data.tracks){var b=e.info?MistUtil.tracks.parse(e.info.meta.tracks):[];for(var g in r.data.tracks){if(o.indexOf(r.data.tracks[g])<0){var h;for(var m in b){if(r.data.tracks[g]in b[m]){h=m;break}}if(!h){continue}MistUtil.event.send("playerUpdate_trackChanged",{type:h,trackid:r.data.tracks[g]},e.video)}}o=r.data.tracks}break}case"tracks":{function v(e,t){if(!t){return false}if(e.length!=t.length){return false}for(var i in e){if(t.indexOf(e[i])<0){return false}}return true}function w(t){var r=i.currentTime.toFixed(3);if(r>t){t=r}if(!i.buffered.length||i.buffered.end(i.buffered.length-1)<t){if(a.debugging){console.log("Desired seeking position ("+MistUtil.format.time(t,{ms:true})+") not yet in buffer ("+(i.buffered.length?MistUtil.format.time(i.buffered.end(i.buffered.length-1),{ms:true}):"null")+")")}a.sb._doNext((function(){w(t)}));return}i.currentTime=t;e.log("Setting playback position to "+MistUtil.format.time(t,{ms:true}));if(i.currentTime.toFixed(3)<t){a.sb._doNext((function(){w(t)}));if(a.debugging){console.log("Could not set playback position")}}else{if(a.debugging){console.log("Set playback position to "+MistUtil.format.time(t,{ms:true}))}var n=function(){a.sb._doNext((function(){if(i.buffered.length){if(i.buffered.start(0)>i.currentTime){var e=i.buffered.start(0);i.currentTime=e;if(i.currentTime!=e){n()}}}else{n()}}))};n()}}if(v(a.last_codecs?a.last_codecs:a.sb._codecs,r.data.codecs)){e.log("Player switched tracks, keeping source buffer as codecs are the same as before.");if(i.currentTime==0&&r.data.current!=0){w((r.data.current*.001).toFixed(3))}}else{if(a.debugging){console.warn("Different codecs!");console.warn("video time",i.currentTime,"switch startpoint",r.data.current*.001)}a.last_codecs=r.data.codecs;if(a.msgqueue){a.msgqueue.push([])}else{a.msgqueue=[[]]}var y=function(){if(a&&a.sb){a.sb._do((function(t){if(!a.sb.updating){if(!isNaN(a.ms.duration))a.sb.remove(0,Infinity);a.sb.queue=[];a.ms.removeSourceBuffer(a.sb);a.sb=null;i.src="";a.ms.onsourceclose=null;a.ms.onsourceended=null;if(a.debugging&&t&&t.length){console.warn("There are do_on_updateend functions queued, which I will re-apply after clearing the sb.")}a.msinit().then((function(){a.sbinit(r.data.codecs);a.sb.do_on_updateend=t;var n=MistUtil.event.addListener(i,"loadedmetadata",(function(){e.log("Buffer cleared");w((r.data.current*.001).toFixed(3));MistUtil.event.removeListener(n)}))}))}else{y()}}))}else{if(a.debugging){console.warn("sb not available to do clear")}a.onsbinit.push(y)}};if(!r.data.codecs||!r.data.codecs.length){e.showError("Track switch does not contain any codecs, aborting.");e.options.setTracks=false;y();break}function k(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");y()}if(i.currentTime==0){k(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 _=MistUtil.event.addListener(i,"timeupdate",(function(){if(r.data.current<i.currentTime*1e3){if(a.debugging){console.log("Track switch: video.currentTime has reached switching point.")}k(r);MistUtil.event.removeListener(_);MistUtil.event.removeListener(M)}}));var M=MistUtil.event.addListener(i,"waiting",(function(){if(a.debugging){console.log("Track switch: video has reached end of buffer.","Gap:",Math.round(r.data.current-i.currentTime*1e3),"ms")}k(r);MistUtil.event.removeListener(_);MistUtil.event.removeListener(M)}))}else{e.log("Track switch: waiting for the received data to reach the current playback point");var _=function(e){if(e.data.current>=i.currentTime*1e3){k(e);a.ws.removeListener("on_time",_)}};a.ws.addListener("on_time",_)}}}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(){if(!a.ws||!a.ws.serverDelay){return}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<this.delays.length;t++){if(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,i){if(!a.ws){throw"No websocket to send to"}if(i>5){throw"Too many retries, giving up"}if(a.ws.readyState<a.ws.OPEN){e.timers.start((function(){u(t,++i)}),500);return}if(a.ws.readyState>=a.ws.CLOSING){if(e.destroyed){return}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);if(!a.ws.send(JSON.stringify(t))){return u(t,++i)}}a.findBuffer=function(e){var t=false;for(var r=0;r<i.buffered.length;r++){if(i.buffered.start(r)<=e&&i.buffered.end(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){i.currentTime=o.data.current*.001;e.log("Setting live playback position to "+MistUtil.format.time(i.currentTime))}i.play().then(r).catch((function(){return n.apply(this,arguments)}));a.sb.paused=false;a.sb.removeEventListener("updateend",u)}}};a.sb.addEventListener("updateend",u)}else{a.sb.paused=false;i.play().then(r).catch((function(){a.api.pause();return n.apply(this,arguments)}))}a.ws.removeListener("on_time",s)}else if(o.data.current>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()},setSubtitle:function(e){var t=i.getElementsByTagName("track");for(var r=t.length-1;r>=0;r--){i.removeChild(t[r])}if(e){var n=document.createElement("track");i.appendChild(n);n.kind="subtitles";n.label=e.label;n.srclang=e.lang;n.src=e.src;n.setAttribute("default","")}}};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)<t){e.log("Failed to seek, wanted: "+t+" got: "+i.currentTime.toFixed(3));if(n>=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(){try{a.sb.remove(0,Infinity)}catch(e){}}))}}));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.length&&i.buffered.start(t+1)-i.currentTime<1e4){e.log("Skipped over buffer gap (from "+MistUtil.format.time(i.currentTime)+" to "+MistUtil.format.time(i.buffered.start(t+1))+")");i.currentTime=i.buffered.start(t+1)}}}));MistUtil.event.addListener(i,"pause",(function(){if(a.sb&&!a.sb.paused){e.log("The browser paused the vid - probably because it has no audio and the tab is no longer visible. Pausing download.");u({type:"hold"});a.sb.paused=true;var t=MistUtil.event.addListener(i,"play",(function(){if(a.sb&&a.sb.paused){u({type:"play"})}MistUtil.event.removeListener(t)}))}}));if(a.debugging){MistUtil.event.addListener(i,"waiting",(function(){var e=[];var t=false;for(var r=0;r<i.buffered.length;r++){if(i.currentTime>=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/rawws.js b/embed/min/wrappers/rawws.js index bf19711c..042bc7a6 100644 --- a/embed/min/wrappers/rawws.js +++ b/embed/min/wrappers/rawws.js @@ -1 +1 @@ -mistplayers.rawws={name:"RAW to Canvas",mimes:["ws/video/raw"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return MistUtil.array.indexOf(this.mimes,e)==-1?false:true},isBrowserSupported:function(e,t,r){if(location.protocol!=MistUtil.http.url.split(t.url.replace(/^ws/,"http")).protocol){if(location.protocol=="file:"&&MistUtil.http.url.split(t.url.replace(/^ws/,"http")).protocol=="http:"){r.log("This page was loaded over file://, the player might not behave as intended.")}else{r.log("HTTP/HTTPS mismatch for this source");return false}}for(var i in r.info.meta.tracks){if(r.info.meta.tracks[i].codec=="HEVC"){return["video"]}}return false},player:function(){this.onreadylist=[]},scriptsrc:function(e){return e+"/libde265.js"}};var p=mistplayers.rawws.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var r=this;r.onDecoderLoad=function(){if(e.destroyed){return}e.log("Building rawws player..");var i={};e.player.api=i;var a=document.createElement("canvas");var n=a.getContext("2d");a.style.objectFit="contain";r.vars={};if(e.options.autoplay){r.vars.wantToPlay=true}r.dropping=false;r.frames={received:0,bitsReceived:0,decoded:0,dropped:0,behind:function(){return this.received-this.decoded-this.dropped},timestamps:{},frame2time:function(e,t){if(e in this.timestamps){if(t){for(var r in this.timestamps){if(r==e){break}delete this.timestamps[r]}}return this.timestamps[e]*.001}return 0},history:{log:[],add:function(){this.log.unshift({time:(new Date).getTime(),received:r.frames.received,bitsReceived:r.frames.bitsReceived,decoded:r.frames.decoded});if(this.log.length>3){this.log.splice(3)}}},framerate_in:function(){var e=this.history.log.length-1;if(e<1){return 0}var t=this.history.log[0].received-this.history.log[e].received;var r=(this.history.log[0].time-this.history.log[e].time)*.001;return t/r},bitrate_in:function(){var e=this.history.log.length-1;if(e<1){return 0}var t=this.history.log[0].bitsReceived-this.history.log[e].bitsReceived;var r=(this.history.log[0].time-this.history.log[e].time)*.001;return t/r},framerate_out:function(){var e=this.history.log.length-1;if(e<1){return 0}var t=this.history.log[0].decoded-this.history.log[e].decoded;var r=(this.history.log[0].time-this.history.log[e].time)*.001;return t/r},framerate:function(){if("rate_theoretical"in this){return this.rate_theoretical}return this.framerate_in()},keepingUp:function(){var e=this.history.log.length-1;if(e<1){return 0}var t=this.history.log[e].received-this.history.log[e].decoded-(this.history.log[0].received-this.history.log[0].decoded);var r=(this.history.log[0].time-this.history.log[e].time)*.001;var i=t/r;return i/this.framerate()}};i.framerate_in=function(){return r.frames.framerate_in()};i.framerate_out=function(){return r.frames.framerate_out()};i.currentBps=function(){return r.frames.bitrate_in()};i.loop=e.options.loop;Object.defineProperty(e.player.api,"webkitDecodedFrameCount",{get:function(){return r.frames.decoded}});Object.defineProperty(e.player.api,"webkitDroppedFrameCount",{get:function(){return r.frames.dropped}});var s;this.decoder=null;function o(e){MistUtil.event.send(e,undefined,a)}function d(){function i(){s=new libde265.Decoder;e.player.decoder=s;var t=[];s.addListener=function(e){t.push(e)};s.removeListener=function(e){var r=t.indexOf(e);if(r<0){return}t.splice(r,1);return true};var i;if(window.requestAnimationFrame){i=function(e){s.pending_image_data=e;window.requestAnimationFrame(function(){if(s.pending_image_data){n.putImageData(s.pending_image_data,0,0);s.pending_image_data=null}})}}else{i=function(e){n.putImageData(e,0,0)}}s.set_image_callback(function(d){r.frames.decoded++;if(r.vars.wantToPlay&&r.state!="seeking"){o("timeupdate")}if(!s.image_data){var l=d.get_width();var p=d.get_height();if(l!=a.width||p!=a.height||!this.image_data){a.width=l;a.height=p;var f=n.createImageData(l,p);s.image_data=f}}if(r.state!="seeking"){d.display(this.image_data,function(e){s.decoding=false;i(e)})}d.free();switch(r.state){case"play":case"waiting":{if(!r.dropping){o("canplay");o("playing");r.state="playing";if(!r.vars.wantToPlay){e.player.send({type:"hold"})}}break}case"seeking":{var c=r.frames.frame2time(r.frames.decoded+r.frames.dropped);if(c>=r.vars.seekTo){o("seeked");r.vars.seekTo=null;r.state="playing";if(!r.vars.wantToPlay){o("timeupdate");e.player.send({type:"hold"})}}break}default:{r.state="playing"}}for(var u in t){t[u]()}})}i();function d(e){return!!e[1]}function l(e){var t=new DataView(new ArrayBuffer(8));for(var r=0;r<8;r++){t.setUint8(r,e[r+2])}return t.getInt32(4)}function p(){o("loadstart");var i=MistUtil.http.url.addParam(e.source.url,{buffer:0,video:"hevc,|minbps"});var n=new WebSocket(i);e.player.ws=n;n.binaryType="arraybuffer";function f(t){if(!e.player.ws){throw"No websocket to send to"}if(n.readyState==1){n.send(JSON.stringify(t))}return false}e.player.send=f;n.wasConnected=false;n.onopen=function(){if(!e.player.built){e.player.built=true;t(a)}f({type:"request_codec_data",supported_codecs:["HEVC"]});n.wasConnected=true};n.onclose=function(){if(this.wasConnected&&!e.destroyed&&e.state=="Stream is online"){e.log("Raw over WS: reopening websocket");p(i)}else{e.showError("Raw over WS: websocket closed")}};n.onerror=function(t){e.showError("Raw over WS: websocket error")};n.onmessage=function(t){if(typeof t.data=="string"){var i=JSON.parse(t.data);switch(i.type){case"on_time":{r.vars.paused=false;r.frames.history.add();if(r.vars.duration!=i.data.end*.001){r.vars.duration=i.data.end*.001;o("durationchange")}break}case"seek":{e.player.frames.timestamps={};if(e.player.dropping){e.log("Emptying drop queue for seek");e.player.frames.dropped+=e.player.dropping.length;e.player.dropping=[]}break}case"codec_data":{o("loadedmetadata");f({type:"play"});r.state="play";break}case"info":{var a=e.info.meta.tracks;var p;for(var c in a){if(a[c].idx==i.data.tracks[0]){p=a[c];break}}if(typeof p!=undefined&&p.fpks>0){r.frames.rate_theoretical=p.fpks*.001}break}case"pause":{r.vars.paused=i.paused;if(i.paused){r.decoder.flush();o("pause")}break}case"on_stop":{if(r.state=="ended"){return}r.state="ended";r.vars.paused=true;n.onclose=function(){};n.close();r.decoder.flush();o("ended");break}default:{}}}else{r.frames.received++;r.frames.bitsReceived+=t.data.byteLength*8;var u=12;var h=new Uint8Array(t.data.slice(0,u));var m=new Uint8Array(t.data.slice(u,t.data.byteLength));r.frames.timestamps[r.frames.received]=l(h);function y(t,i){setTimeout(function(){if(r.dropping){if(r.state!="waiting"){o("waiting");r.state="waiting"}if(d(i)){if(r.dropping.length){r.frames.dropped+=r.dropping.length;e.log("Dropped "+r.dropping.length+" frames");r.dropping=[]}else{e.log("Caught up! no longer dropping");r.dropping=false}}else{r.dropping.push([i,t]);if(!s.decoding){var a=r.dropping.shift();e.player.process(a[1],a[0])}return}}else{if(r.frames.behind()>20){r.dropping=[];e.log("Falling behind, dropping files..")}}e.player.process(t,i)},0)}y(m,h)}};n.listeners={};n.addListener=function(e,t){if(!(e in this.listeners)){this.listeners[e]=[]}this.listeners[e].push(t)};n.removeListener=function(e,t){if(!(e in this.listeners)){return}var r=this.listeners[e].indexOf(t);if(r<0){return}this.listeners[e].splice(r,1);return true}}e.player.connect=p;e.player.process=function(e,t){s.decoding=true;var i=s.push_data(e);if(r.state=="play"){o("loadeddata");r.state="waiting"}if(r.vars.wantToPlay&&r.state!="seeking"){o("progress")}function n(e){if(e==0){return}if(e==libde265.DE265_ERROR_WAITING_FOR_INPUT_DATA){r.state="waiting";return}if(!libde265.de265_isOK(e)){a.error="Decode error: "+libde265.de265_get_error_text(e);o("error");return true}}if(!n(i)){s.decode(n)}else{s.free()}};p()}d();function l(t){Object.defineProperty(e.player.api,t,{get:function(){return r.vars[t]},set:function(e){return r.vars[t]=e}})}var p=["duration","paused","error"];for(var f in p){l(p[f])}i.play=function(){return new Promise(function(t,a){r.vars.wantToPlay=true;var n=function(){t();e.player.decoder.removeListener(n)};e.player.decoder.addListener(n);if(e.player.ws.readyState>e.player.ws.OPEN){e.player.connect();e.log("Websocket was closed: reconnecting to resume playback");return}if(i.paused)e.player.send({type:"play"});r.state="play"})};i.pause=function(){r.vars.wantToPlay=false;e.player.send({type:"hold"})};e.player.api.unload=function(){if(e.player.ws){e.player.ws.onclose=function(){};e.player.ws.close()}if(e.player.decoder){e.player.decoder.push_data=function(){};e.player.decoder.flush();e.player.decoder.free()}};e.player.setSize=function(e){a.style.width=e.width+"px";a.style.height=e.height+"px"};Object.defineProperty(e.player.api,"currentTime",{get:function(){var e=r.frames.decoded+r.frames.dropped;if(r.state=="seeking"){return r.vars.seekTo}if(e in r.frames.timestamps){return r.frames.frame2time(e)}return 0},set:function(t){o("seeking");r.state="seeking";r.vars.seekTo=t;e.player.send({type:"seek",seek_time:t*1e3});return t}});Object.defineProperty(e.player.api,"buffered",{get:function(){return{start:function(e){if(this.length&&e==0){return r.frames.frame2time(r.frames.decoded+r.frames.dropped)}},end:function(e){if(this.length&&e==0){return r.frames.frame2time(r.frames.received)}},length:r.frames.received-r.frames.decoded>0?1:0}}});if(e.info.type!="live"){MistUtil.event.addListener(a,"ended",function(){if(r.api.loop){r.api.play();r.api.currentTime=0}})}};if("libde265"in window){this.onDecoderLoad()}else{var i=MistUtil.scripts.insert(e.urlappend(mistplayers.rawws.scriptsrc(e.options.host)),{onerror:function(t){var r="Failed to load H265 decoder";if(t.message){r+=": "+t.message}e.showError(r)},onload:e.player.onDecoderLoad},e)}}; \ No newline at end of file +mistplayers.rawws={name:"RAW to Canvas",mimes:["ws/video/raw"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return MistUtil.array.indexOf(this.mimes,e)==-1?false:true},isBrowserSupported:function(e,t,r){if(location.protocol!=MistUtil.http.url.split(t.url.replace(/^ws/,"http")).protocol){if(location.protocol=="file:"&&MistUtil.http.url.split(t.url.replace(/^ws/,"http")).protocol=="http:"){r.log("This page was loaded over file://, the player might not behave as intended.")}else{r.log("HTTP/HTTPS mismatch for this source");return false}}for(var i in r.info.meta.tracks){if(r.info.meta.tracks[i].codec=="HEVC"){return["video"]}}return false},player:function(){this.onreadylist=[]},scriptsrc:function(e){return e+"/libde265.js"}};var p=mistplayers.rawws.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var r=this;r.onDecoderLoad=function(){if(e.destroyed){return}e.log("Building rawws player..");var i={};e.player.api=i;var a=document.createElement("canvas");var n=a.getContext("2d");a.style.objectFit="contain";r.vars={};if(e.options.autoplay){r.vars.wantToPlay=true}r.dropping=false;r.frames={received:0,bitsReceived:0,decoded:0,dropped:0,behind:function(){return this.received-this.decoded-this.dropped},timestamps:{},frame2time:function(e,t){if(e in this.timestamps){if(t){for(var r in this.timestamps){if(r==e){break}delete this.timestamps[r]}}return this.timestamps[e]*.001}return 0},history:{log:[],add:function(){this.log.unshift({time:(new Date).getTime(),received:r.frames.received,bitsReceived:r.frames.bitsReceived,decoded:r.frames.decoded});if(this.log.length>3){this.log.splice(3)}}},framerate_in:function(){var e=this.history.log.length-1;if(e<1){return 0}var t=this.history.log[0].received-this.history.log[e].received;var r=(this.history.log[0].time-this.history.log[e].time)*.001;return t/r},bitrate_in:function(){var e=this.history.log.length-1;if(e<1){return 0}var t=this.history.log[0].bitsReceived-this.history.log[e].bitsReceived;var r=(this.history.log[0].time-this.history.log[e].time)*.001;return t/r},framerate_out:function(){var e=this.history.log.length-1;if(e<1){return 0}var t=this.history.log[0].decoded-this.history.log[e].decoded;var r=(this.history.log[0].time-this.history.log[e].time)*.001;return t/r},framerate:function(){if("rate_theoretical"in this){return this.rate_theoretical}return this.framerate_in()},keepingUp:function(){var e=this.history.log.length-1;if(e<1){return 0}var t=this.history.log[e].received-this.history.log[e].decoded-(this.history.log[0].received-this.history.log[0].decoded);var r=(this.history.log[0].time-this.history.log[e].time)*.001;var i=t/r;return i/this.framerate()}};i.framerate_in=function(){return r.frames.framerate_in()};i.framerate_out=function(){return r.frames.framerate_out()};i.currentBps=function(){return r.frames.bitrate_in()};i.loop=e.options.loop;Object.defineProperty(e.player.api,"webkitDecodedFrameCount",{get:function(){return r.frames.decoded}});Object.defineProperty(e.player.api,"webkitDroppedFrameCount",{get:function(){return r.frames.dropped}});var s;this.decoder=null;function o(e){MistUtil.event.send(e,undefined,a)}function d(){function i(){s=new libde265.Decoder;e.player.decoder=s;var t=[];s.addListener=function(e){t.push(e)};s.removeListener=function(e){var r=t.indexOf(e);if(r<0){return}t.splice(r,1);return true};var i;if(window.requestAnimationFrame){i=function(e){s.pending_image_data=e;window.requestAnimationFrame((function(){if(s.pending_image_data){n.putImageData(s.pending_image_data,0,0);s.pending_image_data=null}}))}}else{i=function(e){n.putImageData(e,0,0)}}s.set_image_callback((function(d){r.frames.decoded++;if(r.vars.wantToPlay&&r.state!="seeking"){o("timeupdate")}if(!s.image_data){var l=d.get_width();var p=d.get_height();if(l!=a.width||p!=a.height||!this.image_data){a.width=l;a.height=p;var f=n.createImageData(l,p);s.image_data=f}}if(r.state!="seeking"){d.display(this.image_data,(function(e){s.decoding=false;i(e)}))}d.free();switch(r.state){case"play":case"waiting":{if(!r.dropping){o("canplay");o("playing");r.state="playing";if(!r.vars.wantToPlay){e.player.send({type:"hold"})}}break}case"seeking":{var c=r.frames.frame2time(r.frames.decoded+r.frames.dropped);if(c>=r.vars.seekTo){o("seeked");r.vars.seekTo=null;r.state="playing";if(!r.vars.wantToPlay){o("timeupdate");e.player.send({type:"hold"})}}break}default:{r.state="playing"}}for(var u in t){t[u]()}}))}i();function d(e){return!!e[1]}function l(e){var t=new DataView(new ArrayBuffer(8));for(var r=0;r<8;r++){t.setUint8(r,e[r+2])}return t.getInt32(4)}function p(){o("loadstart");var i=MistUtil.http.url.addParam(e.source.url,{buffer:0,video:"hevc,|minbps"});var n=new WebSocket(i);e.player.ws=n;n.binaryType="arraybuffer";function f(t){if(!e.player.ws){throw"No websocket to send to"}if(n.readyState==1){n.send(JSON.stringify(t))}return false}e.player.send=f;n.wasConnected=false;n.onopen=function(){if(!e.player.built){e.player.built=true;t(a)}f({type:"request_codec_data",supported_codecs:["HEVC"]});n.wasConnected=true};n.onclose=function(){if(this.wasConnected&&!e.destroyed&&e.state=="Stream is online"){e.log("Raw over WS: reopening websocket");p(i)}else{e.showError("Raw over WS: websocket closed")}};n.onerror=function(t){e.showError("Raw over WS: websocket error")};n.onmessage=function(t){if(typeof t.data=="string"){var i=JSON.parse(t.data);switch(i.type){case"on_time":{r.vars.paused=false;r.frames.history.add();if(r.vars.duration!=i.data.end*.001){r.vars.duration=i.data.end*.001;o("durationchange")}break}case"seek":{e.player.frames.timestamps={};if(e.player.dropping){e.log("Emptying drop queue for seek");e.player.frames.dropped+=e.player.dropping.length;e.player.dropping=[]}break}case"codec_data":{o("loadedmetadata");f({type:"play"});r.state="play";break}case"info":{var a=e.info.meta.tracks;var p;for(var c in a){if(a[c].idx==i.data.tracks[0]){p=a[c];break}}if(typeof p!=undefined&&p.fpks>0){r.frames.rate_theoretical=p.fpks*.001}break}case"pause":{r.vars.paused=i.paused;if(i.paused){r.decoder.flush();o("pause")}break}case"on_stop":{if(r.state=="ended"){return}r.state="ended";r.vars.paused=true;n.onclose=function(){};n.close();r.decoder.flush();o("ended");break}default:{}}}else{r.frames.received++;r.frames.bitsReceived+=t.data.byteLength*8;var u=12;var h=new Uint8Array(t.data.slice(0,u));var m=new Uint8Array(t.data.slice(u,t.data.byteLength));r.frames.timestamps[r.frames.received]=l(h);function y(t,i){setTimeout((function(){if(r.dropping){if(r.state!="waiting"){o("waiting");r.state="waiting"}if(d(i)){if(r.dropping.length){r.frames.dropped+=r.dropping.length;e.log("Dropped "+r.dropping.length+" frames");r.dropping=[]}else{e.log("Caught up! no longer dropping");r.dropping=false}}else{r.dropping.push([i,t]);if(!s.decoding){var a=r.dropping.shift();e.player.process(a[1],a[0])}return}}else{if(r.frames.behind()>20){r.dropping=[];e.log("Falling behind, dropping files..")}}e.player.process(t,i)}),0)}y(m,h)}};n.listeners={};n.addListener=function(e,t){if(!(e in this.listeners)){this.listeners[e]=[]}this.listeners[e].push(t)};n.removeListener=function(e,t){if(!(e in this.listeners)){return}var r=this.listeners[e].indexOf(t);if(r<0){return}this.listeners[e].splice(r,1);return true}}e.player.connect=p;e.player.process=function(e,t){s.decoding=true;var i=s.push_data(e);if(r.state=="play"){o("loadeddata");r.state="waiting"}if(r.vars.wantToPlay&&r.state!="seeking"){o("progress")}function n(e){if(e==0){return}if(e==libde265.DE265_ERROR_WAITING_FOR_INPUT_DATA){r.state="waiting";return}if(!libde265.de265_isOK(e)){a.error="Decode error: "+libde265.de265_get_error_text(e);o("error");return true}}if(!n(i)){s.decode(n)}else{s.free()}};p()}d();function l(t){Object.defineProperty(e.player.api,t,{get:function(){return r.vars[t]},set:function(e){return r.vars[t]=e}})}var p=["duration","paused","error"];for(var f in p){l(p[f])}i.play=function(){return new Promise((function(t,a){r.vars.wantToPlay=true;var n=function(){t();e.player.decoder.removeListener(n)};e.player.decoder.addListener(n);if(e.player.ws.readyState>e.player.ws.OPEN){e.player.connect();e.log("Websocket was closed: reconnecting to resume playback");return}if(i.paused)e.player.send({type:"play"});r.state="play"}))};i.pause=function(){r.vars.wantToPlay=false;e.player.send({type:"hold"})};e.player.api.unload=function(){if(e.player.ws){e.player.ws.onclose=function(){};e.player.ws.close()}if(e.player.decoder){e.player.decoder.push_data=function(){};e.player.decoder.flush();e.player.decoder.free()}};e.player.setSize=function(e){a.style.width=e.width+"px";a.style.height=e.height+"px"};Object.defineProperty(e.player.api,"currentTime",{get:function(){var e=r.frames.decoded+r.frames.dropped;if(r.state=="seeking"){return r.vars.seekTo}if(e in r.frames.timestamps){return r.frames.frame2time(e)}return 0},set:function(t){o("seeking");r.state="seeking";r.vars.seekTo=t;e.player.send({type:"seek",seek_time:t*1e3});return t}});Object.defineProperty(e.player.api,"buffered",{get:function(){return{start:function(e){if(this.length&&e==0){return r.frames.frame2time(r.frames.decoded+r.frames.dropped)}},end:function(e){if(this.length&&e==0){return r.frames.frame2time(r.frames.received)}},length:r.frames.received-r.frames.decoded>0?1:0}}});if(e.info.type!="live"){MistUtil.event.addListener(a,"ended",(function(){if(r.api.loop){r.api.play();r.api.currentTime=0}}))}};if("libde265"in window){this.onDecoderLoad()}else{var i=MistUtil.scripts.insert(e.urlappend(mistplayers.rawws.scriptsrc(e.options.host)),{onerror:function(t){var r="Failed to load H265 decoder";if(t.message){r+=": "+t.message}e.showError(r)},onload:e.player.onDecoderLoad},e)}}; \ No newline at end of file diff --git a/embed/min/wrappers/videojs.js b/embed/min/wrappers/videojs.js index 94fde146..94d5d939 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 MistUtil.array.indexOf(this.mimes,e)==-1?false:true},isBrowserSupported:function(e,t,r){if(location.protocol!=MistUtil.http.url.split(t.url).protocol){r.log("HTTP/HTTPS mismatch for this source");return false}if(location.protocol=="file:"&&e=="html5/application/vnd.apple"){r.log("This source ("+e+") won't load if the page is run via file://");return false}function i(e){if(!MediaSource.isTypeSupported){return true}var t={};var i=false;for(var o in r.info.meta.tracks){if(r.info.meta.tracks[o].type=="meta"){if(r.info.meta.tracks[o].codec=="subtitle"){i=true}continue}if(!(r.info.meta.tracks[o].type in t)){t[r.info.meta.tracks[o].type]={}}t[r.info.meta.tracks[o].type][MistUtil.tracks.translateCodec(r.info.meta.tracks[o])]=1}var s=[];for(var a in t){var n=false;for(var l in t[a]){if(MediaSource.isTypeSupported(e+';codecs="'+l+'"')){n=true;break}}if(n){s.push(a)}}if(i){for(var o in r.info.source){if(r.info.source[o].type=="html5/text/vtt"){s.push("subtitle");break}}}return s.length?s:false}if(document.createElement("video").canPlayType(e.replace("html5/",""))){if(!("MediaSource"in window)){return true}if(!MediaSource.isTypeSupported){return true}return i(e.replace("html5/",""))}if(!("MediaSource"in window)){return false}return i("video/mp4")},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 r=this;var i;function o(){if(e.destroyed){return}e.log("Building VideoJS player..");i=document.createElement("video");if(e.source.type!="html5/video/ogg"){i.crossOrigin="anonymous"}i.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);r.source=s;i.appendChild(s);s.type=o.join("/");e.log("Adding "+s.type+" source @ "+e.source.url);MistUtil.class.add(i,"video-js");var a={};if(e.options.autoplay){a.autoplay=true}if(e.options.loop&&e.info.type!="live"){i.setAttribute("loop","")}if(e.options.muted){i.setAttribute("muted","")}if(e.options.poster){a.poster=e.options.poster}if(e.options.controls=="stock"){i.setAttribute("controls","");if(!document.getElementById("videojs-css")){var n=document.createElement("link");n.rel="stylesheet";n.href=e.options.host+"/skins/videojs.css";n.id="videojs-css";document.head.appendChild(n)}}else{a.controls=false}var l=MistUtil.event.addListener(i,"error",function(t){t.stopImmediatePropagation();var r=t.message;if(!r&&i.error){if("code"in i.error&&i.error.code){r="Code "+i.error.code;for(var o in i.error){if(o=="code"){continue}if(i.error[o]==i.error.code){r=o;break}}}else{r=JSON.stringify(i.error)}}e.log("Error captured and stopped because videojs has not yet loaded: "+r)});function d(){var e=navigator.userAgent.toLowerCase().match(/android\s([\d\.]*)/i);return e?e[1]:false}var p=MistUtil.getAndroid();if(p&&parseFloat(p)<7){e.log("Detected android < 7: instructing videojs to override native playback");a.html5={hls:{overrideNative:true}};a.nativeAudioTracks=false;a.nativeVideoTracks=false}r.onready(function(){e.log("Building videojs");r.videojs=videojs(i,a,function(){MistUtil.event.removeListener(l);e.log("Videojs initialized");if(e.info.type=="live"){MistUtil.event.addListener(i,"progress",function(t){var r=e.player.videojs.seekable().length-1;e.info.meta.buffer_window=(Math.max(e.player.videojs.seekable().end(r),i.duration)-e.player.videojs.seekable().start(r))*1e3})}});MistUtil.event.addListener(i,"error",function(t){if(t&&t.target&&t.target.error&&t.target.error.message&&MistUtil.array.indexOf(t.target.error.message,"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)}});r.api.unload=function(){if(r.videojs){r.videojs.autoplay(false);r.videojs.pause();r.videojs.dispose();r.videojs=false;e.log("Videojs instance disposed")}}});e.log("Built html");if("Proxy"in window&&"Reflect"in window){var u={get:{},set:{}};e.player.api=new Proxy(i,{get:function(e,t,r){if(t in u.get){return u.get[t].apply(e,arguments)}var i=e[t];if(typeof i==="function"){return function(){return i.apply(e,arguments)}}return i},set:function(e,t,r){if(t in u.set){return u.set[t].call(e,r)}return e[t]=r}});e.player.api.load=function(){};u.set.currentTime=function(t){e.player.videojs.currentTime(t)};var f=0;var c=Infinity;for(var v in e.info.meta.tracks){f=Math.max(f,e.info.meta.tracks[v].lastms);c=Math.min(c,e.info.meta.tracks[v].firstms)}var y=c*.001;u.get.duration=function(){if(e.info){var t=i.duration;return t+y}return 0};MistUtil.event.addListener(i,"progress",function(){e.player.api.lastProgress=new Date});u.set.currentTime=function(t){var r=e.player.api.currentTime-t;var i=t-e.player.api.duration;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(i*-10)/10+"s from live)");e.player.videojs.currentTime(e.video.currentTime-r)};u.get.currentTime=function(){var t=e.player.videojs?e.player.videojs.currentTime():i.currentTime;if(isNaN(t)){return 0}return t+y};u.get.buffered=function(){var t=e.player.videojs?e.player.videojs.buffered():i.buffered;return{length:t.length,start:function(e){return t.start(e)+y},end:function(e){return t.end(e)+y}}};if(e.info.type=="live"){e.player.api.lastProgress=new Date;e.player.api.liveOffset=0}}else{r.api=i}e.player.setSize=function(t){if("videojs"in e.player){e.player.videojs.dimensions(t.width,t.height);i.parentNode.style.width=t.width+"px";i.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=i.getElementsByTagName("track");for(var r=t.length-1;r>=0;r--){i.removeChild(t[r])}if(e){var o=document.createElement("track");i.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 m=MistUtil.event.addListener(i,"loadstart",function(e){MistUtil.event.removeListener(m);MistUtil.event.send("canplay",false,this)});var g=MistUtil.event.addListener(i,"canplay",function(e){if(m){MistUtil.event.removeListener(m)}MistUtil.event.removeListener(g)})}t(i)}if("videojs"in window){o()}else{var s=false;function a(){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 n=e.urlappend(mistplayers.videojs.scriptsrc(e.options.host));var l;var d=function(e,t,r,i,o){if(!l){return}if(t==l.src){window.removeEventListener("error",d);a()}return false};window.addEventListener("error",d);l=MistUtil.scripts.insert(n,{onerror:function(t){var r="Failed to load videojs.js";if(t.message){r+=": "+t.message}e.showError(r)},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 MistUtil.array.indexOf(this.mimes,e)==-1?false:true},isBrowserSupported:function(e,t,r){if(location.protocol!=MistUtil.http.url.split(t.url).protocol){r.log("HTTP/HTTPS mismatch for this source");return false}if(location.protocol=="file:"&&e=="html5/application/vnd.apple"){r.log("This source ("+e+") won't load if the page is run via file://");return false}function i(e){if(!MediaSource.isTypeSupported){return true}var t={};var i=false;for(var o in r.info.meta.tracks){if(r.info.meta.tracks[o].type=="meta"){if(r.info.meta.tracks[o].codec=="subtitle"){i=true}continue}if(!(r.info.meta.tracks[o].type in t)){t[r.info.meta.tracks[o].type]={}}t[r.info.meta.tracks[o].type][MistUtil.tracks.translateCodec(r.info.meta.tracks[o])]=1}var s=[];for(var a in t){var n=false;for(var l in t[a]){if(MediaSource.isTypeSupported(e+';codecs="'+l+'"')){n=true;break}}if(n){s.push(a)}}if(i){for(var o in r.info.source){if(r.info.source[o].type=="html5/text/vtt"){s.push("subtitle");break}}}return s.length?s:false}if(document.createElement("video").canPlayType(e.replace("html5/",""))){if(!("MediaSource"in window)){return true}if(!MediaSource.isTypeSupported){return true}return i(e.replace("html5/",""))}if(!("MediaSource"in window)){return false}return i("video/mp4")},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 r=this;var i;function o(){if(e.destroyed){return}e.log("Building VideoJS player..");i=document.createElement("video");if(e.source.type!="html5/video/ogg"){i.crossOrigin="anonymous"}i.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);r.source=s;i.appendChild(s);s.type=o.join("/");e.log("Adding "+s.type+" source @ "+e.source.url);MistUtil.class.add(i,"video-js");var a={};if(e.options.autoplay){a.autoplay=true}if(e.options.loop&&e.info.type!="live"){i.setAttribute("loop","")}if(e.options.muted){i.setAttribute("muted","")}if(e.options.poster){a.poster=e.options.poster}if(e.options.controls=="stock"){i.setAttribute("controls","");if(!document.getElementById("videojs-css")){var n=document.createElement("link");n.rel="stylesheet";n.href=e.options.host+"/skins/videojs.css";n.id="videojs-css";document.head.appendChild(n)}}else{a.controls=false}var l=MistUtil.event.addListener(i,"error",(function(t){t.stopImmediatePropagation();var r=t.message;if(!r&&i.error){if("code"in i.error&&i.error.code){r="Code "+i.error.code;for(var o in i.error){if(o=="code"){continue}if(i.error[o]==i.error.code){r=o;break}}}else{r=JSON.stringify(i.error)}}e.log("Error captured and stopped because videojs has not yet loaded: "+r)}));function d(){var e=navigator.userAgent.toLowerCase().match(/android\s([\d\.]*)/i);return e?e[1]:false}var p=MistUtil.getAndroid();if(p&&parseFloat(p)<7){e.log("Detected android < 7: instructing videojs to override native playback");a.html5={hls:{overrideNative:true}};a.nativeAudioTracks=false;a.nativeVideoTracks=false}r.onready((function(){e.log("Building videojs");r.videojs=videojs(i,a,(function(){MistUtil.event.removeListener(l);e.log("Videojs initialized");if(e.info.type=="live"){MistUtil.event.addListener(i,"progress",(function(t){var r=e.player.videojs.seekable().length-1;e.info.meta.buffer_window=(Math.max(e.player.videojs.seekable().end(r),i.duration)-e.player.videojs.seekable().start(r))*1e3}))}}));MistUtil.event.addListener(i,"error",(function(t){if(t&&t.target&&t.target.error&&t.target.error.message&&MistUtil.array.indexOf(t.target.error.message,"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)}}));r.api.unload=function(){if(r.videojs){r.videojs.autoplay(false);r.videojs.pause();r.videojs.dispose();r.videojs=false;e.log("Videojs instance disposed")}}}));e.log("Built html");if("Proxy"in window&&"Reflect"in window){var u={get:{},set:{}};e.player.api=new Proxy(i,{get:function(e,t,r){if(t in u.get){return u.get[t].apply(e,arguments)}var i=e[t];if(typeof i==="function"){return function(){return i.apply(e,arguments)}}return i},set:function(e,t,r){if(t in u.set){return u.set[t].call(e,r)}return e[t]=r}});e.player.api.load=function(){};u.set.currentTime=function(t){e.player.videojs.currentTime(t)};var f=0;var c=Infinity;for(var v in e.info.meta.tracks){f=Math.max(f,e.info.meta.tracks[v].lastms);c=Math.min(c,e.info.meta.tracks[v].firstms)}var y=c*.001;u.get.duration=function(){if(e.info){var t=i.duration;return t+y}return 0};MistUtil.event.addListener(i,"progress",(function(){e.player.api.lastProgress=new Date}));u.set.currentTime=function(t){var r=e.player.api.currentTime-t;var i=t-e.player.api.duration;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(i*-10)/10+"s from live)");e.player.videojs.currentTime(e.video.currentTime-r)};u.get.currentTime=function(){var t=e.player.videojs?e.player.videojs.currentTime():i.currentTime;if(isNaN(t)){return 0}return t+y};u.get.buffered=function(){var t=e.player.videojs?e.player.videojs.buffered():i.buffered;return{length:t.length,start:function(e){return t.start(e)+y},end:function(e){return t.end(e)+y}}};if(e.info.type=="live"){e.player.api.lastProgress=new Date;e.player.api.liveOffset=0}}else{r.api=i}e.player.setSize=function(t){if("videojs"in e.player){e.player.videojs.dimensions(t.width,t.height);i.parentNode.style.width=t.width+"px";i.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=i.getElementsByTagName("track");for(var r=t.length-1;r>=0;r--){i.removeChild(t[r])}if(e){var o=document.createElement("track");i.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 m=MistUtil.event.addListener(i,"loadstart",(function(e){MistUtil.event.removeListener(m);MistUtil.event.send("canplay",false,this)}));var g=MistUtil.event.addListener(i,"canplay",(function(e){if(m){MistUtil.event.removeListener(m)}MistUtil.event.removeListener(g)}))}t(i)}if("videojs"in window){o()}else{var s=false;function a(){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 n=e.urlappend(mistplayers.videojs.scriptsrc(e.options.host));var l;var d=function(e,t,r,i,o){if(!l){return}if(t==l.src){window.removeEventListener("error",d);a()}return false};window.addEventListener("error",d);l=MistUtil.scripts.insert(n,{onerror:function(t){var r="Failed to load videojs.js";if(t.message){r+=": "+t.message}e.showError(r)},onload:o},e)}}; \ No newline at end of file diff --git a/embed/min/wrappers/webrtc.js b/embed/min/wrappers/webrtc.js index 916e8cd6..7eb8dc20 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)||!("RTCRtpReceiver"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}var i={};var r=false;for(var s in n.info.meta.tracks){if(n.info.meta.tracks[s].type=="meta"){if(n.info.meta.tracks[s].codec=="subtitle"){r=true}continue}if(!(n.info.meta.tracks[s].type in i)){i[n.info.meta.tracks[s].type]={}}i[n.info.meta.tracks[s].type][n.info.meta.tracks[s].codec]=1}var o=[];for(var a in i){var c=false;for(var l in i[a]){var f=RTCRtpReceiver.getCapabilities(a).codecs;for(var s in f){if(f[s].mimeType.toLowerCase()==(a+"/"+l).toLowerCase()){c=true;break}}}if(c){o.push(a)}}if(r){for(var s in n.info.source){if(n.info.source[s].type=="html5/text/vtt"){o.push("subtitle");break}}}return o.length?o:false},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 s=["autoplay","loop","poster"];for(var o in s){var a=s[o];if(e.options[a]){r.setAttribute(a,e.options[a]===true?"":e.options[a])}}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 c=0;var l=false;var f=[];this.listeners={on_connected:function(){c=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=c;c=t.current*.001-r.currentTime;if(Math.abs(n-c)>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&&f!=t.tracks){var s=e.info?MistUtil.tracks.parse(e.info.meta.tracks):[];for(var o in t.tracks){if(f.indexOf(t.tracks[o])<0){var a;for(var l in s){if(t.tracks[o]in s[l]){a=l;break}}if(!a){continue}if(a=="subtitle"){continue}MistUtil.event.send("playerUpdate_trackChanged",{type:a,trackid:t.tracks[o]},e.video)}}f=t.tracks}if(e.reporting&&t.tracks){e.reporting.stats.d.tracks=t.tracks.join(",")}},seek:function(e){var t=this;MistUtil.event.send("seeked",c,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()}},set_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 u(){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}case"on_error":{e.showError("WebRTC error: "+MistUtil.format.ucFirst(i.message));return;break}}if(i.type in n.listeners){return n.listeners[i.type].call(n,"data"in i?i.data: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 s=0;s<r.codecs.length;s++){if(r.codecs[s].mimeType=="video/H264"){t("H264 found :)");return}}if(e>0){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.MetaDataTrack=t.peerConn.createDataChannel("*",{protocol:"JSON"});t.peerConn.ontrack=function(e){r.srcObject=e.streams[0];if(n){n()}};t.peerConn.ondatachannel=function(){console.warn("ondatachannel",arguments)};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}}};MistUtil.event.send("webrtc_ready",null,r)})};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 s=MistUtil.event.addListener(e.video,"loadstart",function(){t.seek(n);MistUtil.event.removeListener(s)});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 s=i[r];if(s[1].type=="inbound-rtp"){n[s[0]]=s[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 u;this.api={};var p;Object.defineProperty(this.api,"duration",{get:function(){return p}});Object.defineProperty(this.api,"currentTime",{get:function(){return c+r.currentTime},set:function(e){c=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 o in v){h(v[o])}function g(e){if(e in r){n.api[e]=function(){return r[e].call(r,arguments)}}}var v=["load","getVideoPlaybackQuality"];for(var o in v){g(v[o])}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(function(t){var n={audio:null,video:null};var i=Object.fromEntries(t);for(var r in i){if(i[r].type=="track"){n[i[r].kind]=i[r]}}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(c-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-c;r.endTime=r.orig.end-c;t.push(r)}for(var i in t){n.api.textTracks[0].addCue(t[i])}n.api.textTracks[0].currentOffset=c}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}};n.api.metaTrackSocket=function(){this.origin={};this.CONNECTING=0;this.OPEN=1;this.CLOSING=2;this.CLOSED=3;this.readyState=0;this.listeners=[];var t=this;MistUtil.event.addListener(e.video,"webrtc_ready",function(){t.init()});this.init=function(){this.origin=e.player.webrtc&&e.player.webrtc.MetaDataTrack?e.player.webrtc.MetaDataTrack:{};if("readyState"in this.origin){function n(){t.readyState=t.OPEN;t.onopen()}this.origin.addEventListener("open",n);this.origin.onmessage=function(e){};this.origin.addEventListener("close",function(){t.readyState=t.CLOSED;t.onclose()});if(this.origin.readyState=="open"){n()}return true}else{return false}};this.open=function(){if(this.readyState==this.OPEN)return;switch(this.origin.readyState){case"connecting":{this.readyState=this.CONNECTING;break}case"open":{this.readyState=this.OPEN;break}case"closing":{this.readyState=this.CLOSING;break}case"closed":{this.readyState=this.CLOSED;break}}for(var e in this.listeners){this.origin.addEventListener.apply(this.origin,this.listeners[e])}};this.close=function(){if(this.readyState>=this.CLOSING)return;this.readyState=this.CLOSED;for(var e in this.listeners){this.removeEventListener.apply(this,this.listeners[e])}};this.send=function(){if(this.origin.readyState=="open")return this.origin.send.apply(this,arguments);return false};this.onopen=function(){};this.onclose=function(){};this.addEventListener=function(){this.listeners.push(arguments);return this.origin.addEventListener.apply(this.origin,arguments)};this.removeEventListener=function(e,t){for(var n=this.listeners.length-1;n>=0;n--){if(e==this.listeners[n][0]&&t==this.listeners[n][1]){this.listeners.splice(n,1);break}}return this.origin.removeEventListener.apply(this.origin,arguments)};this.init();return this};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 y=["nackCount","pliCount","packetsLost","packetsReceived","bytesReceived"];for(var w in y){n.api[y[w]]=0}var k=function(){e.timers.start(function(){n.webrtc.getStats(function(e){for(var t in e){for(var i in y){if(y[i]in e[t]){n.api[y[i]]=e[t][y[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)||!("RTCRtpReceiver"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}var i={};var r=false;for(var s in n.info.meta.tracks){if(n.info.meta.tracks[s].type=="meta"){if(n.info.meta.tracks[s].codec=="subtitle"){r=true}continue}if(!(n.info.meta.tracks[s].type in i)){i[n.info.meta.tracks[s].type]={}}i[n.info.meta.tracks[s].type][n.info.meta.tracks[s].codec]=1}var o=[];for(var a in i){var c=false;for(var l in i[a]){var f=RTCRtpReceiver.getCapabilities(a).codecs;for(var s in f){if(f[s].mimeType.toLowerCase()==(a+"/"+l).toLowerCase()){c=true;break}}}if(c){o.push(a)}}if(r){for(var s in n.info.source){if(n.info.source[s].type=="html5/text/vtt"){o.push("subtitle");break}}}return o.length?o:false},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 s=["autoplay","loop","poster"];for(var o in s){var a=s[o];if(e.options[a]){r.setAttribute(a,e.options[a]===true?"":e.options[a])}}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 c=0;var l=false;var f=[];this.listeners={on_connected:function(){c=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=c;c=t.current*.001-r.currentTime;if(Math.abs(n-c)>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&&f!=t.tracks){var s=e.info?MistUtil.tracks.parse(e.info.meta.tracks):[];for(var o in t.tracks){if(f.indexOf(t.tracks[o])<0){var a;for(var l in s){if(t.tracks[o]in s[l]){a=l;break}}if(!a){continue}if(a=="subtitle"){continue}MistUtil.event.send("playerUpdate_trackChanged",{type:a,trackid:t.tracks[o]},e.video)}}f=t.tracks}if(e.reporting&&t.tracks){e.reporting.stats.d.tracks=t.tracks.join(",")}},seek:function(e){var t=this;MistUtil.event.send("seeked",c,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()}},set_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 u(){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}case"on_error":{e.showError("WebRTC error: "+MistUtil.format.ucFirst(i.message));return;break}}if(i.type in n.listeners){return n.listeners[i.type].call(n,"data"in i?i.data: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 s=0;s<r.codecs.length;s++){if(r.codecs[s].mimeType=="video/H264"){t("H264 found :)");return}}if(e>0){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.MetaDataTrack=t.peerConn.createDataChannel("*",{protocol:"JSON"});t.peerConn.ontrack=function(e){r.srcObject=e.streams[0];if(n){n()}};t.peerConn.ondatachannel=function(){console.warn("ondatachannel",arguments)};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}}};MistUtil.event.send("webrtc_ready",null,r)}))};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 s=MistUtil.event.addListener(e.video,"loadstart",(function(){t.seek(n);MistUtil.event.removeListener(s)}));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 s=i[r];if(s[1].type=="inbound-rtp"){n[s[0]]=s[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 u;this.api={};var p;Object.defineProperty(this.api,"duration",{get:function(){return p}});Object.defineProperty(this.api,"currentTime",{get:function(){return c+r.currentTime},set:function(e){c=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 o in v){h(v[o])}function g(e){if(e in r){n.api[e]=function(){return r[e].call(r,arguments)}}}var v=["load","getVideoPlaybackQuality"];for(var o in v){g(v[o])}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((function(t){var n={audio:null,video:null};var i=Object.fromEntries(t);for(var r in i){if(i[r].type=="track"){n[i[r].kind]=i[r]}}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(c-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-c;r.endTime=r.orig.end-c;t.push(r)}for(var i in t){n.api.textTracks[0].addCue(t[i])}n.api.textTracks[0].currentOffset=c}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}};n.api.metaTrackSocket=function(){this.origin={};this.CONNECTING=0;this.OPEN=1;this.CLOSING=2;this.CLOSED=3;this.readyState=0;this.listeners=[];var t=this;MistUtil.event.addListener(e.video,"webrtc_ready",(function(){t.init()}));this.init=function(){this.origin=e.player.webrtc&&e.player.webrtc.MetaDataTrack?e.player.webrtc.MetaDataTrack:{};if("readyState"in this.origin){function n(){t.readyState=t.OPEN;t.onopen()}this.origin.addEventListener("open",n);this.origin.onmessage=function(e){};this.origin.addEventListener("close",(function(){t.readyState=t.CLOSED;t.onclose()}));if(this.origin.readyState=="open"){n()}return true}else{return false}};this.open=function(){if(this.readyState==this.OPEN)return;switch(this.origin.readyState){case"connecting":{this.readyState=this.CONNECTING;break}case"open":{this.readyState=this.OPEN;break}case"closing":{this.readyState=this.CLOSING;break}case"closed":{this.readyState=this.CLOSED;break}}for(var e in this.listeners){this.origin.addEventListener.apply(this.origin,this.listeners[e])}};this.close=function(){if(this.readyState>=this.CLOSING)return;this.readyState=this.CLOSED;for(var e in this.listeners){this.removeEventListener.apply(this,this.listeners[e])}};this.send=function(){if(this.origin.readyState=="open")return this.origin.send.apply(this,arguments);return false};this.onopen=function(){};this.onclose=function(){};this.addEventListener=function(){this.listeners.push(arguments);return this.origin.addEventListener.apply(this.origin,arguments)};this.removeEventListener=function(e,t){for(var n=this.listeners.length-1;n>=0;n--){if(e==this.listeners[n][0]&&t==this.listeners[n][1]){this.listeners.splice(n,1);break}}return this.origin.removeEventListener.apply(this.origin,arguments)};this.init();return this};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 y=["nackCount","pliCount","packetsLost","packetsReceived","bytesReceived"];for(var w in y){n.api[y[w]]=0}var k=function(){e.timers.start((function(){n.webrtc.getStats((function(e){for(var t in e){for(var i in y){if(y[i]in e[t]){n.api[y[i]]=e[t][y[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/lib/config.cpp b/lib/config.cpp index 74c4ccc4..20c0092b 100644 --- a/lib/config.cpp +++ b/lib/config.cpp @@ -763,6 +763,7 @@ void Util::Config::addStandardPushCapabilities(JSON::Value &cap){ pp["track_selectors"]["type"] = "group"; pp["track_selectors"]["name"] = "Track selectors"; pp["track_selectors"]["help"] = "Control which tracks are part of the output"; + pp["track_selectors"]["sort"] = "v"; { JSON::Value & o = pp["track_selectors"]["options"]; o["audio"]["name"] = "Audio track(s)"; @@ -787,6 +788,7 @@ void Util::Config::addStandardPushCapabilities(JSON::Value &cap){ pp["trackwait_opts"]["type"] = "group"; pp["trackwait_opts"]["name"] = "Wait for tracks"; pp["trackwait_opts"]["help"] = "Before starting, ensure the available tracks satisfy certain conditions"; + pp["trackwait_opts"]["sort"] = "w"; { JSON::Value & o = pp["trackwait_opts"]["options"]; o["waittrackcount"]["name"] = "Wait for tracks count"; @@ -823,37 +825,10 @@ void Util::Config::addStandardPushCapabilities(JSON::Value &cap){ o["maxwaittrackms"]["sort"] = "bdad"; } - pp["pls_opts"]["type"] = "group"; - pp["pls_opts"]["name"] = "Playlist writing options"; - pp["pls_opts"]["help"] = "Control the writing of a playlist file when recording to a segmented format"; - { - JSON::Value & o = pp["pls_opts"]["options"]; - o["noendlist"]["name"] = "Don't end playlist"; - o["noendlist"]["help"] = "If set, does not write #X-EXT-ENDLIST when finalizing the playlist on exit"; - o["noendlist"]["type"] = "bool"; - o["noendlist"]["format"] = "set_or_unset"; - o["noendlist"]["sort"] = "bfa"; - - o["m3u8"]["name"] = "Playlist path (relative to segments)"; - o["m3u8"]["help"] = "If set, will write a m3u8 playlist file for the segments to the given path (relative from the first segment path). When this parameter is used, at least one of the variables $segmentCounter or $currentMediaTime must be part of the segment path (to keep segments from overwriting each other). The \"Split interval\" parameter will default to 60 seconds when using this option."; - o["m3u8"]["type"] = "string"; - o["m3u8"]["sort"] = "apa"; - - o["targetAge"]["name"] = "Playlist target age"; - o["targetAge"]["help"] = "When writing a playlist, delete segment entries that are more than this many seconds old from the playlist (and, if possible, also delete said segments themselves). When set to 0 or left empty, does not delete."; - o["targetAge"]["type"] = "int"; - o["targetAge"]["unit"] = "s"; - o["targetAge"]["sort"] = "apb"; - - o["maxEntries"]["name"] = "Playlist max entries"; - o["maxEntries"]["help"] = "When writing a playlist, delete oldest segment entries once this entry count has been reached (and, if possible, also delete said segments themselves). When set to 0 or left empty, does not delete."; - o["maxEntries"]["type"] = "int"; - o["maxEntries"]["sort"] = "apc"; - } - pp["time_opts"]["type"] = "group"; pp["time_opts"]["name"] = "Timing options"; pp["time_opts"]["help"] = "Control speed and the start/stop timing"; + pp["time_opts"]["sort"] = "x"; { JSON::Value & o = pp["time_opts"]["options"]; o["rate"]["name"] = "Playback rate"; @@ -917,17 +892,55 @@ void Util::Config::addStandardPushCapabilities(JSON::Value &cap){ o["split"]["sort"] = "bh"; } - pp["unmask"]["name"] = "Unmask tracks"; - pp["unmask"]["help"] = "If set to any value, removes any applied track masking before selecting tracks, acting as if no mask was applied at all"; - pp["unmask"]["type"] = "bool"; - pp["unmask"]["format"] = "set_or_unset"; - pp["unmask"]["sort"] = "bc"; + pp["pls_opts"]["type"] = "group"; + pp["pls_opts"]["name"] = "Playlist writing options"; + pp["pls_opts"]["help"] = "Control the writing of a playlist file when recording to a segmented format"; + pp["pls_opts"]["sort"] = "y"; + { + JSON::Value & o = pp["pls_opts"]["options"]; + o["noendlist"]["name"] = "Don't end playlist"; + o["noendlist"]["help"] = "If set, does not write #X-EXT-ENDLIST when finalizing the playlist on exit"; + o["noendlist"]["type"] = "bool"; + o["noendlist"]["format"] = "set_or_unset"; + o["noendlist"]["sort"] = "bfa"; - pp["append"]["name"] = "Append to file"; - pp["append"]["help"] = "If set to any value, will (if possible) append to an existing file, rather than overwriting it"; - pp["append"]["type"] = "bool"; - pp["append"]["format"] = "set_or_unset"; - pp["append"]["sort"] = "bf"; + o["m3u8"]["name"] = "Playlist path (relative to segments)"; + o["m3u8"]["help"] = "If set, will write a m3u8 playlist file for the segments to the given path (relative from the first segment path). When this parameter is used, at least one of the variables $segmentCounter or $currentMediaTime must be part of the segment path (to keep segments from overwriting each other). The \"Split interval\" parameter will default to 60 seconds when using this option."; + o["m3u8"]["type"] = "string"; + o["m3u8"]["sort"] = "apa"; + + o["targetAge"]["name"] = "Playlist target age"; + o["targetAge"]["help"] = "When writing a playlist, delete segment entries that are more than this many seconds old from the playlist (and, if possible, also delete said segments themselves). When set to 0 or left empty, does not delete."; + o["targetAge"]["type"] = "int"; + o["targetAge"]["unit"] = "s"; + o["targetAge"]["sort"] = "apb"; + + o["maxEntries"]["name"] = "Playlist max entries"; + o["maxEntries"]["help"] = "When writing a playlist, delete oldest segment entries once this entry count has been reached (and, if possible, also delete said segments themselves). When set to 0 or left empty, does not delete."; + o["maxEntries"]["type"] = "int"; + o["maxEntries"]["sort"] = "apc"; + } + + + + pp["misc_genopts"]["type"] = "group"; + pp["misc_genopts"]["name"] = "Miscellaneous options"; + pp["misc_genopts"]["sort"] = "z"; + { + JSON::Value & o = pp["misc_genopts"]["options"]; + + o["unmask"]["name"] = "Unmask tracks"; + o["unmask"]["help"] = "If set to any value, removes any applied track masking before selecting tracks, acting as if no mask was applied at all"; + o["unmask"]["type"] = "bool"; + o["unmask"]["format"] = "set_or_unset"; + o["unmask"]["sort"] = "bc"; + + o["append"]["name"] = "Append to file"; + o["append"]["help"] = "If set to any value, will (if possible) append to an existing file, rather than overwriting it"; + o["append"]["type"] = "bool"; + o["append"]["format"] = "set_or_unset"; + o["append"]["sort"] = "bf"; + } } diff --git a/lsp/main.css b/lsp/main.css index 4534e4e8..83ffb6ba 100644 --- a/lsp/main.css +++ b/lsp/main.css @@ -637,6 +637,68 @@ input[type=radio] { margin-bottom: 1em; margin-left: 1em; } +.input_container .itemgroup .input_container:first-child > b { + cursor: pointer; + margin-right: 0.5em; +} +.input_container .itemgroup.expanded .input_container:first-child > b:before { + content: '▼'; +} +.input_container .itemgroup .input_container:first-child > b:before { + content: '▲'; + color: var(--accentColor); + opacity: 0.5; + transform: translateY(-0.1em); + display: inline-block; +} +.input_container .itemgroup .input_container:first-child:hover > b:before { + opacity: 1; +} +.input_container .itemgroup .description { + display: none; +} +.input_container .itemgroup.expanded .description { + display: block; +} + +.input_container .itemgroup .summary { + font-size: 0.8em; + margin: 0; + padding-inline: 1.75em; +} +.input_container .itemgroup .summary li::marker { + margin: 0 0.25em 0 0; +} +.input_container .itemgroup .summary:empty { + display: flex; + flex-flow: row wrap; + list-style: none; + padding: 0; +} +.input_container .itemgroup .summary:empty:after { + content: '(Default settings)'; +} +.input_container .itemgroup .summary:empty { + opacity: 0.5; +} +.input_container .itemgroup.expanded .summary { + display: none; +} +.input_container .itemgroup .UIelement { + display: none; +} +.input_container .itemgroup.expanded .UIelement { + display: flex; +} +.input_container .itemgroup:not(.expanded) .input_container:has(.summary:empty) { + flex-direction: row; + align-items: baseline; + margin: 0; +} +.input_container .itemgroup.expanded .input_container { + flex-direction: column; + margin: 0.5em 0; +} .input_container .subitem { font-size: 0.9em; color: #777; diff --git a/lsp/minified.js b/lsp/minified.js index d2b3d0ca..794ccd14 100644 --- a/lsp/minified.js +++ b/lsp/minified.js @@ -30,10 +30,10 @@ TS:-1,"TS.exe":-1},j;for(j in f){for(n in mist.data.config.protocols){var q=mist j.length&&(j[0].style.display="");g+=""==a?"STREAMNAME":a;break;case "TSSRT":case "TSSRT.exe":"srt://"==b.slice(0,6)?i?(g=parseURL(b.replace()),""==g.host&&(g=parseURL(b.replace(/^srt:\/\//,"http://localhost")),g.host=g.host.replace(/^localhost/,"")),g=""!=g.host&&(!g.search||!g.searchParams||"listener"!=g.searchParams.get("mode"))?"Caller mode: you should push to the other side.":g.search&&g.searchParams&&"caller"==g.searchParams.get("mode")?"Caller mode: you should probably add an address.":"srt://"+ c.host+i):g="You must specify a port.":g="srt://"+c.host+j+"?streamid="+(""==a?"STREAMNAME":a);break;case "RTSP":case "RTSP.exe":g="rtsp://"+c.host+j+"/"+(""==a?"STREAMNAME":a)+(e?"?pass="+e:"");break;case "TS":case "TS.exe":g="udp://"+(""==l?c.host:l)+j+"/"}j=d.find(".field."+n.replace(".exe",""));j.length&&(j.setval(g).closest("label")[0].style.display="")}}},buildUI:function(a){var b=$("<div>").addClass("input_container"),d;for(d in a){var c=a[d];if(c instanceof jQuery)b.append(c);else if("help"== c.type){var e=$("<span>").addClass("text_container").append($("<span>").addClass("description").append(c.help));b.append(e);if("classes"in c)for(var l in c.classes)e.addClass(c.classes[l])}else if("text"==c.type)b.append($("<span>").addClass("text_container").append($("<span>").addClass("text").append(c.text)));else if("custom"==c.type)b.append(c.custom);else if("buttons"==c.type)for(l in e=$("<span>").addClass("button_container").on("keydown",function(a){a.stopPropagation()}),"css"in c&&e.css(c.css), -b.append(e),c.buttons){var i=c.buttons[l],f=$("<button>").text(i.label).data("opts",i);"css"in i&&f.css(i.css);if("classes"in i)for(var m in i.classes)f.addClass(i.classes[m]);e.append(f);switch(i.type){case "cancel":f.addClass("cancel").click(i["function"]);break;case "save":f.addClass("save").click(function(){var a=$(this).data("opts").preSave;a&&a.call(this);var b=$(this).closest(".input_container"),c=!1;b.find('.hasValidate:visible, input[type="hidden"].hasValidate').each(function(){if(c=$(this).data("validate")(this, -!0))return!1});(a=$(this).data("opts").failedValidate)&&a.call(this);c||(b.find('.isSetting:visible, input[type="hidden"].isSetting').each(function(){var a=$(this).getval(),b=$(this).data("pointer");if(""===a)if("default"in $(this).data("opts"))a=$(this).data("opts")["default"];else return b.main[b.index]=null,!0;b.main[b.index]=a;(a=$(this).data("opts").postSave)&&a.call(this)}),(a=$(this).data("opts")["function"])&&a(this))});break;default:f.click(i["function"])}}else{i=$("<label>").addClass("UIelement"); -b.append(i);"css"in c&&i.css(c.css);i.append($("<span>").addClass("label").html("label"in c?c.label+":":""));if("classes"in c)for(m in c.classes)i.addClass(c.classes[m]);f=$("<span>").addClass("field_container");i.append(f);switch(c.type){case "password":e=$("<input>").attr("type","password");break;case "int":e=$("<input>").attr("type","number");"min"in c&&e.attr("min",c.min);"max"in c&&e.attr("max",c.max);"step"in c&&e.attr("step",c.step);"validate"in c?c.validate.push("int"):c.validate=["int"]; -break;case "span":e=$("<span>");break;case "debug":c.select=[["","Default"],[0,"0 - All debugging messages disabled"],[1,"1 - Messages about failed operations"],[2,"2 - Previous level, and error messages"],[3,"3 - Previous level, and warning messages"],[4,"4 - Previous level, and status messages for development"],[5,"5 - Previous level, and more status messages for development"],[6,"6 - Previous level, and verbose debugging messages"],[7,"7 - Previous level, and very verbose debugging messages"], +b.append(e),c.buttons){var i=c.buttons[l],f=$("<button>").text(i.label).data("opts",i);"css"in i&&f.css(i.css);if("classes"in i)for(var m in i.classes)f.addClass(i.classes[m]);e.append(f);switch(i.type){case "cancel":f.addClass("cancel").click(i["function"]);break;case "save":f.addClass("save").click(function(){var a=$(this).data("opts").preSave;a&&a.call(this);var b=$(this).closest(".input_container");b.find(".itemgroup:has(.summary:not(:empty))").addClass("expanded");var c=!1;b.find('.hasValidate:visible, input[type="hidden"].hasValidate').each(function(){if(c= +$(this).data("validate")(this,!0))return!1});(a=$(this).data("opts").failedValidate)&&a.call(this);c||(b.find('.isSetting:visible, input[type="hidden"].isSetting').each(function(){var a=$(this).getval(),b=$(this).data("pointer");if(""===a)if("default"in $(this).data("opts"))a=$(this).data("opts")["default"];else return b.main[b.index]=null,!0;b.main[b.index]=a;(a=$(this).data("opts").postSave)&&a.call(this)}),(a=$(this).data("opts")["function"])&&a(this))});break;default:f.click(i["function"])}}else{i= +$("<label>").addClass("UIelement");b.append(i);"css"in c&&i.css(c.css);i.append($("<span>").addClass("label").html("label"in c?c.label+":":""));if("classes"in c)for(m in c.classes)i.addClass(c.classes[m]);f=$("<span>").addClass("field_container");i.append(f);switch(c.type){case "password":e=$("<input>").attr("type","password");break;case "int":e=$("<input>").attr("type","number");"min"in c&&e.attr("min",c.min);"max"in c&&e.attr("max",c.max);"step"in c&&e.attr("step",c.step);"validate"in c?c.validate.push("int"): +c.validate=["int"];break;case "span":e=$("<span>");break;case "debug":c.select=[["","Default"],[0,"0 - All debugging messages disabled"],[1,"1 - Messages about failed operations"],[2,"2 - Previous level, and error messages"],[3,"3 - Previous level, and warning messages"],[4,"4 - Previous level, and status messages for development"],[5,"5 - Previous level, and more status messages for development"],[6,"6 - Previous level, and verbose debugging messages"],[7,"7 - Previous level, and very verbose debugging messages"], [8,"8 - Report everything in extreme detail"],[9,"9 - Report everything in insane detail"],[10,"10 - All messages enabled"]];case "select":e=$("<select>");for(l in c.select){var n=$("<option>");"string"==typeof c.select[l]?n.text(c.select[l]):n.val(c.select[l][0]).text(c.select[l][1]);e.append(n)}break;case "textarea":e=$("<textarea>").on("keydown",function(a){a.stopPropagation()});break;case "checkbox":e=$("<input>").attr("type","checkbox");break;case "hidden":e=$("<input>").attr("type","hidden"); i.hide();break;case "email":e=$("<input>").attr("type","email").attr("autocomplete","on").attr("required","");break;case "browse":e=$("<input>").attr("type","text");"filetypes"in c&&e.data("filetypes",c.filetypes);break;case "geolimited":case "hostlimited":e=$("<input>").attr("type","hidden");break;case "radioselect":e=$("<div>").addClass("radioselect");for(d in c.radioselect){var j=$("<input>").attr("type","radio").val(c.radioselect[d][0]).attr("name",c.label);c.readonly&&j.prop("disabled",!0);n= $("<label>").append(j).append($("<span>").html(c.radioselect[d][1]));e.append(n);if(2<c.radioselect[d].length)for(l in j=$("<select>").change(function(){$(this).parent().find("input[type=radio]:enabled").prop("checked","true")}),n.append(j),c.readonly&&j.prop("disabled",!0),c.radioselect[d][2])n=$("<option>"),j.append(n),c.radioselect[d][2][l]instanceof Array?n.val(c.radioselect[d][2][l][0]).html(c.radioselect[d][2][l][1]):n.html(c.radioselect[d][2][l])}break;case "checklist":e=$("<div>").addClass("checkcontainer"); @@ -104,12 +104,12 @@ $("<table>").css("text-indent","0");j.html(s);s.append($("<tr>").append($("<th>" h.amount:"∞")))}else j.text("None. ");j.append($("<a>").text("More details").attr("href","https://shop.mistserver.org/myinvoices").attr("target","_blank"))}}else l.text("");p=function(){var a={totals:{fields:["clients"],start:-10},active_streams:true};if(!("capabilities"in mist.data))a.capabilities=true;mist.send(function(){ca()},a)};var ca=function(){i.text("active_streams"in mist.data?mist.data.active_streams?mist.data.active_streams.length:0:"?");if("totals"in mist.data&&"all_streams"in mist.data.totals)var a= mist.data.totals.all_streams.all_protocols.clients,a=a.length?UI.format.number(a[a.length-1][1]):0;else a="Loading..";m.text(a);n.text(UI.format.dateTime(mist.data.config.time,"long"));f.html("");a=0;"license"in mist.data.config&&"user_msg"in mist.data.config.license&&mist.data.log.unshift([mist.data.config.license.time,"ERROR",mist.data.config.license.user_msg]);for(var b in mist.data.log){var c=mist.data.log[b];if(["FAIL","ERROR"].indexOf(c[1])>-1){a++;var d=$("<span>").addClass("content").addClass("red"), h=c[2].split("|");for(b in h)d.append($("<span>").text(h[b]));f.append($("<div>").append($("<span>").append(UI.format.time(c[0]))).append(d));if(a==5)break}}a==0&&f.html("None.");a=[];c=[];for(b in mist.data.config.protocols){d=mist.data.config.protocols[b];a.indexOf(d.connector)>-1||a.push(d.connector)}q.text(a.length?a.join(", "):"None.");if("capabilities"in mist.data){for(b in mist.data.capabilities.connectors)a.indexOf(b)==-1&&c.push(b);g.text(c.length?c.join(", "):"None.")}else g.text("Loading..")}; -p();ca();UI.interval.set(p,3E4);break;case "General":var G={serverid:mist.data.config.serverid,debug:mist.data.config.debug,accesslog:mist.data.config.accesslog,prometheus:mist.data.config.prometheus,defaultStream:mist.data.config.defaultStream,trustedproxy:mist.data.config.trustedproxy},H={sessionViewerMode:mist.data.config.sessionViewerMode,sessionInputMode:mist.data.config.sessionInputMode,sessionOutputMode:mist.data.config.sessionOutputMode,sessionUnspecifiedMode:mist.data.config.sessionUnspecifiedMode, -tknMode:mist.data.config.tknMode,sessionStreamInfoMode:mist.data.config.sessionStreamInfoMode},P={location:"location"in mist.data.config?mist.data.config.location:{}},x={limit:""};"bandwidth"in mist.data&&(x=mist.data.bandwidth,null==x&&(x={}),x.limit||(x.limit=""));var da=$("<select>").html($("<option>").val(1).text("bytes/s")).append($("<option>").val(1024).text("KiB/s")).append($("<option>").val(1048576).text("MiB/s")).append($("<option>").val(1073741824).text("GiB/s"));c.html(UI.buildUI([$("<h2>").text("General settings"), -{type:"help",help:"These are settings that apply to your MistServer instance in general."},{type:"str",label:"Human readable name",pointer:{main:G,index:"serverid"},help:"You can name your MistServer here for personal use. You'll still need to set host name within your network yourself."},{type:"debug",label:"Debug level",pointer:{main:G,index:"debug"},help:"You can set the amount of debug information MistServer saves in the log. A full reboot of MistServer is required before some components of MistServer can post debug information."}, -{type:"selectinput",label:"Access log",selectinput:[["","Do not track"],["LOG","Log to MistServer log"],[{type:"str",label:"Path",LTSonly:!0},"Log to file"]],pointer:{main:G,index:"accesslog"},help:"Enable access logs.",LTSonly:!0},{type:"selectinput",label:"Prometheus stats output",selectinput:[["","Disabled"],[{type:"str",label:"Passphrase",LTSonly:!0},"Enabled"]],pointer:{main:G,index:"prometheus"},help:"Make stats available in Prometheus format. These can be accessed via "+h+"/PASSPHRASE or "+ -h+"/PASSPHRASE.json.",LTSonly:!0},{type:"inputlist",label:"Trusted proxies",help:"List of proxy server addresses that are allowed to override the viewer IP address to arbitrary values.<br>You may use a hostname or IP address.",pointer:{main:G,index:"trustedproxy"}},{type:"str",validate:["streamname_with_wildcard_and_variables"],label:"Fallback stream",pointer:{main:G,index:"defaultStream"},help:"When this is set, if someone attempts to view a stream that does not exist, or is offline, they will be redirected to this stream instead. $stream may be used to refer to the original stream name.", -LTSonly:!0},{type:"buttons",buttons:[{type:"save",label:"Save","function":function(a){$(a).text("Saving..");mist.send(function(){UI.navto("General")},{config:G})}}]}]));c.append(UI.buildUI([$("<h3>").text("Sessions"),{type:"bitmask",label:"Bundle viewer sessions by",bitmask:[[8,"Stream name"],[4,"IP address"],[2,"Token"],[1,"Protocol"]],pointer:{main:H,index:"sessionViewerMode"},help:"Change the way viewer connections are bundled into sessions.<br>Default: stream name, viewer IP and token"},{type:"bitmask", +p();ca();UI.interval.set(p,3E4);break;case "General":var A={serverid:mist.data.config.serverid,debug:mist.data.config.debug,accesslog:mist.data.config.accesslog,prometheus:mist.data.config.prometheus,defaultStream:mist.data.config.defaultStream,trustedproxy:mist.data.config.trustedproxy},H={sessionViewerMode:mist.data.config.sessionViewerMode,sessionInputMode:mist.data.config.sessionInputMode,sessionOutputMode:mist.data.config.sessionOutputMode,sessionUnspecifiedMode:mist.data.config.sessionUnspecifiedMode, +tknMode:mist.data.config.tknMode,sessionStreamInfoMode:mist.data.config.sessionStreamInfoMode},P={location:"location"in mist.data.config?mist.data.config.location:{}},D={limit:""};"bandwidth"in mist.data&&(D=mist.data.bandwidth,null==D&&(D={}),D.limit||(D.limit=""));var da=$("<select>").html($("<option>").val(1).text("bytes/s")).append($("<option>").val(1024).text("KiB/s")).append($("<option>").val(1048576).text("MiB/s")).append($("<option>").val(1073741824).text("GiB/s"));c.html(UI.buildUI([$("<h2>").text("General settings"), +{type:"help",help:"These are settings that apply to your MistServer instance in general."},{type:"str",label:"Human readable name",pointer:{main:A,index:"serverid"},help:"You can name your MistServer here for personal use. You'll still need to set host name within your network yourself."},{type:"debug",label:"Debug level",pointer:{main:A,index:"debug"},help:"You can set the amount of debug information MistServer saves in the log. A full reboot of MistServer is required before some components of MistServer can post debug information."}, +{type:"selectinput",label:"Access log",selectinput:[["","Do not track"],["LOG","Log to MistServer log"],[{type:"str",label:"Path",LTSonly:!0},"Log to file"]],pointer:{main:A,index:"accesslog"},help:"Enable access logs.",LTSonly:!0},{type:"selectinput",label:"Prometheus stats output",selectinput:[["","Disabled"],[{type:"str",label:"Passphrase",LTSonly:!0},"Enabled"]],pointer:{main:A,index:"prometheus"},help:"Make stats available in Prometheus format. These can be accessed via "+h+"/PASSPHRASE or "+ +h+"/PASSPHRASE.json.",LTSonly:!0},{type:"inputlist",label:"Trusted proxies",help:"List of proxy server addresses that are allowed to override the viewer IP address to arbitrary values.<br>You may use a hostname or IP address.",pointer:{main:A,index:"trustedproxy"}},{type:"str",validate:["streamname_with_wildcard_and_variables"],label:"Fallback stream",pointer:{main:A,index:"defaultStream"},help:"When this is set, if someone attempts to view a stream that does not exist, or is offline, they will be redirected to this stream instead. $stream may be used to refer to the original stream name.", +LTSonly:!0},{type:"buttons",buttons:[{type:"save",label:"Save","function":function(a){$(a).text("Saving..");mist.send(function(){UI.navto("General")},{config:A})}}]}]));c.append(UI.buildUI([$("<h3>").text("Sessions"),{type:"bitmask",label:"Bundle viewer sessions by",bitmask:[[8,"Stream name"],[4,"IP address"],[2,"Token"],[1,"Protocol"]],pointer:{main:H,index:"sessionViewerMode"},help:"Change the way viewer connections are bundled into sessions.<br>Default: stream name, viewer IP and token"},{type:"bitmask", label:"Bundle input sessions by",bitmask:[[8,"Stream name"],[4,"IP address"],[2,"Token"],[1,"Protocol"]],pointer:{main:H,index:"sessionInputMode"},help:"Change the way input connections are bundled into sessions.<br>Default: stream name, input IP, token and protocol"},{type:"bitmask",label:"Bundle output sessions by",bitmask:[[8,"Stream name"],[4,"IP address"],[2,"Token"],[1,"Protocol"]],pointer:{main:H,index:"sessionOutputMode"},help:"Change the way output connections are bundled into sessions.<br>Default: stream name, output IP, token and protocol"}, {type:"bitmask",label:"Bundle unspecified sessions by",bitmask:[[8,"Stream name"],[4,"IP address"],[2,"Token"],[1,"Protocol"]],pointer:{main:H,index:"sessionUnspecifiedMode"},help:"Change the way unspecified connections are bundled into sessions.<br>Default: none"},{type:"select",label:"Treat HTTP-only sessions as",select:[[1,"A viewer session"],[2,"An output session: skip executing the USER_NEW and USER_END triggers"],[4,"A separate 'unspecified' session: skip executing the USER_NEW and USER_END triggers"], [3,"Do not start a session: skip executing the USER_NEW and USER_END triggers and do not count for statistics"]],pointer:{main:H,index:"sessionStreamInfoMode"},help:"Change the way the stream info connection gets treated.<br>Default: as a viewer session"},{type:"bitmask",label:"Communicate session token",bitmask:[[8,"Write to cookie"],[4,"Write to URL parameter"],[2,"Read from cookie"],[1,"Read from URL parameter"]],pointer:{main:H,index:"tknMode"},help:"Change the way the session token gets passed to and from MistServer, which can be set as a cookie or URL parameter named `tkn`. Reading the session token as a URL parameter takes precedence over reading from the cookie.<br>Default: all"}, @@ -117,25 +117,25 @@ label:"Bundle input sessions by",bitmask:[[8,"Stream name"],[4,"IP address"],[2, for(var c in a.variable_list){var d=a.variable_list[c];b.append($("<tr>").addClass("variable").attr("data-name",c).html($("<td>").text("$"+c)).append($("<td>").html($("<code>").text(typeof d=="string"?JSON.stringify(d):d[2]>0?JSON.stringify(d[3]):""))).append($("<td>").text(typeof d=="string"?"":d[0])).append($("<td>").html(typeof d=="string"?"Never":d[1]==0?"Once":UI.format.duration(d[1]))).append($("<td>").attr("title",d[2]>0?typeof d=="string"?"":"At "+UI.format.dateTime(new Date(d[2]),"long"): "Not yet").html(typeof d=="string"?"":d[2]>0?UI.format.duration((new Date).getTime()*0.001-d[2])+" ago":"Not yet")).append($("<td>").html($("<button>").text("Edit").click(function(){var a=$(this).closest("tr").attr("data-name");UI.navto("Edit variable",a)})).append($("<button>").text("Remove").click(function(){var a=$(this).closest("tr").attr("data-name");confirm("Are you sure you want to remove the custom variable $"+a+"?")&&mist.send(function(){UI.showTab("General")},{variable_remove:a})}))))}}else S.html("None configured.")}, {variable_list:!0});c.append(UI.buildUI([$("<h3>").text("Custom variables"),{type:"help",help:"In certain places, like target URL's and pushes, variable substitution is applied in order to replace a $variable with their corresponding value. Here you can define your own constants and variables which will be used when variable substitution is applied. Variables can be used within variables but will not be reflected in their latest value on this page."},$("<div>").addClass("button_container").css("text-align", -"right").html($("<button>").text("New variable").click(function(){UI.navto("Edit variable","")})),S]));c.append(UI.buildUI([$("<h3>").text("Load balancer"),{type:"help",help:"If you're using MistServer's load balancer, the information below is passed to it so that it can make informed decisions."},{type:"selectinput",label:"Server's bandwidth limit",selectinput:[["","Default (1 gbps)"],[{label:"Custom",type:"int",min:0,unit:da},"Custom"]],pointer:{main:x,index:"limit"},help:"This is the amount of traffic this server is willing to handle."}, -{type:"inputlist",label:"Bandwidth exceptions",pointer:{main:x,index:"exceptions"},help:"Data sent to the hosts and subnets listed here will not count towards reported bandwidth usage.<br>Examples:<ul><li>192.168.0.0/16</li><li>localhost</li><li>10.0.0.0/8</li><li>fe80::/16</li></ul>"},{type:"int",step:1E-8,label:"Server latitude",pointer:{main:P.location,index:"lat"},help:"This setting is only useful when MistServer is combined with a load balancer. When this is set, the balancer can send users to a server close to them."}, +"right").html($("<button>").text("New variable").click(function(){UI.navto("Edit variable","")})),S]));c.append(UI.buildUI([$("<h3>").text("Load balancer"),{type:"help",help:"If you're using MistServer's load balancer, the information below is passed to it so that it can make informed decisions."},{type:"selectinput",label:"Server's bandwidth limit",selectinput:[["","Default (1 gbps)"],[{label:"Custom",type:"int",min:0,unit:da},"Custom"]],pointer:{main:D,index:"limit"},help:"This is the amount of traffic this server is willing to handle."}, +{type:"inputlist",label:"Bandwidth exceptions",pointer:{main:D,index:"exceptions"},help:"Data sent to the hosts and subnets listed here will not count towards reported bandwidth usage.<br>Examples:<ul><li>192.168.0.0/16</li><li>localhost</li><li>10.0.0.0/8</li><li>fe80::/16</li></ul>"},{type:"int",step:1E-8,label:"Server latitude",pointer:{main:P.location,index:"lat"},help:"This setting is only useful when MistServer is combined with a load balancer. When this is set, the balancer can send users to a server close to them."}, {type:"int",step:1E-8,label:"Server longitude",pointer:{main:P.location,index:"lon"},help:"This setting is only useful when MistServer is combined with a load balancer. When this is set, the balancer can send users to a server close to them."},{type:"str",label:"Server location name",pointer:{main:P.location,index:"name"},help:"This setting is only useful when MistServer is combined with a load balancer. This will be displayed as the server's location."},{type:"buttons",buttons:[{type:"save",label:"Save", -"function":function(a){$(a).text("Saving..");var a={config:P},b={};b.limit=x.limit?da.val()*x.limit:0;b.exceptions=x.exceptions;if(b.exceptions===null)b.exceptions=[];a.bandwidth=b;mist.send(function(){UI.navto("Overview")},a)}}]}]));var C=$("<div>").html("Loading..");c.append(UI.buildUI([$("<h3>").text("External writers"),{type:"help",help:"When pushing a stream to a target unsupported by MistServer like S3 storage, an external writer can be provided which handles writing the media data to the target location. The writer will receive data over stdin and MistServer will print any info written to stdout and stderr as log messages."}, +"function":function(a){$(a).text("Saving..");var a={config:P},b={};b.limit=D.limit?da.val()*D.limit:0;b.exceptions=D.exceptions;if(b.exceptions===null)b.exceptions=[];a.bandwidth=b;mist.send(function(){UI.navto("Overview")},a)}}]}]));var C=$("<div>").html("Loading..");c.append(UI.buildUI([$("<h3>").text("External writers"),{type:"help",help:"When pushing a stream to a target unsupported by MistServer like S3 storage, an external writer can be provided which handles writing the media data to the target location. The writer will receive data over stdin and MistServer will print any info written to stdout and stderr as log messages."}, $("<div>").addClass("button_container").css("text-align","right").html($("<button>").text("New external writer").click(function(){UI.navto("Edit external writer","")})),C]));mist.send(function(a){if(a.external_writer_list){var b=$("<tbody>");C.html($("<table>").html($("<thead>").html($("<tr>").append($("<th>").text("Name")).append($("<th>").text("Command line")).append($("<th>").text("URI protocols handled")).append($("<th>")))).append(b));for(var c in a.external_writer_list){var d=a.external_writer_list[c]; b.append($("<tr>").addClass("uploader").attr("data-name",c).html($("<td>").text(d[0])).append($("<td>").html($("<code>").html(d[1]))).append($("<td>").text(d[2]?d[2].join(", "):"none").addClass("desc")).append($("<td>").html($("<button>").text("Edit").click(function(){var a=$(this).closest("tr").attr("data-name");UI.navto("Edit external writer",a)})).append($("<button>").text("Remove").click(function(){var b=$(this).closest("tr").attr("data-name"),b=a.external_writer_list[b][0];confirm("Are you sure you want to remove the Uploader '"+ -b+"'?")&&mist.send(function(){UI.showTab("General")},{external_writer_remove:b})}))))}}else C.html("None configured.")},{external_writer_list:!0});break;case "Edit external writer":var u=!1;""!=b&&(u=!0);var D=function(){u?c.html($("<h2>").text("Edit external writer '"+b+"'")):c.html($("<h2>").text("New external writer"));var a={};if(mist.data.external_writer_list&&b in mist.data.external_writer_list){var d=mist.data.external_writer_list[b];a.name=d[0];a.cmdline=d[1];a.protocols=d[2]}c.append(UI.buildUI([{type:"str", +b+"'?")&&mist.send(function(){UI.showTab("General")},{external_writer_remove:b})}))))}}else C.html("None configured.")},{external_writer_list:!0});break;case "Edit external writer":var u=!1;""!=b&&(u=!0);var E=function(){u?c.html($("<h2>").text("Edit external writer '"+b+"'")):c.html($("<h2>").text("New external writer"));var a={};if(mist.data.external_writer_list&&b in mist.data.external_writer_list){var d=mist.data.external_writer_list[b];a.name=d[0];a.cmdline=d[1];a.protocols=d[2]}c.append(UI.buildUI([{type:"str", label:"Human readable name",help:"A human readable name for the external writer.",validate:["required"],pointer:{main:a,index:"name"}},{type:"str",label:"Command line",help:"Command line for a local command (with optional arguments) which will write media data to the target.",validate:["required"],pointer:{main:a,index:"cmdline"}},{type:"inputlist",label:"URI protocols handled",help:"URI protocols which the external writer will be handling.",validate:["required",function(a){for(var b in a){var c= a[b];if(c.match(/^([a-z\d\+\-\.])+?$/)===null)return{classes:["red"],msg:"There was a problem with the protocol URI '"+$("<div>").text(c).html()+"':<br>A protocol URI may only contain lower case letters, digits, and the following special characters . + and -"}}}],input:{type:"str",unit:"://"},pointer:{main:a,index:"protocols"}},{type:"buttons",buttons:[{type:"cancel",label:"Cancel","function":function(){UI.navto("General")}},{type:"save",label:"Save","function":function(){var c={external_writer_add:a}, -d=null;b!=""&&b in mist.data.external_writer_list&&(d=mist.data.external_writer_list[b][0]);if(d!==null&&a.name!=d)c.external_writer_remove=d;mist.send(function(){UI.navto("General")},c)}}]}]))};"external_writer_list"in mist.data?D():mist.send(function(){D()},{external_writer_list:!0});break;case "Edit variable":u=!1;""!=b&&(u=!0);var v=function(a,d){u?c.html($("<h2>").text('Edit Variable "$'+b+'"')):c.html($("<h2>").text("New Variable"));var h=$("<div>");c.append(UI.buildUI([{type:"str",maxlength:31, +d=null;b!=""&&b in mist.data.external_writer_list&&(d=mist.data.external_writer_list[b][0]);if(d!==null&&a.name!=d)c.external_writer_remove=d;mist.send(function(){UI.navto("General")},c)}}]}]))};"external_writer_list"in mist.data?E():mist.send(function(){E()},{external_writer_list:!0});break;case "Edit variable":u=!1;""!=b&&(u=!0);var v=function(a,d){u?c.html($("<h2>").text('Edit Variable "$'+b+'"')):c.html($("<h2>").text("New Variable"));var h=$("<div>");c.append(UI.buildUI([{type:"str",maxlength:31, label:"Variable name",prefix:"$",help:"What should the variable be called? A dollar sign will automatically be prepended.",pointer:{main:a,index:"name"},validate:["required",function(a){if(a.length&&a[0]=="$")return{msg:"The dollar sign will automatically be prepended. You don't need to type it here.",classes:["red"]};if(a.indexOf("{")!==-1||a.indexOf("}")!==-1||a.indexOf("$")!==-1)return{msg:'The following symbols are not permitted: "$ { }".',classes:["red"]}}]},{type:"select",label:"Type",help:"What kind of variable is this? It can either be a static value that you can enter below, or a dynamic one that is returned by a command.", select:[["value","Static value"],["command","Dynamic through command"]],value:"value",pointer:{main:d,index:"type"},"function":function(){var a=[$("Invalid variable type")];switch($(this).val()){case "value":a=[{type:"str",label:"Value",pointer:{main:d,index:"value"},help:"The static value that this variable should be replaced with. There is a character limit of 63 characters.",validate:["required"]}];break;case "command":a=[{type:"str",label:"Command",help:"The command that should be executed to retrieve the value for this variable.<br>For example:<br><code>/usr/bin/date +%A</code><br>There is a character limit of 511 characters.", validate:["required"],pointer:{main:d,index:"target"}},{type:"int",min:0,max:4294967295,"default":0,label:"Checking interval",unit:"s",help:"At what interval, in seconds, MistServer should execute the command and update the value.<br>To execute the command once when MistServer starts up (and then never update), set the interval to 0.",pointer:{main:d,index:"interval"}},{type:"int",min:0,max:4294967295,"default":1,label:"Wait time",unit:"s",help:"Specifies the maximum time, in seconds, MistServer should wait for data when executing the variable target. If set to 0 this variable takes on the same value as the interval.<br>MistServer only updates one variable at a time, so setting this value too high can block other variables from updating.", pointer:{main:d,index:"waitTime"}}]}h.html(UI.buildUI(a))}},h,{type:"buttons",buttons:[{type:"cancel",label:"Cancel","function":function(){UI.navto("General")}},{type:"save",label:"Save","function":function(){var c={variable_add:a};switch(d.type){case "value":a.value=d.value;break;case "command":a.target=d.target;a.interval=d.interval;a.waitTime=d.waitTime}if(a.name!=b)c.variable_remove=b;mist.send(function(){UI.navto("General")},c)}}]}]))};c.html("Loading..");u?mist.send(function(a){if(b in a.variable_list){a= -a.variable_list[b];v({name:b},typeof a=="string"?{value:a,type:"value"}:{target:a[0],interval:a[1],waitTime:a[4],type:"command"})}else c.append('Variable "$'+b+'" does not exist.')},{variable_list:!0}):v({},{});break;case "Protocols":if("undefined"==typeof mist.data.capabilities){mist.send(function(){UI.navto(a)},{capabilities:!0});c.append("Loading..");return}var A=$("<tbody>");c.append(UI.buildUI([{type:"help",help:"You can find an overview of all the protocols and their relevant information here. You can add, edit or delete protocols."}])).append($("<button>").text("Delete all protocols").click(function(){if(confirm("Are you sure you want to delete all currently configured protocols?")){mist.data.config.protocols= +a.variable_list[b];v({name:b},typeof a=="string"?{value:a,type:"value"}:{target:a[0],interval:a[1],waitTime:a[4],type:"command"})}else c.append('Variable "$'+b+'" does not exist.')},{variable_list:!0}):v({},{});break;case "Protocols":if("undefined"==typeof mist.data.capabilities){mist.send(function(){UI.navto(a)},{capabilities:!0});c.append("Loading..");return}var z=$("<tbody>");c.append(UI.buildUI([{type:"help",help:"You can find an overview of all the protocols and their relevant information here. You can add, edit or delete protocols."}])).append($("<button>").text("Delete all protocols").click(function(){if(confirm("Are you sure you want to delete all currently configured protocols?")){mist.data.config.protocols= [];mist.send(function(){UI.navto("Protocols")},{config:mist.data.config})}})).append($("<button>").text("Enable default protocols").click(function(){var a=Object.keys(mist.data.capabilities.connectors),b;for(b in mist.data.config.protocols){var c=a.indexOf(mist.data.config.protocols[b].connector);c>-1&&a.splice(c,1)}var d=[];for(b in a)(!("required"in mist.data.capabilities.connectors[a[b]])||Object.keys(mist.data.capabilities.connectors[a[b]].required).length==0)&&d.push(a[b]);c="Click OK to enable disabled protocols with their default settings:\n "; c=d.length?c+d.join(", "):c+"None.";if(d.length!=a.length){a=a.filter(function(a){return d.indexOf(a)<0});c=c+("\n\nThe following protocols can only be set manually:\n "+a.join(", "))}if(confirm(c)&&d.length){if(mist.data.config.protocols===null)mist.data.config.protocols=[];for(b in d)mist.data.config.protocols.push({connector:d[b]});mist.send(function(){UI.navto("Protocols")},{config:mist.data.config})}})).append("<br>").append($("<button>").text("New protocol").click(function(){UI.navto("Edit Protocol")}).css("clear", -"both")).append($("<table>").html($("<thead>").html($("<tr>").html($("<th>").text("Protocol")).append($("<th>").text("Status")).append($("<th>").text("Settings")).append($("<th>")))).append(A));var L=function(){function a(b){var c=mist.data.capabilities.connectors[b.connector];if(!c)return"";var d=[],h=["required","optional"],e;for(e in h)for(var g in c[h[e]])b[g]&&b[g]!=""?d.push(g+": "+b[g]):c[h[e]][g]["default"]&&d.push(g+": "+c[h[e]][g]["default"]);return $("<span>").addClass("description").text(d.join(", "))} -A.html("");for(var b in mist.data.config.protocols){var c=mist.data.config.protocols[b],d=mist.data.capabilities.connectors[c.connector];A.append($("<tr>").data("index",b).append($("<td>").text(d&&d.friendly?d.friendly:c.connector)).append($("<td>").html(UI.format.status(c))).append($("<td>").html(a(c))).append($("<td>").css("text-align","right").html($("<button>").text("Edit").click(function(){UI.navto("Edit Protocol",$(this).closest("tr").data("index"))})).append($("<button>").text("Delete").click(function(){var a= +"both")).append($("<table>").html($("<thead>").html($("<tr>").html($("<th>").text("Protocol")).append($("<th>").text("Status")).append($("<th>").text("Settings")).append($("<th>")))).append(z));var L=function(){function a(b){var c=mist.data.capabilities.connectors[b.connector];if(!c)return"";var d=[],h=["required","optional"],e;for(e in h)for(var g in c[h[e]])b[g]&&b[g]!=""?d.push(g+": "+b[g]):c[h[e]][g]["default"]&&d.push(g+": "+c[h[e]][g]["default"]);return $("<span>").addClass("description").text(d.join(", "))} +z.html("");for(var b in mist.data.config.protocols){var c=mist.data.config.protocols[b],d=mist.data.capabilities.connectors[c.connector];z.append($("<tr>").data("index",b).append($("<td>").text(d&&d.friendly?d.friendly:c.connector)).append($("<td>").html(UI.format.status(c))).append($("<td>").html(a(c))).append($("<td>").css("text-align","right").html($("<button>").text("Edit").click(function(){UI.navto("Edit Protocol",$(this).closest("tr").data("index"))})).append($("<button>").text("Delete").click(function(){var a= $(this).closest("tr").data("index");if(confirm('Are you sure you want to delete the protocol "'+mist.data.config.protocols[a].connector+'"?')){mist.send(function(){UI.navto("Protocols")},{deleteprotocol:mist.data.config.protocols[a]});mist.data.config.protocols.splice(a,1)}}))))}};L();UI.interval.set(function(){mist.send(function(){L()})},1E4);break;case "Edit Protocol":if("undefined"==typeof mist.data.capabilities){mist.send(function(){UI.navto(a,b)},{capabilities:!0});c.append("Loading..");return}u= !1;""!=b&&0<=b&&(u=!0);var M={};for(p in mist.data.config.protocols)M[mist.data.config.protocols[p].connector]=1;var ea=function(a){var b=mist.data.capabilities.connectors[a],c=mist.convertBuildOptions(b,r);if(u)var d=$.extend({},r);c.push({type:"hidden",pointer:{main:r,index:"connector"},value:a});c.push({type:"buttons",buttons:[{type:"save",label:"Save","function":function(){var a={};u?a.updateprotocol=[d,r]:a.addprotocol=r;mist.send(function(){UI.navto("Protocols")},a)}},{type:"cancel",label:"Cancel", "function":function(){UI.navto("Protocols")}}]});if("deps"in b&&b.deps!=""){s=$("<span>").text("Dependencies:");$ul=$("<ul>");s.append($ul);if(typeof b.deps=="string")b.deps=b.deps.split(", ");for(var h in b.deps){a=$("<li>").text(b.deps[h]+" ");$ul.append(a);typeof M[b.deps[h]]!="undefined"||typeof M[b.deps[h]+".exe"]!="undefined"?a.append($("<span>").addClass("green").text("(Configured)")):a.append($("<span>").addClass("red").text("(Not yet configured)"))}c.unshift({type:"text",text:s[0].innerHTML})}return UI.buildUI(c)}, @@ -169,27 +169,27 @@ d)){g=e;break}if(g===null){Q.html($("<h3>").text("Unrecognized input").addClass( switch(f.name){case "Buffer":case "Buffer.exe":g.push({label:"RTMP full url",type:"span",clipboard:true,readonly:true,classes:["RTMP"],help:"Use this RTMP url if your client doesn't ask for a stream key"});g.push({label:"RTMP url",type:"span",clipboard:true,readonly:true,classes:["RTMPurl"],help:"Use this RTMP url if your client also asks for a stream key"});g.push({label:"RTMP stream key",type:"span",clipboard:true,readonly:true,classes:["RTMPkey"],help:"Use this key if your client asks for a stream key"}); g.push({label:"SRT",type:"span",clipboard:true,readonly:true,classes:["TSSRT"]});g.push({label:"RTSP",type:"span",clipboard:true,readonly:true,classes:["RTSP"]});break;case "TS":case "TS.exe":d.charAt(0)=="/"||d.slice(0,7)=="ts-exec"?g=[]:g.push({label:"TS",type:"span",clipboard:true,readonly:true,classes:["TS"]});break;case "TSSRT":case "TSSRT.exe":g.push({label:"SRT",type:"span",clipboard:true,readonly:true,classes:["TSSRT"]})}K.html(UI.buildUI(g));UI.updateLiveStreamHint(c.find("[name=name]").val(), c.find("[name=source]").val(),K)}a(d)}}}},e,J,{label:"Stop sessions",type:"checkbox",help:"When saving these stream settings, kill this stream's current connections.",pointer:{main:r,index:"stop_sessions"}},K,$("<br>"),{type:"custom",custom:Q},j,{type:"buttons",buttons:[{type:"cancel",label:"Cancel","function":function(){UI.navto("Streams")}},{type:"save",label:"Save","function":function(){ja("Streams")}},{type:"save",label:"Save and Preview","function":function(){ja("Preview")},classes:["saveandpreview"]}]}])); -c.find("[name=name]").keyup(function(){UI.updateLiveStreamHint($(this).val(),c.find("[name=source]").val(),K)});UI.updateLiveStreamHint(c.find("[name=name]").val(),c.find("[name=source]").val(),K);c.find('[name="source"]').attr("list","source_datalist");break;case "Status":if(""==b){UI.navto("Streams");return}-1==b.indexOf("+")&&$("<button>").text("Settings").addClass("settings").click(function(){UI.navto("Edit",b)});var y=$("<div>").addClass("dashboard");c.html(UI.modules.stream.bigbuttons(b,a)).append($("<h2>").text('Status of "'+ -b+'"')).append(y);p=UI.modules.stream.findMist(function(){y.append(UI.modules.stream.status(b));y.append(UI.modules.stream.metadata(b));y.append($("<section>").addClass("logcont").append(UI.modules.stream.logs(b)).append(UI.modules.stream.accesslogs(b)));y.append(UI.modules.stream.processes(b));y.append(UI.modules.stream.triggers(b,"Status"));y.append(UI.modules.stream.pushes(b))});y.append(p);y.append(UI.modules.stream.actions("Status",b));break;case "Preview":if(""==b){UI.navto("Streams");return}var y= -$("<div>").addClass("dashboard"),ma=$("<div>");c.html(UI.modules.stream.bigbuttons(b,a)).append($("<h2>").text('Preview of "'+b+'"')).append(ma).append(y);p=UI.modules.stream.findMist(function(){if(typeof mistplayers=="undefined")throw"Player.js was not applied properly.";ma.replaceWith(UI.modules.stream.status(b,{tags:false,thumbnail:false}));window.mv={};$preview=UI.modules.stream.preview(b,window.mv);y.append($preview);y.append(UI.modules.stream.playercontrols(window.mv,$preview)).append(UI.modules.stream.logs(b)).append(UI.modules.stream.metadata(b))}); -y.append(p);break;case "Embed":if(""==b){UI.navto("Streams");return}c.html(UI.modules.stream.bigbuttons(b,a)).append($("<h2>").text('Embed "'+b+'"'));$("<span>");c.append(UI.modules.stream.findMist(function(a){c.append(UI.modules.stream.embedurls(b,a,this.getUrls()))},!1,!0));break;case "Push":var F=$("<div>").text("Loading..");c.append(F);mist.send(function(a){function b(a){setTimeout(function(){mist.send(function(c){var d=false;if("push_list"in c&&c.push_list&&c.push_list.length){var d=true,g;for(g in c.push_list)if(a.indexOf(c.push_list[g][0])> +c.find("[name=name]").keyup(function(){UI.updateLiveStreamHint($(this).val(),c.find("[name=source]").val(),K)});UI.updateLiveStreamHint(c.find("[name=name]").val(),c.find("[name=source]").val(),K);c.find('[name="source"]').attr("list","source_datalist");break;case "Status":if(""==b){UI.navto("Streams");return}-1==b.indexOf("+")&&$("<button>").text("Settings").addClass("settings").click(function(){UI.navto("Edit",b)});var x=$("<div>").addClass("dashboard");c.html(UI.modules.stream.bigbuttons(b,a)).append($("<h2>").text('Status of "'+ +b+'"')).append(x);p=UI.modules.stream.findMist(function(){x.append(UI.modules.stream.status(b));x.append(UI.modules.stream.metadata(b));x.append($("<section>").addClass("logcont").append(UI.modules.stream.logs(b)).append(UI.modules.stream.accesslogs(b)));x.append(UI.modules.stream.processes(b));x.append(UI.modules.stream.triggers(b,"Status"));x.append(UI.modules.stream.pushes(b))});x.append(p);x.append(UI.modules.stream.actions("Status",b));break;case "Preview":if(""==b){UI.navto("Streams");return}var x= +$("<div>").addClass("dashboard"),ma=$("<div>");c.html(UI.modules.stream.bigbuttons(b,a)).append($("<h2>").text('Preview of "'+b+'"')).append(ma).append(x);p=UI.modules.stream.findMist(function(){if(typeof mistplayers=="undefined")throw"Player.js was not applied properly.";ma.replaceWith(UI.modules.stream.status(b,{tags:false,thumbnail:false}));window.mv={};$preview=UI.modules.stream.preview(b,window.mv);x.append($preview);x.append(UI.modules.stream.playercontrols(window.mv,$preview)).append(UI.modules.stream.logs(b)).append(UI.modules.stream.metadata(b))}); +x.append(p);break;case "Embed":if(""==b){UI.navto("Streams");return}c.html(UI.modules.stream.bigbuttons(b,a)).append($("<h2>").text('Embed "'+b+'"'));$("<span>");c.append(UI.modules.stream.findMist(function(a){c.append(UI.modules.stream.embedurls(b,a,this.getUrls()))},!1,!0));break;case "Push":var G=$("<div>").text("Loading..");c.append(G);mist.send(function(a){function b(a){setTimeout(function(){mist.send(function(c){var d=false;if("push_list"in c&&c.push_list&&c.push_list.length){var d=true,g;for(g in c.push_list)if(a.indexOf(c.push_list[g][0])> -1){d=false;break}}else d=true;if(d)for(g in a)h.find("tr[data-pushid="+a[g]+"]").remove();else b()},{push_list:1})},1E3)}function c(g,e){var f=$("<span>"),m=$("<span>");if(e=="Automatic"&&g.length>=4){var q=function(a,b,c){a=""+("$"+a+" ");switch(Number(b)){case 0:a=a+"is true";break;case 1:a=a+"is false";break;case 2:a=a+("== "+c);break;case 3:a=a+("!= "+c);break;case 10:a=a+("> (numerical) "+c);break;case 11:a=a+(">= (numerical) "+c);break;case 12:a=a+("< (numerical) "+c);break;case 13:a=a+("<= (numerical) "+ c);break;case 20:a=a+("> (lexical) "+c);break;case 21:a=a+(">= (lexical) "+c);break;case 22:a=a+("< (lexical) "+c);break;case 23:a=a+("<= (lexical) "+c);break;default:a=a+"comparison operator unknown"}return a};f.append($("<span>").text(g[2]));g[3]&&f.append($("<span>").text(", schedule on "+(new Date(g[3]*1E3)).toLocaleString()));g.length>=5&&g[4]&&f.append($("<span>").text(", complete on "+(new Date(g[4]*1E3)).toLocaleString()));g.length>=8&&g[5]&&f.append($("<span>").text(", starts if "+q(g[5], g[6],g[7])));g.length>=11&&g[8]&&f.append($("<span>").text(", stops if "+q(g[8],g[9],g[10])))}else g.length>=4&&g[2]!=g[3]?f.append($("<span>").text(g[2])).append($("<span>").html("»").addClass("unit").css("margin","0 0.5em")).append($("<span>").text(g[3])):f.append($("<span>").text(g[2]));q=$("<td>").append($("<button>").text(e=="Automatic"?"Remove":"Stop").click(function(){if(confirm("Are you sure you want to "+$(this).text().toLowerCase()+" this push?\n"+g[1]+" to "+g[2])){var a=$(this).closest("tr"); a.html($("<td colspan=99>").html($("<span>").addClass("red").text(e=="Automatic"?"Removing..":"Stopping..")));if(e=="Automatic"){var c=g.slice(1);mist.send(function(){a.remove()},{push_auto_remove:[c]})}else mist.send(function(){b([g[0]])},{push_stop:[g[0]]})}}));if(e=="Automatic"){q.prepend($("<button>").text("Edit").click(function(){UI.navto("Start Push","auto_"+($(this).closest("tr").index()-1))}));q.append($("<button>").text("Stop pushes").click(function(){if(confirm('Are you sure you want to stop all pushes matching \n"'+ g[1]+" to "+g[2]+'"?'+(d.wait!=0?"\n\nRetrying is enabled. That means the push will just restart. You'll probably want to set that to 0.":""))){var c=$(this);c.text("Stopping pushes..");var e=[],f;for(f in a.push_list)if(g[1]==a.push_list[f][1]&&g[2]==a.push_list[f][2]){e.push(a.push_list[f][0]);h.find("tr[data-pushid="+a.push_list[f][0]+"]").html($("<td colspan=99>").html($("<span>").addClass("red").text("Stopping..")))}mist.send(function(){c.text("Stop pushes");b(e)},{push_stop:e})}}))}else{if(g.length>= 6){var j=g[5];m.append($("<div>").append("Active for: "+UI.format.duration(j.active_seconds))).append($("<div>").append("Data transferred: "+UI.format.bytes(j.bytes))).append($("<div>").append("Media time transferred: "+UI.format.duration(j.mediatime*0.001)));"pkt_retrans_count"in j&&m.append($("<div>").append("Packets retransmitted: "+UI.format.number(j.pkt_retrans_count||0)));"pkt_loss_count"in j&&m.append($("<div>").append("Packets lost: "+UI.format.number(j.pkt_loss_count||0)+" ("+UI.format.addUnit(UI.format.number(j.pkt_loss_perc|| -0),"%")+" over the last "+UI.format.addUnit(5,"s")+")"))}if(g.length>=5)for(var k in g[4]){j=g[4][k];m.append($("<div>").append(UI.format.time(j[0])+" ["+j[1]+"] "+j[2]))}}return $("<tr>").css("vertical-align","top").attr("data-pushid",g[0]).append($("<td>").text(g[1])).append($("<td>").append(f.children())).append($("<td>").addClass("logs").append(m.children())).append(q)}F.html(UI.buildUI([{type:"help",help:"You can push streams to files or other servers, allowing them to broadcast your stream as well."}])); -var d=a.push_settings;d||(d={});var h=$("<table>").append($("<tr>").append($("<th>").text("Stream")).append($("<th>").text("Target")).append($("<th>")).append($("<th>"))),g=h.clone();if("push_list"in a)for(var e in a.push_list)h.append(c(a.push_list[e],"Manual"));if("push_auto_list"in a)for(e in a.push_auto_list){var f=a.push_auto_list[e].slice();f.unshift(-1);g.append(c(f,"Automatic"))}F.append($("<h3>").text("Automatic push settings")).append(UI.buildUI([{label:"Delay before retry",unit:"s",type:"int", +0),"%")+" over the last "+UI.format.addUnit(5,"s")+")"))}if(g.length>=5)for(var k in g[4]){j=g[4][k];m.append($("<div>").append(UI.format.time(j[0])+" ["+j[1]+"] "+j[2]))}}return $("<tr>").css("vertical-align","top").attr("data-pushid",g[0]).append($("<td>").text(g[1])).append($("<td>").append(f.children())).append($("<td>").addClass("logs").append(m.children())).append(q)}G.html(UI.buildUI([{type:"help",help:"You can push streams to files or other servers, allowing them to broadcast your stream as well."}])); +var d=a.push_settings;d||(d={});var h=$("<table>").append($("<tr>").append($("<th>").text("Stream")).append($("<th>").text("Target")).append($("<th>")).append($("<th>"))),g=h.clone();if("push_list"in a)for(var e in a.push_list)h.append(c(a.push_list[e],"Manual"));if("push_auto_list"in a)for(e in a.push_auto_list){var f=a.push_auto_list[e].slice();f.unshift(-1);g.append(c(f,"Automatic"))}G.append($("<h3>").text("Automatic push settings")).append(UI.buildUI([{label:"Delay before retry",unit:"s",type:"int", min:0,help:"How long the delay should be before MistServer retries an automatic push.<br>If set to 0, it does not retry.","default":3,pointer:{main:d,index:"wait"}},{label:"Maximum retries",unit:"/s",type:"int",min:0,help:"The maximum amount of retries per second (for all automatic pushes).<br>If set to 0, there is no limit.","default":0,pointer:{main:d,index:"maxspeed"}},{type:"buttons",buttons:[{type:"save",label:"Save","function":function(){mist.send(function(){UI.navto("Push")},{push_settings:d})}}]}])).append($("<h3>").text("Automatic push settings")).append($("<button>").text("Add an automatic push").click(function(){UI.navto("Start Push", -"auto")}));g.find("tr").length==1?F.append($("<div>").text("No automatic pushes have been configured.").addClass("text").css("margin-top","0.5em")):F.append(g);F.append($("<h3>").text("Pushes")).append($("<button>").text("Start a push").click(function(){UI.navto("Start Push")}));if(h.find("tr").length==1)F.append($("<div>").text("No pushes are active.").addClass("text").css("margin-top","0.5em"));else{var g=[],f=[],m=$("<select>").css("margin-left","0.5em").append($("<option>").text("Any stream").val("")), -q=$("<select>").css("margin-left","0.5em").append($("<option>").text("Any target").val(""));for(e in a.push_list){g.indexOf(a.push_list[e][1])==-1&&g.push(a.push_list[e][1]);f.indexOf(a.push_list[e][2])==-1&&f.push(a.push_list[e][2])}g.sort();f.sort();for(e in g)m.append($("<option>").text(g[e]));for(e in f)q.append($("<option>").text(f[e]));F.append($("<button>").text("Stop all pushes").click(function(){var c=[],d;for(d in a.push_list)c.push(a.push_list[d][0]);if(c.length!=0&&confirm("Are you sure you want to stop all pushes?")){mist.send(function(){b(c)}, +"auto")}));g.find("tr").length==1?G.append($("<div>").text("No automatic pushes have been configured.").addClass("text").css("margin-top","0.5em")):G.append(g);G.append($("<h3>").text("Pushes")).append($("<button>").text("Start a push").click(function(){UI.navto("Start Push")}));if(h.find("tr").length==1)G.append($("<div>").text("No pushes are active.").addClass("text").css("margin-top","0.5em"));else{var g=[],f=[],m=$("<select>").css("margin-left","0.5em").append($("<option>").text("Any stream").val("")), +q=$("<select>").css("margin-left","0.5em").append($("<option>").text("Any target").val(""));for(e in a.push_list){g.indexOf(a.push_list[e][1])==-1&&g.push(a.push_list[e][1]);f.indexOf(a.push_list[e][2])==-1&&f.push(a.push_list[e][2])}g.sort();f.sort();for(e in g)m.append($("<option>").text(g[e]));for(e in f)q.append($("<option>").text(f[e]));G.append($("<button>").text("Stop all pushes").click(function(){var c=[],d;for(d in a.push_list)c.push(a.push_list[d][0]);if(c.length!=0&&confirm("Are you sure you want to stop all pushes?")){mist.send(function(){b(c)}, {push_stop:c});h.find("tr:not(:first-child)").html($("<td colspan=99>").append($("<span>").addClass("red").text("Stopping..")));$(this).remove()}})).append($("<label>").css("margin-left","1em").append($("<span>").text("Stop all pushes that match: ").css("font-size","0.9em")).append(m).append($("<span>").css("margin-left","0.5em").text("and").css("font-size","0.9em")).append(q).append($("<button>").css("margin-left","0.5em").text("Apply").click(function(){var c=m.val(),d=q.val();if(c==""&&d=="")return alert("Looks like you want to stop all pushes. Maybe you should use that button?"); var g={},e;for(e in a.push_list)if((c==""||a.push_list[e][1]==c)&&(d==""||a.push_list[e][2]==d))g[a.push_list[e][0]]=a.push_list[e];if(Object.keys(g).length==0)return alert("No matching pushes.");c="Are you sure you want to stop these pushes?\n\n";for(e in g)c=c+(g[e][1]+" to "+g[e][2]+"\n");if(confirm(c)){g=Object.keys(g);mist.send(function(){b(g)},{push_stop:g});for(e in g)h.find("tr[data-pushid="+g[e]+"]").html($("<td colspan=99>").html($("<span>").addClass("red").text("Stopping..")))}}))).append(h)}UI.interval.set(function(){mist.send(function(a){var b= h.find("tr").first();h.empty();h.append(b);for(var d in a.push_list)h.append(c(a.push_list[d]))},{push_list:1})},5E3)},{push_settings:1,push_list:1,push_auto_list:1});break;case "Start Push":if(!("capabilities"in mist.data)||!("variable_list"in mist.data)||!("external_writer_list"in mist.data)){c.append("Loading MistServer capabilities..");mist.send(function(){UI.showTab("Start Push",b,d)},{capabilities:!0,variable_list:!0,external_writer_list:!0});return}var w,R=function(g){var h=false,e=b.split("_"); b=e[0];e.length==2&&(h=e[1]);if(h!==false&&typeof g=="undefined")mist.send(function(a){R(a.push_auto_list[h])},{push_auto_list:1});else{var f=[],m=[],q={},j=[],k;for(k in mist.data.capabilities.connectors){e=mist.data.capabilities.connectors[k];if("push_urls"in e){q[k]=e.push_urls;for(var l in e.push_urls)e.push_urls[l][0]=="/"?f.push(e.push_urls[l]):m.push(e.push_urls[l])}}if(mist.data.external_writer_list)for(k in mist.data.external_writer_list){e=mist.data.external_writer_list[k];if(e.length>= 3)for(l in e[2])j.push(e[2][l]+"://")}f.sort();m.sort();b=="auto"&&c.find("h2").text("Add automatic push");var i={params:{}},n=[];if(b=="auto"&&typeof g!="undefined"){i={stream:g[0],target:g[1],params:{}};l=i.target.split("?");if(l.length>1){n=l.pop();i.target=l.join("?");n=n.split("&");for(k in n){l=n[k].split("=");i.params[l.shift()]=l.join("=")}}if(g.length>=3)i.scheduletime=g[2]!=0?g[2]:null;if(g.length>=4)i.completetime=g[3]!=0?g[3]:null;if(g.length>=5)i.startVariableName=g[4]!=""?g[4]:null; -if(g.length>=6)i.startVariableOperator=g[5]!=""?g[5]:null;if(g.length>=7)i.startVariableValue=g[6]!=""?g[6]:null;if(g.length>=8)i.endVariableName=g[7]!=""?g[7]:null;if(g.length>=9)i.endVariableOperator=g[8]!=""?g[8]:null;if(g.length>=10)i.endVariableValue=g[9]!=""?g[9]:null}var o=$("<div>").css("margin","1em 0"),p=$("<div>"),r,x;if(b=="auto"){p.css("margin","1em 0").html(UI.buildUI([{label:"This push should be active",help:"When 'based on server time' is selected, a start and/or end timestamp can be configured. When it's 'based on a variable', the push will be activated while the specified variable matches the specified value.", +if(g.length>=6)i.startVariableOperator=g[5]!=""?g[5]:null;if(g.length>=7)i.startVariableValue=g[6]!=""?g[6]:null;if(g.length>=8)i.endVariableName=g[7]!=""?g[7]:null;if(g.length>=9)i.endVariableOperator=g[8]!=""?g[8]:null;if(g.length>=10)i.endVariableValue=g[9]!=""?g[9]:null}var o=$("<div>").css("margin","1em 0"),p=$("<div>"),r,A;if(b=="auto"){p.css("margin","1em 0").html(UI.buildUI([$("<h3>").text("Automatic push options"),{label:"This push should be active",help:"When 'based on server time' is selected, a start and/or end timestamp can be configured. When it's 'based on a variable', the push will be activated while the specified variable matches the specified value.", type:"select",select:[["time","Based on server time"],["variable","Based on a variable"]],value:i.startVariableName||i.endVariableName?"variable":"time",classes:["activewhen"],"function":function(){var a=p.find(".varbased").closest(".UIelement"),b=p.find(".timebased").closest(".UIelement");if($(this).getval()=="time"){a.hide();b.css("display","")}else{b.hide();a.css("display","");p.find('[name="startVariableOperator"]').trigger("change");p.find('[name="endVariableOperator"]').trigger("change")}}}, $("<br>"),$("<span>").addClass("UIelement").append($("<h3>").text("Start the push").addClass("varbased")),{classes:["varbased"],label:"Use this variable",type:"str",help:"This variable should be used to determine if this push should be started.",prefix:"$",datalist:Object.keys(mist.data.variable_list||[]),pointer:{main:i,index:"startVariableName"}},{classes:["varbased"],label:"Comparison operator",type:"select",select:[[0,"is true"],[1,"is false"],[2,"=="],[3,"!="],[10,"> (numerical)"],[11,">= (numerical)"], [12,"< (numerical)"],[13,"<= (numerical)"],[20,"> (lexical)"],[21,">= (lexical)"],[22,"< (lexical)"],[23,"<= (lexical)"]],value:2,css:{display:"none"},help:"How would you like to compare this variable?",pointer:{main:i,index:"startVariableOperator"},"function":function(){var a=p.find('[name="startVariableValue"]').closest(".UIelement");Number($(this).getval())<2?a.hide():a.css("display","")}},{classes:["varbased"],label:"Variable value",type:"str",help:"The variable will be compared with this value to determine if this push should be started.<br>You can also enter another variable here!", @@ -201,39 +201,38 @@ help:"This may either be a full stream name, a partial wildcard stream name, or validate:["required",function(a){a=a.split("+");a=a[0];return a in mist.data.streams?false:{msg:"'"+a+"' is not a stream name.",classes:["orange"],"break":false}}],datalist:w,value:d[1]!=""?d[1]:""},{label:"Target",type:"str",help:"Where the stream will be pushed to.<br> Valid push formats: <ul> <li>"+m.join("</li><li>")+"</li> </ul> Valid file formats: <ul> <li>"+f.join("</li><li>")+"</li> </ul> "+ (j.length?"Additionally, the following protocols (from generic writers) may be used in combination with any of the above file formats:<ul><li>"+j.join("</li><li>")+"</li></ul>":"")+" Valid text replacements: <ul> <li>$stream - inserts the stream name used to push to MistServer</li> <li>$day - inserts the current day number</li><li>$month - inserts the current month number</li> <li>$year - inserts the current year number</li><li>$hour - inserts the hour timestamp when stream was received</li> <li>$minute - inserts the minute timestamp the stream was received</li> <li>$seconds - inserts the seconds timestamp when the stream was received</li> <li>$datetime - inserts $year.$month.$day.$hour.$minute.$seconds timestamp when the stream was received</li> </ul>", pointer:{main:i,index:"target"},validate:["required",function(a){for(var b in m)if(mist.inputMatch(m[b],a))return false;for(b in f){if(mist.inputMatch(f[b],a))return false;for(var c in j)if(mist.inputMatch(j[c]+f[b].slice(1),a))return false}return{msg:"Does not match a valid target.<br>Valid push formats: <ul> <li>"+m.join("</li><li>")+"</li> </ul> Valid file formats: <ul> <li>"+f.join("</li><li>")+ -"</li> </ul> "+(j.length?"Additionally, the following protocols may be used in combination with any of the above file formats:<ul><li>"+j.join("</li><li>")+"</li></ul>":""),classes:["red"]}}],"function":function(){function a(b,d){if(b.prot_only&&String().match&&c.match(/.+\:\/\/.+/)===null)delete r[d];else if(b.file_only&&c[0]!="/")delete r[d];else if(b.type=="group")for(var g in b.options)a(b.options[g],g);else x[d]=b}var b=false,c=$(this).getval();for(connector in q)for(var d in q[connector]){if(mist.inputMatch(q[connector][d], -c)){b=connector;break}if(q[connector][d][0]=="/")for(var g in j)if(mist.inputMatch(j[g]+q[connector][d].slice(1),c)){b=connector;break}}if(b){if(!("friendly"in mist.data.capabilities.connectors[b]))mist.data.capabilities.connectors[b].friendly=mist.data.capabilities.connectors[b].name;o.html($("<h3>").text(mist.data.capabilities.connectors[b].friendly.replace("over HTTP","")));r=$.extend({},mist.data.capabilities.connectors[b].push_parameters);x={};for(d in mist.data.capabilities.connectors[b].push_parameters)a(mist.data.capabilities.connectors[b].push_parameters[d], -d);b={desc:mist.data.capabilities.connectors[b].desc.replace("over HTTP",""),optional:r,sort:"sort"};b=mist.convertBuildOptions(b,i.params);g=[];for(d in n){var h=n[d].split("="),e=h[0];e in r||g.push(e+(h.length>1?"="+h.slice(1).join("="):""))}b.push($("<br>"));b.push({type:"inputlist",label:"Custom url parameters",value:g,classes:["custom_url_parameters"],input:{type:"str",placeholder:"name=value",prefix:""},help:"Any custom url parameters not covered by the parameters configurable above.",pointer:{main:i, -index:"custom_url_params"}});o.append(UI.buildUI(b))}else o.html($("<h4>").addClass("red").text("Unrecognized target.")).append($("<span>").text("Please edit the push target."))}},p,o];k.push({type:"buttons",buttons:[{type:"cancel",label:"Cancel","function":function(){d[0]&&d[0]!=a?UI.navto(d[0],d[1]):UI.navto("Push")}},{type:"save",label:"Save",preSave:function(){delete i.startVariableName;delete i.startVariableOperator;delete i.startVariableValue;delete i.endVariableName;delete i.endVariableOperator; -delete i.endVariableValue;delete i.completetime;delete i.scheduletime},"function":function(){var c=i.params,h;for(h in c)c[h]===null?delete c[h]:h in x||delete c[h];if(i.startVariableName||i.endVariableName){i.scheduletime=0;i.completetime=0}if(i.startVariableName===null){delete i.startVariableName;delete i.startVariableOperator;delete i.startVariableValue}if(i.endVariableName===null){delete i.endVariableName;delete i.endVariableOperator;delete i.endVariableValue}if(i.scheduletime)c.recstartunix= -i.scheduletime;if(Object.keys(c).length||i.custom_url_params&&i.custom_url_params.length){var e="?",f=i.target.split("?");if(f.length>1){e="&";f=f[f.length-1];f=f.split("&");for(h in f){var m=f[h].split("=")[0];m in c&&delete c[m]}}if(Object.keys(c).length||i.custom_url_params&&i.custom_url_params.length){f=[];for(h in c)f.push(h+"="+c[h]);for(h in i.custom_url_params)f.push(i.custom_url_params[h]);e=e+f.join("&");i.target=i.target+e}}delete i.params;delete i.custom_url_params;c={};c[b=="auto"?"push_auto_add": -"push_start"]=i;if(typeof g!="undefined"&&(g[0]!=i.stream||g[1]!=i.target))c.push_auto_remove=[g];mist.send(function(){d[0]&&d[0]!=a?UI.navto(d[0],d[1]):UI.navto("Push")},c)}}]});c.append(UI.buildUI(k))}};mist.data.LTS?mist.send(function(a){(w=a.active_streams)||(w=[]);var a=[],b;for(b in w)w[b].indexOf("+")!=-1&&a.push(w[b].replace(/\+.*/,"")+"+");w=w.concat(a);var c=0,d=0;for(b in mist.data.streams){w.push(b);if(mist.inputMatch(UI.findInput("Folder").source_match,mist.data.streams[b].source)){w.push(b+ -"+");mist.send(function(a,b){var g=b.stream,h;for(h in a.browse.files)for(var e in mist.data.capabilities.inputs)e.indexOf("Buffer")>=0||(e.indexOf("Folder")>=0||e.indexOf("Buffer.exe")>=0||e.indexOf("Folder.exe")>=0)||mist.inputMatch(mist.data.capabilities.inputs[e].source_match,"/"+a.browse.files[h])&&w.push(g+"+"+a.browse.files[h]);d++;if(c==d){w=w.filter(function(a,b,c){return c.lastIndexOf(a)===b}).sort();R()}},{browse:mist.data.streams[b].source},{stream:b});c++}}if(c==d){w=w.filter(function(a, -b,c){return c.lastIndexOf(a)===b}).sort();R()}},{active_streams:1}):(w=Object.keys(mist.data.streams),R());break;case "Triggers":if(!("triggers"in mist.data.config)||!mist.data.config.triggers)mist.data.config.triggers={};A=$("<tbody>");h=$("<table>").html($("<thead>").html($("<tr>").html($("<th>").text("Trigger on").attr("data-sort-type","string").addClass("sorting-asc")).append($("<th>").text("Applies to").attr("data-sort-type","string")).append($("<th>").text("Handler").attr("data-sort-type","string")).append($("<th>")))).append(A); -c.append(UI.buildUI([{type:"help",help:"Triggers are a way to react to events that occur inside MistServer. These allow you to block specific users, redirect streams, keep tabs on what is being pushed where, etcetera. For full documentation, please refer to the developer documentation section on the MistServer website."}])).append($("<button>").text("New trigger").click(function(){UI.navto("Edit Trigger")})).append(h);h.stupidtable();h=mist.data.config.triggers;for(p in h)for(j in h[p])e=triggerRewrite(h[p][j]), -A.append($("<tr>").attr("data-index",p+","+j).append($("<td>").text(p)).append($("<td>").text("streams"in e?e.streams.join(", "):"")).append($("<td>").text(e.handler)).append($("<td>").html($("<button>").text("Edit").click(function(){UI.navto("Edit Trigger",$(this).closest("tr").attr("data-index"))})).append($("<button>").text("Delete").click(function(){var a=$(this).closest("tr").attr("data-index").split(",");if(confirm("Are you sure you want to delete this "+a[0]+" trigger?")){mist.data.config.triggers[a[0]].splice(a[1], -1);mist.data.config.triggers[a[0]].length==0&&delete mist.data.config.triggers[a[0]];mist.send(function(){UI.navto("Triggers")},{config:mist.data.config})}}))));break;case "Edit Trigger":if(!("triggers"in mist.data.config)||!mist.data.config.triggers)mist.data.config.triggers={};if("undefined"==typeof mist.data.capabilities){mist.send(function(){UI.showTab(a,b,d)},{capabilities:!0});c.append("Loading..");return}b?(b=b.split(","),j=triggerRewrite(mist.data.config.triggers[b[0]][b[1]]),r={triggeron:b[0], -appliesto:j.streams,url:j.handler,async:j.sync,"default":j["default"],params:j.params}):(c.html($("<h2>").text("New Trigger")),r={});j=[];for(p in mist.data.capabilities.triggers)j.push([p,p+": "+mist.data.capabilities.triggers[p].when]);var Y=$("<div>").addClass("desc"),na=$("<div>");c.append(UI.buildUI([{label:"Trigger on",pointer:{main:r,index:"triggeron"},help:"For what event this trigger should activate.",type:"select",select:j,validate:["required"],"function":function(){var a=$(this).getval(), -b=mist.data.capabilities.triggers[a];Y.html("");if(b){a=[$("<h4>").text("Trigger properties"),{type:"help",help:'The trigger "<i>'+a+'</i>" has the following properties:'},{type:"span",label:"Triggers",value:b.when,help:"When this trigger is activated"}];b.payload!=""&&a.push({label:"Payload",type:"textarea",value:b.payload,rows:b.payload.split("\n").length,readonly:true,clipboard:true,help:"The information this trigger sends to the handler."});a.push({type:"span",label:"Requires response",value:function(a){switch(a){case "ignored":return"No. The trigger will ignore the response of the handler."; -case "always":return"Yes. The trigger needs a response to proceed.";case "when-blocking":return"The trigger needs a response to proceed if it is configured to be blocking.";default:return a}}(b.response),help:"Whether this trigger requires a response from the trigger handler"});a.push({type:"span",label:"Response action",value:b.response_action,help:"What this trigger will do with its handler's response"});Y.append(UI.buildUI(a));b.stream_specific?$("[name=appliesto]").closest(".UIelement").show(): -$("[name=appliesto]").setval([]).closest(".UIelement").hide();if(b.argument){$("[name=params]").closest(".UIelement").show();na.text(b.argument)}else $("[name=params]").setval("").closest(".UIelement").hide()}}},Y,$("<h4>").text("Trigger settings"),{label:"Applies to",pointer:{main:r,index:"appliesto"},help:"For triggers that can apply to specific streams, this value decides what streams they are triggered for. (none checked = always triggered)",type:"checklist",checklist:Object.keys(mist.data.streams), -value:""!=d[1]?[d[1]]:[]},$("<br>"),{label:"Handler (URL or executable)",help:"This can be either an HTTP URL or a full path to an executable.",pointer:{main:r,index:"url"},validate:["required"],type:"str"},{label:"Blocking",type:"checkbox",help:"If checked, pauses processing and uses the response of the handler. If the response does not start with 1, true, yes or cont, further processing is aborted. If unchecked, processing is never paused and the response is not checked.",pointer:{main:r,index:"async"}}, -{label:"Parameters",type:"str",help:$("<div>").text("The extra data you want this trigger to use.").append(na),pointer:{main:r,index:"params"}},{label:"Default response",type:"str",help:"The default response in case the handler fails or is set to non-blocking.",placeholder:"true",pointer:{main:r,index:"default"}},{type:"buttons",buttons:[{type:"cancel",label:"Cancel","function":function(){d[0]&&d[0]!=a?UI.navto(d[0],d[1]):UI.navto("Triggers")}},{type:"save",label:"Save","function":function(){b&&mist.data.config.triggers[b[0]].splice(b[1], -1);var c={handler:r.url,sync:r.async?true:false,streams:typeof r.appliesto=="undefined"?[]:r.appliesto,params:r.params,"default":r["default"]};if(!("triggers"in mist.data.config))mist.data.config.triggers={};r.triggeron in mist.data.config.triggers||(mist.data.config.triggers[r.triggeron]=[]);mist.data.config.triggers[r.triggeron].push(c);mist.send(function(){d[0]&&d[0]!=a?UI.navto(d[0],d[1]):UI.navto("Triggers")},{config:mist.data.config})}}]}]));$("[name=triggeron]").trigger("change");break;case "Logs":var oa= -$("<button>").text("Refresh now").click(function(){$(this).text("Loading..");mist.send(function(){Z();oa.text("Refresh now")})}).css("padding","0.2em 0.5em").css("flex-grow",0);c.append(UI.buildUI([{type:"help",help:"Here you have an overview of all edited settings within MistServer and possible warnings or errors MistServer has encountered. MistServer stores up to 100 logs at a time."},{label:"Refresh every",type:"select",select:[[10,"10 seconds"],[30,"30 seconds"],[60,"minute"],[300,"5 minutes"]], -value:30,"function":function(){UI.interval.clear();UI.interval.set(function(){mist.send(function(){Z()})},$(this).val()*1E3)},help:"How often the table below should be updated."},{label:"..or",type:"DOMfield",DOMfield:oa,help:"Instantly refresh the table below."}]));c.append($("<button>").text("Purge logs").click(function(){mist.send(function(){mist.data.log=[];UI.navto("Logs")},{clearstatlogs:true})}));A=$("<tbody>").css("font-size","0.9em");c.append($("<table>").addClass("logs").append(A));var qa= -function(a){var b=$("<span>").text(a);switch(a){case "WARN":b.addClass("orange");break;case "ERROR":case "FAIL":b.addClass("red")}return b},Z=function(){var a=mist.data.log;if(a){a.length>=2&&a[0][0]<a[a.length-1][0]&&a.reverse();A.html("");for(var b in a){var c=$("<span>").addClass("content"),d=a[b][2].split("|"),g;for(g in d)c.append($("<span>").text(d[g]));A.append($("<tr>").html($("<td>").text(UI.format.dateTime(a[b][0],"long")).css("white-space","nowrap")).append($("<td>").html(qa(a[b][1])).css("text-align", -"center")).append($("<td>").html(c).css("text-align","left")))}}};Z();break;case "Statistics":var E=$("<span>").text("Loading..");c.append(E);var r={graph:"new"},z=mist.stored.get().graphs?$.extend(!0,{},mist.stored.get().graphs):{},O={};for(p in mist.data.streams)O[p]=!0;for(p in mist.data.active_streams)O[mist.data.active_streams[p]]=!0;var O=Object.keys(O).sort(),aa=[];for(p in mist.data.config.protocols)aa.push(mist.data.config.protocols[p].connector);aa.sort();mist.send(function(){UI.plot.datatype.templates.cpuload.cores= -0;for(var a in mist.data.capabilities.cpu)UI.plot.datatype.templates.cpuload.cores=UI.plot.datatype.templates.cpuload.cores+mist.data.capabilities.cpu[a].cores;E.html(UI.buildUI([{type:"help",help:"Here you will find the MistServer stream statistics, you can select various categories yourself. All statistics are live: up to five minutes are saved."},$("<h3>").text("Select the data to display"),{label:"Add to",type:"select",select:[["new","New graph"]],pointer:{main:r,index:"graph"},classes:["graph_ids"], -"function":function(){if($(this).val()){var a=E.find(".graph_xaxis"),b=E.find(".graph_id");if($(this).val()=="new"){a.children("option").prop("disabled",false);b.setval("Graph "+(Object.keys(z).length+1)).closest("label").show()}else{var c=z[$(this).val()].xaxis;a.children("option").prop("disabled",true).filter('[value="'+c+'"]').prop("disabled",false);b.closest("label").hide()}a.children('option[value="'+a.val()+'"]:disabled').length&&a.val(a.children("option:enabled").first().val());a.trigger("change")}}}, -{label:"Graph id",type:"str",pointer:{main:r,index:"id"},classes:["graph_id"],validate:[function(a){return a in z?{msg:"This graph id has already been used. Please enter something else.",classes:["red"]}:false}]},{label:"Axis type",type:"select",select:[["time","Time line"]],pointer:{main:r,index:"xaxis"},value:"time",classes:["graph_xaxis"],"function":function(){$s=E.find(".graph_datatype");switch($(this).getval()){case "coords":$s.children("option").prop("disabled",true).filter('[value="coords"]').prop("disabled", -false);break;case "time":$s.children("option").prop("disabled",false).filter('[value="coords"]').prop("disabled",true)}if(!$s.val()||$s.children('option[value="'+$s.val()+'"]:disabled').length){$s.val($s.children("option:enabled").first().val());$s.trigger("change")}}},{label:"Data type",type:"select",select:[["clients","Connections"],["upbps","Bandwidth (up)"],["downbps","Bandwidth (down)"],["cpuload","CPU use"],["memload","Memory load"],["coords","Client location"],["perc_lost","Lost packages"], -["perc_retrans","Re-transmitted packages"]],pointer:{main:r,index:"datatype"},classes:["graph_datatype"],"function":function(){$s=E.find(".graph_origin");switch($(this).getval()){case "cpuload":case "memload":$s.find("input[type=radio]").not('[value="total"]').prop("disabled",true);$s.find('input[type=radio][value="total"]').prop("checked",true);break;default:$s.find("input[type=radio]").prop("disabled",false)}}},{label:"Data origin",type:"radioselect",radioselect:[["total","All"],["stream","The stream:", -O],["protocol","The protocol:",aa]],pointer:{main:r,index:"origin"},value:["total"],classes:["graph_origin"]},{type:"buttons",buttons:[{label:"Add data set",type:"save","function":function(){var a;if(r.graph=="new"){a=UI.plot.addGraph(r,b);z[a.id]=a;E.find("input.graph_id").val("");E.find("select.graph_ids").append($("<option>").text(a.id)).val(a.id).trigger("change")}else a=z[r.graph];var c=UI.plot.datatype.getOptions({datatype:r.datatype,origin:r.origin});a.datasets.push(c);UI.plot.save(a);UI.plot.go(z)}}]}])); -var b=$("<div>").addClass("graph_container");c.append(b);var d=E.find("select.graph_ids");for(a in z){var g=UI.plot.addGraph(z[a],b);d.append($("<option>").text(g.id)).val(g.id);var h=[],e;for(e in z[a].datasets){var f=UI.plot.datatype.getOptions({datatype:z[a].datasets[e].datatype,origin:z[a].datasets[e].origin});h.push(f)}g.datasets=h;z[g.id]=g}d.trigger("change");UI.plot.go(z);UI.interval.set(function(){UI.plot.go(z)},1E4)},{active_streams:!0,capabilities:!0});break;case "Server Stats":if("undefined"== -typeof mist.data.capabilities){mist.send(function(){UI.showTab(a)},{capabilities:!0});c.append("Loading..");return}var ba=$("<table>"),I=$("<table>"),j={vheader:"CPUs",labels:["Model","Processor speed","Amount of cores","Amount of threads"],content:[]};for(p in mist.data.capabilities.cpu)h=mist.data.capabilities.cpu[p],j.content.push({header:"CPU #"+(Number(p)+1),body:[h.model,UI.format.addUnit(UI.format.number(h.mhz),"MHz"),h.cores,h.threads]});p=UI.buildVheaderTable(j);var pa=function(){var a=mist.data.capabilities.mem, -b=mist.data.capabilities.load,a={vheader:"Memory",labels:["Used","Cached","Available","Total"],content:[{header:"Physical memory",body:[UI.format.bytes(a.used*1048576)+" ("+UI.format.addUnit(b.memory,"%")+")",UI.format.bytes(a.cached*1048576),UI.format.bytes(a.free*1048576),UI.format.bytes(a.total*1048576)]},{header:"Swap memory",body:[UI.format.bytes((a.swaptotal-a.swapfree)*1048576),UI.format.addUnit("","N/A"),UI.format.bytes(a.swapfree*1048576),UI.format.bytes(a.swaptotal*1048576)]}]},a=UI.buildVheaderTable(a); -ba.replaceWith(a);ba=a;b={vheader:"Load average",labels:["CPU use","1 minute","5 minutes","15 minutes"],content:[{header:" ",body:[UI.format.addUnit(UI.format.number(mist.data.capabilities.cpu_use/10),"%"),UI.format.number(b.one/100),UI.format.number(b.five/100),UI.format.number(b.fifteen/100)]}]};b=UI.buildVheaderTable(b);I.replaceWith(b);I=b};pa();c.append(UI.buildUI([{type:"help",help:"You can find general server statistics here. Note that memory and CPU usage is for your entire machine, not just MistServer."}])).append($("<table>").css("width", +"</li> </ul> "+(j.length?"Additionally, the following protocols may be used in combination with any of the above file formats:<ul><li>"+j.join("</li><li>")+"</li></ul>":""),classes:["red"]}}],"function":function(){function a(b,d){if(b.prot_only&&String().match&&c.match(/.+\:\/\/.+/)===null)delete r[d];else if(b.file_only&&c[0]!="/")delete r[d];else if(b.type=="group")for(var g in b.options)a(b.options[g],g);else A[d]=b}var b=false,c=$(this).getval();for(connector in q)for(var d in q[connector]){if(mist.inputMatch(q[connector][d], +c)){b=connector;break}if(q[connector][d][0]=="/")for(var g in j)if(mist.inputMatch(j[g]+q[connector][d].slice(1),c)){b=connector;break}}if($(this).data("last_match")!=b){$(this).data("last_match",b);if(b){if(!("friendly"in mist.data.capabilities.connectors[b]))mist.data.capabilities.connectors[b].friendly=mist.data.capabilities.connectors[b].name;o.html($("<h3>").text(mist.data.capabilities.connectors[b].friendly.replace("over HTTP","")));r=$.extend({},mist.data.capabilities.connectors[b].push_parameters); +A={};for(d in mist.data.capabilities.connectors[b].push_parameters)a(mist.data.capabilities.connectors[b].push_parameters[d],d);b={desc:mist.data.capabilities.connectors[b].desc.replace("over HTTP",""),optional:r,sort:"sort"};b=mist.convertBuildOptions(b,i.params);b[1].is("h4")&&b.splice(1,1);g=[];for(d in n){var h=n[d].split("="),e=h[0];e in A||g.push(e+(h.length>1?"="+h.slice(1).join("="):""))}b.push($("<br>"));b.push({type:"inputlist",label:"Custom url parameters",value:g,classes:["custom_url_parameters"], +input:{type:"str",placeholder:"name=value",prefix:""},help:"Any custom url parameters not covered by the parameters configurable above.",pointer:{main:i,index:"custom_url_params"}});o.append(UI.buildUI(b))}else o.html($("<h4>").addClass("red").text("Unrecognized target.")).append($("<span>").text("Please edit the push target."))}}},o,p];k.push({type:"buttons",buttons:[{type:"cancel",label:"Cancel","function":function(){d[0]&&d[0]!=a?UI.navto(d[0],d[1]):UI.navto("Push")}},{type:"save",label:"Save", +preSave:function(){delete i.startVariableName;delete i.startVariableOperator;delete i.startVariableValue;delete i.endVariableName;delete i.endVariableOperator;delete i.endVariableValue;delete i.completetime;delete i.scheduletime},"function":function(){var c=i.params,h;for(h in c)c[h]===null?delete c[h]:h in A||delete c[h];if(i.startVariableName||i.endVariableName){i.scheduletime=0;i.completetime=0}if(i.startVariableName===null){delete i.startVariableName;delete i.startVariableOperator;delete i.startVariableValue}if(i.endVariableName=== +null){delete i.endVariableName;delete i.endVariableOperator;delete i.endVariableValue}if(i.scheduletime)c.recstartunix=i.scheduletime;if(Object.keys(c).length||i.custom_url_params&&i.custom_url_params.length){var e=[];for(h in c)e.push(h+"="+c[h]);for(h in i.custom_url_params)e.push(i.custom_url_params[h]);i.target=i.target+("?"+e.join("&"))}delete i.params;delete i.custom_url_params;c={};c[b=="auto"?"push_auto_add":"push_start"]=i;if(typeof g!="undefined"&&(g[0]!=i.stream||g[1]!=i.target))c.push_auto_remove= +[g];mist.send(function(){d[0]&&d[0]!=a?UI.navto(d[0],d[1]):UI.navto("Push")},c)}}]});c.append(UI.buildUI(k))}};mist.data.LTS?mist.send(function(a){(w=a.active_streams)||(w=[]);var a=[],b;for(b in w)w[b].indexOf("+")!=-1&&a.push(w[b].replace(/\+.*/,"")+"+");w=w.concat(a);var c=0,d=0;for(b in mist.data.streams){w.push(b);if(mist.inputMatch(UI.findInput("Folder").source_match,mist.data.streams[b].source)){w.push(b+"+");mist.send(function(a,b){var g=b.stream,h;for(h in a.browse.files)for(var e in mist.data.capabilities.inputs)e.indexOf("Buffer")>= +0||(e.indexOf("Folder")>=0||e.indexOf("Buffer.exe")>=0||e.indexOf("Folder.exe")>=0)||mist.inputMatch(mist.data.capabilities.inputs[e].source_match,"/"+a.browse.files[h])&&w.push(g+"+"+a.browse.files[h]);d++;if(c==d){w=w.filter(function(a,b,c){return c.lastIndexOf(a)===b}).sort();R()}},{browse:mist.data.streams[b].source},{stream:b});c++}}if(c==d){w=w.filter(function(a,b,c){return c.lastIndexOf(a)===b}).sort();R()}},{active_streams:1}):(w=Object.keys(mist.data.streams),R());break;case "Triggers":if(!("triggers"in +mist.data.config)||!mist.data.config.triggers)mist.data.config.triggers={};z=$("<tbody>");h=$("<table>").html($("<thead>").html($("<tr>").html($("<th>").text("Trigger on").attr("data-sort-type","string").addClass("sorting-asc")).append($("<th>").text("Applies to").attr("data-sort-type","string")).append($("<th>").text("Handler").attr("data-sort-type","string")).append($("<th>")))).append(z);c.append(UI.buildUI([{type:"help",help:"Triggers are a way to react to events that occur inside MistServer. These allow you to block specific users, redirect streams, keep tabs on what is being pushed where, etcetera. For full documentation, please refer to the developer documentation section on the MistServer website."}])).append($("<button>").text("New trigger").click(function(){UI.navto("Edit Trigger")})).append(h); +h.stupidtable();h=mist.data.config.triggers;for(p in h)for(j in h[p])e=triggerRewrite(h[p][j]),z.append($("<tr>").attr("data-index",p+","+j).append($("<td>").text(p)).append($("<td>").text("streams"in e?e.streams.join(", "):"")).append($("<td>").text(e.handler)).append($("<td>").html($("<button>").text("Edit").click(function(){UI.navto("Edit Trigger",$(this).closest("tr").attr("data-index"))})).append($("<button>").text("Delete").click(function(){var a=$(this).closest("tr").attr("data-index").split(","); +if(confirm("Are you sure you want to delete this "+a[0]+" trigger?")){mist.data.config.triggers[a[0]].splice(a[1],1);mist.data.config.triggers[a[0]].length==0&&delete mist.data.config.triggers[a[0]];mist.send(function(){UI.navto("Triggers")},{config:mist.data.config})}}))));break;case "Edit Trigger":if(!("triggers"in mist.data.config)||!mist.data.config.triggers)mist.data.config.triggers={};if("undefined"==typeof mist.data.capabilities){mist.send(function(){UI.showTab(a,b,d)},{capabilities:!0});c.append("Loading.."); +return}b?(b=b.split(","),j=triggerRewrite(mist.data.config.triggers[b[0]][b[1]]),r={triggeron:b[0],appliesto:j.streams,url:j.handler,async:j.sync,"default":j["default"],params:j.params}):(c.html($("<h2>").text("New Trigger")),r={});j=[];for(p in mist.data.capabilities.triggers)j.push([p,p+": "+mist.data.capabilities.triggers[p].when]);var Y=$("<div>").addClass("desc"),na=$("<div>");c.append(UI.buildUI([{label:"Trigger on",pointer:{main:r,index:"triggeron"},help:"For what event this trigger should activate.", +type:"select",select:j,validate:["required"],"function":function(){var a=$(this).getval(),b=mist.data.capabilities.triggers[a];Y.html("");if(b){a=[$("<h4>").text("Trigger properties"),{type:"help",help:'The trigger "<i>'+a+'</i>" has the following properties:'},{type:"span",label:"Triggers",value:b.when,help:"When this trigger is activated"}];b.payload!=""&&a.push({label:"Payload",type:"textarea",value:b.payload,rows:b.payload.split("\n").length,readonly:true,clipboard:true,help:"The information this trigger sends to the handler."}); +a.push({type:"span",label:"Requires response",value:function(a){switch(a){case "ignored":return"No. The trigger will ignore the response of the handler.";case "always":return"Yes. The trigger needs a response to proceed.";case "when-blocking":return"The trigger needs a response to proceed if it is configured to be blocking.";default:return a}}(b.response),help:"Whether this trigger requires a response from the trigger handler"});a.push({type:"span",label:"Response action",value:b.response_action, +help:"What this trigger will do with its handler's response"});Y.append(UI.buildUI(a));b.stream_specific?$("[name=appliesto]").closest(".UIelement").show():$("[name=appliesto]").setval([]).closest(".UIelement").hide();if(b.argument){$("[name=params]").closest(".UIelement").show();na.text(b.argument)}else $("[name=params]").setval("").closest(".UIelement").hide()}}},Y,$("<h4>").text("Trigger settings"),{label:"Applies to",pointer:{main:r,index:"appliesto"},help:"For triggers that can apply to specific streams, this value decides what streams they are triggered for. (none checked = always triggered)", +type:"checklist",checklist:Object.keys(mist.data.streams),value:""!=d[1]?[d[1]]:[]},$("<br>"),{label:"Handler (URL or executable)",help:"This can be either an HTTP URL or a full path to an executable.",pointer:{main:r,index:"url"},validate:["required"],type:"str"},{label:"Blocking",type:"checkbox",help:"If checked, pauses processing and uses the response of the handler. If the response does not start with 1, true, yes or cont, further processing is aborted. If unchecked, processing is never paused and the response is not checked.", +pointer:{main:r,index:"async"}},{label:"Parameters",type:"str",help:$("<div>").text("The extra data you want this trigger to use.").append(na),pointer:{main:r,index:"params"}},{label:"Default response",type:"str",help:"The default response in case the handler fails or is set to non-blocking.",placeholder:"true",pointer:{main:r,index:"default"}},{type:"buttons",buttons:[{type:"cancel",label:"Cancel","function":function(){d[0]&&d[0]!=a?UI.navto(d[0],d[1]):UI.navto("Triggers")}},{type:"save",label:"Save", +"function":function(){b&&mist.data.config.triggers[b[0]].splice(b[1],1);var c={handler:r.url,sync:r.async?true:false,streams:typeof r.appliesto=="undefined"?[]:r.appliesto,params:r.params,"default":r["default"]};if(!("triggers"in mist.data.config))mist.data.config.triggers={};r.triggeron in mist.data.config.triggers||(mist.data.config.triggers[r.triggeron]=[]);mist.data.config.triggers[r.triggeron].push(c);mist.send(function(){d[0]&&d[0]!=a?UI.navto(d[0],d[1]):UI.navto("Triggers")},{config:mist.data.config})}}]}])); +$("[name=triggeron]").trigger("change");break;case "Logs":var oa=$("<button>").text("Refresh now").click(function(){$(this).text("Loading..");mist.send(function(){Z();oa.text("Refresh now")})}).css("padding","0.2em 0.5em").css("flex-grow",0);c.append(UI.buildUI([{type:"help",help:"Here you have an overview of all edited settings within MistServer and possible warnings or errors MistServer has encountered. MistServer stores up to 100 logs at a time."},{label:"Refresh every",type:"select",select:[[10, +"10 seconds"],[30,"30 seconds"],[60,"minute"],[300,"5 minutes"]],value:30,"function":function(){UI.interval.clear();UI.interval.set(function(){mist.send(function(){Z()})},$(this).val()*1E3)},help:"How often the table below should be updated."},{label:"..or",type:"DOMfield",DOMfield:oa,help:"Instantly refresh the table below."}]));c.append($("<button>").text("Purge logs").click(function(){mist.send(function(){mist.data.log=[];UI.navto("Logs")},{clearstatlogs:true})}));z=$("<tbody>").css("font-size", +"0.9em");c.append($("<table>").addClass("logs").append(z));var qa=function(a){var b=$("<span>").text(a);switch(a){case "WARN":b.addClass("orange");break;case "ERROR":case "FAIL":b.addClass("red")}return b},Z=function(){var a=mist.data.log;if(a){a.length>=2&&a[0][0]<a[a.length-1][0]&&a.reverse();z.html("");for(var b in a){var c=$("<span>").addClass("content"),d=a[b][2].split("|"),g;for(g in d)c.append($("<span>").text(d[g]));z.append($("<tr>").html($("<td>").text(UI.format.dateTime(a[b][0],"long")).css("white-space", +"nowrap")).append($("<td>").html(qa(a[b][1])).css("text-align","center")).append($("<td>").html(c).css("text-align","left")))}}};Z();break;case "Statistics":var F=$("<span>").text("Loading..");c.append(F);var r={graph:"new"},y=mist.stored.get().graphs?$.extend(!0,{},mist.stored.get().graphs):{},O={};for(p in mist.data.streams)O[p]=!0;for(p in mist.data.active_streams)O[mist.data.active_streams[p]]=!0;var O=Object.keys(O).sort(),aa=[];for(p in mist.data.config.protocols)aa.push(mist.data.config.protocols[p].connector); +aa.sort();mist.send(function(){UI.plot.datatype.templates.cpuload.cores=0;for(var a in mist.data.capabilities.cpu)UI.plot.datatype.templates.cpuload.cores=UI.plot.datatype.templates.cpuload.cores+mist.data.capabilities.cpu[a].cores;F.html(UI.buildUI([{type:"help",help:"Here you will find the MistServer stream statistics, you can select various categories yourself. All statistics are live: up to five minutes are saved."},$("<h3>").text("Select the data to display"),{label:"Add to",type:"select",select:[["new", +"New graph"]],pointer:{main:r,index:"graph"},classes:["graph_ids"],"function":function(){if($(this).val()){var a=F.find(".graph_xaxis"),b=F.find(".graph_id");if($(this).val()=="new"){a.children("option").prop("disabled",false);b.setval("Graph "+(Object.keys(y).length+1)).closest("label").show()}else{var c=y[$(this).val()].xaxis;a.children("option").prop("disabled",true).filter('[value="'+c+'"]').prop("disabled",false);b.closest("label").hide()}a.children('option[value="'+a.val()+'"]:disabled').length&& +a.val(a.children("option:enabled").first().val());a.trigger("change")}}},{label:"Graph id",type:"str",pointer:{main:r,index:"id"},classes:["graph_id"],validate:[function(a){return a in y?{msg:"This graph id has already been used. Please enter something else.",classes:["red"]}:false}]},{label:"Axis type",type:"select",select:[["time","Time line"]],pointer:{main:r,index:"xaxis"},value:"time",classes:["graph_xaxis"],"function":function(){$s=F.find(".graph_datatype");switch($(this).getval()){case "coords":$s.children("option").prop("disabled", +true).filter('[value="coords"]').prop("disabled",false);break;case "time":$s.children("option").prop("disabled",false).filter('[value="coords"]').prop("disabled",true)}if(!$s.val()||$s.children('option[value="'+$s.val()+'"]:disabled').length){$s.val($s.children("option:enabled").first().val());$s.trigger("change")}}},{label:"Data type",type:"select",select:[["clients","Connections"],["upbps","Bandwidth (up)"],["downbps","Bandwidth (down)"],["cpuload","CPU use"],["memload","Memory load"],["coords", +"Client location"],["perc_lost","Lost packages"],["perc_retrans","Re-transmitted packages"]],pointer:{main:r,index:"datatype"},classes:["graph_datatype"],"function":function(){$s=F.find(".graph_origin");switch($(this).getval()){case "cpuload":case "memload":$s.find("input[type=radio]").not('[value="total"]').prop("disabled",true);$s.find('input[type=radio][value="total"]').prop("checked",true);break;default:$s.find("input[type=radio]").prop("disabled",false)}}},{label:"Data origin",type:"radioselect", +radioselect:[["total","All"],["stream","The stream:",O],["protocol","The protocol:",aa]],pointer:{main:r,index:"origin"},value:["total"],classes:["graph_origin"]},{type:"buttons",buttons:[{label:"Add data set",type:"save","function":function(){var a;if(r.graph=="new"){a=UI.plot.addGraph(r,b);y[a.id]=a;F.find("input.graph_id").val("");F.find("select.graph_ids").append($("<option>").text(a.id)).val(a.id).trigger("change")}else a=y[r.graph];var c=UI.plot.datatype.getOptions({datatype:r.datatype,origin:r.origin}); +a.datasets.push(c);UI.plot.save(a);UI.plot.go(y)}}]}]));var b=$("<div>").addClass("graph_container");c.append(b);var d=F.find("select.graph_ids");for(a in y){var g=UI.plot.addGraph(y[a],b);d.append($("<option>").text(g.id)).val(g.id);var h=[],e;for(e in y[a].datasets){var f=UI.plot.datatype.getOptions({datatype:y[a].datasets[e].datatype,origin:y[a].datasets[e].origin});h.push(f)}g.datasets=h;y[g.id]=g}d.trigger("change");UI.plot.go(y);UI.interval.set(function(){UI.plot.go(y)},1E4)},{active_streams:!0, +capabilities:!0});break;case "Server Stats":if("undefined"==typeof mist.data.capabilities){mist.send(function(){UI.showTab(a)},{capabilities:!0});c.append("Loading..");return}var ba=$("<table>"),I=$("<table>"),j={vheader:"CPUs",labels:["Model","Processor speed","Amount of cores","Amount of threads"],content:[]};for(p in mist.data.capabilities.cpu)h=mist.data.capabilities.cpu[p],j.content.push({header:"CPU #"+(Number(p)+1),body:[h.model,UI.format.addUnit(UI.format.number(h.mhz),"MHz"),h.cores,h.threads]}); +p=UI.buildVheaderTable(j);var pa=function(){var a=mist.data.capabilities.mem,b=mist.data.capabilities.load,a={vheader:"Memory",labels:["Used","Cached","Available","Total"],content:[{header:"Physical memory",body:[UI.format.bytes(a.used*1048576)+" ("+UI.format.addUnit(b.memory,"%")+")",UI.format.bytes(a.cached*1048576),UI.format.bytes(a.free*1048576),UI.format.bytes(a.total*1048576)]},{header:"Swap memory",body:[UI.format.bytes((a.swaptotal-a.swapfree)*1048576),UI.format.addUnit("","N/A"),UI.format.bytes(a.swapfree* +1048576),UI.format.bytes(a.swaptotal*1048576)]}]},a=UI.buildVheaderTable(a);ba.replaceWith(a);ba=a;b={vheader:"Load average",labels:["CPU use","1 minute","5 minutes","15 minutes"],content:[{header:" ",body:[UI.format.addUnit(UI.format.number(mist.data.capabilities.cpu_use/10),"%"),UI.format.number(b.one/100),UI.format.number(b.five/100),UI.format.number(b.fifteen/100)]}]};b=UI.buildVheaderTable(b);I.replaceWith(b);I=b};pa();c.append(UI.buildUI([{type:"help",help:"You can find general server statistics here. Note that memory and CPU usage is for your entire machine, not just MistServer."}])).append($("<table>").css("width", "auto").addClass("nolay").append($("<tr>").append($("<td>").append(ba)).append($("<td>").append(I))).append($("<tr>").append($("<td>").append(p).attr("colspan",2))));UI.interval.set(function(){mist.send(function(){pa()},{capabilities:true})},3E4);break;case "Email for Help":p=$.extend({},mist.data);delete p.statistics;delete p.totals;delete p.clients;delete p.capabilities;p=JSON.stringify(p);p="Version: "+mist.data.config.version+"\n\nConfig:\n"+p;r={};c.append(UI.buildUI([{type:"help",help:"You can use this form to email MistServer support if you're having difficulties.<br>A copy of your server config file will automatically be included."}, {type:"str",label:"Your name",validate:["required"],pointer:{main:r,index:"name"},value:mist.user.name},{type:"email",label:"Your email address",validate:["required"],pointer:{main:r,index:"email"}},{type:"hidden",value:"Integrated Help",pointer:{main:r,index:"subject"}},{type:"hidden",value:"-",pointer:{main:r,index:"company"}},{type:"textarea",rows:20,label:"Your message",validate:["required"],pointer:{main:r,index:"message"}},{type:"textarea",rows:20,label:"Your config file",readonly:!0,value:p, pointer:{main:r,index:"configfile"}},{type:"buttons",buttons:[{type:"save",label:"Send","function":function(a){$(a).text("Sending..");$.ajax({type:"POST",url:"https://mistserver.org/contact?skin=plain",data:r,success:function(a){a=$("<span>").html(a);a.find("script").remove();c.html(a[0].innerHTML)}})}}]}]));break;case "Disconnect":mist.user.password="";delete mist.user.authstring;delete mist.user.loggedin;sessionStorage.removeItem("mistLogin");UI.navto("Login");break;default:c.append($("<p>").text("This tab does not exist."))}c.find(".field").filter(function(){var a= @@ -312,9 +311,9 @@ return c},embedurls:function(a,b,d){function c(){function b(a){switch(typeof a){ c+'">');k.push(" <noscript>");k.push(' <a href="'+n+j+'.html" target="_blank">');k.push(" Click here to play this video");k.push(" </a>");k.push(" </noscript>");k.push(" <script>");k.push(" var a = function(){");k.push(' mistPlay("'+a+'",{');k.push(" "+e.join(",\n "));k.push(" });");k.push(" };");k.push(" if (!window.mistplayers) {");k.push(' var p = document.createElement("script");');d.HTTPS.length?(k.push(' if (location.protocol == "https:") { p.src = "'+ ("https://"==parseURL(n).protocol?n:d.HTTPS[0])+'player.js" } '),k.push(' else { p.src = "'+("http://"==parseURL(n).protocol?n:d.HTTP[0])+'player.js" } ')):k.push(' p.src = "'+n+'player.js"');k.push(" document.head.appendChild(p);");k.push(" p.onload = a;");k.push(" }");k.push(" else { a(); }");k.push(" <\/script>");k.push("</div>");return k.join("\n")}function e(d){UI.sockets.ws.info_json.subscribe(function(a){if("error"==a.type)if(d==n)e(b);else throw a;else{if("source"in a&&(!q||a.source.length)){var g=d==n?!1:n,f=[],i=l.find(".field.forceType"),j=l.find(".field.prioritize_type");g&&(g=g.replace(parseURL(g).protocol,""),f.push($("<div>").addClass("orange").html('Warning: the provided base URL <a href="'+n+'">'+n+"</a> could not be reached. These links are my best guess but will probably not work properly.").css({margin:"0.5em 0",width:"45em","word-break":"normal"})));for(var m in a.source){var s=a.source[m],C=UI.humanMime(s.type),u=s.url;g&&(u=parseURL(s.url).protocol+ -g+s.relurl);var D=u.match(/[\?\&]tkn=\d+\&?/);D&&(D=D[0],u=u.replace(D,"?"==D[0]&&"&"==D.slice(-1)?"?":"&"==D.slice(-1)?"&":""));f.push({label:C?C+" <span class=description>("+s.type+")</span>":UI.format.capital(s.type),type:"str",value:u,readonly:!0,qrcode:!0,clipboard:!0});C=UI.humanMime(s.type);0==i.children('option[value="'+s.type+'"]').length&&(i.append($("<option>").text(C?C+" ("+s.type+")":UI.format.capital(s.type)).val(s.type)),j.append($("<option>").text(C?C+" ("+s.type+")":UI.format.capital(s.type)).val(s.type)))}i.val(h.forceType); +g+s.relurl);var E=u.match(/[\?\&]tkn=\d+\&?/);E&&(E=E[0],u=u.replace(E,"?"==E[0]&&"&"==E.slice(-1)?"?":"&"==E.slice(-1)?"&":""));f.push({label:C?C+" <span class=description>("+s.type+")</span>":UI.format.capital(s.type),type:"str",value:u,readonly:!0,qrcode:!0,clipboard:!0});C=UI.humanMime(s.type);0==i.children('option[value="'+s.type+'"]').length&&(i.append($("<option>").text(C?C+" ("+s.type+")":UI.format.capital(s.type)).val(s.type)),j.append($("<option>").text(C?C+" ("+s.type+")":UI.format.capital(s.type)).val(s.type)))}i.val(h.forceType); j.val(h.prioritize_type);o.html(UI.buildUI(f));q=!0}if("meta"in a&&"tracks"in a.meta){var g={},v;for(v in a.meta.tracks)if(f=a.meta.tracks[v],"subtitle"==f.codec&&(f.type="subtitle"),!("audio"!=f.type&&"video"!=f.type&&"subtitle"!=f.type))f.type in g||(g[f.type]="subtitle"==f.type?[]:[["","Autoselect "+f.type]]),g[f.type].push([f.trackid,UI.format.capital(f.type)+" track "+(g[f.type].length+("subtitle"==f.type?1:0))]);k.html("");if(Object.keys(g).length){k.closest("label").show();var a=["audio","video", -"subtitle"],A;for(A in a)if(v=a[A],g[v]&&g[v].length){f=$("<select>").attr("data-type",v).css("flex-grow","1").change(function(){""==$(this).val()?delete h.setTracks[$(this).attr("data-type")]:h.setTracks[$(this).attr("data-type")]=$(this).val();$(".embed_code").setval(c(h))});k.append(f);"subtitle"==v?g[v].unshift(["","No "+v]):g[v].push([-1,"No "+v]);for(var L in g[v])f.append($("<option>").val(g[v][L][0]).text(g[v][L][1]));v in h.setTracks&&(f.val(h.setTracks[v]),null==f.val()&&(f.val(""),delete h.setTracks[v], +"subtitle"],z;for(z in a)if(v=a[z],g[v]&&g[v].length){f=$("<select>").attr("data-type",v).css("flex-grow","1").change(function(){""==$(this).val()?delete h.setTracks[$(this).attr("data-type")]:h.setTracks[$(this).attr("data-type")]=$(this).val();$(".embed_code").setval(c(h))});k.append(f);"subtitle"==v?g[v].unshift(["","No "+v]):g[v].push([-1,"No "+v]);for(var L in g[v])f.append($("<option>").val(g[v][L][0]).text(g[v][L][1]));v in h.setTracks&&(f.val(h.setTracks[v]),null==f.val()&&(f.val(""),delete h.setTracks[v], $(".embed_code").setval(c(h))))}}else k.closest("label").hide()}}},a,d.replace(/^http/,"ws")+"json_"+encodeURIComponent(a)+".js",!1,"?inclzero=1")}var l=$("<section>").addClass("embedurls"),i=$("<datalist>").attr("id","urlhints"),f=d.HTTPS.concat(d.HTTP),m;for(m in f)i.append($("<option>").val(f[m]));var n=otherhost.host?otherhost.host:f.length?f[0]:b;l.append($("<span>").addClass("input_container").append($("<label>").addClass("UIelement").append($("<span>").addClass("label").text("Use base URL:")).append($("<span>").addClass("field_container").append($("<input>").attr("type", "text").addClass("field").val(n).attr("list","urlhints")).append(i).append($("<span>").addClass("unit").append($("<button>").text("Apply").click(function(){otherhost.host=$(this).closest("label").find("input").val();"/"!=otherhost.host.slice(-1)&&(otherhost.host+="/");UI.navto("Embed",a)}))))));var j=encodeURIComponent(a),q=!1,g={forcePlayer:"",forceType:"",controls:!0,autoplay:!0,loop:!1,muted:!1,fillSpace:!1,poster:"",urlappend:"",setTracks:{}},h=$.extend({},g),i=UI.stored.getOpts();"embedoptions"in i&&(h=$.extend(h,i.embedoptions,!0),"object"!=typeof h.setTracks&&(h.setTracks={}));i={};switch(h.controls){case "stock":i.controls="stock";break;case !0:i.controls=1;break;case !1:i.controls=0}var f=c(h),k=$("<div>").text("Loading..").css("display","flex").css("flex-flow","column nowrap"),o=$("<span>").text("Loading..").css("word-break","break-all");if(mistplayers){var s=[["","Automatic"]];for(m in mistplayers)s.push([m,mistplayers[m].name])}l.append(UI.buildUI([$("<h3>").text("Urls"),{label:"Stream info json", @@ -342,10 +341,12 @@ mist.data.totals[stream]||(mist.data.totals[stream][protocol]={});$.extend(mist. "")UI.navto("Login");else{mist.user.authstring=e.authorize.challenge;mist.send(a,b,d);sessionStorage.setItem("mistLogin",JSON.stringify({host:mist.user.host,name:mist.user.name,password:mist.user.password}))}break;case "NOACC":UI.navto("Create a new account");break;case "ACC_MADE":delete b.authorize;mist.send(a,b,d);break;default:UI.navto("Login")}}};d.hide||UI.elements.connection.msg.removeClass("red").text("Data sent, waiting for a reply..").append($("<br>")).append($("<a>").text("Cancel request").click(function(){l.abort()})); var l=$.ajax(e)},inputMatch:function(a,b){if(typeof a=="undefined")return false;typeof a=="string"&&(a=[a]);for(var d in a){var c=a[d].replace(/[^\w\s]/g,"\\$&"),c=c.replace(/\\\*/g,".*");if(RegExp("^(?:[a-zA-Z]:)?"+c+"(?:\\?[^\\?]*)?$","i").test(b))return true}return false},convertBuildOptions:function(a,b){function d(a,c,d){var f={label:UI.format.capital(d.name?d.name:c),pointer:{main:b,index:c},validate:[]};e[a]=="required"&&(!("default"in d)||d["default"]=="")&&f.validate.push("required");if("default"in d){f.placeholder=d["default"];if(d.type=="select")for(var i in d.select)if(d.select[i][0]==d["default"]){f.placeholder=d.select[i][1];break}}if("help"in d)f.help=d.help;if("unit"in d)f.unit=d.unit;if("placeholder"in d)f.placeholder=d.placeholder;if("datalist"in d)f.datalist=d.datalist;if("type"in d)switch(d.type){case "int":f.type="int";if("max"in d)f.max=d.max;if("min"in d)f.min=d.min;break;case "uint":f.type="int";f.min=0;if("max"in d)f.max=d.max;if("min"in d)f.min=Math.max(f.min,d.min);break;case "radioselect":f.type= -"radioselect";f.radioselect=d.radioselect;break;case "select":f.type="select";f.select=d.select.slice(0);f.validate.indexOf("required")>=0&&f.select.unshift(["","placeholder"in f?"Default ("+f.placeholder+")":""]);break;case "sublist":f.type="sublist";f.saveas={};f.itemLabel=d.itemLabel;f.sublist=mist.convertBuildOptions(d,f.saveas);break;case "group":a=mist.convertBuildOptions({optional:d.options},b);a=a.slice(1);"help"in d&&a.unshift($("<span>").addClass("description").text(d.help));"name"in d&& -a.unshift($("<b>").text(d.name));return $("<div>").addClass("itemsettings").append(UI.buildUI(a));case "bool":f.type="checkbox";break;case "unixtime":f.type="unix";break;case "json":case "debug":case "inputlist":f.type=d.type;break;default:f.type="str"}else f.type="checkbox";if("format"in d)switch(d.format){case "set_or_unset":f.postSave=function(){var a=$(this).data("pointer");a.main[a.index]||delete a.main[a.index]}}"influences"in d?f["function"]=function(){var a=$(this).closest(".UIelement"),b= -a.find("style");if(b.length)b=b[0];else{b=$("<style>").addClass("dependencies")[0];a.append(b)}b.innerHTML=".UIelement[data-dependent-"+c+"]:not([data-dependent-"+c+'~="'+$(this).getval()+'"]) { display: none; }\n';$(b).data("content",b.innerHTML);$("style.dependencies.hidden").each(function(){$(this).html($(this).data("content")).removeClass("hidden")});$(".UIelement:not(:visible) style.dependencies:not(.hidden)").each(function(){$(this).addClass("hidden");$(this).html("")})}:"disable"in d&&(f["function"]= -function(){for(var a=$(this).closest(".input_container"),b=$(this).getval(),c=0;c<d.disable.length;c++){var e=a.find('.field[name="'+d.disable[c]+'"]').closest(".UIelement");if(e.length)b==""?e[0].style.display="":e.hide()}});if("dependent"in d)f.dependent=d.dependent;if("value"in d)f.value=d.value;if("validate"in d){f.validate=f.validate.concat(d.validate);if(d.validate.indexOf("track_selector_parameter")>-1)f.help="<div>"+d.help+"</div><p>Track selector parameters consist of a string value which may be any of the following:</p> <ul><li><code>selector,selector</code>: Selects the union of the given selectors. Any number of comma-separated selector combinations may be used, they are evaluated one by one from left to right.</li> <li><code>selector,!selector</code>: Selects the difference of the given selectors. Specifically, all tracks part of the first selector that are not part of the second selector. Any number of comma-separated selector combinations may be used, they are evaluated one by one from left to right.</li> <li><code>selector,|selector</code>: Selects the intersection of the given selectors. Any number of comma-separated selector combinations may be used, they are evaluated one by one from left to right.</li> <li><code>none</code> or <code>-1</code>: Selects no tracks of this type.</li> <li><code>all</code> or <code>*</code>: Selects all tracks of this type.</li> <li>Any positive integer: Select this specific track ID. Does not apply if the given track ID does not exist or is of the wrong type. <strong>Does</strong> apply if the given track ID is incompatible with the currently active protocol or container format.</li> <li>ISO 639-1/639-3 language code: Select all tracks marked as the given language. Case insensitive.</li> <li>Codec string (e.g. <code>h264</code>): Select all tracks of the given codec. Case insensitive.</li> <li><code>highbps</code>, <code>maxbps</code> or <code>bestbps</code>: Select the track of this type with the highest bit rate.</li> <li><code>lowbps</code>, <code>minbps</code> or <code>worstbps</code>: Select the track of this type with the lowest bit rate.</li> <li><code>Xbps</code> or <code>Xkbps</code> or <code>Xmbps</code>: Select the single of this type which has a bit rate closest to the given number X. This number is in bits, not bytes.</li> <li><code>>Xbps</code> or <code>>Xkbps</code> or <code>>Xmbps</code>: Select all tracks of this type which have a bit rate greater than the given number X. This number is in bits, not bytes.</li> <li><code><Xbps</code> or <code><Xkbps</code> or <code><Xmbps</code>: Select all tracks of this type which have a bit rate less than the given number X. This number is in bits, not bytes.</li> <li><code>max<Xbps</code> or <code>max<Xkbps</code> or <code>max<Xmbps</code>: Select the one track of this type which has the highest bit rate less than the given number X. This number is in bits, not bytes.</li> <li><code>highres</code>, <code>maxres</code> or <code>bestres</code>: Select the track of this type with the highest pixel surface area. Only applied when the track type is video.</li> <li><code>lowres</code>, <code>minres</code> or <code>worstres</code>: Select the track of this type with the lowest pixel surface area. Only applied when the track type is video.</li> <li><code>XxY</code>: Select all tracks of this type with the given pixel surface area in X by Y pixels. Only applied when the track type is video.</li> <li><code>~XxY</code>: Select the single track of this type closest to the given pixel surface area in X by Y pixels. Only applied when the track type is video.</li> <li><code>>XxY</code>: Select all tracks of this type with a pixel surface area greater than X by Y pixels. Only applied when the track type is video.</li> <li><code><XxY</code>: Select all tracks of this type with a pixel surface area less than X by Y pixels. Only applied when the track type is video.</li> <li><code>720p</code>, <code>1080p</code>, <code>1440p</code>, <code>2k</code>, <code>4k</code>, <code>5k</code>, or <code>8k</code>: Select all tracks of this type with the given pixel surface area. Only applied when the track type is video.</li> <li><code>surround</code>, <code>mono</code>, <code>stereo</code>, <code>Xch</code>: Select all tracks of this type with the given channel count. The 'Xch' variant can use any positive integer for 'X'. Only applied when the track type is audio.</li></ul>"; +"radioselect";f.radioselect=d.radioselect;break;case "select":f.type="select";f.select=d.select.slice(0);f.validate.indexOf("required")>=0&&f.select.unshift(["","placeholder"in f?"Default ("+f.placeholder+")":""]);break;case "sublist":f.type="sublist";f.saveas={};f.itemLabel=d.itemLabel;f.sublist=mist.convertBuildOptions(d,f.saveas);break;case "group":var j=$("<div>").addClass("itemgroup"),a=mist.convertBuildOptions({optional:d.options},b),a=a.slice(1),l=$("<ul>").addClass("summary");a.unshift(l); +"help"in d&&a.unshift($("<span>").addClass("description").text(d.help));"name"in d&&a.unshift($("<b>").text(d.name).click(function(){j.toggleClass("expanded")}).attr("title","Click to show / hide these options"));(d.expand||d.expand!==false&&Object.keys(d.options).length<2)&&j.addClass("expanded");return j.change(function(){l.html("");$(this).find('.isSetting, input[type="hidden"].isSetting').each(function(){var a=$(this).getval();if(a!=""){var b=$(this).data("opts");if(a!=b["default"]){var c=b.label+ +": ";switch(b.type){case "select":a=b.select.filter(function(b){return b[0]==a?true:false})[0][1];break;case "unix":a=UI.format.dateTime(a);break;case "checkbox":a="";c=c.slice(0,-2)}l.append($("<li>").addClass("setting").append($("<span>").addClass("label").text(c)).append($("<span>").text(a)).append($("<span>").addClass("unit").text(typeof b.unit=="string"?b.unit:"")))}}})}).append(UI.buildUI(a)).trigger("change");case "bool":f.type="checkbox";break;case "unixtime":f.type="unix";break;case "json":case "debug":case "inputlist":f.type= +d.type;break;default:f.type="str"}else f.type="checkbox";if("format"in d)switch(d.format){case "set_or_unset":f.postSave=function(){var a=$(this).data("pointer");a.main[a.index]||delete a.main[a.index]}}"influences"in d?f["function"]=function(){var a=$(this).closest(".UIelement"),b=a.find("style");if(b.length)b=b[0];else{b=$("<style>").addClass("dependencies")[0];a.append(b)}b.innerHTML=".UIelement[data-dependent-"+c+"]:not([data-dependent-"+c+'~="'+$(this).getval()+'"]) { display: none; }\n';$(b).data("content", +b.innerHTML);$("style.dependencies.hidden").each(function(){$(this).html($(this).data("content")).removeClass("hidden")});$(".UIelement:not(:visible) style.dependencies:not(.hidden)").each(function(){$(this).addClass("hidden");$(this).html("")})}:"disable"in d&&(f["function"]=function(){for(var a=$(this).closest(".input_container"),b=$(this).getval(),c=0;c<d.disable.length;c++){var e=a.find('.field[name="'+d.disable[c]+'"]').closest(".UIelement");if(e.length)b==""?e[0].style.display="":e.hide()}}); +if("dependent"in d)f.dependent=d.dependent;if("value"in d)f.value=d.value;if("validate"in d){f.validate=f.validate.concat(d.validate);if(d.validate.indexOf("track_selector_parameter")>-1)f.help="<div>"+d.help+"</div><p>Track selector parameters consist of a string value which may be any of the following:</p> <ul><li><code>selector,selector</code>: Selects the union of the given selectors. Any number of comma-separated selector combinations may be used, they are evaluated one by one from left to right.</li> <li><code>selector,!selector</code>: Selects the difference of the given selectors. Specifically, all tracks part of the first selector that are not part of the second selector. Any number of comma-separated selector combinations may be used, they are evaluated one by one from left to right.</li> <li><code>selector,|selector</code>: Selects the intersection of the given selectors. Any number of comma-separated selector combinations may be used, they are evaluated one by one from left to right.</li> <li><code>none</code> or <code>-1</code>: Selects no tracks of this type.</li> <li><code>all</code> or <code>*</code>: Selects all tracks of this type.</li> <li>Any positive integer: Select this specific track ID. Does not apply if the given track ID does not exist or is of the wrong type. <strong>Does</strong> apply if the given track ID is incompatible with the currently active protocol or container format.</li> <li>ISO 639-1/639-3 language code: Select all tracks marked as the given language. Case insensitive.</li> <li>Codec string (e.g. <code>h264</code>): Select all tracks of the given codec. Case insensitive.</li> <li><code>highbps</code>, <code>maxbps</code> or <code>bestbps</code>: Select the track of this type with the highest bit rate.</li> <li><code>lowbps</code>, <code>minbps</code> or <code>worstbps</code>: Select the track of this type with the lowest bit rate.</li> <li><code>Xbps</code> or <code>Xkbps</code> or <code>Xmbps</code>: Select the single of this type which has a bit rate closest to the given number X. This number is in bits, not bytes.</li> <li><code>>Xbps</code> or <code>>Xkbps</code> or <code>>Xmbps</code>: Select all tracks of this type which have a bit rate greater than the given number X. This number is in bits, not bytes.</li> <li><code><Xbps</code> or <code><Xkbps</code> or <code><Xmbps</code>: Select all tracks of this type which have a bit rate less than the given number X. This number is in bits, not bytes.</li> <li><code>max<Xbps</code> or <code>max<Xkbps</code> or <code>max<Xmbps</code>: Select the one track of this type which has the highest bit rate less than the given number X. This number is in bits, not bytes.</li> <li><code>highres</code>, <code>maxres</code> or <code>bestres</code>: Select the track of this type with the highest pixel surface area. Only applied when the track type is video.</li> <li><code>lowres</code>, <code>minres</code> or <code>worstres</code>: Select the track of this type with the lowest pixel surface area. Only applied when the track type is video.</li> <li><code>XxY</code>: Select all tracks of this type with the given pixel surface area in X by Y pixels. Only applied when the track type is video.</li> <li><code>~XxY</code>: Select the single track of this type closest to the given pixel surface area in X by Y pixels. Only applied when the track type is video.</li> <li><code>>XxY</code>: Select all tracks of this type with a pixel surface area greater than X by Y pixels. Only applied when the track type is video.</li> <li><code><XxY</code>: Select all tracks of this type with a pixel surface area less than X by Y pixels. Only applied when the track type is video.</li> <li><code>720p</code>, <code>1080p</code>, <code>1440p</code>, <code>2k</code>, <code>4k</code>, <code>5k</code>, or <code>8k</code>: Select all tracks of this type with the given pixel surface area. Only applied when the track type is video.</li> <li><code>surround</code>, <code>mono</code>, <code>stereo</code>, <code>Xch</code>: Select all tracks of this type with the given channel count. The 'Xch' variant can use any positive integer for 'X'. Only applied when the track type is audio.</li></ul>"; if(d.validate.indexOf("track_selector")>-1)f.help="<div>"+d.help+"</div><p>A track selector is at least one track type (audio, video or subtitle) combined with a track selector parameter. For example: <code>audio=none&video=maxres</code>.<p>Track selector parameters consist of a string value which may be any of the following:</p> <ul><li><code>selector,selector</code>: Selects the union of the given selectors. Any number of comma-separated selector combinations may be used, they are evaluated one by one from left to right.</li> <li><code>selector,!selector</code>: Selects the difference of the given selectors. Specifically, all tracks part of the first selector that are not part of the second selector. Any number of comma-separated selector combinations may be used, they are evaluated one by one from left to right.</li> <li><code>selector,|selector</code>: Selects the intersection of the given selectors. Any number of comma-separated selector combinations may be used, they are evaluated one by one from left to right.</li> <li><code>none</code> or <code>-1</code>: Selects no tracks of this type.</li> <li><code>all</code> or <code>*</code>: Selects all tracks of this type.</li> <li>Any positive integer: Select this specific track ID. Does not apply if the given track ID does not exist or is of the wrong type. <strong>Does</strong> apply if the given track ID is incompatible with the currently active protocol or container format.</li> <li>ISO 639-1/639-3 language code: Select all tracks marked as the given language. Case insensitive.</li> <li>Codec string (e.g. <code>h264</code>): Select all tracks of the given codec. Case insensitive.</li> <li><code>highbps</code>, <code>maxbps</code> or <code>bestbps</code>: Select the track of this type with the highest bit rate.</li> <li><code>lowbps</code>, <code>minbps</code> or <code>worstbps</code>: Select the track of this type with the lowest bit rate.</li> <li><code>Xbps</code> or <code>Xkbps</code> or <code>Xmbps</code>: Select the single of this type which has a bit rate closest to the given number X. This number is in bits, not bytes.</li> <li><code>>Xbps</code> or <code>>Xkbps</code> or <code>>Xmbps</code>: Select all tracks of this type which have a bit rate greater than the given number X. This number is in bits, not bytes.</li> <li><code><Xbps</code> or <code><Xkbps</code> or <code><Xmbps</code>: Select all tracks of this type which have a bit rate less than the given number X. This number is in bits, not bytes.</li> <li><code>max<Xbps</code> or <code>max<Xkbps</code> or <code>max<Xmbps</code>: Select the one track of this type which has the highest bit rate less than the given number X. This number is in bits, not bytes.</li> <li><code>highres</code>, <code>maxres</code> or <code>bestres</code>: Select the track of this type with the highest pixel surface area. Only applied when the track type is video.</li> <li><code>lowres</code>, <code>minres</code> or <code>worstres</code>: Select the track of this type with the lowest pixel surface area. Only applied when the track type is video.</li> <li><code>XxY</code>: Select all tracks of this type with the given pixel surface area in X by Y pixels. Only applied when the track type is video.</li> <li><code>~XxY</code>: Select the single track of this type closest to the given pixel surface area in X by Y pixels. Only applied when the track type is video.</li> <li><code>>XxY</code>: Select all tracks of this type with a pixel surface area greater than X by Y pixels. Only applied when the track type is video.</li> <li><code><XxY</code>: Select all tracks of this type with a pixel surface area less than X by Y pixels. Only applied when the track type is video.</li> <li><code>720p</code>, <code>1080p</code>, <code>1440p</code>, <code>2k</code>, <code>4k</code>, <code>5k</code>, or <code>8k</code>: Select all tracks of this type with the given pixel surface area. Only applied when the track type is video.</li> <li><code>surround</code>, <code>mono</code>, <code>stereo</code>, <code>Xch</code>: Select all tracks of this type with the given channel count. The 'Xch' variant can use any positive integer for 'X'. Only applied when the track type is audio.</li></ul>"}return f} var c=[],e=["required","optional"];"desc"in a&&c.push({type:"help",help:a.desc});for(var l in e)if(a[e[l]]){c.push($("<h4>").text(UI.format.capital(e[l])+" parameters"));var i=Object.keys(a[e[l]]);"sort"in a&&i.sort(function(b,c){return(""+a[e[l]][b][a.sort]).localeCompare(a[e[l]][c][a.sort])});for(var f in i){var m=i[f],n=a[e[l]][m];if(Array.isArray(n))for(var j in n)c.push(d(l,m,n[j]));else c.push(d(l,m,n))}}return c},stored:{get:function(){return mist.data.ui_settings||{}},set:function(a,b){var d= this.get();d[a]=b;mist.send(function(){},{ui_settings:d})},del:function(a){delete mist.data.ui_settings[a];mist.send(function(){},{ui_settings:mist.data.ui_settings})}}};function log(){try{UI.debug&&[].push.call(arguments,Error().stack);[].unshift.call(arguments,"["+UI.format.time((new Date).getTime()/1E3)+"]");console.log.apply(console,arguments)}catch(a){}} diff --git a/lsp/mist.js b/lsp/mist.js index 38312e80..02e256a0 100644 --- a/lsp/mist.js +++ b/lsp/mist.js @@ -619,6 +619,9 @@ var UI = { var $ic = $(this).closest('.input_container'); + //ensure any grouped options (with non-default settings) are expanded + $ic.find(".itemgroup:has(.summary:not(:empty))").addClass("expanded"); + //skip any hidden fields //validate @@ -5795,7 +5798,8 @@ var UI = { var $autopush = $("<div>"); var push_parameters, full_list_of_push_parameters; if (other == "auto") { - $autopush.css("margin","1em 0").html(UI.buildUI([{ + $autopush.css("margin","1em 0").html(UI.buildUI([ + $("<h3>").text("Automatic push options"),{ label: "This push should be active", help: "When 'based on server time' is selected, a start and/or end timestamp can be configured. When it's 'based on a variable', the push will be activated while the specified variable matches the specified value.", type: "select", @@ -6042,37 +6046,39 @@ var UI = { } } } - if (!match) { - $additional_params.html( - $("<h4>").addClass("red").text("Unrecognized target.") - ).append( - $("<span>").text("Please edit the push target.") - ); - return; - } - if (!("friendly" in mist.data.capabilities.connectors[match])) { mist.data.capabilities.connectors[match].friendly = mist.data.capabilities.connectors[match].name; } + if ($(this).data("last_match") == match) { return; } + $(this).data("last_match",match); + if (!match) { + $additional_params.html( + $("<h4>").addClass("red").text("Unrecognized target.") + ).append( + $("<span>").text("Please edit the push target.") + ); + return; + } + if (!("friendly" in mist.data.capabilities.connectors[match])) { mist.data.capabilities.connectors[match].friendly = mist.data.capabilities.connectors[match].name; } $additional_params.html($("<h3>").text(mist.data.capabilities.connectors[match].friendly.replace("over HTTP",""))); - push_parameters = $.extend({},mist.data.capabilities.connectors[match].push_parameters); - full_list_of_push_parameters = {}; - function processPushParam(param,key) { - //filter out protocol only or file only options. This does not need to be dynamic as when the target changes, the whole $additional_params container is overwritten anyway - if (param.prot_only && String().match && (val.match(/.+\:\/\/.+/) === null)) { - delete push_parameters[key]; - return; - } - if (param.file_only && (val[0] != "/")) { - delete push_parameters[key]; - return; - } - if (param.type == "group") { - for (var i in param.options) { - processPushParam(param.options[i],i); + push_parameters = $.extend({},mist.data.capabilities.connectors[match].push_parameters); + full_list_of_push_parameters = {}; + function processPushParam(param,key) { + //filter out protocol only or file only options. This does not need to be dynamic as when the target changes, the whole $additional_params container is overwritten anyway + if (param.prot_only && String().match && (val.match(/.+\:\/\/.+/) === null)) { + delete push_parameters[key]; + return; + } + if (param.file_only && (val[0] != "/")) { + delete push_parameters[key]; + return; + } + if (param.type == "group") { + for (var i in param.options) { + processPushParam(param.options[i],i); + } + } + else { + full_list_of_push_parameters[key] = param; } } - else { - full_list_of_push_parameters[key] = param; - } - } for (var i in mist.data.capabilities.connectors[match].push_parameters) { processPushParam(mist.data.capabilities.connectors[match].push_parameters[i],i); } @@ -6083,13 +6089,14 @@ var UI = { sort: "sort" }; var capaform = mist.convertBuildOptions(capa,saveas.params); + if (capaform[1].is("h4")) capaform.splice(1,1); //find left over url params that are not covered by this connector's capabilities var custom_params = []; for (var i in params) { var p = params[i].split("="); var name = p[0]; - if (!(name in push_parameters)) { + if (!(name in full_list_of_push_parameters)) { custom_params.push(name+(p.length > 1 ? "="+p.slice(1).join("=") : "")); } } @@ -6115,46 +6122,10 @@ var UI = { $additional_params.append(UI.buildUI(capaform)); } }, - $autopush, - $additional_params + $additional_params, + $autopush ]; - - - /* - if (other == "auto") { //options only for automatic pushes - - build.push($("<h4>").text("Optional parameters"),{ - type: "unix", - label: "Schedule time", - min: 0, - help: "The time where the push will become active. The default is to start immediately.", - pointer: { - main: saveas, - index: "scheduletime" - } - },{ - type: "unix", - label: "Recording start time", - min: 0, - help: "Where in the media buffer the recording will start. Defaults to the most recently received keyframe.<br>Only makes sense for live streams.", - pointer: { - main: saveas, - index: "recstartunix" - } - },{ - type: "unix", - label: "Complete time", - min: 0, - help: "The time where the push will stop. Defaults to never stop automatically.<br>Only makes sense for live streams.", - pointer: { - main: saveas, - index: "completetime" - } - }); - - }*/ - build.push({ type: 'buttons', buttons: [{ @@ -6192,7 +6163,7 @@ var UI = { delete params[i]; } else if (!(i in full_list_of_push_parameters)) { - //remove any params that are not supported by this protocol (they will have been duplicatec to saveas.custom_url_parameters if the user wanted to keep them) + //remove any params that are not supported by this protocol (they will have been duplicated to saveas.custom_url_parameters if the user wanted to keep them) delete params[i]; } } @@ -6214,28 +6185,14 @@ var UI = { params["recstartunix"] = saveas.scheduletime; } if (Object.keys(params).length || (saveas.custom_url_params && saveas.custom_url_params.length)) { - var append = "?"; - var curparams = saveas.target.split("?"); - if (curparams.length > 1) { - append = "&"; - curparams = curparams[curparams.length-1]; - curparams = curparams.split("&"); - for (var i in curparams) { - var key = curparams[i].split("=")[0]; - if (key in params) { delete params[key]; } - } + var str = []; + for (var i in params) { //the MistServer settings as entered in "Optional parameters" + str.push(i+"="+params[i]); } - if (Object.keys(params).length || (saveas.custom_url_params && saveas.custom_url_params.length)) { - var str = []; - for (var i in params) { - str.push(i+"="+params[i]); - } - for (var i in saveas.custom_url_params) { - str.push(saveas.custom_url_params[i]); - } - append += str.join("&"); - saveas.target += append; + for (var i in saveas.custom_url_params) { //the MistServer settings custom url parameters + str.push(saveas.custom_url_params[i]); } + saveas.target += "?"+str.join("&"); } delete saveas.params; //these are now part of the target url and we don't need them separately delete saveas.custom_url_params; @@ -10310,10 +10267,13 @@ var mist = { break; } case 'group': { + var $cont = $("<div>").addClass("itemgroup"); var children = mist.convertBuildOptions({ optional: ele.options },saveas); children = children.slice(1); //remove h4 "Optional parameters" + var $summary = $("<ul>").addClass("summary"); + children.unshift($summary); if ("help" in ele) { children.unshift( $("<span>").addClass("description").text(ele.help) @@ -10321,10 +10281,51 @@ var mist = { } if ("name" in ele) { children.unshift( - $("<b>").text(ele.name) + $("<b>").text(ele.name).click(function(){ + $cont.toggleClass("expanded") + }).attr("title","Click to show / hide these options") ); } - return $("<div>").addClass("itemsettings").append(UI.buildUI(children)); + if (ele.expand || (!(ele.expand === false) && Object.keys(ele.options).length < 2)) { + //do not collapse fields on creation if expand: true is passed + //always collapse fields if expand: false is passed + //otherwise, collapse if group contains 2 fields or more + $cont.addClass("expanded"); + } + return $cont.change(function(){ + $summary.html(""); + $(this).find(".isSetting, input[type=\"hidden\"].isSetting").each(function(){ + var val = $(this).getval(); + if (val == "") { return; } + var opts = $(this).data('opts'); + if (val != opts['default']) { + var label = opts["label"]+": "; + switch (opts.type) { + case "select": { + val = opts.select.filter(function(v){ if (v[0] == val) return true; return false; })[0][1]; break; + } + case "unix": { + val = UI.format.dateTime(val); break; + } + case "checkbox": { + val = ""; + label = label.slice(0,-2); + break; + } + } + $summary.append( + $("<li>").addClass("setting").append( + $("<span>").addClass("label").text(label) + ).append( + $("<span>").text(val) + ).append( + $("<span>").addClass("unit").text(typeof opts.unit == "string" ? opts["unit"] : "") + ) + ); + } + }); + }).append(UI.buildUI(children)).trigger("change"); + } case 'bool': { diff --git a/src/output/output_tssrt.cpp b/src/output/output_tssrt.cpp index d2abed7f..5f03bf9b 100644 --- a/src/output/output_tssrt.cpp +++ b/src/output/output_tssrt.cpp @@ -182,11 +182,14 @@ namespace Mist{ seek(seekPos); } - static void addIntOpt(JSON::Value & pp, const std::string & param, const std::string & name, const std::string & help, size_t def = 0){ + static void addIntOpt(JSON::Value & pp, const std::string & param, const std::string & name, const std::string & help, size_t def = 0,const std::string unit = ""){ pp[param]["name"] = name; pp[param]["help"] = help; pp[param]["type"] = "int"; pp[param]["default"] = (uint64_t)def; + if (unit != "") { + pp[param]["unit"] = unit; + } } static void addStrOpt(JSON::Value & pp, const std::string & param, const std::string & name, const std::string & help, const std::string & def = ""){ @@ -200,16 +203,16 @@ namespace Mist{ pp[param]["name"] = name; pp[param]["help"] = help; pp[param]["type"] = "select"; - pp[param]["select"][0u][0u] = 0; - pp[param]["select"][0u][1u] = "False"; - pp[param]["select"][1u][0u] = 1; - pp[param]["select"][1u][1u] = "True"; + pp[param]["select"][0u][0u] = ""; + pp[param]["select"][0u][1u] = def?"Default (true)":"Default (false)"; + pp[param]["select"][1u][0u] = 0; + pp[param]["select"][1u][1u] = "False"; + pp[param]["select"][2u][0u] = 1; + pp[param]["select"][2u][1u] = "True"; pp[param]["type"] = "select"; - pp[param]["default"] = def?1:0; } - void OutTSSRT::init(Util::Config *cfg){ Output::init(cfg); capa["name"] = "TSSRT"; @@ -266,61 +269,104 @@ namespace Mist{ config->addStandardPushCapabilities(capa); JSON::Value & pp = capa["push_parameters"]; - pp["mode"]["name"] = "Mode"; - pp["mode"]["help"] = "The connection mode. Can be listener, caller, or rendezvous. By default is listener if the host is missing from the URL, and is caller otherwise."; - pp["mode"]["type"] = "select"; - pp["mode"]["select"][0u][0u] = "default"; - pp["mode"]["select"][0u][1u] = "Default"; - pp["mode"]["select"][1u][0u] = "listener"; - pp["mode"]["select"][1u][1u] = "Listener"; - pp["mode"]["select"][2u][0u] = "caller"; - pp["mode"]["select"][2u][1u] = "Caller"; - pp["mode"]["select"][3u][0u] = "rendezvous"; - pp["mode"]["select"][3u][1u] = "Rendezvous"; - pp["mode"]["type"] = "select"; + pp["srtopts_main"]["name"] = "Commonly used SRT options"; + pp["srtopts_main"]["help"] = "Control the SRT connection"; + pp["srtopts_main"]["type"] = "group"; + pp["srtopts_main"]["sort"] = "aaa"; + pp["srtopts_main"]["expand"] = true; - pp["transtype"]["name"] = "Transmission type"; - pp["transtype"]["help"] = "This should be set to live (the default) unless you know what you're doing."; - pp["transtype"]["type"] = "select"; - pp["transtype"]["select"][0u][0u] = ""; - pp["transtype"]["select"][0u][1u] = "Live"; - pp["transtype"]["select"][1u][0u] = "file"; - pp["transtype"]["select"][1u][1u] = "File"; - pp["transtype"]["type"] = "select"; + addIntOpt(pp["srtopts_main"]["options"], "latency", "Latency", "Socket latency, in milliseconds.", 120,"ms"); + addStrOpt(pp["srtopts_main"]["options"], "streamid", "Stream ID", "Stream ID to transmit to the other side. MistServer uses this field for the stream name, but the field is entirely free-form and may contain anything."); + addStrOpt(pp["srtopts_main"]["options"], "passphrase", "Encryption passphrase", "Enables encryption with the given passphrase."); + + + pp["srtopts"]["name"] = "More SRT options"; + pp["srtopts"]["help"] = "Control the SRT connection"; + pp["srtopts"]["type"] = "group"; + pp["srtopts"]["sort"] = "ab"; + + pp["srtopts"]["options"]["mode"]["name"] = "Mode"; + pp["srtopts"]["options"]["mode"]["help"] = "The connection mode. Can be listener, caller, or rendezvous. By default is listener if the host is missing from the URL, and is caller otherwise."; + pp["srtopts"]["options"]["mode"]["type"] = "select"; + pp["srtopts"]["options"]["mode"]["select"][0u][0u] = ""; + pp["srtopts"]["options"]["mode"]["select"][0u][1u] = "Default (listener)"; + pp["srtopts"]["options"]["mode"]["select"][1u][0u] = "listener"; + pp["srtopts"]["options"]["mode"]["select"][1u][1u] = "Listener"; + pp["srtopts"]["options"]["mode"]["select"][2u][0u] = "caller"; + pp["srtopts"]["options"]["mode"]["select"][2u][1u] = "Caller"; + pp["srtopts"]["options"]["mode"]["select"][3u][0u] = "rendezvous"; + pp["srtopts"]["options"]["mode"]["select"][3u][1u] = "Rendezvous"; + + pp["srtopts"]["options"]["transtype"]["name"] = "Transmission type"; + pp["srtopts"]["options"]["transtype"]["help"] = "This should be set to live (the default) unless you know what you're doing."; + pp["srtopts"]["options"]["transtype"]["select"][0u][0u] = ""; + pp["srtopts"]["options"]["transtype"]["select"][0u][1u] = "Default (live)"; + pp["srtopts"]["options"]["transtype"]["select"][1u][0u] = "live"; + pp["srtopts"]["options"]["transtype"]["select"][1u][1u] = "Live"; + pp["srtopts"]["options"]["transtype"]["select"][2u][0u] = "file"; + pp["srtopts"]["options"]["transtype"]["select"][2u][1u] = "File"; + pp["srtopts"]["options"]["transtype"]["type"] = "select"; + //addStrOpt(pp, "adapter", "", ""); //addIntOpt(pp, "timeout", "", ""); //addIntOpt(pp, "port", "", ""); - addBoolOpt(pp, "tsbpd", "Timestamp-based Packet Delivery mode", "In this mode the packet's time is assigned at the sending time (or allowed to be predefined), transmitted in the packet's header, and then restored on the receiver side so that the time intervals between consecutive packets are preserved when delivering to the application.", true); - addBoolOpt(pp, "linger", "Linger closed sockets", "Whether to keep closed sockets around for 180 seconds of linger time or not.", true); - addIntOpt(pp, "maxbw", "Maximum send bandwidth", "Maximum send bandwidth in bytes per second, -1 for infinite, 0 for relative to input bandwidth.", -1); - addIntOpt(pp, "pbkeylen", "Encryption key length", "May be 0 (auto), 16 (AES-128), 24 (AES-192) or 32 (AES-256).", 0); - addStrOpt(pp, "passphrase", "Encryption passphrase", "Enables encryption with the given passphrase."); - addIntOpt(pp, "mss", "Maximum Segment Size", "Maximum size for packets including all headers, in bytes. The default of 1500 is generally the maximum value you can use in most networks.", 1500); - addIntOpt(pp, "fc", "Flight Flag Size", "Maximum packets that may be 'in flight' without being acknowledged.", 25600); - addIntOpt(pp, "sndbuf", "Send Buffer Size", "Size of the send buffer, in bytes"); - addIntOpt(pp, "rcvbuf", "Receive Buffer Size", "Size of the receive buffer, in bytes"); - addIntOpt(pp, "ipttl", "TTL", "Time To Live for IPv4 connections or unicast hops for IPv6 connections. Defaults to system default."); - addIntOpt(pp, "iptos", "Type of Service", "TOS for IPv4 connections or Traffic Class for IPv6 connections. Defaults to system default."); - addIntOpt(pp, "inputbw", "Input bandwidth", "Estimated bandwidth of data to be sent. Default of 0 means automatic."); - addIntOpt(pp, "oheadbw", "Recovery Bandwidth Overhead", "Percentage of bandwidth to use for recovery.", 25); - addIntOpt(pp, "latency", "Latency", "Socket latency, in milliseconds.", 120); + + addBoolOpt(pp["srtopts"]["options"], "tsbpd", "Timestamp-based Packet Delivery mode", "In this mode the packet's time is assigned at the sending time (or allowed to be predefined), transmitted in the packet's header, and then restored on the receiver side so that the time intervals between consecutive packets are preserved when delivering to the application.", true); + + addBoolOpt(pp["srtopts"]["options"], "linger", "Linger closed sockets", "Whether to keep closed sockets around for 180 seconds of linger time or not.", true); + addIntOpt(pp["srtopts"]["options"], "maxbw", "Maximum send bandwidth", "Maximum send bandwidth in bytes per second, -1 for infinite, 0 for relative to input bandwidth.", -1,"bytes/s"); + + + pp["srtopts"]["options"]["pbkeylen"]["name"] = "Encryption key length"; + pp["srtopts"]["options"]["pbkeylen"]["help"] = "The encryption key length. Default: auto."; + pp["srtopts"]["options"]["pbkeylen"]["select"][0u][0u] = ""; + pp["srtopts"]["options"]["pbkeylen"]["select"][0u][1u] = "Default (auto)"; + pp["srtopts"]["options"]["pbkeylen"]["select"][1u][0u] = "0"; + pp["srtopts"]["options"]["pbkeylen"]["select"][1u][1u] = "Auto"; + pp["srtopts"]["options"]["pbkeylen"]["select"][2u][0u] = "16"; + pp["srtopts"]["options"]["pbkeylen"]["select"][2u][1u] = "AES-128"; + pp["srtopts"]["options"]["pbkeylen"]["select"][3u][0u] = "24"; + pp["srtopts"]["options"]["pbkeylen"]["select"][3u][1u] = "AES-192"; + pp["srtopts"]["options"]["pbkeylen"]["select"][4u][0u] = "32"; + pp["srtopts"]["options"]["pbkeylen"]["select"][4u][1u] = "AES-256"; + pp["srtopts"]["options"]["pbkeylen"]["default"] = "0"; + pp["srtopts"]["options"]["pbkeylen"]["type"] = "select"; + + + + addIntOpt(pp["srtopts"]["options"], "mss", "Maximum Segment Size", "Maximum size for packets including all headers, in bytes. The default of 1500 is generally the maximum value you can use in most networks.", 1500,"bytes"); + addIntOpt(pp["srtopts"]["options"], "fc", "Flight Flag Size", "Maximum packets that may be 'in flight' without being acknowledged.", 25600,"packets"); + addIntOpt(pp["srtopts"]["options"], "sndbuf", "Send Buffer Size", "Size of the send buffer, in bytes",0,"bytes"); + addIntOpt(pp["srtopts"]["options"], "rcvbuf", "Receive Buffer Size", "Size of the receive buffer, in bytes",0,"bytes"); + addIntOpt(pp["srtopts"]["options"], "ipttl", "TTL", "Time To Live for IPv4 connections or unicast hops for IPv6 connections. Defaults to system default.",0,"hops"); + addIntOpt(pp["srtopts"]["options"], "iptos", "Type of Service", "TOS for IPv4 connections or Traffic Class for IPv6 connections. Defaults to system default."); + addIntOpt(pp["srtopts"]["options"], "inputbw", "Input bandwidth", "Estimated bandwidth of data to be sent. Default of 0 means automatic.",0,"bytes/s"); + addIntOpt(pp["srtopts"]["options"], "oheadbw", "Recovery Bandwidth Overhead", "Percentage of bandwidth to use for recovery.",25,"%"); //addIntOpt(pp, "rcvlatency", "Receive Latency", "Latency in receive mode, in milliseconds", 120); //addIntOpt(pp, "peerlatency", "", ""); - addBoolOpt(pp, "tlpktdrop", "Too-late Packet Drop", "Skips packets that cannot (sending) or have not (receiving) been delivered in time", true); - addIntOpt(pp, "snddropdelay", "Send Drop Delay", "Extra delay before Too-late packet drop on sender side is triggered, in milliseconds."); - addBoolOpt(pp, "nakreport", "Repeat loss reports", "When enabled, repeats loss reports every time the retransmission timeout has expired.", true); - addIntOpt(pp, "conntimeo", "Connect timeout", "Milliseconds to wait before timing out a connection attempt for caller and rendezvous modes.", 3000); - addIntOpt(pp, "lossmaxttl", "Reorder Tolerance", "Maximum amount of packets that may be out of order, or 0 to disable this mechanism."); - addIntOpt(pp, "minversion", "Minimum SRT version", "Minimum SRT version to require the other side of the connection to support."); - addStrOpt(pp, "streamid", "Stream ID", "Stream ID to transmit to the other side. MistServer uses this field for the stream name, but the field is entirely free-form and may contain anything."); - addStrOpt(pp, "congestion", "Congestion controller", "May be set to 'live' or 'file'", "live"); - addBoolOpt(pp, "messageapi", "Message API", "When true, uses the default Message API. When false, uses the Stream API", true); + addBoolOpt(pp["srtopts"]["options"], "tlpktdrop", "Too-late Packet Drop", "Skips packets that cannot (sending) or have not (receiving) been delivered in time", true); + addIntOpt(pp["srtopts"]["options"], "snddropdelay", "Send Drop Delay", "Extra delay before Too-late packet drop on sender side is triggered, in milliseconds.",0,"ms"); + addBoolOpt(pp["srtopts"]["options"], "nakreport", "Repeat loss reports", "When enabled, repeats loss reports every time the retransmission timeout has expired.", true); + addIntOpt(pp["srtopts"]["options"], "conntimeo", "Connect timeout", "Milliseconds to wait before timing out a connection attempt for caller and rendezvous modes.", 3000,"ms"); + addIntOpt(pp["srtopts"]["options"], "lossmaxttl", "Reorder Tolerance", "Maximum amount of packets that may be out of order, or 0 to disable this mechanism.",0,"packets"); + addIntOpt(pp["srtopts"]["options"], "minversion", "Minimum SRT version", "Minimum SRT version to require the other side of the connection to support."); + + addStrOpt(pp["srtopts"]["options"], "congestion", "Congestion controller", "May be set to 'live' or 'file'", "live"); + pp["srtopts"]["options"]["congestion"]["select"][0u][0u] = ""; + pp["srtopts"]["options"]["congestion"]["select"][0u][1u] = "Default (live)"; + pp["srtopts"]["options"]["congestion"]["select"][1u][0u] = "live"; + pp["srtopts"]["options"]["congestion"]["select"][1u][1u] = "Live"; + pp["srtopts"]["options"]["congestion"]["select"][2u][0u] = "file"; + pp["srtopts"]["options"]["congestion"]["select"][2u][1u] = "File"; + pp["srtopts"]["options"]["congestion"]["type"] = "select"; + + addBoolOpt(pp["srtopts"]["options"], "messageapi", "Message API", "When true, uses the default Message API. When false, uses the Stream API", true); //addIntOpt(pp, "kmrefreshrate", "", ""); //addIntOpt(pp, "kmreannounce", "", ""); - addBoolOpt(pp, "enforcedencryption", "Enforced Encryption", "If enabled, enforces that both sides either set no passphrase, or set the same passphrase. When disabled, falls back to no passphrase if the passphrases do not match.", true); - addIntOpt(pp, "peeridletimeo", "Peer Idle Timeout", "Time to wait, in milliseconds, before the connection is considered broken if the peer does not respond.", 5000); - addStrOpt(pp, "packetfilter", "Packet Filter", "Sets the SRT packet filter string, see SRT library documentation for details."); + addBoolOpt(pp["srtopts"]["options"], "enforcedencryption", "Enforced Encryption", "If enabled, enforces that both sides either set no passphrase, or set the same passphrase. When disabled, falls back to no passphrase if the passphrases do not match.", true); + addIntOpt(pp["srtopts"]["options"], "peeridletimeo", "Peer Idle Timeout", "Time to wait, in milliseconds, before the connection is considered broken if the peer does not respond.", 5000,"ms"); + addStrOpt(pp["srtopts"]["options"], "packetfilter", "Packet Filter", "Sets the SRT packet filter string, see SRT library documentation for details."); JSON::Value opt; opt["arg"] = "string";