- fixes as a result of documentation, fixed secondaryVideo
- added muted option, changing tracks sets options.setTracks
- no positive values for startunix when live seeking
- dashjs tracks updated, videojs display tweaked
- fixes for track selection and live seeking
This commit is contained in:
Cat 2018-12-20 16:48:39 +01:00 committed by Thulinma
parent 0a1b00cb5e
commit 998d7c6d03
22 changed files with 283 additions and 119 deletions

File diff suppressed because one or more lines are too long

View file

@ -1,7 +1,7 @@
.mistvideo{display:inline-block;position:relative;color:$stroke;font-family:sans-serif;background-color:#000;justify-content:center;align-items:center} .mistvideo{display:inline-block;position:relative;color:$stroke;font-family:sans-serif;background-color:#000;justify-content:center;align-items:center}
.mistvideo-controls{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none} .mistvideo-controls{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
.mistvideo.novideo{overflow:visible} .mistvideo.novideo{overflow:visible}
.mistvideo-video{overflow:hidden} .mistvideo-video{overflow:hidden;outline:0}
svg.icon.loading{z-index:-1;position:absolute;top:0;left:0;right:0;bottom:0;margin:auto;opacity:0} svg.icon.loading{z-index:-1;position:absolute;top:0;left:0;right:0;bottom:0;margin:auto;opacity:0}
[data-loading]{position:relative} [data-loading]{position:relative}
[data-loading=stalled] svg.icon.loading{transition:opacity 0s 3s} [data-loading=stalled] svg.icon.loading{transition:opacity 0s 3s}
@ -61,6 +61,7 @@ svg.icon .semiFill,svg.icon.semiFill{fill:$semiFill}
svg.icon .stroke,svg.icon.stroke{stroke:$stroke;vector-effect:non-scaling-stroke} svg.icon .stroke,svg.icon.stroke{stroke:$stroke;vector-effect:non-scaling-stroke}
svg.icon.off .toggle .fill,svg.icon.off .toggle .semiFill,svg.icon.off .toggle.fill,svg.icon.off .toggle.semiFill{fill:none} svg.icon.off .toggle .fill,svg.icon.off .toggle .semiFill,svg.icon.off .toggle.fill,svg.icon.off .toggle.semiFill{fill:none}
svg.icon .spin,svg.icon.spin{animation:spin 1.5s infinite linear;transform-origin:50% 50%} svg.icon .spin,svg.icon.spin{animation:spin 1.5s infinite linear;transform-origin:50% 50%}
.vjs-text-track-display{pointer-events:none}
.mistvideo{line-height:1.2;font-size:14.5px} .mistvideo{line-height:1.2;font-size:14.5px}
.mistvideo svg{margin:2.5px} .mistvideo svg{margin:2.5px}
.mistvideo-background{background-color:$background} .mistvideo-background{background-color:$background}
@ -79,7 +80,7 @@ svg.icon.timeout{display:inline-block;height:1em;width:1em;margin:0;margin-right
.mist.largeplay,.mist.muted{position:absolute;opacity:.5} .mist.largeplay,.mist.muted{position:absolute;opacity:.5}
.mist.largeplay{top:50%;left:0;right:0;margin:auto;transform:translateY(-50%)} .mist.largeplay{top:50%;left:0;right:0;margin:auto;transform:translateY(-50%)}
.mist.muted{top:0;right:0;margin:1em} .mist.muted{top:0;right:0;margin:1em}
.mistvideo-secondaryVideo{z-index:1;width:50%;height:50%} .mistvideo-secondaryVideo{z-index:1;position:absolute;right:0;top:0;width:50%;height:50%;max-width:fit-content;max-height:fit-content}
.mistvideo-polling{display:inline-block;position:relative;width:25px;height:25px} .mistvideo-polling{display:inline-block;position:relative;width:25px;height:25px}
.mistvideo-polling svg.icon.loading{z-index:0;opacity:1} .mistvideo-polling svg.icon.loading{z-index:0;opacity:1}
.mistvideo[data-show-submenu] .mistvideo-submenu{right:5px} .mistvideo[data-show-submenu] .mistvideo-submenu{right:5px}

View file

@ -1,7 +1,7 @@
.mistvideo{display:inline-block;position:relative;color:$stroke;font-family:sans-serif;background-color:#000;justify-content:center;align-items:center} .mistvideo{display:inline-block;position:relative;color:$stroke;font-family:sans-serif;background-color:#000;justify-content:center;align-items:center}
.mistvideo-controls{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none} .mistvideo-controls{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
.mistvideo.novideo{overflow:visible} .mistvideo.novideo{overflow:visible}
.mistvideo-video{overflow:hidden} .mistvideo-video{overflow:hidden;outline:0}
svg.icon.loading{z-index:-1;position:absolute;top:0;left:0;right:0;bottom:0;margin:auto;opacity:0} svg.icon.loading{z-index:-1;position:absolute;top:0;left:0;right:0;bottom:0;margin:auto;opacity:0}
[data-loading]{position:relative} [data-loading]{position:relative}
[data-loading=stalled] svg.icon.loading{transition:opacity 0s 3s} [data-loading=stalled] svg.icon.loading{transition:opacity 0s 3s}
@ -61,6 +61,7 @@ svg.icon .semiFill,svg.icon.semiFill{fill:$semiFill}
svg.icon .stroke,svg.icon.stroke{stroke:$stroke;vector-effect:non-scaling-stroke} svg.icon .stroke,svg.icon.stroke{stroke:$stroke;vector-effect:non-scaling-stroke}
svg.icon.off .toggle .fill,svg.icon.off .toggle .semiFill,svg.icon.off .toggle.fill,svg.icon.off .toggle.semiFill{fill:none} svg.icon.off .toggle .fill,svg.icon.off .toggle .semiFill,svg.icon.off .toggle.fill,svg.icon.off .toggle.semiFill{fill:none}
svg.icon .spin,svg.icon.spin{animation:spin 1.5s infinite linear;transform-origin:50% 50%} svg.icon .spin,svg.icon.spin{animation:spin 1.5s infinite linear;transform-origin:50% 50%}
.vjs-text-track-display{pointer-events:none}
.mistvideo{line-height:1.2;font-size:14.5px} .mistvideo{line-height:1.2;font-size:14.5px}
.mistvideo svg{margin:2.5px} .mistvideo svg{margin:2.5px}
.mistvideo-background{background-color:$background} .mistvideo-background{background-color:$background}
@ -79,7 +80,7 @@ svg.icon.timeout{display:inline-block;height:1em;width:1em;margin:0;margin-right
.mist.largeplay,.mist.muted{position:absolute;opacity:.5} .mist.largeplay,.mist.muted{position:absolute;opacity:.5}
.mist.largeplay{top:50%;left:0;right:0;margin:auto;transform:translateY(-50%)} .mist.largeplay{top:50%;left:0;right:0;margin:auto;transform:translateY(-50%)}
.mist.muted{top:0;right:0;margin:1em} .mist.muted{top:0;right:0;margin:1em}
.mistvideo-secondaryVideo{z-index:1;width:50%;height:50%} .mistvideo-secondaryVideo{z-index:1;position:absolute;right:0;top:0;width:50%;height:50%;max-width:fit-content;max-height:fit-content}
.mistvideo-polling{display:inline-block;position:relative;width:25px;height:25px} .mistvideo-polling{display:inline-block;position:relative;width:25px;height:25px}
.mistvideo-polling svg.icon.loading{z-index:0;opacity:1} .mistvideo-polling svg.icon.loading{z-index:0;opacity:1}
.mistvideo[data-show-submenu] .mistvideo-submenu{right:5px} .mistvideo[data-show-submenu] .mistvideo-submenu{right:5px}

View file

@ -1 +1 @@
mistplayers.dashjs={name:"Dash.js player",mimes:["dash/video/mp4"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(t){return MistUtil.array.indexOf(this.mimes,t)==-1?false:true},isBrowserSupported:function(t,e,i){if(location.protocol!=MistUtil.http.url.split(e.url).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}if(location.protocol=="file:"){i.log("This source ("+t+") won't load if the page is run via file://");return false}return"MediaSource"in window},player:function(){this.onreadylist=[]},scriptsrc:function(t){return t+"/dashjs.js"}};var p=mistplayers.dashjs.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var i=this;this.onDashLoad=function(){if(t.destroyed){return}t.log("Building DashJS player..");var r=document.createElement("video");if("Proxy"in window){var a={get:{},set:{}};t.player.api=new Proxy(r,{get:function(t,e,i){if(e in a.get){return a.get[e].apply(t,arguments)}var r=t[e];if(typeof r==="function"){return function(){return r.apply(t,arguments)}}return r},set:function(t,e,i){if(e in a.set){return a.set[e].call(t,i)}return t[e]=i}});if(t.info.type=="live"){a.get.duration=function(){var e=0;if(this.buffered.length){e=this.buffered.end(this.buffered.length-1)}var i=((new Date).getTime()-t.player.api.lastProgress.getTime())*.001;return e+i+-1*t.player.api.liveOffset+45};a.set.currentTime=function(e){var i=e-t.player.api.duration;t.log("Seeking to "+MistUtil.format.time(e)+" ("+Math.round(i*-10)/10+"s from live)");t.video.currentTime=e};MistUtil.event.addListener(r,"progress",function(){t.player.api.lastProgress=new Date});t.player.api.lastProgress=new Date;t.player.api.liveOffset=0}}else{i.api=r}if(t.options.autoplay){r.setAttribute("autoplay","")}if(t.options.loop&&t.info.type!="live"){r.setAttribute("loop","")}if(t.options.poster){r.setAttribute("poster",t.options.poster)}if(t.options.controls=="stock"){r.setAttribute("controls","")}var s=dashjs.MediaPlayer().create();s.initialize(r,t.source.url,t.options.autoplay);i.dash=s;var o=["METRIC_ADDED","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(e){t.log("Player event fired: "+e.type)})}}t.player.setSize=function(t){this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};t.player.api.setSource=function(e){t.player.dash.attachSource(e)};t.player.api.setTrack=function(e,r){var a=MistUtil.tracks.parse(t.info.meta.tracks);if(!(e in a)||!(r in a[e])&&r!=0){t.log("Skipping trackselection of "+e+" track "+r+" because it does not exist");return}var s=i.dash.getBitrateInfoListFor("video").length-1;for(var o in t.info.meta.tracks){var n=t.info.meta.tracks[o];if(n.type==e){if(n.trackid==r){break}s--}}i.dash.setAutoSwitchQualityFor(e,false);i.dash.setFastSwitchEnabled(true);i.dash.setQualityFor(e,s)};i.dash.on("qualityChangeRendered",function(e){var r=i.dash.getBitrateInfoListFor("video").length-1;var a;for(var s in t.info.meta.tracks){var o=t.info.meta.tracks[s];if(o.type==e.mediaType){if(e.newQuality==r){a=o.trackid;break}r--}}MistUtil.event.send("playerUpdate_trackChanged",{type:e.mediaType,trackid:a},t.video)});MistUtil.event.addListener(r,"progress",function(e){if(t.container.getAttribute("data-loading")=="stalled"){t.container.removeAttribute("data-loading")}});i.api.unload=function(){i.dash.reset()};t.log("Built html");e(r)};if("dashjs"in window){this.onDashLoad()}else{var r=MistUtil.scripts.insert(t.urlappend(mistplayers.dashjs.scriptsrc(t.options.host)),{onerror:function(e){var i="Failed to load dashjs.js";if(e.message){i+=": "+e.message}t.showError(i)},onload:i.onDashLoad},t)}}; mistplayers.dashjs={name:"Dash.js player",mimes:["dash/video/mp4"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(t){return MistUtil.array.indexOf(this.mimes,t)==-1?false:true},isBrowserSupported:function(t,e,i){if(location.protocol!=MistUtil.http.url.split(e.url).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}if(location.protocol=="file:"){i.log("This source ("+t+") won't load if the page is run via file://");return false}return"MediaSource"in window},player:function(){this.onreadylist=[]},scriptsrc:function(t){return t+"/dashjs.js"}};var p=mistplayers.dashjs.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var i=this;this.onDashLoad=function(){if(t.destroyed){return}t.log("Building DashJS player..");var r=document.createElement("video");if("Proxy"in window){var a={get:{},set:{}};t.player.api=new Proxy(r,{get:function(t,e,i){if(e in a.get){return a.get[e].apply(t,arguments)}var r=t[e];if(typeof r==="function"){return function(){return r.apply(t,arguments)}}return r},set:function(t,e,i){if(e in a.set){return a.set[e].call(t,i)}return t[e]=i}});if(t.info.type=="live"){a.get.duration=function(){var e=0;if(this.buffered.length){e=this.buffered.end(this.buffered.length-1)}var i=((new Date).getTime()-t.player.api.lastProgress.getTime())*.001;return e+i+-1*t.player.api.liveOffset+45};a.set.currentTime=function(e){var i=e-t.player.api.duration;t.log("Seeking to "+MistUtil.format.time(e)+" ("+Math.round(i*-10)/10+"s from live)");t.video.currentTime=e};MistUtil.event.addListener(r,"progress",function(){t.player.api.lastProgress=new Date});t.player.api.lastProgress=new Date;t.player.api.liveOffset=0}}else{i.api=r}if(t.options.autoplay){r.setAttribute("autoplay","")}if(t.options.loop&&t.info.type!="live"){r.setAttribute("loop","")}if(t.options.poster){r.setAttribute("poster",t.options.poster)}if(t.options.muted){r.muted=true}if(t.options.controls=="stock"){r.setAttribute("controls","")}var s=dashjs.MediaPlayer().create();s.initialize(r,t.source.url,t.options.autoplay);i.dash=s;var n=["METRIC_ADDED","METRIC_CHANGED","METRICS_CHANGED","FRAGMENT_LOADING_STARTED","FRAGMENT_LOADING_COMPLETED","LOG","PLAYBACK_TIME_UPDATED","PLAYBACK_PROGRESS"];for(var o in dashjs.MediaPlayer.events){if(n.indexOf(o)<0){i.dash.on(dashjs.MediaPlayer.events[o],function(e){t.log("Player event fired: "+e.type)})}}t.player.setSize=function(t){this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};t.player.api.setSource=function(e){t.player.dash.attachSource(e)};t.player.api.setTrack=function(e,r){var a=MistUtil.tracks.parse(t.info.meta.tracks);if(!(e in a)||!(r in a[e])&&r!=0){t.log("Skipping trackselection of "+e+" track "+r+" because it does not exist");return}var s=[];for(var n in t.info.meta.tracks){var o=t.info.meta.tracks[n];if(o.type==e){s.push(o)}}MistUtil.array.multiSort(s,["bps"]);var l=false;for(var n in s){if(s[n].trackid==r){l=n;break}}if(l===false){return false}i.dash.setAutoSwitchQualityFor(e,false);i.dash.setFastSwitchEnabled(true);i.dash.setQualityFor(e,l);return true};i.dash.on("qualityChangeRendered",function(e){var i=[];for(var r in t.info.meta.tracks){var a=t.info.meta.tracks[r];if(a.type==e.mediaType){i.push(a)}}MistUtil.array.multiSort(i,["bps"]);var s=i[e.newQuality].trackid;MistUtil.event.send("playerUpdate_trackChanged",{type:e.mediaType,trackid:s},t.video)});var l=false;i.dash.on("allTextTracksAdded",function(){l=true});t.player.api.setSubtitle=function(e){if(!l){var r=function(){t.player.api.setSubtitle(e);i.dash.off("allTextTracksAdded",r)};i.dash.on("allTextTracksAdded",r);return}if(!e){i.dash.enableText(false);return}var a=i.dash.getTracksFor("text");for(var s in a){if(a[s].id==e.trackid){i.dash.setTextTrack(s);if(!i.dash.isTextEnabled()){i.dash.enableText()}return true}}return false};MistUtil.event.addListener(r,"progress",function(e){if(t.container.getAttribute("data-loading")=="stalled"){t.container.removeAttribute("data-loading")}});i.api.unload=function(){i.dash.reset()};t.log("Built html");e(r)};if("dashjs"in window){this.onDashLoad()}else{var r=MistUtil.scripts.insert(t.urlappend(mistplayers.dashjs.scriptsrc(t.options.host)),{onerror:function(e){var i="Failed to load dashjs.js";if(e.message){i+=": "+e.message}t.showError(i)},onload:i.onDashLoad},t)}};

View file

@ -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 s="src="+encodeURIComponent(e)+"&controlBarMode="+(a.controls?"floating":"none")+"&initialBufferTime=0.5&expandedBufferTime=5&minContinuousPlaybackTime=3"+(a.live?"&streamType=live":"")+(a.autoplay?"&autoPlay=true":"");i.appendChild(l("flashvars",s));i.appendChild(l("allowFullScreen","true"));i.appendChild(l("wmode","direct"));if(a.autoplay){i.appendChild(l("autoPlay","true"))}r.setAttribute("src",t.urlappend(t.source.player_url));r.setAttribute("type","application/x-shockwave-flash");r.setAttribute("allowfullscreen","true");r.setAttribute("flashvars",s)}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)}; 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)};

View file

@ -1 +1 @@
mistplayers.html5={name:"HTML5 video player",mimes:["html5/application/vnd.apple.mpegurl","html5/video/mp4","html5/video/ogg","html5/video/webm","html5/audio/mp3","html5/audio/webm","html5/audio/ogg","html5/audio/wav"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(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}}var r=false;var a=e.split("/");a.shift();try{a=a.join("/");function n(e){var t=document.createElement("video");if(t&&t.canPlayType(e)!=""){r=t.canPlayType(e)}return r}if(a=="video/mp4"){function o(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()}}var s={};for(var l in i.info.meta.tracks){if(i.info.meta.tracks[l].type!="meta"){s[o(i.info.meta.tracks[l])]=1}}s=MistUtil.object.keys(s);if(s.length){if(s.length>t.simul_tracks){var p=0;for(var l in s){var u=n(a+';codecs="'+s[l]+'"');if(u){p++}}return p>=t.simul_tracks}a+=';codecs="'+s.join(",")+'"'}}r=n(a)}catch(e){}return r},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");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.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;e.player.api.liveOffset=i;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(i*-10)/10+"s from live)");e.player.api.setSource(MistUtil.http.url.addParam(e.source.url,{startunix:i}))};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"){l.get.currentTime=function(){return this.currentTime-e.player.api.liveOffset+e.info.lastms*.001}}}else{if(!isFinite(r.duration)){var p=0;for(var o in e.info.meta.tracks){p=Math.max(p,e.info.meta.tracks[o].lastms)}l.get.duration=function(){if(isFinite(this.duration)){return this.duration}return p*.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)}; mistplayers.html5={name:"HTML5 video player",mimes:["html5/application/vnd.apple.mpegurl","html5/video/mp4","html5/video/ogg","html5/video/webm","html5/audio/mp3","html5/audio/webm","html5/audio/ogg","html5/audio/wav"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(t){return MistUtil.array.indexOf(this.mimes,t)==-1?false:true},isBrowserSupported:function(t,e,i){if(location.protocol!=MistUtil.http.url.split(e.url).protocol){if(location.protocol=="file:"&&MistUtil.http.url.split(e.url).protocol=="http:"){i.log("This page was loaded over file://, the player might not behave as intended.")}else{i.log("HTTP/HTTPS mismatch for this source");return false}}var r=false;var a=t.split("/");a.shift();try{a=a.join("/");function n(t){var e=document.createElement("video");if(e&&e.canPlayType(t)!=""){r=e.canPlayType(t)}return r}if(a=="video/mp4"){function o(t){function e(e){return("0"+t.init.charCodeAt(e).toString(16)).slice(-2)}switch(t.codec){case"AAC":return"mp4a.40.2";case"MP3":return"mp3";case"AC3":return"ec-3";case"H264":return"avc1."+e(1)+e(2)+e(3);case"HEVC":return"hev1."+e(1)+e(6)+e(7)+e(8)+e(9)+e(10)+e(11)+e(12);default:return t.codec.toLowerCase()}}var s={};for(var l in i.info.meta.tracks){if(i.info.meta.tracks[l].type!="meta"){s[o(i.info.meta.tracks[l])]=1}}s=MistUtil.object.keys(s);if(s.length){if(s.length>e.simul_tracks){var p=0;for(var l in s){var u=n(a+';codecs="'+s[l]+'"');if(u){p++}}return p>=e.simul_tracks}a+=';codecs="'+s.join(",")+'"'}}r=n(a)}catch(t){}return r},player:function(){this.onreadylist=[]},mistControls:true};var p=mistplayers.html5.player;p.prototype=new MistPlayer;p.prototype.build=function(t,e){var i=t.source.type.split("/");i.shift();var r=document.createElement("video");r.setAttribute("crossorigin","anonymous");var a=document.createElement("source");a.setAttribute("src",t.source.url);r.source=a;r.appendChild(a);a.type=i.join("/");var n=["autoplay","loop","poster"];for(var o in n){var s=n[o];if(t.options[s]){r.setAttribute(s,t.options[s]===true?"":t.options[s])}}if(t.options.muted){r.muted=true}if(t.options.controls=="stock"){r.setAttribute("controls","")}if(t.info.type=="live"){r.loop=false}if("Proxy"in window&&"Reflect"in window){var l={get:{},set:{}};t.player.api=new Proxy(r,{get:function(t,e,i){if(e in l.get){return l.get[e].apply(t,arguments)}var r=t[e];if(typeof r==="function"){return function(){return r.apply(t,arguments)}}return r},set:function(t,e,i){if(e in l.set){return l.set[e].call(t,i)}return t[e]=i}});if(t.source.type=="html5/audio/mp3"){l.set.currentTime=function(){t.log("Seek attempted, but MistServer does not currently support seeking in MP3.");return false}}if(t.info.type=="live"){l.get.duration=function(){var e=0;if(this.buffered.length){e=this.buffered.end(this.buffered.length-1)}var i=((new Date).getTime()-t.player.api.lastProgress.getTime())*.001;return e+i-t.player.api.liveOffset};l.set.currentTime=function(e){var i=e-t.player.api.duration;if(i>0){i=0}t.player.api.liveOffset=i;t.log("Seeking to "+MistUtil.format.time(e)+" ("+Math.round(i*-10)/10+"s from live)");var r={startunix:i};if(i==0){r={}}t.player.api.setSource(MistUtil.http.url.addParam(t.source.url,r))};MistUtil.event.addListener(r,"progress",function(){t.player.api.lastProgress=new Date});t.player.api.lastProgress=new Date;t.player.api.liveOffset=0;MistUtil.event.addListener(r,"pause",function(){t.player.api.pausedAt=new Date});l.get.play=function(){return function(){if(t.player.api.paused&&t.player.api.pausedAt&&new Date-t.player.api.pausedAt>5e3){r.load();t.log("Reloading source..")}return r.play.apply(r,arguments)}};if(t.source.type=="html5/video/mp4"){l.get.currentTime=function(){return this.currentTime-t.player.api.liveOffset+t.info.lastms*.001}}}else{if(!isFinite(r.duration)){var p=0;for(var o in t.info.meta.tracks){p=Math.max(p,t.info.meta.tracks[o].lastms)}l.get.duration=function(){if(isFinite(this.duration)){return this.duration}return p*.001}}}}else{t.player.api=r}t.player.api.setSource=function(t){if(t!=this.source.src){this.source.src=t;this.load()}};t.player.api.setSubtitle=function(t){var e=r.getElementsByTagName("track");for(var i=e.length-1;i>=0;i--){r.removeChild(e[i])}if(t){var a=document.createElement("track");r.appendChild(a);a.kind="subtitles";a.label=t.label;a.srclang=t.lang;a.src=t.src;a.setAttribute("default","")}};t.player.setSize=function(t){this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};e(r)};

View file

@ -1 +1 @@
mistplayers.videojs={name:"VideoJS player",mimes:["html5/application/vnd.apple.mpegurl"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return this.mimes.indexOf(e)==-1?false:true},isBrowserSupported:function(e,t,i){if(location.protocol!=MistUtil.http.url.split(t.url).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}if(location.protocol=="file:"&&e=="html5/application/vnd.apple"){i.log("This source ("+e+") won't load if the page is run via file://");return false}return"MediaSource"in window},player:function(){},scriptsrc:function(e){return e+"/videojs.js"}};var p=mistplayers.videojs.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var i=this;function r(){if(e.destroyed){return}e.log("Building VideoJS player..");var r=document.createElement("video");if(e.source.type!="html5/video/ogg"){r.crossOrigin="anonymous"}var o=e.source.type.split("/");o.shift();var n=document.createElement("source");n.setAttribute("src",e.source.url);i.source=n;r.appendChild(n);n.type=o.join("/");e.log("Adding "+n.type+" source @ "+e.source.url);if(n.type=="application/vnd.apple.mpegurl"){n.type="application/x-mpegURL"}MistUtil.class.add(r,"video-js");var s={};if(e.options.autoplay){s.autoplay=true}if(e.options.loop&&e.info.type!="live"){s.loop=true;r.loop=true}if(e.options.poster){s.poster=e.options.poster}if(e.options.controls=="stock"){r.setAttribute("controls","");if(!document.getElementById("videojs-css")){var l=document.createElement("link");l.rel="stylesheet";l.href=e.options.host+"/skins/videojs.css";l.id="videojs-css";document.head.appendChild(l)}}i.onready(function(){i.videojs=videojs(r,s,function(){e.log("Videojs initialized")});i.api.unload=function(){videojs(r).dispose()}});e.log("Built html");if("Proxy"in window&&"Reflect"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"){function p(e){var t=0;if(e.buffered.length){t=e.buffered.end(e.buffered.length-1)}return t}var u=90;a.get.duration=function(){return(e.info.lastms+(new Date).getTime()-e.info.updated.getTime())*.001};e.player.api.lastProgress=new Date;e.player.api.liveOffset=0;MistUtil.event.addListener(r,"progress",function(){e.player.api.lastProgress=new Date});a.set.currentTime=function(t){var i=e.player.api.currentTime-t;var r=t-e.player.api.duration;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(r*-10)/10+"s from live)");e.video.currentTime-=i};a.get.currentTime=function(){return this.currentTime+e.info.lastms*.001-e.player.api.liveOffset-u}}}else{i.api=r}e.player.setSize=function(t){if("videojs"in e.player){e.player.videojs.dimensions(t.width,t.height);r.parentNode.style.width=t.width+"px";r.parentNode.style.height=t.height+"px"}this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};e.player.api.setSource=function(t){if(!e.player.videojs){return}if(e.player.videojs.src()!=t){e.player.videojs.src({type:e.player.videojs.currentSource().type,src:t})}};e.player.api.setSubtitle=function(e){var t=r.getElementsByTagName("track");for(var i=t.length-1;i>=0;i--){r.removeChild(t[i])}if(e){var o=document.createElement("track");r.appendChild(o);o.kind="subtitles";o.label=e.label;o.srclang=e.lang;o.src=e.src;o.setAttribute("default","")}};t(r)}if("videojs"in window){r()}else{var o=MistUtil.scripts.insert(e.urlappend(mistplayers.videojs.scriptsrc(e.options.host)),{onerror:function(t){var i="Failed to load videojs.js";if(t.message){i+=": "+t.message}e.showError(i)},onload:r},e)}}; mistplayers.videojs={name:"VideoJS player",mimes:["html5/application/vnd.apple.mpegurl"],priority:MistUtil.object.keys(mistplayers).length+1,isMimeSupported:function(e){return this.mimes.indexOf(e)==-1?false:true},isBrowserSupported:function(e,t,i){if(location.protocol!=MistUtil.http.url.split(t.url).protocol){i.log("HTTP/HTTPS mismatch for this source");return false}if(location.protocol=="file:"&&e=="html5/application/vnd.apple"){i.log("This source ("+e+") won't load if the page is run via file://");return false}return"MediaSource"in window},player:function(){},scriptsrc:function(e){return e+"/videojs.js"}};var p=mistplayers.videojs.player;p.prototype=new MistPlayer;p.prototype.build=function(e,t){var i=this;function r(){if(e.destroyed){return}e.log("Building VideoJS player..");var r=document.createElement("video");if(e.source.type!="html5/video/ogg"){r.crossOrigin="anonymous"}var o=e.source.type.split("/");o.shift();var n=document.createElement("source");n.setAttribute("src",e.source.url);i.source=n;r.appendChild(n);n.type=o.join("/");e.log("Adding "+n.type+" source @ "+e.source.url);if(n.type=="application/vnd.apple.mpegurl"){n.type="application/x-mpegURL"}MistUtil.class.add(r,"video-js");var s={};if(e.options.autoplay){s.autoplay=true}if(e.options.loop&&e.info.type!="live"){s.loop=true;r.loop=true}if(e.options.muted){s.muted=true;r.muted=true}if(e.options.poster){s.poster=e.options.poster}if(e.options.controls=="stock"){r.setAttribute("controls","");if(!document.getElementById("videojs-css")){var l=document.createElement("link");l.rel="stylesheet";l.href=e.options.host+"/skins/videojs.css";l.id="videojs-css";document.head.appendChild(l)}}i.onready(function(){i.videojs=videojs(r,s,function(){e.log("Videojs initialized")});i.api.unload=function(){videojs(r).dispose()}});e.log("Built html");if("Proxy"in window&&"Reflect"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"){function p(e){var t=0;if(e.buffered.length){t=e.buffered.end(e.buffered.length-1)}return t}var u=90;a.get.duration=function(){return(e.info.lastms+(new Date).getTime()-e.info.updated.getTime())*.001};e.player.api.lastProgress=new Date;e.player.api.liveOffset=0;MistUtil.event.addListener(r,"progress",function(){e.player.api.lastProgress=new Date});a.set.currentTime=function(t){var i=e.player.api.currentTime-t;var r=t-e.player.api.duration;e.log("Seeking to "+MistUtil.format.time(t)+" ("+Math.round(r*-10)/10+"s from live)");e.video.currentTime-=i};a.get.currentTime=function(){return this.currentTime+e.info.lastms*.001-e.player.api.liveOffset-u}}}else{i.api=r}e.player.setSize=function(t){if("videojs"in e.player){e.player.videojs.dimensions(t.width,t.height);r.parentNode.style.width=t.width+"px";r.parentNode.style.height=t.height+"px"}this.api.style.width=t.width+"px";this.api.style.height=t.height+"px"};e.player.api.setSource=function(t){if(!e.player.videojs){return}if(e.player.videojs.src()!=t){e.player.videojs.src({type:e.player.videojs.currentSource().type,src:t})}};e.player.api.setSubtitle=function(e){var t=r.getElementsByTagName("track");for(var i=t.length-1;i>=0;i--){r.removeChild(t[i])}if(e){var o=document.createElement("track");r.appendChild(o);o.kind="subtitles";o.label=e.label;o.srclang=e.lang;o.src=e.src;o.setAttribute("default","")}};t(r)}if("videojs"in window){r()}else{var o=MistUtil.scripts.insert(e.urlappend(mistplayers.videojs.scriptsrc(e.options.host)),{onerror:function(t){var i="Failed to load videojs.js";if(t.message){i+=": "+t.message}e.showError(i)},onload:r},e)}};

File diff suppressed because one or more lines are too long

View file

@ -1,10 +1,20 @@
#!/bin/bash #!/bin/bash
CHANGES="$(git diff --name-only --cached | grep embed/)";
readarray -t CHANGES <<<"$CHANGES";
elementIn () {
local e match="$1";
shift;
for e; do [[ "$e" == "$match" ]] && return 0; done;
return 1;
}
echo "Minimizing player code.."; echo "Minimizing player code..";
echo " Minimizing JS.."; echo " Minimizing JS..";
if [ "min/player.js" -ot "util.js" ] || [ "min/player.js" -ot "skins.js" ] || [ "min/player.js" -ot "controls.js" ] || [ "min/player.js" -ot "player.js" ]; then if elementIn "embed/util.js" "${CHANGES[@]}" || elementIn "embed/skins.js" "${CHANGES[@]}" || elementIn "embed/controls.js" "${CHANGES[@]}" || elementIn "embed/player.js" "${CHANGES[@]}" ; then
echo " Minimizing 'util.js skins.js controls.js player.js' into 'min/player.js'.."; echo " Minimizing 'util.js skins.js controls.js player.js' into 'min/player.js'..";
terser -mc -o min/player.js -- util.js skins.js controls.js player.js terser -mc -o min/player.js -- util.js skins.js controls.js player.js
fi fi
@ -12,23 +22,23 @@ echo " Done.";
echo " Minimizing wrappers.." echo " Minimizing wrappers.."
if [ "min/wrappers/dashjs.js" -ot "wrappers/dashjs.js" ]; then if elementIn "embed/wrappers/dashjs.js" "${CHANGES[@]}"; then
echo " Minimizing dashjs"; echo " Minimizing dashjs";
terser -mn -o min/wrappers/dashjs.js -- wrappers/dashjs.js terser -mn -o min/wrappers/dashjs.js -- wrappers/dashjs.js
fi fi
if [ "min/wrappers/flash_strobe.js" -ot "wrappers/flash_strobe.js" ]; then if elementIn "embed/wrappers/flash_strobe.js" "${CHANGES[@]}"; then
echo " Minimizing flash_strobe"; echo " Minimizing flash_strobe";
terser -mn -o min/wrappers/flash_strobe.js -- wrappers/flash_strobe.js terser -mn -o min/wrappers/flash_strobe.js -- wrappers/flash_strobe.js
fi fi
if [ "min/wrappers/html5.js" -ot "wrappers/html5.js" ]; then if elementIn "embed/wrappers/html5.js" "${CHANGES[@]}"; then
echo " Minimizing html5"; echo " Minimizing html5";
terser -mn -o min/wrappers/html5.js -- wrappers/html5.js terser -mn -o min/wrappers/html5.js -- wrappers/html5.js
fi fi
if [ "min/wrappers/videojs.js" -ot "wrappers/videojs.js" ]; then if elementIn "embed/wrappers/videojs.js" "${CHANGES[@]}"; then
echo " Minimizing videojs"; echo " Minimizing videojs";
terser -mn -o min/wrappers/videojs.js -- wrappers/videojs.js terser -mn -o min/wrappers/videojs.js -- wrappers/videojs.js
fi fi
if [ "min/wrappers/webrtc.js" -ot "wrappers/webrtc.js" ]; then if elementIn "embed/wrappers/webrtc.js" "${CHANGES[@]}"; then
echo " Minimizing webrtc"; echo " Minimizing webrtc";
terser -mn -o min/wrappers/webrtc.js -- wrappers/webrtc.js terser -mn -o min/wrappers/webrtc.js -- wrappers/webrtc.js
fi fi
@ -36,11 +46,11 @@ echo " Done.";
echo " Minimizing CSS.."; echo " Minimizing CSS..";
if [ "min/skins/default.css" -ot "skins/default.css" ] || [ "min/skins/default.css" -ot "skins/general.css" ]; then if elementIn "embed/skins/default.css" "${CHANGES[@]}" || elementIn "embed/skins/general.css" "${CHANGES[@]}"; then
echo " Minimizing default"; echo " Minimizing default";
cleancss --format keep-breaks -o min/skins/default.css skins/general.css skins/default.css cleancss --format keep-breaks -o min/skins/default.css skins/general.css skins/default.css
fi fi
if [ "min/skins/dev.css" -ot "skins/default.css" ] || [ "min/skins/dev.css" -ot "skins/general.css" ] || [ "min/skins/dev.css" -ot "skins/dev.css" ]; then if elementIn "embed/skins/default.css" "${CHANGES[@]}" || elementIn "embed/skins/general.css" "${CHANGES[@]}" || elementIn "embed/skins/dev.css" "${CHANGES[@]}"; then
echo " Minimizing dev"; echo " Minimizing dev";
cleancss --format keep-breaks -o min/skins/dev.css skins/general.css skins/default.css skins/dev.css cleancss --format keep-breaks -o min/skins/dev.css skins/general.css skins/default.css skins/dev.css
fi fi

View file

@ -15,7 +15,8 @@ function MistVideo(streamName,options) {
autoplay: true, //start playing when loaded autoplay: true, //start playing when loaded
controls: true, //show controls (MistControls when available) controls: true, //show controls (MistControls when available)
loop: false, //don't loop when the stream has finished loop: false, //don't loop when the stream has finished
poster: null, //don't show an image before the stream has started poster: false, //don't show an image before the stream has started
muted: false, //don't start muted
callback: false, //don't call a function when the player has finished building callback: false, //don't call a function when the player has finished building
streaminfo: false, //don't use this streaminfo but collect it from the mistserverhost streaminfo: false, //don't use this streaminfo but collect it from the mistserverhost
startCombo: false, //start looking for a player/source match at the start startCombo: false, //start looking for a player/source match at the start
@ -99,7 +100,7 @@ function MistVideo(streamName,options) {
new MistSkin(this); new MistSkin(this);
this.checkPlayer = function(options,quiet) { this.checkCombo = function(options,quiet) {
if (!options) { if (!options) {
options = {}; options = {};
} }
@ -244,7 +245,7 @@ function MistVideo(streamName,options) {
this.choosePlayer = function() { this.choosePlayer = function() {
MistVideo.log("Checking available players.."); MistVideo.log("Checking available players..");
var result = this.checkPlayer(); var result = this.checkCombo();
if (!result) { return false; } if (!result) { return false; }
var player = mistplayers[result.player]; var player = mistplayers[result.player];
@ -257,7 +258,7 @@ function MistVideo(streamName,options) {
source.url = MistVideo.urlappend(source.url); source.url = MistVideo.urlappend(source.url);
MistVideo.source = source; MistVideo.source = source;
MistUtil.event.send("playerChosen","Player/source combination selected",MistVideo.options.target); MistUtil.event.send("comboChosen","Player/source combination selected",MistVideo.options.target);
return true; return true;
} }
@ -605,7 +606,7 @@ function MistVideo(streamName,options) {
if ("setSize" in MistVideo.player) { if ("setSize" in MistVideo.player) {
MistVideo.player.videocontainer = MistVideo.video.parentNode; MistVideo.player.videocontainer = MistVideo.video.parentNode;
MistVideo.video.currentTarget = MistVideo.options.target; MistVideo.video.currentTarget = MistVideo.options.target;
if (!MistUtil.class.has(MistVideo.options.target,"secondaryVideo")) { if (!MistUtil.class.has(MistVideo.options.target,"mistvideo-secondaryVideo")) {
//this is the main MistVideo //this is the main MistVideo
MistVideo.player.resizeAll = function(){ MistVideo.player.resizeAll = function(){
function findVideo(startAt,matchTarget) { function findVideo(startAt,matchTarget) {
@ -622,14 +623,18 @@ function MistVideo(streamName,options) {
} }
//find the video that is in the main container, and resize that one //find the video that is in the main container, and resize that one
findVideo(MistVideo,MistVideo.options.target).p.resize(); var main = findVideo(MistVideo,MistVideo.options.target);
if (!main) { throw "Main video not found"; }
main.p.resize();
//then, resize the secondaries //then, resize the secondaries
if ("secondary" in MistVideo) { if ("secondary" in MistVideo) {
function tryResize(mv){ function tryResize(mv){
if (mv.MistVideo) { if (mv.MistVideo) {
if ("player" in mv.MistVideo) { if ("player" in mv.MistVideo) {
findVideo(MistVideo,mv.MistVideo.options.target).p.resize(); var sec = findVideo(MistVideo,mv.MistVideo.options.target);
if (!sec) { throw "Secondary video not found"; }
sec.p.resize();
} }
} }
else { else {
@ -647,13 +652,14 @@ function MistVideo(streamName,options) {
} }
MistVideo.player.resize = function(options){ MistVideo.player.resize = function(options){
if (!MistVideo.container.hasAttribute("data-fullscreen")) { var container = MistVideo.video.currentTarget.querySelector(".mistvideo");
if (!container.hasAttribute("data-fullscreen")) {
//if ((!document.fullscreenElement) || (document.fullscreenElement.parentElement != MistVideo.video.currentTarget)) { //if ((!document.fullscreenElement) || (document.fullscreenElement.parentElement != MistVideo.video.currentTarget)) {
//first, base the size on the video dimensions //first, base the size on the video dimensions
size = MistVideo.calcSize(options); size = MistVideo.calcSize(options);
this.setSize(size); this.setSize(size);
MistVideo.container.style.width = size.width+"px"; container.style.width = size.width+"px";
MistVideo.container.style.height = size.height+"px"; container.style.height = size.height+"px";
if ((MistVideo.options.fillSpace) && (!options || !options.reiterating)) { if ((MistVideo.options.fillSpace) && (!options || !options.reiterating)) {
//if this container is set to fill the available space //if this container is set to fill the available space
@ -686,13 +692,6 @@ function MistVideo(streamName,options) {
return true; return true;
} }
else { else {
function findVideo(parent) {
for (var i = 0; i < parent.children.length; i++) {
if (MistUtil.class.has(parent.children[i],"video")) {
return parent.children[i];
}
}
}
//this is the video that is in the main container, and resize this one to the screen dimensions //this is the video that is in the main container, and resize this one to the screen dimensions
this.setSize({ this.setSize({
@ -704,7 +703,7 @@ function MistVideo(streamName,options) {
}; };
//if this is the main video //if this is the main video
if (!MistUtil.class.has(MistVideo.options.target,"secondaryVideo")) { if (!MistUtil.class.has(MistVideo.options.target,"mistvideo-secondaryVideo")) {
MistUtil.event.addListener(window,"resize",function(){ MistUtil.event.addListener(window,"resize",function(){
if (MistVideo.destroyed) { return; } if (MistVideo.destroyed) { return; }
MistVideo.player.resizeAll(); MistVideo.player.resizeAll();
@ -738,7 +737,7 @@ function MistVideo(streamName,options) {
MistVideo.log("Skipping trackselection of "+i+" track "+usetracks[i]+" because it does not exist"); MistVideo.log("Skipping trackselection of "+i+" track "+usetracks[i]+" because it does not exist");
delete usetracks[i]; delete usetracks[i];
} }
if (!MistUtil.object.keys(usetracks).length) { return; } //if (!MistUtil.object.keys(usetracks).length) { return; } //don't do this; allow switching back to auto
//create source url //create source url
var newurl; var newurl;
@ -771,11 +770,13 @@ function MistVideo(streamName,options) {
this.setSourceParams(newurl,usetracks); this.setSourceParams(newurl,usetracks);
//restore video position //restore video position
var f = function(){ if (MistVideo.info.type != "live") {
this.currentTime = time; var f = function(){
this.removeEventListener("loadedmetadata",f); this.currentTime = time;
}; this.removeEventListener("loadedmetadata",f);
MistUtil.event.addListener(MistVideo.video,"loadedmetadata",f); };
MistUtil.event.addListener(MistVideo.video,"loadedmetadata",f);
}
} }
@ -1091,9 +1092,9 @@ function MistVideo(streamName,options) {
source: this.source.index, source: this.source.index,
player: this.playerName player: this.playerName
}; };
if (!this.checkPlayer({startCombo:startCombo},true)) { if (!this.checkCombo({startCombo:startCombo},true)) {
//the nextCombo won't yield a result //the nextCombo won't yield a result
if (this.checkPlayer({startCombo: false},true)) { if (this.checkCombo({startCombo: false},true)) {
//..but resetting the startcombo would //..but resetting the startcombo would
startCombo = false; startCombo = false;
} }
@ -1107,7 +1108,7 @@ function MistVideo(streamName,options) {
opts.startCombo = startCombo; opts.startCombo = startCombo;
MistVideo = mistPlay(this.stream,opts); MistVideo = mistPlay(this.stream,opts);
if ((time) && (isFinite(time))) { if ((time) && (isFinite(time) && (this.info.type != "live"))) {
//after load, try to restore the video position //after load, try to restore the video position
var f = function(){ var f = function(){
if (("player" in MistVideo) && ("api" in MistVideo.player)) { MistVideo.player.api.currentTime = time; } if (("player" in MistVideo) && ("api" in MistVideo.player)) { MistVideo.player.api.currentTime = time; }

View file

@ -205,15 +205,16 @@ MistSkins["default"] = {
mode: "pos", mode: "pos",
transition: { transition: {
hide: "left: 10px; bottom: -40px;", hide: "left: 10px; bottom: -40px;",
show: "bottom: 10px;" show: "bottom: 10px;",
viewport: "left: 0; right: 0; top: 0; bottom: 0"
}, },
button: { button: {
type: "container", type: "container",
children: [{type: "video"}] children: [{type: "videocontainer"}]
}, },
window: { window: {
type: "switchVideo", type: "switchVideo",
classes: ["mistvideo-controls","mistvideo-padding","mistvideo-background"], classes: ["mistvideo-controls","mistvideo-padding","mistvideo-background","mistvideo-pointer"],
containers: switchThese containers: switchThese
} }
}; };
@ -448,7 +449,8 @@ MistSkins["default"] = {
MistVideo.secondary = []; MistVideo.secondary = [];
} }
var options = MistUtil.object.extend(o.options,MistVideo.options,true); var options = MistUtil.object.extend({},MistVideo.options);
options = MistUtil.object.extend(options,o.options);
MistVideo.secondary.push(options); MistVideo.secondary.push(options);
var pointer = { var pointer = {
@ -457,7 +459,14 @@ MistSkins["default"] = {
}; };
options.target = document.createElement("div"); options.target = document.createElement("div");
options.callback = function(mv){ delete options.container;
var mvo = {};
options.MistVideoObject = mvo;
MistUtil.event.addListener(options.target,"initialized",function(){
var mv = mvo.reference;
//options.callback = function(mv){
options.MistVideo = mv; //tell the main video we exist options.MistVideo = mv; //tell the main video we exist
pointer.secondary = mv; pointer.secondary = mv;
@ -467,7 +476,7 @@ MistSkins["default"] = {
//as all event listeners are tied to the video element (not the container), events don't bubble up and disturb higher players //as all event listeners are tied to the video element (not the container), events don't bubble up and disturb higher players
//prevent clicks on the control container from bubbling down to underlying elements //prevent clicks on the control container from bubbling down to underlying elements
var controlContainers = options.target.querySelectorAll(".controls"); var controlContainers = options.target.querySelectorAll(".mistvideo-controls");
for (var i = 0; i < controlContainers.length; i++) { for (var i = 0; i < controlContainers.length; i++) {
MistUtil.event.addListener(controlContainers[i],"click",function(e){ MistUtil.event.addListener(controlContainers[i],"click",function(e){
e.stopPropagation(); e.stopPropagation();
@ -516,7 +525,7 @@ MistSkins["default"] = {
mv.player.api.pausedesync = false; mv.player.api.pausedesync = false;
}); });
}; });
options.skin = MistUtil.object.extend({},MistVideo.skin,true); options.skin = MistUtil.object.extend({},MistVideo.skin,true);
options.skin.structure.main = MistUtil.object.extend({},MistVideo.skin.structure.secondaryVideo(pointer)); options.skin.structure.main = MistUtil.object.extend({},MistVideo.skin.structure.secondaryVideo(pointer));
@ -582,6 +591,8 @@ MistSkins["default"] = {
}, },
controls: function(){ controls: function(){
if ((this.options.controls) && (this.options.controls != "stock")) { if ((this.options.controls) && (this.options.controls != "stock")) {
MistUtil.class.add(this.container,"hasControls");
var container = this.UI.buildStructure(this.skin.structure.controls); var container = this.UI.buildStructure(this.skin.structure.controls);
if (MistUtil.isTouchDevice()) { if (MistUtil.isTouchDevice()) {
container.style.zoom = 1.5; container.style.zoom = 1.5;
@ -1274,28 +1285,31 @@ MistSkins["default"] = {
function changeToTracks(type,value){ function changeToTracks(type,value){
MistVideo.log("User selected "+type+" track with id "+value); MistVideo.log("User selected "+type+" track with id "+value);
if ("setTrack" in MistVideo.player.api) { if (!MistVideo.options.setTracks) { MistVideo.options.setTracks = {}; }
MistVideo.player.api.setTrack(type,value); MistVideo.options.setTracks[type] = value;
return;
}
if ("setTrack" in MistVideo.player.api) {
return MistVideo.player.api.setTrack(type,value);
}
else {
//gather what tracks we should use //gather what tracks we should use
var usetracks = {}; var usetracks = {};
for (var i in selections) { for (var i in selections) {
if (i == "subtitle") { continue; } //subtitle tracks are handled seperately if ((i == "subtitle") || (selections[i].value == "")) { continue; } //subtitle tracks are handled seperately
usetracks[i] = selections[i].value; usetracks[i] = selections[i].value;
} }
usetracks[type] = value; if (value != ""){ usetracks[type] = value; }
//use setTracks //use setTracks
if ("setTracks" in MistVideo.player.api) { if ("setTracks" in MistVideo.player.api) {
MistVideo.player.api.setTracks(usetracks); return MistVideo.player.api.setTracks(usetracks);
} }
//use setSource //use setSource
if ("setSource" in MistVideo.player.api) { if ("setSource" in MistVideo.player.api) {
MistVideo.player.api.setSource( return MistVideo.player.api.setSource(
MistUtil.http.url.addParam(MistVideo.source.url,usetracks) MistUtil.http.url.addParam(MistVideo.source.url,usetracks)
); );
} }
}
} }
//sort the tracks to ["audio","video",..,"subtitle",..etc] //sort the tracks to ["audio","video",..,"subtitle",..etc]
@ -1373,6 +1387,7 @@ MistSkins["default"] = {
if (i == this.trackType) { continue; } if (i == this.trackType) { continue; }
if (!checkboxes[i].checked) { if (!checkboxes[i].checked) {
checkboxes[i].checked = true; checkboxes[i].checked = true;
changeToTracks(i,true);
break; break;
} }
} }
@ -1405,13 +1420,14 @@ MistSkins["default"] = {
//var determine the display info for the tracks //var determine the display info for the tracks
function orderValues(trackinfoobj) { function orderValues(trackinfoobj) {
var order = { var order = {
width: 1, trackid: 0,
bps: 2, language: 1,
width: 2,
bps: 3,
fpks: 4, fpks: 4,
channels: 5, channels: 5,
rate: 7, codec: 6,
language: 0, rate: 7
codec: 6
}; };
return MistUtil.object.values(trackinfoobj,function(keya,keyb,valuea,valueb){ return MistUtil.object.values(trackinfoobj,function(keya,keyb,valuea,valueb){
if (order[keya] > order[keyb]) { return 1; } if (order[keya] > order[keyb]) { return 1; }
@ -1429,6 +1445,13 @@ MistSkins["default"] = {
select.trackType = type; select.trackType = type;
cell.appendChild(select); cell.appendChild(select);
if (type != "subtitle") {
var option = document.createElement("option");
select.appendChild(option);
option.value = "";
option.appendChild(document.createTextNode("Automatic"));
}
//display properties that are the same for all tracks //display properties that are the same for all tracks
var same = orderValues(t[MistUtil.object.keys(t)[0]].same); var same = orderValues(t[MistUtil.object.keys(t)[0]].same);
if (same.length) { if (same.length) {
@ -1440,7 +1463,9 @@ MistSkins["default"] = {
//add options to the select //add options to the select
var options = MistUtil.object.keys(t,true); //sort them var options = MistUtil.object.keys(t,function(a,b){
return Number(a) - Number(b);
}); //sort them
for (var i in options) { for (var i in options) {
var track = t[options[i]]; var track = t[options[i]];
var option = document.createElement("option"); var option = document.createElement("option");
@ -1495,11 +1520,14 @@ MistSkins["default"] = {
checkboxes[this.trackType].checked = true; checkboxes[this.trackType].checked = true;
} }
changeToTracks(this.trackType,this.value); if (!changeToTracks(this.trackType,this.value)) {
//trackchange failed, reset select to old value
}
}); });
//set to the track that plays by default //set to the track that plays by default
/*
if (MistVideo.info.type == "live") { if (MistVideo.info.type == "live") {
//for live, the default track is the highest index //for live, the default track is the highest index
select.value = MistUtil.object.keys(t).pop(); select.value = MistUtil.object.keys(t).pop();
@ -1508,6 +1536,7 @@ MistSkins["default"] = {
//for vod, the default track is the lowest index //for vod, the default track is the lowest index
select.value = MistUtil.object.keys(t).shift(); select.value = MistUtil.object.keys(t).shift();
} }
*/
MistUtil.event.addListener(MistVideo.video,"playerUpdate_trackChanged",function(e){ MistUtil.event.addListener(MistVideo.video,"playerUpdate_trackChanged",function(e){
@ -1736,8 +1765,8 @@ MistSkins["default"] = {
this.showError = function(message,options){ this.showError = function(message,options){
if (!options) { if (!options) {
options = { options = {
softReload: true, softReload: !!((MistVideo.video) && (MistVideo.video.load)),
reload: true,//(MistVideo.options.reloadDelay ? MistVideo.options.reloadDelay : 10), reload: true,
nextCombo: !!MistVideo.info, nextCombo: !!MistVideo.info,
polling: false, polling: false,
passive: false passive: false
@ -2456,7 +2485,7 @@ function MistSkin(MistVideo) {
if ((typeof skinOptions == "string") && (skinOptions in MistSkins)) { skinOptions = MistUtil.object.extend({},MistSkins[skinOptions],true); } if ((typeof skinOptions == "string") && (skinOptions in MistSkins)) { skinOptions = MistUtil.object.extend({},MistSkins[skinOptions],true); }
var skinParent; var skinParent;
if (("inherit" in skinOptions) && (skinOptions.inherit)) { if (("inherit" in skinOptions) && (skinOptions.inherit) && (skinOptions.inherit in MistSkins)) {
skinParent = this.applySkinOptions(skinOptions.inherit); skinParent = this.applySkinOptions(skinOptions.inherit);
} }
else { else {
@ -2545,6 +2574,7 @@ function MistSkin(MistVideo) {
} }
this.applySkinOptions("skin" in MistVideo.options ? MistVideo.options.skin : "default"); this.applySkinOptions("skin" in MistVideo.options ? MistVideo.options.skin : "default");
//load css //load css
var styles = []; var styles = [];
var toload = 0; var toload = 0;

View file

@ -88,8 +88,13 @@ svg.icon.timeout {
} }
.mistvideo-secondaryVideo { .mistvideo-secondaryVideo {
z-index: 1; z-index: 1;
position: absolute;
right: 0;
top: 0;
width: 50%; width: 50%;
height: 50%; height: 50%;
max-width: fit-content;
max-height: fit-content;
} }
.mistvideo-polling { .mistvideo-polling {
display: inline-block; display: inline-block;

View file

@ -18,6 +18,7 @@
} }
.mistvideo-video { .mistvideo-video {
overflow: hidden; overflow: hidden;
outline: none;
} }
svg.icon.loading { svg.icon.loading {
z-index: -1; /* don't use display: none because of transition for [data-loading=stalled] */ z-index: -1; /* don't use display: none because of transition for [data-loading=stalled] */
@ -222,3 +223,6 @@ svg.icon.spin, svg.icon .spin {
animation: spin 1.5s infinite linear; animation: spin 1.5s infinite linear;
transform-origin: 50% 50%; transform-origin: 50% 50%;
} }
.vjs-text-track-display {
pointer-events: none;
}

View file

@ -213,10 +213,8 @@ var MistUtil = {
if (sorting) { if (sorting) {
if (typeof sorting != "function") { if (typeof sorting != "function") {
sorting = function(keya,keyb){ sorting = function(a,b){
if (keya > keyb) { return 1; } return a.localeCompare(b);
if (keya < keyb) { return -1; }
return 0;
}; };
} }
@ -764,6 +762,22 @@ var MistUtil = {
var d = MistUtil.object.values(different); var d = MistUtil.object.values(different);
output[type][i].displayName = (d.length ? d.join(", ") : MistUtil.object.values(output[type][i].describe).join(" ")); output[type][i].displayName = (d.length ? d.join(", ") : MistUtil.object.values(output[type][i].describe).join(" "));
} }
//check if some tracks have the same display name
var names = {};
for (var i in output[type]) {
if (output[type][i].displayName in names) {
//we have double names, add the track id
var n = 1;
for (var i in output[type]) {
output[type][i].different.trackid = n+")";
output[type][i].displayName = "Track "+n+" ("+output[type][i].displayName+")";
n++;
}
break;
}
names[output[type][i].displayName] = 1;
}
} }
return output; return output;

View file

@ -103,6 +103,9 @@ p.prototype.build = function (MistVideo,callback) {
if (MistVideo.options.poster) { if (MistVideo.options.poster) {
ele.setAttribute("poster",MistVideo.options.poster); ele.setAttribute("poster",MistVideo.options.poster);
} }
if (MistVideo.options.muted) {
ele.muted = true;
}
if (MistVideo.options.controls == "stock") { if (MistVideo.options.controls == "stock") {
ele.setAttribute("controls",""); ele.setAttribute("controls","");
} }
@ -141,20 +144,34 @@ p.prototype.build = function (MistVideo,callback) {
} }
//figure out what the track number is //figure out what the track number is
//whyyyy did it have to be reverse order //for dash: 0 lowest bitrate, going up
var n = me.dash.getBitrateInfoListFor("video").length - 1; //get the relevant tracks
var mistTracks = [];
for (var i in MistVideo.info.meta.tracks) { for (var i in MistVideo.info.meta.tracks) {
var t = MistVideo.info.meta.tracks[i]; var t = MistVideo.info.meta.tracks[i];
if (t.type == type) { if (t.type == type) {
if (t.trackid == id) { break; } mistTracks.push(t);
n--;
} }
} }
//sort by bitrate
MistUtil.array.multiSort(mistTracks,["bps"]);
var n = false;
for (var i in mistTracks) {
if (mistTracks[i].trackid == id) {
n = i;
break;
}
}
if (n === false) {
return false; //track not found
}
me.dash.setAutoSwitchQualityFor(type,false); //turn off ABR rules //TODO do we want this by default? me.dash.setAutoSwitchQualityFor(type,false); //turn off ABR rules //TODO do we want this by default?
me.dash.setFastSwitchEnabled(true); //show the new track asap me.dash.setFastSwitchEnabled(true); //show the new track asap
me.dash.setQualityFor(type,n); me.dash.setQualityFor(type,n);
//dash does change the track, but is appended to the buffer, so it seems to take a while.. //dash does change the track, but is appended to the buffer, so it seems to take a while..
return true; //track found and change requested
} }
//react to automatic trackswitching //react to automatic trackswitching
@ -162,19 +179,19 @@ p.prototype.build = function (MistVideo,callback) {
//the newQuality-th track of type mediaType is being selected //the newQuality-th track of type mediaType is being selected
//figure out the track id //figure out the track id
//whyyyy did it have to be reverse order //for dash: 0 lowest bitrate, going up
var n = me.dash.getBitrateInfoListFor("video").length - 1; //get the relevant tracks
var id; var mistTracks = [];
for (var i in MistVideo.info.meta.tracks) { for (var i in MistVideo.info.meta.tracks) {
var t = MistVideo.info.meta.tracks[i]; var t = MistVideo.info.meta.tracks[i];
if (t.type == e.mediaType) { if (t.type == e.mediaType) {
if (e.newQuality == n) { mistTracks.push(t);
id = t.trackid;
break;
}
n--;
} }
} }
//sort by bitrate
MistUtil.array.multiSort(mistTracks,["bps"]);
//get mist's id for the track
var id = mistTracks[e.newQuality].trackid;
//create an event to pass this to the skin //create an event to pass this to the skin
MistUtil.event.send("playerUpdate_trackChanged",{ MistUtil.event.send("playerUpdate_trackChanged",{
@ -183,6 +200,37 @@ p.prototype.build = function (MistVideo,callback) {
},MistVideo.video); },MistVideo.video);
}); });
var subsloaded = false;
me.dash.on("allTextTracksAdded",function(){
subsloaded = true;
});
MistVideo.player.api.setSubtitle = function(trackmeta) {
if (!subsloaded) {
var f = function(){
MistVideo.player.api.setSubtitle(trackmeta);
me.dash.off("allTextTracksAdded",f);
};
me.dash.on("allTextTracksAdded",f);
return;
}
if (!trackmeta) {
me.dash.enableText(false);
return;
}
var dashsubs = me.dash.getTracksFor("text");
for (var i in dashsubs) {
if (dashsubs[i].id == trackmeta.trackid) {
me.dash.setTextTrack(i);
if (!me.dash.isTextEnabled()) { me.dash.enableText(); }
return true;
}
}
return false; //failed to find subtitle
};
//dashjs keeps on spamming the stalled icon >_> //dashjs keeps on spamming the stalled icon >_>
MistUtil.event.addListener(ele,"progress",function(e){ MistUtil.event.addListener(ele,"progress",function(e){

View file

@ -56,13 +56,22 @@ p.prototype.build = function (MistVideo,callback) {
MistUtil.empty(ele); MistUtil.empty(ele);
ele.appendChild(createParam("movie",MistVideo.urlappend(options.host+MistVideo.source.player_url))); ele.appendChild(createParam("movie",MistVideo.urlappend(options.host+MistVideo.source.player_url)));
var flashvars = "src="+encodeURIComponent(source)+"&controlBarMode="+(options.controls ? "floating" : "none")+"&initialBufferTime=0.5&expandedBufferTime=5&minContinuousPlaybackTime=3"+(options.live ? "&streamType=live" : "")+(options.autoplay ? "&autoPlay=true" : "" ); var flashvars = "src="+encodeURIComponent(source)+"&controlBarMode="+(options.controls ? "floating" : "none")+"&initialBufferTime=0.5&expandedBufferTime=5&minContinuousPlaybackTime=3"+(options.live ? "&streamType=live" : "")+(options.autoplay ? "&autoPlay=true" : "" )+(options.loop ? "&loop=true" : "" )+(options.poster ? "&poster="+options.poster : "" )+(options.muted ? "&muted=true" : "" );
ele.appendChild(createParam("flashvars",flashvars)); ele.appendChild(createParam("flashvars",flashvars));
ele.appendChild(createParam("allowFullScreen","true")); ele.appendChild(createParam("allowFullScreen","true"));
ele.appendChild(createParam("wmode","direct")); ele.appendChild(createParam("wmode","direct"));
if (options.autoplay) { if (options.autoplay) {
ele.appendChild(createParam("autoPlay","true")); ele.appendChild(createParam("autoPlay","true"));
} }
if (options.loop) {
ele.appendChild(createParam("loop","true"));
}
if (options.poster) {
ele.appendChild(createParam("poster",options.poster));
}
if (options.muted) {
ele.appendChild(createParam("muted","true"));
}
e.setAttribute("src",MistVideo.urlappend(MistVideo.source.player_url)); e.setAttribute("src",MistVideo.urlappend(MistVideo.source.player_url));
e.setAttribute("type","application/x-shockwave-flash"); e.setAttribute("type","application/x-shockwave-flash");

View file

@ -114,6 +114,9 @@ p.prototype.build = function (MistVideo,callback) {
video.setAttribute(attr,(MistVideo.options[attr] === true ? "" : MistVideo.options[attr])); video.setAttribute(attr,(MistVideo.options[attr] === true ? "" : MistVideo.options[attr]));
} }
} }
if (MistVideo.options.muted) {
video.muted = true; //don't use attribute because of Chrome bug: https://stackoverflow.com/questions/14111917/html5-video-muted-but-stilly-playing?rq=1
}
if (MistVideo.options.controls == "stock") { if (MistVideo.options.controls == "stock") {
video.setAttribute("controls",""); video.setAttribute("controls","");
} }
@ -168,11 +171,19 @@ p.prototype.build = function (MistVideo,callback) {
}; };
overrides.set.currentTime = function(value){ overrides.set.currentTime = function(value){
var offset = value - MistVideo.player.api.duration; var offset = value - MistVideo.player.api.duration;
if (offset > 0) {offset = 0;} //don't allow positive numbers, as Mist will interpret them as unix timestamps
MistVideo.player.api.liveOffset = offset; MistVideo.player.api.liveOffset = offset;
MistVideo.log("Seeking to "+MistUtil.format.time(value)+" ("+Math.round(offset*-10)/10+"s from live)"); MistVideo.log("Seeking to "+MistUtil.format.time(value)+" ("+Math.round(offset*-10)/10+"s from live)");
MistVideo.player.api.setSource(MistUtil.http.url.addParam(MistVideo.source.url,{startunix:offset})); var params = {startunix:offset};
if (offset == 0) {
params = {};
}
MistVideo.player.api.setSource(MistUtil.http.url.addParam(MistVideo.source.url,params));
} }
MistUtil.event.addListener(video,"progress",function(){ MistUtil.event.addListener(video,"progress",function(){
MistVideo.player.api.lastProgress = new Date(); MistVideo.player.api.lastProgress = new Date();

View file

@ -59,6 +59,10 @@ p.prototype.build = function (MistVideo,callback) {
vjsopts.loop = true; vjsopts.loop = true;
ele.loop = true; ele.loop = true;
} }
if (MistVideo.options.muted) {
vjsopts.muted = true;
ele.muted = true;
}
if (MistVideo.options.poster) { vjsopts.poster = MistVideo.options.poster; } if (MistVideo.options.poster) { vjsopts.poster = MistVideo.options.poster; }
if (MistVideo.options.controls == "stock") { if (MistVideo.options.controls == "stock") {
ele.setAttribute("controls",""); ele.setAttribute("controls","");
@ -71,7 +75,6 @@ p.prototype.build = function (MistVideo,callback) {
} }
} }
me.onready(function(){ me.onready(function(){
me.videojs = videojs(ele,vjsopts,function(){ me.videojs = videojs(ele,vjsopts,function(){
MistVideo.log("Videojs initialized"); MistVideo.log("Videojs initialized");

View file

@ -49,6 +49,9 @@ p.prototype.build = function (MistVideo,callback) {
video.setAttribute(attr,(MistVideo.options[attr] === true ? "" : MistVideo.options[attr])); video.setAttribute(attr,(MistVideo.options[attr] === true ? "" : MistVideo.options[attr]));
} }
} }
if (MistVideo.options.muted) {
video.muted = true; //don't use attribute because of Chrome bug
}
if (MistVideo.info.type == "live") { if (MistVideo.info.type == "live") {
video.loop = false; video.loop = false;
} }

View file

@ -1,7 +1,18 @@
#!/bin/bash #!/bin/bash
CHANGES="$(git diff --name-only --cached | grep lsp/)";
readarray -t CHANGES <<<"$CHANGES";
elementIn () {
local e match="$1";
shift;
for e; do [[ "$e" == "$match" ]] && return 0; done;
return 1;
}
echo "Minimizing LSP.."; echo "Minimizing LSP..";
if [ "minified.js" -ot "plugins/md5.js" ] || [ "minified.js" -ot "plugins/plugins/cattablesort.js" ] || [ "minified.js" -ot "mist.js" ]; then if elementIn "lsp/plugins/md5.js" "${CHANGES[@]}" || elementIn "lsp/plugins/cattablesort.js" "${CHANGES[@]}" || elementIn "lsp/mist.js" "${CHANGES[@]}" ; then
echo " Generating minified.js.." echo " Generating minified.js.."
java -jar closure-compiler.jar --warning_level QUIET plugins/md5.js plugins/cattablesort.js mist.js > minified.js java -jar closure-compiler.jar --warning_level QUIET plugins/md5.js plugins/cattablesort.js mist.js > minified.js
fi fi

View file

@ -133,40 +133,40 @@ c.push({label:"RTSP",type:"span",clipboard:true,readonly:true,classes:["RTSP"]})
help:"To enable encryption, the licence acquisition url must be entered, as well as either the content key or the key ID and seed.<br>Unsure how you should fill in your encryption or missing your preferred encryption? Please contact us."},{label:"License acquisition url",type:"str",LTSonly:!0,pointer:{main:p,index:"la_url"}},$("<br>"),{label:"Content key",type:"str",LTSonly:!0,pointer:{main:p,index:"contentkey"}},{type:"text",text:" - or - "},{label:"Key ID",type:"str",LTSonly:!0,pointer:{main:p, help:"To enable encryption, the licence acquisition url must be entered, as well as either the content key or the key ID and seed.<br>Unsure how you should fill in your encryption or missing your preferred encryption? Please contact us."},{label:"License acquisition url",type:"str",LTSonly:!0,pointer:{main:p,index:"la_url"}},$("<br>"),{label:"Content key",type:"str",LTSonly:!0,pointer:{main:p,index:"contentkey"}},{type:"text",text:" - or - "},{label:"Key ID",type:"str",LTSonly:!0,pointer:{main:p,
index:"keyid"}},{label:"Key seed",type:"str",LTSonly:!0,pointer:{main:p,index:"keyseed"}},{type:"buttons",buttons:[{type:"cancel",label:"Cancel","function":function(){UI.navto("Streams")}},{type:"save",label:"Save","function":function(){ma("Streams")}},{type:"save",label:"Save and Preview","function":function(){ma("Preview")},classes:["saveandpreview"]}]}]));d.find("[name=name]").keyup(function(){X()});X();break;case "Preview":""==c&&UI.navto("Streams");b=":8080";for(o in mist.data.config.protocols)if(t= index:"keyid"}},{label:"Key seed",type:"str",LTSonly:!0,pointer:{main:p,index:"keyseed"}},{type:"buttons",buttons:[{type:"cancel",label:"Cancel","function":function(){UI.navto("Streams")}},{type:"save",label:"Save","function":function(){ma("Streams")}},{type:"save",label:"Save and Preview","function":function(){ma("Preview")},classes:["saveandpreview"]}]}]));d.find("[name=name]").keyup(function(){X()});X();break;case "Preview":""==c&&UI.navto("Streams");b=":8080";for(o in mist.data.config.protocols)if(t=
mist.data.config.protocols[o],"HTTP"==t.connector||"HTTP.exe"==t.connector)b=t.port?":"+t.port:":8080";var j=parseURL(mist.user.host),K=j.protocol+j.host+b+"/",J=$("<div>").css({display:"flex","flex-flow":"row wrap","flex-shrink":1,"min-width":"auto"}),j="";-1==c.indexOf("+")&&(j=$("<button>").text("Settings").addClass("settings").click(function(){UI.navto("Edit",c)}));d.html($("<div>").addClass("bigbuttons").append(j).append($("<button>").text("Embed").addClass("embed").click(function(){UI.navto("Embed", mist.data.config.protocols[o],"HTTP"==t.connector||"HTTP.exe"==t.connector)b=t.port?":"+t.port:":8080";var j=parseURL(mist.user.host),K=j.protocol+j.host+b+"/",J=$("<div>").css({display:"flex","flex-flow":"row wrap","flex-shrink":1,"min-width":"auto"}),j="";-1==c.indexOf("+")&&(j=$("<button>").text("Settings").addClass("settings").click(function(){UI.navto("Edit",c)}));d.html($("<div>").addClass("bigbuttons").append(j).append($("<button>").text("Embed").addClass("embed").click(function(){UI.navto("Embed",
c)})).append($("<button>").addClass("cancel").addClass("return").text("Return").click(function(){UI.navto("Streams")}))).append($("<h2>").text('Preview of "'+c+'"')).append(J);var C=encodeURIComponent(c);o=$("<div>").css("flex-shrink","1").css("min-width","auto").css("max-width","100%");J.append(o);var pa=$("<div>"),N=$("<div>").addClass("mistvideo").text("Loading player..").css("max-width","100%").css("flex-shrink","1").css("min-width","auto"),Z=$("<div>").addClass("controls");o.append(N).append(pa).append(Z); c)})).append($("<button>").addClass("cancel").addClass("return").text("Return").click(function(){UI.navto("Streams")}))).append($("<h2>").text('Preview of "'+c+'"')).append(J);var C=encodeURIComponent(c);o=$("<div>").css("flex-shrink","1").css("min-width","auto").css("max-width","100%");J.append(o);var pa=$("<div>"),N=$("<div>").text("Loading player..").css("max-width","100%").css("flex-shrink","1").css("min-width","auto"),Z=$("<div>").addClass("controls");o.append(N).append(pa).append(Z);$("link#devcss").length||
$("link#devcss").length||d.append($("<link>").attr("rel","stylesheet").attr("type","text/css").attr("href",K+"skins/dev.css").attr("id","devcss"));var qa=function(){pa.text("");var b=document.createElement("script");d.append(b);b.src=K+"player.js";b.onerror=function(){N.html("Failed to load player.js").append($("<button>").text("Reload").css("display","block").click(function(){qa()}))};b.onload=function(){var g=c,f=function(){var a=MistVideoObject.reference;Z.html("");Z.append(a.UI.buildStructure({type:"container", d.append($("<link>").attr("rel","stylesheet").attr("type","text/css").attr("href",K+"skins/dev.css").attr("id","devcss"));var qa=function(){pa.text("");var b=document.createElement("script");d.append(b);b.src=K+"player.js";b.onerror=function(){N.html("Failed to load player.js").append($("<button>").text("Reload").css("display","block").click(function(){qa()}))};b.onload=function(){var g=c,f=function(){var a=MistVideoObject.reference;Z.html("");Z.append(a.UI.buildStructure({type:"container",classes:["mistvideo-column"],
classes:["mistvideo-column"],style:{flexShrink:1},children:[{"if":function(){return this.playerName&&this.source},then:{type:"container",classes:["mistvideo-description"],style:{display:"block"},children:[{type:"playername",style:{display:"inline"}},{type:"text",text:"is playing",style:{margin:"0 0.2em"}},{type:"mimetype"}]}},{type:"decodingIssues",style:{"max-width":"30em","flex-flow":"column nowrap"}},{type:"container",classes:["mistvideo-column","mistvideo-devcontrols"],children:[{type:"text", style:{flexShrink:1},children:[{"if":function(){return this.playerName&&this.source},then:{type:"container",classes:["mistvideo-description"],style:{display:"block"},children:[{type:"playername",style:{display:"inline"}},{type:"text",text:"is playing",style:{margin:"0 0.2em"}},{type:"mimetype"}]}},{type:"decodingIssues",style:{"max-width":"30em","flex-flow":"column nowrap"}},{type:"container",classes:["mistvideo-column","mistvideo-devcontrols"],children:[{type:"text",text:"Player control"},{type:"container",
text:"Player control"},{type:"container",classes:["mistvideo-devbuttons"],style:{"flex-wrap":"wrap"},children:[{"if":function(){return!(!this.player||!this.player.api)},then:{type:"button",title:"Reload the video source",label:"Reload video",onclick:function(){this.player.api.load()}}},{type:"button",title:"Build MistVideo again",label:"Reload player",onclick:function(){this.reload()}},{type:"button",title:"Switch to the next available player and source combination",label:"Try next combination",onclick:function(){this.nextCombo()}}]}, classes:["mistvideo-devbuttons"],style:{"flex-wrap":"wrap"},children:[{"if":function(){return!(!this.player||!this.player.api)},then:{type:"button",title:"Reload the video source",label:"Reload video",onclick:function(){this.player.api.load()}}},{type:"button",title:"Build MistVideo again",label:"Reload player",onclick:function(){this.reload()}},{type:"button",title:"Switch to the next available player and source combination",label:"Try next combination",onclick:function(){this.nextCombo()}}]},{type:"forcePlayer"},
{type:"forcePlayer"},{type:"forceType"},{type:"forceSource"}]},{type:"log"}]}))};if(!(a!="Preview"||!c||c==""||g!=c)){N[0].addEventListener("initialized",f);N[0].addEventListener("initializeFailed",f);MistVideoObject.reference=mistPlay(g,{target:N[0],host:K,skin:"dev",loop:true,MistVideoObject:MistVideoObject})}d[0].removeChild(b)};MistVideoObject.reference={unload:function(){b.onload=function(){this.parentElement&&this.parentElement.removeChild(this)}}}};qa();o=$("<div>").append($("<h3>").text("Meta information")); {type:"forceType"},{type:"forceSource"}]},{type:"log"}]}))};if(!(a!="Preview"||!c||c==""||g!=c)){N[0].addEventListener("initialized",f);N[0].addEventListener("initializeFailed",f);MistVideoObject.reference=mistPlay(g,{target:N[0],host:K,skin:"dev",loop:true,MistVideoObject:MistVideoObject})}d[0].removeChild(b)};MistVideoObject.reference={unload:function(){b.onload=function(){this.parentElement&&this.parentElement.removeChild(this)}}}};qa();o=$("<div>").append($("<h3>").text("Meta information"));var S=
var S=$("<span>").text("Loading..");o.append(S);J.append(o);""!=C&&$.ajax({type:"GET",url:K+"json_"+C+".js",success:function(a){var b=function(a,b){return"maxbps"in a?UI.format.bytes(a[b],1):b=="maxbps"?UI.format.bytes(a.bps,1):"unknown"},c=a.meta;if(!c||!c.tracks)S.html("No meta information available.");else{a=[];a.push({label:"Type",type:"span",value:c.live?"Live":"Pre-recorded (VoD)"});"format"in c&&a.push({label:"Format",type:"span",value:c.format});c.live&&a.push({label:"Buffer window",type:"span", $("<span>").text("Loading..");o.append(S);J.append(o);""!=C&&$.ajax({type:"GET",url:K+"json_"+C+".js",success:function(a){var b=function(a,b){return"maxbps"in a?UI.format.bytes(a[b],1):b=="maxbps"?UI.format.bytes(a.bps,1):"unknown"},c=a.meta;if(!c||!c.tracks)S.html("No meta information available.");else{a=[];a.push({label:"Type",type:"span",value:c.live?"Live":"Pre-recorded (VoD)"});"format"in c&&a.push({label:"Format",type:"span",value:c.format});c.live&&a.push({label:"Buffer window",type:"span",
value:UI.format.addUnit(c.buffer_window,"ms")});var d={audio:{vheader:"Audio",labels:["Codec","Duration","Avg bitrate","Peak bitrate","Channels","Samplerate","Language","Track index"],content:[]},video:{vheader:"Video",labels:["Codec","Duration","Avg bitrate","Peak bitrate","Size","Framerate","Language","Track index"],content:[]},subtitle:{vheader:"Subtitles",labels:["Codec","Duration","Avg bitrate","Peak bitrate","Language","Track index"],content:[]}},g=Object.keys(c.tracks);g.sort(function(a,b){a= value:UI.format.addUnit(c.buffer_window,"ms")});var d={audio:{vheader:"Audio",labels:["Codec","Duration","Avg bitrate","Peak bitrate","Channels","Samplerate","Language","Track index"],content:[]},video:{vheader:"Video",labels:["Codec","Duration","Avg bitrate","Peak bitrate","Size","Framerate","Language","Track index"],content:[]},subtitle:{vheader:"Subtitles",labels:["Codec","Duration","Avg bitrate","Peak bitrate","Language","Track index"],content:[]}},g=Object.keys(c.tracks);g.sort(function(a,b){a=
a.split("_").pop();b=b.split("_").pop();return a-b});var f=1,e=1,i=1,h;for(h in g){var k=g[h],j=c.tracks[k];switch(j.type){case "audio":d.audio.content.push({header:"Track "+k.split("_").pop(),body:[j.codec,UI.format.duration((j.lastms-j.firstms)/1E3)+"<br><span class=description>"+UI.format.duration(j.firstms/1E3)+" to "+UI.format.duration(j.lastms/1E3)+"</span>",b(j,"bps"),b(j,"maxbps"),j.channels,UI.format.addUnit(UI.format.number(j.rate),"Hz"),"language"in j?j.language:"unknown",f]});f++;break; a.split("_").pop();b=b.split("_").pop();return a-b});var f=1,e=1,i=1,h;for(h in g){var k=g[h],j=c.tracks[k];switch(j.type){case "audio":d.audio.content.push({header:"Track "+k.split("_").pop(),body:[j.codec,UI.format.duration((j.lastms-j.firstms)/1E3)+"<br><span class=description>"+UI.format.duration(j.firstms/1E3)+" to "+UI.format.duration(j.lastms/1E3)+"</span>",b(j,"bps"),b(j,"maxbps"),j.channels,UI.format.addUnit(UI.format.number(j.rate),"Hz"),"language"in j?j.language:"unknown",f]});f++;break;
case "video":d.video.content.push({header:"Track "+k.split("_").pop(),body:[j.codec,UI.format.duration((j.lastms-j.firstms)/1E3)+"<br><span class=description>"+UI.format.duration(j.firstms/1E3)+" to "+UI.format.duration(j.lastms/1E3)+"</span>",b(j,"bps"),b(j,"maxbps"),UI.format.addUnit(j.width,"x ")+UI.format.addUnit(j.height,"px"),UI.format.addUnit(UI.format.number(j.fpks/1E3),"fps"),"language"in j?j.language:"unknown",e]});e++;break;case "meta":case "subtitle":if(j.codec=="subtitle"||j.type=="subtitle"){d.subtitle.content.push({header:"Track "+ case "video":d.video.content.push({header:"Track "+k.split("_").pop(),body:[j.codec,UI.format.duration((j.lastms-j.firstms)/1E3)+"<br><span class=description>"+UI.format.duration(j.firstms/1E3)+" to "+UI.format.duration(j.lastms/1E3)+"</span>",b(j,"bps"),b(j,"maxbps"),UI.format.addUnit(j.width,"x ")+UI.format.addUnit(j.height,"px"),UI.format.addUnit(UI.format.number(j.fpks/1E3),"fps"),"language"in j?j.language:"unknown",e]});e++;break;case "meta":case "subtitle":if(j.codec=="subtitle"||j.type=="subtitle"){d.subtitle.content.push({header:"Track "+
k.split("_").pop(),body:[j.codec,UI.format.duration((j.lastms-j.firstms)/1E3)+"<br><span class=description>"+UI.format.duration(j.firstms/1E3)+" to "+UI.format.duration(j.lastms/1E3)+"</span>",b(j,"bps"),b(j,"maxbps"),"language"in j?j.language:"unknown",i]});i++}}}b=["audio","video","subtitle"];h=$("<div>").css({display:"flex","flex-flow":"row wrap","font-size":"0.9em"});for(k in b)d[b[k]].content.length&&h.append(UI.buildVheaderTable(d[b[k]]).css("width","auto"));a.push($("<span>").text("Tracks:")); k.split("_").pop(),body:[j.codec,UI.format.duration((j.lastms-j.firstms)/1E3)+"<br><span class=description>"+UI.format.duration(j.firstms/1E3)+" to "+UI.format.duration(j.lastms/1E3)+"</span>",b(j,"bps"),b(j,"maxbps"),"language"in j?j.language:"unknown",i]});i++}}}b=["audio","video","subtitle"];h=$("<div>").css({display:"flex","flex-flow":"row wrap","font-size":"0.9em"});for(k in b)d[b[k]].content.length&&h.append(UI.buildVheaderTable(d[b[k]]).css("width","auto"));a.push($("<span>").text("Tracks:"));
a.push(h);S.html(UI.buildUI(a))}},error:function(){S.html("Error while retrieving stream info.")}});break;case "Embed":""==c&&UI.navTo("Streams");j="";-1==c.indexOf("+")&&(j=$("<button>").addClass("settings").text("Settings").click(function(){UI.navto("Edit",c)}));d.html($("<div>").addClass("bigbuttons").append(j).append($("<button>").text("Preview").addClass("preview").click(function(){UI.navto("Preview",c)})).append($("<button>").addClass("cancel").addClass("return").text("Return").click(function(){UI.navto("Streams")}))).append($("<h2>").text('Embed "'+ a.push(h);S.html(UI.buildUI(a))}},error:function(){S.html("Error while retrieving stream info.")}});break;case "Embed":""==c&&UI.navTo("Streams");j="";-1==c.indexOf("+")&&(j=$("<button>").addClass("settings").text("Settings").click(function(){UI.navto("Edit",c)}));d.html($("<div>").addClass("bigbuttons").append(j).append($("<button>").text("Preview").addClass("preview").click(function(){UI.navto("Preview",c)})).append($("<button>").addClass("cancel").addClass("return").text("Return").click(function(){UI.navto("Streams")}))).append($("<h2>").text('Embed "'+
c+'"'));var O=$("<span>");d.append(O);C=encodeURIComponent(c);j=parseURL(mist.user.host);b={"":{port:":8080"}};for(o in mist.data.config.protocols){t=mist.data.config.protocols[o];if("HTTP"==t.connector||"HTTP.exe"==t.connector)b[""].port=t.port?":"+t.port:":8080";if("HTTPS"==t.connector||"HTTPS.exe"==t.connector)b.s={},b.s.port=t.port?":"+t.port:":4433"}var H=K="http://"+j.host+b[""].port+"/";if(otherhost.host||otherhost.https)H=(otherhost.https&&"s"in b?"https://":"http://")+(otherhost.host?otherhost.host: c+'"'));var O=$("<span>");d.append(O);C=encodeURIComponent(c);j=parseURL(mist.user.host);b={"":{port:":8080"}};for(o in mist.data.config.protocols){t=mist.data.config.protocols[o];if("HTTP"==t.connector||"HTTP.exe"==t.connector)b[""].port=t.port?":"+t.port:":8080";if("HTTPS"==t.connector||"HTTPS.exe"==t.connector)b.s={},b.s.port=t.port?":"+t.port:":4433"}var H=K="http://"+j.host+b[""].port+"/";if(otherhost.host||otherhost.https)H=(otherhost.https&&"s"in b?"https://":"http://")+(otherhost.host?otherhost.host:
j.host)+(otherhost.https&&"s"in b?b.s.port:b[""].port)+"/";var P=!1,aa={forcePlayer:"",forceType:"",controls:!0,autoplay:!0,loop:!1,fillSpace:!1,poster:"",urlappend:"",setTracks:{}},q=$.extend({},aa);o=UI.stored.getOpts();"embedoptions"in o&&(q=$.extend(q,o.embedoptions,!0),"object"!=typeof q.setTracks&&(q.setTracks={}));o={};switch(q.controls){case "stock":o.controls="stock";break;case !0:o.controls=1;break;case !1:o.controls=0}var y=function(){function a(b){switch(typeof b){case "string":return $.isNumeric(b)? j.host)+(otherhost.https&&"s"in b?b.s.port:b[""].port)+"/";var P=!1,aa={forcePlayer:"",forceType:"",controls:!0,autoplay:!0,loop:!1,muted:!1,fillSpace:!1,poster:"",urlappend:"",setTracks:{}},q=$.extend({},aa);o=UI.stored.getOpts();"embedoptions"in o&&(q=$.extend(q,o.embedoptions,!0),"object"!=typeof q.setTracks&&(q.setTracks={}));o={};switch(q.controls){case "stock":o.controls="stock";break;case !0:o.controls=1;break;case !1:o.controls=0}var x=function(){function a(b){switch(typeof b){case "string":return $.isNumeric(b)?
b:'"'+b+'"';case "object":return JSON.stringify(b);default:return b}}P&&UI.stored.saveOpt("embedoptions",q);for(var b=c+"_",d=12,g="";d--;){var f;f=Math.floor(Math.random()*62);f=f<10?f:f<36?String.fromCharCode(f+55):String.fromCharCode(f+61);g=g+f}var b=b+g,d=['target: document.getElementById("'+b+'")'],e;for(e in q)e=="prioritize_type"?q[e]&&q[e]!=""&&d.push("forcePriority: "+JSON.stringify({source:[["type",[q[e]]]]})):e=="monitor_action"?q[e]&&q[e]!=""&&q[e]=="nextCombo"&&d.push('monitor: {\n action: function(){\n this.MistVideo.log("Switching to nextCombo because of poor playback in "+this.MistVideo.source.type+" ("+Math.round(this.vars.score*1000)/10+"%)");\n this.MistVideo.nextCombo();\n }\n }'): b:'"'+b+'"';case "object":return JSON.stringify(b);default:return b}}P&&UI.stored.saveOpt("embedoptions",q);for(var b=c+"_",d=12,g="";d--;){var f;f=Math.floor(Math.random()*62);f=f<10?f:f<36?String.fromCharCode(f+55):String.fromCharCode(f+61);g=g+f}var b=b+g,d=['target: document.getElementById("'+b+'")'],e;for(e in q)e=="prioritize_type"?q[e]&&q[e]!=""&&d.push("forcePriority: "+JSON.stringify({source:[["type",[q[e]]]]})):e=="monitor_action"?q[e]&&q[e]!=""&&q[e]=="nextCombo"&&d.push('monitor: {\n action: function(){\n this.MistVideo.log("Switching to nextCombo because of poor playback in "+this.MistVideo.source.type+" ("+Math.round(this.vars.score*1000)/10+"%)");\n this.MistVideo.nextCombo();\n }\n }'):
q[e]!=aa[e]&&(q[e]!=null&&(typeof q[e]!="object"||JSON.stringify(q[e])!=JSON.stringify(aa[e])))&&d.push(e+": "+a(q[e]));e=[];e.push('<div class="mistvideo" id="'+b+'">');e.push(" <noscript>");e.push(' <a href="'+H+C+'.html" target="_blank">');e.push(" Click here to play this video");e.push(" </a>");e.push(" </noscript>");e.push(" <script>");e.push(" var a = function(){");e.push(' mistPlay("'+c+'",{');e.push(" "+d.join(",\n "));e.push(" });");e.push(" };"); q[e]!=aa[e]&&(q[e]!=null&&(typeof q[e]!="object"||JSON.stringify(q[e])!=JSON.stringify(aa[e])))&&d.push(e+": "+a(q[e]));e=[];e.push('<div class="mistvideo" id="'+b+'">');e.push(" <noscript>");e.push(' <a href="'+H+C+'.html" target="_blank">');e.push(" Click here to play this video");e.push(" </a>");e.push(" </noscript>");e.push(" <script>");e.push(" var a = function(){");e.push(' mistPlay("'+c+'",{');e.push(" "+d.join(",\n "));e.push(" });");e.push(" };");
e.push(" if (!window.mistplayers) {");e.push(' var p = document.createElement("script");');e.push(' p.src = "'+H+'player.js"');e.push(" document.head.appendChild(p);");e.push(" p.onload = a;");e.push(" }");e.push(" else { a(); }");e.push(" <\/script>");e.push("</div>");return e.join("\n")},ba=$("<span>").text("Loading.."),t=y(q),L=$("<div>").text("Loading..").css("display","flex").css("flex-flow","column nowrap"),ra="";"s"in b&&(ra=UI.buildUI([{label:"Use HTTPS",type:"checkbox", e.push(" if (!window.mistplayers) {");e.push(' var p = document.createElement("script");');e.push(' p.src = "'+H+'player.js"');e.push(" document.head.appendChild(p);");e.push(" p.onload = a;");e.push(" }");e.push(" else { a(); }");e.push(" <\/script>");e.push("</div>");return e.join("\n")},ba=$("<span>").text("Loading.."),t=x(q),L=$("<div>").text("Loading..").css("display","flex").css("flex-flow","column nowrap"),ra="";"s"in b&&(ra=UI.buildUI([{label:"Use HTTPS",type:"checkbox",
"function":function(){if($(this).getval()!=otherhost.https){otherhost.https=$(this).getval();UI.navto("Embed",c)}},value:otherhost.https}]).find("label"));O.append($("<span>").addClass("input_container").append($("<label>").addClass("UIelement").append($("<span>").addClass("label").text("Use a different host:")).append($("<span>").addClass("field_container").append($("<input>").attr("type","text").addClass("field").val(otherhost.host?otherhost.host:j.host)).append($("<span>").addClass("unit").append($("<button>").text("Apply").click(function(){otherhost.host= "function":function(){if($(this).getval()!=otherhost.https){otherhost.https=$(this).getval();UI.navto("Embed",c)}},value:otherhost.https}]).find("label"));O.append($("<span>").addClass("input_container").append($("<label>").addClass("UIelement").append($("<span>").addClass("label").text("Use a different host:")).append($("<span>").addClass("field_container").append($("<input>").attr("type","text").addClass("field").val(otherhost.host?otherhost.host:j.host)).append($("<span>").addClass("unit").append($("<button>").text("Apply").click(function(){otherhost.host=
$(this).closest("label").find("input").val();UI.navto("Embed",c)}))))).append(ra)).append(UI.buildUI([$("<h3>").text("Urls"),{label:"Stream info json",type:"str",value:H+"json_"+C+".js",readonly:!0,clipboard:!0,help:"Information about this stream as a json page."},{label:"Stream info script",type:"str",value:H+"info_"+C+".js",readonly:!0,clipboard:!0,help:"This script loads information about this stream into a mistvideo javascript object."},{label:"HTML page",type:"str",value:H+C+".html",readonly:!0, $(this).closest("label").find("input").val();UI.navto("Embed",c)}))))).append(ra)).append(UI.buildUI([$("<h3>").text("Urls"),{label:"Stream info json",type:"str",value:H+"json_"+C+".js",readonly:!0,clipboard:!0,help:"Information about this stream as a json page."},{label:"Stream info script",type:"str",value:H+"info_"+C+".js",readonly:!0,clipboard:!0,help:"This script loads information about this stream into a mistvideo javascript object."},{label:"HTML page",type:"str",value:H+C+".html",readonly:!0,
qrcode:!0,clipboard:!0,help:"A basic html containing the embedded stream."},$("<h3>").text("Embed code"),{label:"Embed code",type:"textarea",value:t,rows:t.split("\n").length+3,readonly:!0,classes:["embed_code"],clipboard:!0,help:"Include this code on your webpage to embed the stream. The options below can be used to configure how your content is displayed."},$("<h4>").text("Embed code options (optional)").css("margin-top",0),{type:"help",help:"Use these controls to customise what this embedded video will look like.<br>Not all players have all of these options."}, qrcode:!0,clipboard:!0,help:"A basic html containing the embedded stream."},$("<h3>").text("Embed code"),{label:"Embed code",type:"textarea",value:t,rows:t.split("\n").length+3,readonly:!0,classes:["embed_code"],clipboard:!0,help:"Include this code on your webpage to embed the stream. The options below can be used to configure how your content is displayed."},$("<h4>").text("Embed code options (optional)").css("margin-top",0),{type:"help",help:"Use these controls to customise what this embedded video will look like.<br>Not all players have all of these options."},
{label:"Prioritize type",type:"select",select:[["","Automatic"]],pointer:{main:q,index:"prioritize_type"},classes:["prioritize_type"],"function":function(){if(P){q.prioritize_type=$(this).getval();$(".embed_code").setval(y(q))}},help:"Try to use this source type first, but full back to something else if it is not available."},{label:"Force type",type:"select",select:[["","Automatic"]],pointer:{main:q,index:"forceType"},classes:["forceType"],"function":function(){if(P){q.forceType=$(this).getval(); {label:"Prioritize type",type:"select",select:[["","Automatic"]],pointer:{main:q,index:"prioritize_type"},classes:["prioritize_type"],"function":function(){if(P){q.prioritize_type=$(this).getval();$(".embed_code").setval(x(q))}},help:"Try to use this source type first, but full back to something else if it is not available."},{label:"Force type",type:"select",select:[["","Automatic"]],pointer:{main:q,index:"forceType"},classes:["forceType"],"function":function(){if(P){q.forceType=$(this).getval();
$(".embed_code").setval(y(q))}},help:"Only use this particular source."},{label:"Force player",type:"select",select:[["","Automatic"]],pointer:{main:q,index:"forcePlayer"},classes:["forcePlayer"],"function":function(){if(P){q.forcePlayer=$(this).getval();$(".embed_code").setval(y(q))}},help:"Only use this particular player."},{label:"Controls",type:"select",select:[["1","MistServer Controls"],["stock","Player controls"],["0","None"]],pointer:{main:o,index:"controls"},"function":function(){q.controls= $(".embed_code").setval(x(q))}},help:"Only use this particular source."},{label:"Force player",type:"select",select:[["","Automatic"]],pointer:{main:q,index:"forcePlayer"},classes:["forcePlayer"],"function":function(){if(P){q.forcePlayer=$(this).getval();$(".embed_code").setval(x(q))}},help:"Only use this particular player."},{label:"Controls",type:"select",select:[["1","MistServer Controls"],["stock","Player controls"],["0","None"]],pointer:{main:o,index:"controls"},"function":function(){q.controls=
$(this).getval()==1;switch($(this).getval()){case 0:q.controls=false;break;case 1:q.controls=true;break;case "stock":q.controls="stock"}$(".embed_code").setval(y(q))},help:"The type of controls that should be shown."},{label:"Autoplay",type:"checkbox",pointer:{main:q,index:"autoplay"},"function":function(){q.autoplay=$(this).getval();$(".embed_code").setval(y(q))},help:"Whether or not the video should play as the page is loaded."},{label:"Loop",type:"checkbox",pointer:{main:q,index:"loop"},"function":function(){q.loop= $(this).getval()==1;switch($(this).getval()){case 0:q.controls=false;break;case 1:q.controls=true;break;case "stock":q.controls="stock"}$(".embed_code").setval(x(q))},help:"The type of controls that should be shown."},{label:"Autoplay",type:"checkbox",pointer:{main:q,index:"autoplay"},"function":function(){q.autoplay=$(this).getval();$(".embed_code").setval(x(q))},help:"Whether or not the video should play as the page is loaded."},{label:"Loop",type:"checkbox",pointer:{main:q,index:"loop"},"function":function(){q.loop=
$(this).getval();$(".embed_code").setval(y(q))},help:"If the video should restart when the end is reached."},{label:"Fill available space",type:"checkbox",pointer:{main:q,index:"fillSpace"},"function":function(){q.fillSpace=$(this).getval();$(".embed_code").setval(y(q))},help:"The video will fit the available space in its container, even if the video stream has a smaller resolution."},{label:"Poster",type:"str",pointer:{main:q,index:"poster"},"function":function(){q.poster=$(this).getval();$(".embed_code").setval(y(q))}, $(this).getval();$(".embed_code").setval(x(q))},help:"If the video should restart when the end is reached."},{label:"Start muted",type:"checkbox",pointer:{main:q,index:"muted"},"function":function(){q.muted=$(this).getval();$(".embed_code").setval(x(q))},help:"If the video should restart when the end is reached."},{label:"Fill available space",type:"checkbox",pointer:{main:q,index:"fillSpace"},"function":function(){q.fillSpace=$(this).getval();$(".embed_code").setval(x(q))},help:"The video will fit the available space in its container, even if the video stream has a smaller resolution."},
help:"URL to an image that is displayed when the video is not playing."},{label:"Video URL addition",type:"str",pointer:{main:q,index:"urlappend"},help:"The embed script will append this string to the video url, useful for sending through params.",classes:["embed_code_forceprotocol"],"function":function(){q.urlappend=$(this).getval();$(".embed_code").setval(y(q))}},{label:"Preselect tracks",type:"DOMfield",DOMfield:L,help:"Pre-select these tracks."},{label:"Monitoring action",type:"select",select:[["", {label:"Poster",type:"str",pointer:{main:q,index:"poster"},"function":function(){q.poster=$(this).getval();$(".embed_code").setval(x(q))},help:"URL to an image that is displayed when the video is not playing."},{label:"Video URL addition",type:"str",pointer:{main:q,index:"urlappend"},help:"The embed script will append this string to the video url, useful for sending through params.",classes:["embed_code_forceprotocol"],"function":function(){q.urlappend=$(this).getval();$(".embed_code").setval(x(q))}},
"Ask the viewer what to do"],["nextCombo","Try the next source / player combination"]],pointer:{main:q,index:"monitor_action"},"function":function(){q.monitor_action=$(this).getval();$(".embed_code").setval(y(q))},help:"What the player should do when playback is poor."},$("<h3>").text("Protocol stream urls"),ba]));$.ajax({type:"GET",url:H+"json_"+C+".js",success:function(a){var b=[],c=O.find(".forceType"),d=O.find(".prioritize_type"),g;for(g in a.source){var e=a.source[g],f=UI.humanMime(e.type);b.push({label:f? {label:"Preselect tracks",type:"DOMfield",DOMfield:L,help:"Pre-select these tracks."},{label:"Monitoring action",type:"select",select:[["","Ask the viewer what to do"],["nextCombo","Try the next source / player combination"]],pointer:{main:q,index:"monitor_action"},"function":function(){q.monitor_action=$(this).getval();$(".embed_code").setval(x(q))},help:"What the player should do when playback is poor."},$("<h3>").text("Protocol stream urls"),ba]));$.ajax({type:"GET",url:H+"json_"+C+".js",success:function(a){var b=
f+" <span class=description>("+e.type+")</span>":UI.format.capital(e.type),type:"str",value:e.url,readonly:true,qrcode:true,clipboard:true});f=UI.humanMime(e.type);if(c.children('option[value="'+e.type+'"]').length==0){c.append($("<option>").text(f?f+" ("+e.type+")":UI.format.capital(e.type)).val(e.type));d.append($("<option>").text(f?f+" ("+e.type+")":UI.format.capital(e.type)).val(e.type))}}c.val(q.forceType);d.val(q.prioritize_type);ba.html(UI.buildUI(b));L.html("");b={};for(g in a.meta.tracks){c= [],c=O.find(".forceType"),d=O.find(".prioritize_type"),g;for(g in a.source){var e=a.source[g],f=UI.humanMime(e.type);b.push({label:f?f+" <span class=description>("+e.type+")</span>":UI.format.capital(e.type),type:"str",value:e.url,readonly:true,qrcode:true,clipboard:true});f=UI.humanMime(e.type);if(c.children('option[value="'+e.type+'"]').length==0){c.append($("<option>").text(f?f+" ("+e.type+")":UI.format.capital(e.type)).val(e.type));d.append($("<option>").text(f?f+" ("+e.type+")":UI.format.capital(e.type)).val(e.type))}}c.val(q.forceType);
a.meta.tracks[g];c.type!="audio"&&c.type!="video"||(c.type in b?b[c.type].push([c.trackid,UI.format.capital(c.type)+" track "+(b[c.type].length+1)]):b[c.type]=[["",UI.format.capital(c.type)+" track 1"]])}if(Object.keys(b).length){L.closest("label").show();for(g in b){a=$("<select>").attr("data-type",g).css("flex-grow","1").change(function(){$(this).val()==""?delete q.setTracks[$(this).attr("data-type")]:q.setTracks[$(this).attr("data-type")]=$(this).val();$(".embed_code").setval(y(q))});L.append(a); d.val(q.prioritize_type);ba.html(UI.buildUI(b));L.html("");b={};for(g in a.meta.tracks){c=a.meta.tracks[g];c.type!="audio"&&c.type!="video"||(c.type in b?b[c.type].push([c.trackid,UI.format.capital(c.type)+" track "+(b[c.type].length+1)]):b[c.type]=[["",UI.format.capital(c.type)+" track 1"]])}if(Object.keys(b).length){L.closest("label").show();for(g in b){a=$("<select>").attr("data-type",g).css("flex-grow","1").change(function(){$(this).val()==""?delete q.setTracks[$(this).attr("data-type")]:q.setTracks[$(this).attr("data-type")]=
b[g].push([-1,"No "+g]);for(var h in b[g])a.append($("<option>").val(b[g][h][0]).text(b[g][h][1]));if(g in q.setTracks){a.val(q.setTracks[g]);if(a.val()==null){a.val("");delete q.setTracks[g];$(".embed_code").setval(y(q))}}}}else L.closest("label").hide();P=true},error:function(){ba.html("Error while retrieving stream info.");L.closest("label").hide();q.setTracks={}}});o=document.createElement("script");o.src=K+"player.js";document.head.appendChild(o);o.onload=function(){var a=O.find(".forcePlayer"), $(this).val();$(".embed_code").setval(x(q))});L.append(a);b[g].push([-1,"No "+g]);for(var h in b[g])a.append($("<option>").val(b[g][h][0]).text(b[g][h][1]));if(g in q.setTracks){a.val(q.setTracks[g]);if(a.val()==null){a.val("");delete q.setTracks[g];$(".embed_code").setval(x(q))}}}}else L.closest("label").hide();P=true},error:function(){ba.html("Error while retrieving stream info.");L.closest("label").hide();q.setTracks={}}});o=document.createElement("script");o.src=K+"player.js";document.head.appendChild(o);
b;for(b in mistplayers)a.append($("<option>").text(mistplayers[b].name).val(b));document.head.removeChild(this)};o.onerror=function(){document.head.removeChild(this)};break;case "Push":var D=$("<div>").text("Loading..");d.append(D);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,e;for(e in c.push_list)if(a.indexOf(c.push_list[e][0])>-1){d=false;break}}else d=true;if(d)for(e in a)g.find("tr[data-pushid="+ o.onload=function(){var a=O.find(".forcePlayer"),b;for(b in mistplayers)a.append($("<option>").text(mistplayers[b].name).val(b));document.head.removeChild(this)};o.onerror=function(){document.head.removeChild(this)};break;case "Push":var D=$("<div>").text("Loading..");d.append(D);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,e;for(e in c.push_list)if(a.indexOf(c.push_list[e][0])>-1){d=false;
a[e]+"]").remove();else b()},{push_list:1})},1E3)}function c(e,f){var h=$("<span>");if(f=="Automatic"&&e.length>=4){h.append($("<span>").text(e[2]));e[3]&&h.append($("<span>").text(", schedule on "+(new Date(e[3]*1E3)).toLocaleString()));e.length>=5&&e[4]&&h.append($("<span>").text(", complete on "+(new Date(e[4]*1E3)).toLocaleString()))}else e.length>=4&&e[2]!=e[3]?h.append($("<span>").text(e[2])).append($("<span>").html("&#187").addClass("unit").css("margin","0 0.5em")).append($("<span>").text(e[3])): break}}else d=true;if(d)for(e in a)g.find("tr[data-pushid="+a[e]+"]").remove();else b()},{push_list:1})},1E3)}function c(e,f){var h=$("<span>");if(f=="Automatic"&&e.length>=4){h.append($("<span>").text(e[2]));e[3]&&h.append($("<span>").text(", schedule on "+(new Date(e[3]*1E3)).toLocaleString()));e.length>=5&&e[4]&&h.append($("<span>").text(", complete on "+(new Date(e[4]*1E3)).toLocaleString()))}else e.length>=4&&e[2]!=e[3]?h.append($("<span>").text(e[2])).append($("<span>").html("&#187").addClass("unit").css("margin",
h.append($("<span>").text(e[2]));var i=$("<td>").append($("<button>").text(f=="Automatic"?"Remove":"Stop").click(function(){if(confirm("Are you sure you want to "+$(this).text().toLowerCase()+" this push?\n"+e[1]+" to "+e[2])){var a=$(this).closest("tr");a.html($("<td colspan=99>").html($("<span>").addClass("red").text(f=="Automatic"?"Removing..":"Stopping..")));if(f=="Automatic"){var c=e.slice(1);mist.send(function(){a.remove()},{push_auto_remove:[c]})}else mist.send(function(){b([e[0]])},{push_stop:[e[0]]})}})); "0 0.5em")).append($("<span>").text(e[3])):h.append($("<span>").text(e[2]));var i=$("<td>").append($("<button>").text(f=="Automatic"?"Remove":"Stop").click(function(){if(confirm("Are you sure you want to "+$(this).text().toLowerCase()+" this push?\n"+e[1]+" to "+e[2])){var a=$(this).closest("tr");a.html($("<td colspan=99>").html($("<span>").addClass("red").text(f=="Automatic"?"Removing..":"Stopping..")));if(f=="Automatic"){var c=e.slice(1);mist.send(function(){a.remove()},{push_auto_remove:[c]})}else mist.send(function(){b([e[0]])},
if(f=="Automatic"){i.prepend($("<button>").text("Edit").click(function(){UI.navto("Start Push","auto_"+($(this).closest("tr").index()-1))}));i.append($("<button>").text("Stop pushes").click(function(){if(confirm('Are you sure you want to stop all pushes matching \n"'+e[1]+" to "+e[2]+'"?'+(d.wait!=0?"\n\nRetrying is enabled. You'll probably want to set that to 0.":""))){var c=$(this);c.text("Stopping pushes..");var f=[],h;for(h in a.push_list)if(e[1]==a.push_list[h][1]&&e[2]==a.push_list[h][2]){f.push(a.push_list[h][0]); {push_stop:[e[0]]})}}));if(f=="Automatic"){i.prepend($("<button>").text("Edit").click(function(){UI.navto("Start Push","auto_"+($(this).closest("tr").index()-1))}));i.append($("<button>").text("Stop pushes").click(function(){if(confirm('Are you sure you want to stop all pushes matching \n"'+e[1]+" to "+e[2]+'"?'+(d.wait!=0?"\n\nRetrying is enabled. You'll probably want to set that to 0.":""))){var c=$(this);c.text("Stopping pushes..");var f=[],h;for(h in a.push_list)if(e[1]==a.push_list[h][1]&&e[2]==
g.find("tr[data-pushid="+a.push_list[h][0]+"]").html($("<td colspan=99>").html($("<span>").addClass("red").text("Stopping..")))}mist.send(function(){c.text("Stop pushes");b(f)},{push_stop:f,push_settings:{wait:0}})}}))}return $("<tr>").attr("data-pushid",e[0]).append($("<td>").text(e[1])).append($("<td>").append(h.children())).append(i)}D.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|| a.push_list[h][2]){f.push(a.push_list[h][0]);g.find("tr[data-pushid="+a.push_list[h][0]+"]").html($("<td colspan=99>").html($("<span>").addClass("red").text("Stopping..")))}mist.send(function(){c.text("Stop pushes");b(f)},{push_stop:f,push_settings:{wait:0}})}}))}return $("<tr>").attr("data-pushid",e[0]).append($("<td>").text(e[1])).append($("<td>").append(h.children())).append(i)}D.html(UI.buildUI([{type:"help",help:"You can push streams to files or other servers, allowing them to broadcast your stream as well."}]));
(d={});var g=$("<table>").append($("<tr>").append($("<th>").text("Stream")).append($("<th>").text("Target")).append($("<th>"))),e=g.clone();if("push_list"in a)for(var f in a.push_list)g.append(c(a.push_list[f],"Manual"));if("push_auto_list"in a)for(f in a.push_auto_list){var h=a.push_auto_list[f].slice();h.unshift(-1);e.append(c(h,"Automatic"))}D.append($("<h3>").text("Automatic pushes")).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.", var d=a.push_settings;d||(d={});var g=$("<table>").append($("<tr>").append($("<th>").text("Stream")).append($("<th>").text("Target")).append($("<th>"))),e=g.clone();if("push_list"in a)for(var f in a.push_list)g.append(c(a.push_list[f],"Manual"));if("push_auto_list"in a)for(f in a.push_auto_list){var h=a.push_auto_list[f].slice();h.unshift(-1);e.append(c(h,"Automatic"))}D.append($("<h3>").text("Automatic pushes")).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":0,pointer:{main:d,index:"wait"},LTSonly:1},{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"},LTSonly:1},{type:"buttons",buttons:[{type:"save",label:"Save","function":function(){mist.send(function(){UI.navto("Push")},{push_settings:d})}}]}])).append($("<button>").text("Add an automatic push").click(function(){UI.navto("Start Push", "default":0,pointer:{main:d,index:"wait"},LTSonly:1},{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"},LTSonly:1},{type:"buttons",buttons:[{type:"save",label:"Save","function":function(){mist.send(function(){UI.navto("Push")},{push_settings:d})}}]}])).append($("<button>").text("Add an automatic push").click(function(){UI.navto("Start Push",
"auto")}));e.find("tr").length==1?D.append($("<div>").text("No automatic pushes have been configured.").addClass("text").css("margin-top","0.5em")):D.append(e);D.append($("<h3>").text("Pushes")).append($("<button>").text("Start a push").click(function(){UI.navto("Start Push")}));if(g.find("tr").length==1)D.append($("<div>").text("No pushes are active.").addClass("text").css("margin-top","0.5em"));else{var e=[],h=[],i=$("<select>").css("margin-left","0.5em").append($("<option>").text("Any stream").val("")), "auto")}));e.find("tr").length==1?D.append($("<div>").text("No automatic pushes have been configured.").addClass("text").css("margin-top","0.5em")):D.append(e);D.append($("<h3>").text("Pushes")).append($("<button>").text("Start a push").click(function(){UI.navto("Start Push")}));if(g.find("tr").length==1)D.append($("<div>").text("No pushes are active.").addClass("text").css("margin-top","0.5em"));else{var e=[],h=[],i=$("<select>").css("margin-left","0.5em").append($("<option>").text("Any stream").val("")),
j=$("<select>").css("margin-left","0.5em").append($("<option>").text("Any target").val(""));for(f in a.push_list){e.indexOf(a.push_list[f][1])==-1&&e.push(a.push_list[f][1]);h.indexOf(a.push_list[f][2])==-1&&h.push(a.push_list[f][2])}e.sort();h.sort();for(f in e)i.append($("<option>").text(e[f]));for(f in h)j.append($("<option>").text(h[f]));D.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)}, j=$("<select>").css("margin-left","0.5em").append($("<option>").text("Any target").val(""));for(f in a.push_list){e.indexOf(a.push_list[f][1])==-1&&e.push(a.push_list[f][1]);h.indexOf(a.push_list[f][2])==-1&&h.push(a.push_list[f][2])}e.sort();h.sort();for(f in e)i.append($("<option>").text(e[f]));for(f in h)j.append($("<option>").text(h[f]));D.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)},
@ -194,14 +194,14 @@ pointer:{main:p,index:"async"},LTSonly:!0},{label:"Parameters",type:"str",help:$
break;case "Logs":var ta=$("<button>").text("Refresh now").click(function(){$(this).text("Loading..");mist.send(function(){da();ta.text("Refresh now")})}).css("padding","0.2em 0.5em").css("flex-grow",0);d.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, break;case "Logs":var ta=$("<button>").text("Refresh now").click(function(){$(this).text("Loading..");mist.send(function(){da();ta.text("Refresh now")})}).css("padding","0.2em 0.5em").css("flex-grow",0);d.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(){da()})},$(this).val()*1E3)},help:"How often the table below should be updated."},{label:"..or",type:"DOMfield",DOMfield:ta,help:"Instantly refresh the table below."}]));d.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");d.append($("<table>").addClass("logs").append(A)); "minute"],[300,"5 minutes"]],value:30,"function":function(){UI.interval.clear();UI.interval.set(function(){mist.send(function(){da()})},$(this).val()*1E3)},help:"How often the table below should be updated."},{label:"..or",type:"DOMfield",DOMfield:ta,help:"Instantly refresh the table below."}]));d.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");d.append($("<table>").addClass("logs").append(A));
var va=function(a){var b=$("<span>").text(a);switch(a){case "WARN":b.addClass("orange");break;case "ERROR":case "FAIL":b.addClass("red")}return b},da=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("|"),e;for(e in d)c.append($("<span>").text(d[e]));A.append($("<tr>").html($("<td>").text(UI.format.dateTime(a[b][0],"long")).css("white-space","nowrap")).append($("<td>").html(va(a[b][1])).css("text-align", var va=function(a){var b=$("<span>").text(a);switch(a){case "WARN":b.addClass("orange");break;case "ERROR":case "FAIL":b.addClass("red")}return b},da=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("|"),e;for(e in d)c.append($("<span>").text(d[e]));A.append($("<tr>").html($("<td>").text(UI.format.dateTime(a[b][0],"long")).css("white-space","nowrap")).append($("<td>").html(va(a[b][1])).css("text-align",
"center")).append($("<td>").html(c).css("text-align","left")))}}};da();break;case "Statistics":var B=$("<span>").text("Loading..");d.append(B);var p={graph:"new"},x=mist.stored.get().graphs?$.extend(!0,{},mist.stored.get().graphs):{},Q={};for(o in mist.data.streams)Q[o]=!0;for(o in mist.data.active_streams)Q[mist.data.active_streams[o]]=!0;var Q=Object.keys(Q).sort(),ea=[];for(o in mist.data.config.protocols)ea.push(mist.data.config.protocols[o].connector);ea.sort();mist.send(function(){UI.plot.datatype.templates.cpuload.cores= "center")).append($("<td>").html(c).css("text-align","left")))}}};da();break;case "Statistics":var B=$("<span>").text("Loading..");d.append(B);var p={graph:"new"},y=mist.stored.get().graphs?$.extend(!0,{},mist.stored.get().graphs):{},Q={};for(o in mist.data.streams)Q[o]=!0;for(o in mist.data.active_streams)Q[mist.data.active_streams[o]]=!0;var Q=Object.keys(Q).sort(),ea=[];for(o in mist.data.config.protocols)ea.push(mist.data.config.protocols[o].connector);ea.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;B.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:p,index:"graph"},classes:["graph_ids"], 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;B.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:p,index:"graph"},classes:["graph_ids"],
"function":function(){if($(this).val()){var a=B.find(".graph_xaxis"),b=B.find(".graph_id");if($(this).val()=="new"){a.children("option").prop("disabled",false);b.setval("Graph "+(Object.keys(x).length+1)).closest("label").show()}else{var c=x[$(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")}}}, "function":function(){if($(this).val()){var a=B.find(".graph_xaxis"),b=B.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:p,index:"id"},classes:["graph_id"],validate:[function(a){return a in x?{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:p,index:"xaxis"},value:"time",classes:["graph_xaxis"],"function":function(){$s=B.find(".graph_datatype");switch($(this).getval()){case "coords":$s.children("option").prop("disabled",true).filter('[value="coords"]').prop("disabled", {label:"Graph id",type:"str",pointer:{main:p,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:p,index:"xaxis"},value:"time",classes:["graph_xaxis"],"function":function(){$s=B.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"]],pointer:{main:p,index:"datatype"}, 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"]],pointer:{main:p,index:"datatype"},
classes:["graph_datatype"],"function":function(){$s=B.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:",Q],["protocol","The protocol:",ea]],pointer:{main:p,index:"origin"},value:["total"], classes:["graph_datatype"],"function":function(){$s=B.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:",Q],["protocol","The protocol:",ea]],pointer:{main:p,index:"origin"},value:["total"],
classes:["graph_origin"]},{type:"buttons",buttons:[{label:"Add data set",type:"save","function":function(){var a;if(p.graph=="new"){a=UI.plot.addGraph(p,b);x[a.id]=a;B.find("input.graph_id").val("");B.find("select.graph_ids").append($("<option>").text(a.id)).val(a.id).trigger("change")}else a=x[p.graph];var c=UI.plot.datatype.getOptions({datatype:p.datatype,origin:p.origin});a.datasets.push(c);UI.plot.save(a);UI.plot.go(x)}}]}]));var b=$("<div>").addClass("graph_container");d.append(b);var c=B.find("select.graph_ids"); classes:["graph_origin"]},{type:"buttons",buttons:[{label:"Add data set",type:"save","function":function(){var a;if(p.graph=="new"){a=UI.plot.addGraph(p,b);y[a.id]=a;B.find("input.graph_id").val("");B.find("select.graph_ids").append($("<option>").text(a.id)).val(a.id).trigger("change")}else a=y[p.graph];var c=UI.plot.datatype.getOptions({datatype:p.datatype,origin:p.origin});a.datasets.push(c);UI.plot.save(a);UI.plot.go(y)}}]}]));var b=$("<div>").addClass("graph_container");d.append(b);var c=B.find("select.graph_ids");
for(a in x){var e=UI.plot.addGraph(x[a],b);c.append($("<option>").text(e.id)).val(e.id);var g=[],f;for(f in x[a].datasets){var h=UI.plot.datatype.getOptions({datatype:x[a].datasets[f].datatype,origin:x[a].datasets[f].origin});g.push(h)}e.datasets=g;x[e.id]=e}c.trigger("change");UI.plot.go(x);UI.interval.set(function(){UI.plot.go(x)},1E4)},{active_streams:!0,capabilities:!0});break;case "Server Stats":if("undefined"==typeof mist.data.capabilities){mist.send(function(){UI.navto(a)},{capabilities:!0}); for(a in y){var e=UI.plot.addGraph(y[a],b);c.append($("<option>").text(e.id)).val(e.id);var g=[],f;for(f in y[a].datasets){var h=UI.plot.datatype.getOptions({datatype:y[a].datasets[f].datatype,origin:y[a].datasets[f].origin});g.push(h)}e.datasets=g;y[e.id]=e}c.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.navto(a)},{capabilities:!0});
d.append("Loading..");return}var fa=$("<table>"),F=$("<table>"),j={vheader:"CPUs",labels:["Model","Processor speed","Amount of cores","Amount of threads"],content:[]};for(o in mist.data.capabilities.cpu)b=mist.data.capabilities.cpu[o],j.content.push({header:"CPU #"+(Number(o)+1),body:[b.model,UI.format.addUnit(UI.format.number(b.mhz),"MHz"),b.cores,b.threads]});o=UI.buildVheaderTable(j);var ua=function(){var a=mist.data.capabilities.mem,b=mist.data.capabilities.load,a={vheader:"Memory",labels:["Used", d.append("Loading..");return}var fa=$("<table>"),F=$("<table>"),j={vheader:"CPUs",labels:["Model","Processor speed","Amount of cores","Amount of threads"],content:[]};for(o in mist.data.capabilities.cpu)b=mist.data.capabilities.cpu[o],j.content.push({header:"CPU #"+(Number(o)+1),body:[b.model,UI.format.addUnit(UI.format.number(b.mhz),"MHz"),b.cores,b.threads]});o=UI.buildVheaderTable(j);var ua=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);fa.replaceWith(a);fa=a;b={vheader:"Load average", "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);fa.replaceWith(a);fa=a;b={vheader:"Load average",
labels:["CPU use","1 minute","5 minutes","15 minutes"],content:[{header:"&nbsp;",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);F.replaceWith(b);F=b};ua();d.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", labels:["CPU use","1 minute","5 minutes","15 minutes"],content:[{header:"&nbsp;",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);F.replaceWith(b);F=b};ua();d.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",

View file

@ -3932,7 +3932,7 @@ var UI = {
var $preview_cont = $('<div>').css("flex-shrink","1").css("min-width","auto").css("max-width","100%"); var $preview_cont = $('<div>').css("flex-shrink","1").css("min-width","auto").css("max-width","100%");
$cont.append($preview_cont); $cont.append($preview_cont);
var $title = $('<div>'); var $title = $('<div>');
var $video = $('<div>').addClass('mistvideo').text('Loading player..').css("max-width","100%").css("flex-shrink","1").css("min-width","auto"); var $video = $('<div>').text('Loading player..').css("max-width","100%").css("flex-shrink","1").css("min-width","auto");
var $controls = $('<div>').addClass('controls'); var $controls = $('<div>').addClass('controls');
$preview_cont.append($video).append($title).append($controls);//.append($switches); $preview_cont.append($video).append($title).append($controls);//.append($switches);
@ -4279,6 +4279,7 @@ var UI = {
controls: true, controls: true,
autoplay: true, autoplay: true,
loop: false, loop: false,
muted: false,
fillSpace: false, fillSpace: false,
poster: '', poster: '',
urlappend: '', urlappend: '',
@ -4558,6 +4559,18 @@ var UI = {
$('.embed_code').setval(embedhtml(embedoptions)); $('.embed_code').setval(embedhtml(embedoptions));
}, },
help: 'If the video should restart when the end is reached.' help: 'If the video should restart when the end is reached.'
},{
label: 'Start muted',
type: 'checkbox',
pointer: {
main: embedoptions,
index: 'muted'
},
'function': function(){
embedoptions.muted = $(this).getval();
$('.embed_code').setval(embedhtml(embedoptions));
},
help: 'If the video should restart when the end is reached.'
},{ },{
label: 'Fill available space', label: 'Fill available space',
type: 'checkbox', type: 'checkbox',