Embed: allow options.setTracks to set subtitles

This commit is contained in:
Cat 2019-02-18 13:56:27 +01:00 committed by Thulinma
parent b5750a5de7
commit 06eb78c345
5 changed files with 128 additions and 61 deletions

File diff suppressed because one or more lines are too long

View file

@ -782,21 +782,68 @@ function MistVideo(streamName,options) {
}
if (options.setTracks) {
if ("setTrack" in MistVideo.player.api) {
MistVideo.player.onready(function(){
for (var i in options.setTracks) {
MistVideo.player.api.setTrack(i,options.setTracks[i]);
}
if (options.setTracks) {
var setTracks = MistUtil.object.extend({},options.setTracks);
if (("subtitle" in options.setTracks) && ("setSubtitle" in MistVideo.player.api)) {
MistVideo.player.onready(function(){
//find the source for subtitles
var subtitleSource = false;
for (var i in MistVideo.info.source) {
var source = MistVideo.info.source[i];
//this is a subtitle source, and it's the same protocol (HTTP/HTTPS) as the video source
if ((source.type == "html5/text/vtt") && (MistUtil.http.url.split(source.url).protocol == MistUtil.http.url.split(MistVideo.source.url).protocol)) {
subtitleSource = source.url.replace(/.srt$/,".vtt");
break;
}
});
}
else if ("setTracks" in MistVideo.player.api) {
MistVideo.player.onready(function(){
MistVideo.player.api.setTracks(options.setTracks);
});
}
}
if (!subtitleSource) { return; }
//find the track meta information
var tracks = MistUtil.tracks.parse(MistVideo.info.meta.tracks);
if (!("subtitle" in tracks) || !(setTracks.subtitle in tracks.subtitle)) { return; }
meta = tracks.subtitle[setTracks.subtitle];
//add source to the meta
meta.src = MistUtil.http.url.addParam(subtitleSource,{track:setTracks.subtitle});
meta.label = "automatic";
meta.lang = "unknown";
MistVideo.player.api.setSubtitle(meta);
MistUtil.event.send("playerUpdate_trackChanged",{
type: "subtitle",
trackid: setTracks.subtitle
}, MistVideo.video);
delete setTracks.subtitle;
});
}
if ("setTrack" in MistVideo.player.api) {
MistVideo.player.onready(function(){
for (var i in setTracks) {
MistVideo.player.api.setTrack(i,setTracks[i]);
MistUtil.event.send("playerUpdate_trackChanged",{
type: i,
trackid: setTracks[i]
}, MistVideo.video);
}
});
}
else if ("setTracks" in MistVideo.player.api) {
MistVideo.player.onready(function(){
MistVideo.player.api.setTracks(setTracks);
});
for (var i in setTracks) {
MistUtil.event.send("playerUpdate_trackChanged",{
type: i,
trackid: setTracks[i]
}, MistVideo.video);
}
}
}
}

View file

@ -1292,23 +1292,23 @@ MistSkins["default"] = {
return MistVideo.player.api.setTrack(type,value);
}
else {
//gather what tracks we should use
var usetracks = {};
for (var i in selections) {
if ((i == "subtitle") || (selections[i].value == "")) { continue; } //subtitle tracks are handled seperately
usetracks[i] = selections[i].value;
}
if (value != ""){ usetracks[type] = value; }
//use setTracks
if ("setTracks" in MistVideo.player.api) {
return MistVideo.player.api.setTracks(usetracks);
}
//use setSource
if ("setSource" in MistVideo.player.api) {
return MistVideo.player.api.setSource(
MistUtil.http.url.addParam(MistVideo.source.url,usetracks)
);
}
//gather what tracks we should use
var usetracks = {};
for (var i in selections) {
if ((i == "subtitle") || (selections[i].value == "")) { continue; } //subtitle tracks are handled seperately
usetracks[i] = selections[i].value;
}
if (value != ""){ usetracks[type] = value; }
//use setTracks
if ("setTracks" in MistVideo.player.api) {
return MistVideo.player.api.setTracks(usetracks);
}
//use setSource
if ("setSource" in MistVideo.player.api) {
return MistVideo.player.api.setSource(
MistUtil.http.url.addParam(MistVideo.source.url,usetracks)
);
}
}
}
@ -1463,8 +1463,12 @@ MistSkins["default"] = {
//add options to the select
function n(str) {
if (str == "") { return -1; }
return Number(str);
}
var options = MistUtil.object.keys(t,function(a,b){
return Number(a) - Number(b);
return n(a) - n(b);
}); //sort them
for (var i in options) {
var track = t[options[i]];
@ -1479,6 +1483,15 @@ MistSkins["default"] = {
option.appendChild(document.createTextNode("Track "+(Number(i)+1)));
}
}
MistUtil.event.addListener(MistVideo.video,"playerUpdate_trackChanged",function(e){
if (e.message.type != type) { return; }
select.value = e.message.trackid;
MistVideo.log("Player selected "+type+" track with id "+e.message.trackid);
},select);
if (type == "subtitle") {
MistUtil.event.addListener(select,"change",function(){
try {
@ -1538,13 +1551,6 @@ MistSkins["default"] = {
}
*/
MistUtil.event.addListener(MistVideo.video,"playerUpdate_trackChanged",function(e){
if (e.message.type != type) { return; }
select.value = e.message.trackid;
MistVideo.log("Player selected "+type+" track with id "+e.message.trackid);
},select);
}
}
else {

View file

@ -159,22 +159,22 @@ $(this).getval();$(".embed_code").setval(x(q))},help:"If the video should restar
{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))}},
{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=
[],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);
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")]=
$(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);
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;
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",
"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]])},
{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]==
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."}]));
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",
"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)},
{push_stop:c});g.find("tr:not(:first-child)").html($("<td colspan=99>").append($("<span>").addClass("red").text("Stopping..")));$(this).remove()}})).append($("<label>").css("margin-left","1em").append($("<span>").text("Stop all pushes that match: ").css("font-size","0.9em")).append(i).append($("<span>").css("margin-left","0.5em").text("and").css("font-size","0.9em")).append(j).append($("<button>").css("margin-left","0.5em").text("Apply").click(function(){var c=i.val(),d=j.val();if(c==""&&d=="")return alert("Looks like you want to stop all pushes. Maybe you should use that button?");
var e={},f;for(f in a.push_list)if((c==""||a.push_list[f][1]==c)&&(d==""||a.push_list[f][2]==d))e[a.push_list[f][0]]=a.push_list[f];if(Object.keys(e).length==0)return alert("No matching pushes.");c="Are you sure you want to stop these pushes?\n\n";for(f in e)c=c+(e[f][1]+" to "+e[f][2]+"\n");if(confirm(c)){e=Object.keys(e);mist.send(function(){b(e)},{push_stop:e});for(f in e)g.find("tr[data-pushid="+e[f]+"]").html($("<td colspan=99>").html($("<span>").addClass("red").text("Stopping..")))}}))).append(g)}},
{push_settings:1,push_list:1,push_auto_list:1});break;case "Start Push":if(!("capabilities"in mist.data)){d.append("Loading Mist capabilities..");mist.send(function(){UI.navto("Start Push",c)},{capabilities:1});return}var v,T=function(a){var b=false,e=c.split("_");c=e[0];e.length==2&&(b=e[1]);if(b!==false&&typeof a=="undefined")mist.send(function(a){T(a.push_auto_list[b])},{push_auto_list:1});else{var g=[],f;for(f in mist.data.capabilities.connectors){e=mist.data.capabilities.connectors[f];"push_urls"in
e&&(g=g.concat(e.push_urls))}c=="auto"&&d.find("h2").text("Add automatic push");var h={};if(c=="auto"&&typeof a!="undefined"){h={stream:a[0],target:a[1]};if(a.length>=3)h.scheduletime=a[2];if(a.length>=4)h.completetime=a[3];if(h.target.indexOf("recstartunix=")>-1){f=h.target.split("recstartunix=")[1];h.recstartunix=f.split("&")[0];h.target=h.target.replace("recstartunix="+h.recstartunix,"").replace("?&","?").replace("&&","&");if(h.target[h.target.length-1]=="?")h.target=h.target.slice(0,-1)}}f=[{label:"Stream name",
type:"str",help:"This may either be a full stream name, a partial wildcard stream name, or a full wildcard stream name.<br>For example, given the stream <i>a</i> you can use: <ul> <li><i>a</i>: the stream configured as <i>a</i></li> <li><i>a+</i>: all streams configured as <i>a</i> with a wildcard behind it, but not <i>a</i> itself</li> <li><i>a+b</i>: only the version of stream <i>a</i> that has wildcard <i>b</i></li> </ul>",
d.val(q.prioritize_type);ba.html(UI.buildUI(b));L.html("");b={};for(g in a.meta.tracks){c=a.meta.tracks[g];if(c.codec=="subtitle")c.type="subtitle";if(!(c.type!="audio"&&c.type!="video"&&c.type!="subtitle")){c.type in b||(b[c.type]=c.type=="subtitle"?[]:[["","Autoselect "+c.type]]);b[c.type].push([c.trackid,UI.format.capital(c.type)+" track "+(b[c.type].length+(c.type=="subtitle"?1:0))])}}if(Object.keys(b).length){L.closest("label").show();var a=["audio","video","subtitle"],h;for(h in a){g=a[h];if(b[g].length){c=
$("<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(x(q))});L.append(c);g=="subtitle"?b[g].unshift(["","No "+g]):b[g].push([-1,"No "+g]);for(var i in b[g])c.append($("<option>").val(b[g][i][0]).text(b[g][i][1]));if(g in q.setTracks){c.val(q.setTracks[g]);if(c.val()==null){c.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);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;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","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]])},{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]==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."}]));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","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)},{push_stop:c});g.find("tr:not(:first-child)").html($("<td colspan=99>").append($("<span>").addClass("red").text("Stopping..")));$(this).remove()}})).append($("<label>").css("margin-left","1em").append($("<span>").text("Stop all pushes that match: ").css("font-size","0.9em")).append(i).append($("<span>").css("margin-left","0.5em").text("and").css("font-size",
"0.9em")).append(j).append($("<button>").css("margin-left","0.5em").text("Apply").click(function(){var c=i.val(),d=j.val();if(c==""&&d=="")return alert("Looks like you want to stop all pushes. Maybe you should use that button?");var e={},f;for(f in a.push_list)if((c==""||a.push_list[f][1]==c)&&(d==""||a.push_list[f][2]==d))e[a.push_list[f][0]]=a.push_list[f];if(Object.keys(e).length==0)return alert("No matching pushes.");c="Are you sure you want to stop these pushes?\n\n";for(f in e)c=c+(e[f][1]+
" to "+e[f][2]+"\n");if(confirm(c)){e=Object.keys(e);mist.send(function(){b(e)},{push_stop:e});for(f in e)g.find("tr[data-pushid="+e[f]+"]").html($("<td colspan=99>").html($("<span>").addClass("red").text("Stopping..")))}}))).append(g)}},{push_settings:1,push_list:1,push_auto_list:1});break;case "Start Push":if(!("capabilities"in mist.data)){d.append("Loading Mist capabilities..");mist.send(function(){UI.navto("Start Push",c)},{capabilities:1});return}var v,T=function(a){var b=false,e=c.split("_");
c=e[0];e.length==2&&(b=e[1]);if(b!==false&&typeof a=="undefined")mist.send(function(a){T(a.push_auto_list[b])},{push_auto_list:1});else{var g=[],f;for(f in mist.data.capabilities.connectors){e=mist.data.capabilities.connectors[f];"push_urls"in e&&(g=g.concat(e.push_urls))}c=="auto"&&d.find("h2").text("Add automatic push");var h={};if(c=="auto"&&typeof a!="undefined"){h={stream:a[0],target:a[1]};if(a.length>=3)h.scheduletime=a[2];if(a.length>=4)h.completetime=a[3];if(h.target.indexOf("recstartunix=")>
-1){f=h.target.split("recstartunix=")[1];h.recstartunix=f.split("&")[0];h.target=h.target.replace("recstartunix="+h.recstartunix,"").replace("?&","?").replace("&&","&");if(h.target[h.target.length-1]=="?")h.target=h.target.slice(0,-1)}}f=[{label:"Stream name",type:"str",help:"This may either be a full stream name, a partial wildcard stream name, or a full wildcard stream name.<br>For example, given the stream <i>a</i> you can use: <ul> <li><i>a</i>: the stream configured as <i>a</i></li> <li><i>a+</i>: all streams configured as <i>a</i> with a wildcard behind it, but not <i>a</i> itself</li> <li><i>a+b</i>: only the version of stream <i>a</i> that has wildcard <i>b</i></li> </ul>",
pointer:{main:h,index:"stream"},validate:["required",function(a){a=a.split("+");a=a[0];return a in mist.data.streams?false:{msg:"'"+a+"' is not a stream name.",classes:["orange"],"break":false}}],datalist:v,LTSonly:1},{label:"Target",type:"str",help:"Where the stream will be pushed to.<br> Valid formats: <ul> <li>"+g.join("</li><li>")+"</li> </ul> Valid text replacements: <ul> <li>$stream - inserts the stream name used to push to MistServer</li> <li>$day - inserts the current day number</li><li>$month - inserts the current month number</li> <li>$year - inserts the current year number</li><li>$hour - inserts the hour timestamp when stream was received</li> <li>$minute - inserts the minute timestamp the stream was received</li> <li>$seconds - inserts the seconds timestamp when the stream was received</li> <li>$datetime - inserts $year.$month.$day.$hour.$minute.$seconds timestamp when the stream was received</li> </ul> Valid URL parameters: <ul> <li>recstart=123 - media timestamp in milisseconds where the push should start</li> <li>recstop=456 - media timestamp in miliseconds where the push should stop</li> <li>recstartunix=150000000 - unix time in seconds where the push should start. This will override the recstart parameter.</li> <li>recstopunix=150000000 - unix time in seconds where the push should stop. This will override the recstop parameter.</li> </ul>",
pointer:{main:h,index:"target"},validate:["required",function(a){for(var b in g)if(mist.inputMatch(g[b],a))return false;return{msg:"Does not match a valid target.<br>Valid formats:<ul><li>"+g.join("</li><li>")+"</li></ul>",classes:["red"]}}],LTSonly:1}];c=="auto"&&f.push($("<h4>").text("Optional parameters"),{type:"unix",label:"Schedule time",min:0,help:"The time where the push will become active. The default is to start immediately.",pointer:{main:h,index:"scheduletime"}},{type:"unix",label:"Recording start time",
min:0,help:"Where in the media buffer the recording will start. Defaults to the most recently received keyframe.<br>Only makes sense for live streams.",pointer:{main:h,index:"recstartunix"}},{type:"unix",label:"Complete time",min:0,help:"The time where the push will stop. Defaults to never stop automatically.<br>Only makes sense for live streams.",pointer:{main:h,index:"completetime"}});f.push({type:"buttons",buttons:[{type:"cancel",label:"Cancel","function":function(){UI.navto("Push")}},{type:"save",

View file

@ -4667,18 +4667,27 @@ var UI = {
var tracks = {};
for (var i in d.meta.tracks) {
var t = d.meta.tracks[i];
if ((t.type != 'audio') && (t.type != 'video')) { continue; }
if (t.codec == "subtitle") {
t.type = "subtitle";
}
if ((t.type != 'audio') && (t.type != 'video') && (t.type != "subtitle")) { continue; }
if (!(t.type in tracks)) {
tracks[t.type] = [['',UI.format.capital(t.type)+' track 1']];
}
else {
tracks[t.type].push([t.trackid,UI.format.capital(t.type)+' track '+(tracks[t.type].length+1)]);
if (t.type == "subtitle") {
tracks[t.type] = [];
}
else {
tracks[t.type] = [[(''),"Autoselect "+t.type]];
}
}
tracks[t.type].push([t.trackid,UI.format.capital(t.type)+' track '+(tracks[t.type].length+(t.type == "subtitle" ? 1 : 0))]);
}
if (Object.keys(tracks).length) {
$setTracks.closest('label').show();
for (var i in tracks) {
var trackarray = ["audio","video","subtitle"];
for (var n in trackarray) {
var i = trackarray[n];
if (!tracks[i].length) { continue; }
var $select = $('<select>').attr('data-type',i).css('flex-grow','1').change(function(){
if ($(this).val() == '') {
delete embedoptions.setTracks[$(this).attr('data-type')];
@ -4689,7 +4698,12 @@ var UI = {
$('.embed_code').setval(embedhtml(embedoptions));
});
$setTracks.append($select);
tracks[i].push([-1,'No '+i]);
if (i == "subtitle") {
tracks[i].unshift(["","No "+i]);
}
else {
tracks[i].push([-1,'No '+i]);
}
for (var j in tracks[i]) {
$select.append(
$('<option>').val(tracks[i][j][0]).text(tracks[i][j][1])