diff --git a/embed/core.js b/embed/core.js index 16a87052..d3d7265b 100644 --- a/embed/core.js +++ b/embed/core.js @@ -56,18 +56,21 @@ MistPlayer.prototype.timer = { return i; }, remove: function(i){ - if (this.timers[i].interval) { - clearInterval(i); + if (i in this.timers) { + if (this.timers[i].interval) { + clearInterval(i); + } + else { + clearTimeout(i); + } + delete this.timers[i]; } - else { - clearTimeout(i); - } - delete this.timers[i]; }, clear: function(){ for (var i in this.timers) { this.remove(i); } + this.timers = {}; } }; @@ -900,12 +903,17 @@ function mistPlay(streamName,options) { err.innerHTML = displaymsg.replace(new RegExp("\n",'g'),'')+''; err.className = 'error'; var button = document.createElement('button'); + var i = document.createElement('div'); + button.appendChild(i); var t = document.createTextNode('Reload'); button.appendChild(t); err.appendChild(button); button.onclick = function(){ options.target.removeChild(err); delete options.startCombo; + if (err.timeOut) { + clearTimeout(err.timeOut); + } mistPlay(streamName,options); } @@ -913,6 +921,20 @@ function mistPlay(streamName,options) { protoplay.sendEvent('error',msg,options.target); + if (!('type' in info) || (info.type != 'vod')) { //always show the button timer, unless its a vod + //reload timeout + var delay = ('type' in info ? 20 : 60); + i.className = 'countdown'+delay; + err.timeOut = protoplay.timer.add(function(){ + protoplay.report({ + type: 'playback', + warn: 'Automatically checking if the stream is working now' + }); + embedLog('Triggering reload button because of timeout'); + button.click(); + },delay*1e3); + } + return err; } @@ -974,7 +996,7 @@ function mistPlay(streamName,options) { function onstreaminfo() { options.target.innerHTML = ''; options.target.removeAttribute('data-loading'); - embedLog('Stream info was loaded succesfully'); + embedLog('Stream info was loaded succesfully.'); //get streaminfo data var streaminfo = mistvideo[streamName]; @@ -982,12 +1004,22 @@ function mistPlay(streamName,options) { streaminfo.initTime = new Date(); if (!('source' in streaminfo)) { - mistError('Error while loading stream info.'); - protoplay.report({ - type: 'init', - error: 'No sources' - }); - return; + if ((streaminfo.type) && (streaminfo.type == 'live')) { + mistError('The live stream is currently offline.'); + return; + } + else if ('error' in streaminfo) { + mistError(streaminfo.error); + return; + } + else { + mistError('Error while parsing stream info.'); + protoplay.report({ + type: 'init', + error: 'No sources' + }); + return; + } } if (('forceType' in options) && (options.forceType)) { diff --git a/embed/mist.css b/embed/mist.css index a8793eaf..99364fc1 100644 --- a/embed/mist.css +++ b/embed/mist.css @@ -360,7 +360,7 @@ } } -.countdown { +.countdown, .countdown20, .countdown60 { height: 1em; width: 1em; display: inline-block; @@ -372,7 +372,7 @@ opacity: 0; animation: appear 20s step-start 1; } -.countdown:before { +.countdown:before, .countdown20:before, .countdown60:before { content: ''; display: block; margin-left: 50%; @@ -382,6 +382,12 @@ transform-origin: 0 50%; animation: rotate 10s linear 2, bg 20s step-end 1; } +.countdown60 { + animation: appear 60s step-start 1; +} +.coutndown60:before { + animation: rotate 30s linear 2, bg 60s step-end 1; +} @keyframes rotate { to { transform: rotate(.5turn); } } diff --git a/lsp/minified.js b/lsp/minified.js index a1e2af48..918e7539 100644 --- a/lsp/minified.js +++ b/lsp/minified.js @@ -123,11 +123,11 @@ M=$("").append($("").text("Automatic").val("")).change(function( 1E3)+"]";if(ma==c){var a=A.children().last(),b=a.children("[data-amount]"),e=b.attr("data-amount");e++;b.text("("+e+"x)").attr("data-amount",e);a.children(".timestamp").text(d)}else{A.append($("").append($("").addClass("timestamp").text(d).css("margin-right","0.5em")).append($("").text(a.originalEvent.message)).append($("").attr("data-amount",1).css("margin-left","0.5em")).addClass(a.type=="error"?"red":""));b&&A.scrollTop(A[0].scrollHeight)}ma=c});var na=function(){Y.text(""); var a=document.createElement("script");c.append(a);a.src=Q+"player.js";a.onerror=function(){N.html("Failed to load player.js").append($("").text("Reload").css("display","block").click(function(){na()}))};a.onload=function(){for(var d in mistplayers)R.append($("").text(mistplayers[d].name).val(d));Z();N.on("initialized",function(){if(M.children().length<=1)for(var a in mistvideo[b].source){var c=mistvideo[b].source[a],d=UI.humanMime(c.type);M.append($("").val(a).text(d?d+" @ "+ c.url.substring(c.url.length-c.relurl.length,0):UI.format.capital(c.type)+" @ "+c.url.substring(c.url.length-c.relurl.length,0)))}a=mistvideo[b].embedded[mistvideo[b].embedded.length-1];d=UI.humanMime(a.player.options.source.type);Y.html("You're watching "+(d?d+" ("+a.player.options.source.type+")":UI.format.capital(a.player.options.source.type))+" through "+mistplayers[a.selectedPlayer].name+".")});c[0].removeChild(a)}};na();g=$("").append($("").text("Meta information")); -var S=$("").text("Loading..");g.append(S);I.append(g);$.ajax({type:"GET",url:Q+"json_"+F+".js",success:function(a){var b=a.meta;if(b){a=[];a.push({label:"Type",type:"span",value:b.live?"Live":"Pre-recorded (VoD)"});"format"in b&&a.push({label:"Format",type:"span",value:b.format});b.live&&a.push({label:"Buffer window",type:"span",value:UI.format.addUnit(b.buffer_window,"ms")});var c={audio:{vheader:"Audio",labels:["Codec","Duration","Peak bitrate","Channels","Samplerate","Language"],content:[]}, -video:{vheader:"Video",labels:["Codec","Duration","Peak bitrate","Size","Framerate","Language"],content:[]},subtitle:{vheader:"Subtitles",labels:["Codec","Duration","Peak bitrate","Language"],content:[]}},d=Object.keys(b.tracks);d.sort(function(a,b){a=a.split("_").pop();b=b.split("_").pop();return a-b});for(var e in d){var g=d[e],f=b.tracks[g];switch(f.type){case "audio":c.audio.content.push({header:"Track "+g.split("_").pop(),body:[f.codec,UI.format.duration((f.lastms-f.firstms)/1E3)+""+ -UI.format.duration(f.firstms/1E3)+" to "+UI.format.duration(f.lastms/1E3)+"",UI.format.bytes(f.bps,1),f.channels,UI.format.addUnit(UI.format.number(f.rate),"Hz"),"lang"in f?f.lang:"unknown"]});break;case "video":c.video.content.push({header:"Track "+g.split("_").pop(),body:[f.codec,UI.format.duration((f.lastms-f.firstms)/1E3)+""+UI.format.duration(f.firstms/1E3)+" to "+UI.format.duration(f.lastms/1E3)+"",UI.format.bytes(f.bps,1),UI.format.addUnit(f.width, -"x ")+UI.format.addUnit(f.height,"px"),UI.format.addUnit(UI.format.number(f.fpks/1E3),"fps"),"lang"in f?f.lang:"unknown"]});break;case "subtitle":c.subtitle.content.push({header:"Track "+g.split("_").pop(),body:[f.codec,UI.format.duration((f.lastms-f.firstms)/1E3)+""+UI.format.duration(f.firstms/1E3)+" to "+UI.format.duration(f.lastms/1E3)+"",UI.format.bytes(f.bps,1),"lang"in f?f.lang:"unknown"]})}}e=["audio","video","subtitle"];b=$("").css({display:"flex", -"flex-flow":"row wrap","font-size":"0.9em"});for(g in e)c[e[g]].content.length&&b.append(UI.buildVheaderTable(c[e[g]]).css("width","auto"));a.push($("").text("Tracks:"));a.push(b);S.html(UI.buildUI(a))}else S.html("No meta information available.")},error:function(){S.html("Error while retrieving stream info.")}});break;case "Embed":""==b&&UI.navTo("Streams");r="";-1==b.indexOf("+")&&(r=$("").addClass("settings").text("Settings").click(function(){UI.navto("Edit",b)}));c.html($("").addClass("bigbuttons").append(r).append($("").text("Preview").addClass("preview").click(function(){UI.navto("Preview", +var S=$("").text("Loading..");g.append(S);I.append(g);$.ajax({type:"GET",url:Q+"json_"+F+".js",success:function(a){var b=a.meta;if(!b||!b.tracks)S.html("No meta information available.");else{a=[];a.push({label:"Type",type:"span",value:b.live?"Live":"Pre-recorded (VoD)"});"format"in b&&a.push({label:"Format",type:"span",value:b.format});b.live&&a.push({label:"Buffer window",type:"span",value:UI.format.addUnit(b.buffer_window,"ms")});var c={audio:{vheader:"Audio",labels:["Codec","Duration","Peak bitrate", +"Channels","Samplerate","Language"],content:[]},video:{vheader:"Video",labels:["Codec","Duration","Peak bitrate","Size","Framerate","Language"],content:[]},subtitle:{vheader:"Subtitles",labels:["Codec","Duration","Peak bitrate","Language"],content:[]}},d=Object.keys(b.tracks);d.sort(function(a,b){a=a.split("_").pop();b=b.split("_").pop();return a-b});for(var e in d){var g=d[e],f=b.tracks[g];switch(f.type){case "audio":c.audio.content.push({header:"Track "+g.split("_").pop(),body:[f.codec,UI.format.duration((f.lastms- +f.firstms)/1E3)+""+UI.format.duration(f.firstms/1E3)+" to "+UI.format.duration(f.lastms/1E3)+"",UI.format.bytes(f.bps,1),f.channels,UI.format.addUnit(UI.format.number(f.rate),"Hz"),"lang"in f?f.lang:"unknown"]});break;case "video":c.video.content.push({header:"Track "+g.split("_").pop(),body:[f.codec,UI.format.duration((f.lastms-f.firstms)/1E3)+""+UI.format.duration(f.firstms/1E3)+" to "+UI.format.duration(f.lastms/1E3)+"",UI.format.bytes(f.bps, +1),UI.format.addUnit(f.width,"x ")+UI.format.addUnit(f.height,"px"),UI.format.addUnit(UI.format.number(f.fpks/1E3),"fps"),"lang"in f?f.lang:"unknown"]});break;case "subtitle":c.subtitle.content.push({header:"Track "+g.split("_").pop(),body:[f.codec,UI.format.duration((f.lastms-f.firstms)/1E3)+""+UI.format.duration(f.firstms/1E3)+" to "+UI.format.duration(f.lastms/1E3)+"",UI.format.bytes(f.bps,1),"lang"in f?f.lang:"unknown"]})}}e=["audio","video","subtitle"];b=$("").css({display:"flex", +"flex-flow":"row wrap","font-size":"0.9em"});for(g in e)c[e[g]].content.length&&b.append(UI.buildVheaderTable(c[e[g]]).css("width","auto"));a.push($("").text("Tracks:"));a.push(b);S.html(UI.buildUI(a))}},error:function(){S.html("Error while retrieving stream info.")}});break;case "Embed":""==b&&UI.navTo("Streams");r="";-1==b.indexOf("+")&&(r=$("").addClass("settings").text("Settings").click(function(){UI.navto("Edit",b)}));c.html($("").addClass("bigbuttons").append(r).append($("").text("Preview").addClass("preview").click(function(){UI.navto("Preview", b)})).append($("").addClass("cancel").addClass("return").text("Return").click(function(){UI.navto("Streams")}))).append($("").text('Embed "'+b+'"'));var T=$("");c.append(T);F=encodeURIComponent(b);r=parseURL(mist.user.host);e={"":{port:":8080"}};for(g in mist.data.config.protocols){d=mist.data.config.protocols[g];if("HTTP"==d.connector||"HTTP.exe"==d.connector)e[""].port=d.port?":"+d.port:":8080";if("HTTPS"==d.connector||"HTTPS.exe"==d.connector)e.s={},e.s.port=d.port?":"+d.port: ":4433"}var G=Q="http://"+r.host+e[""].port+"/";if(otherhost.host||otherhost.https)G=(otherhost.https&&"s"in e?"https://":"http://")+(otherhost.host?otherhost.host:r.host)+(otherhost.https&&"s"in e?e.s.port:e[""].port)+"/";var aa={forcePlayer:"",forceType:"",controls:!0,autoplay:!0,loop:!1,width:"",height:"",maxwidth:"",maxheight:"",poster:"",urlappend:"",setTracks:{}},o=$.extend({},aa);g=UI.stored.getOpts();"embedoptions"in g&&(o=$.extend(o,g.embedoptions,!0),"object"!=typeof o.setTracks&&(o.setTracks= {}));g={};switch(o.controls){case "stock":g.controls="stock";break;case !0:g.controls=1;break;case !1:g.controls=0}var w=function(){function a(b){switch(typeof b){case "string":return $.isNumeric(b)?b:'"'+b+'"';case "object":return JSON.stringify(b);default:return b}}UI.stored.saveOpt("embedoptions",o);for(var c=b+"_",d=12,e="";d--;){var g;g=Math.floor(Math.random()*62);g=g<10?g:g<36?String.fromCharCode(g+55):String.fromCharCode(g+61);e=e+g}var c=c+e,d=['target: document.getElementById("'+c+'")'], diff --git a/lsp/mist.js b/lsp/mist.js index 574f286a..7fa538b5 100644 --- a/lsp/mist.js +++ b/lsp/mist.js @@ -3531,7 +3531,7 @@ var UI = { $cont.append($trackinfo); function buildTrackinfo(info) { var meta = info.meta; - if (!meta) { + if ((!meta) || (!meta.tracks)) { $tracktable.html('No meta information available.'); return; }