From c66d236e5896d896ff7e12e467468269b7f41995 Mon Sep 17 00:00:00 2001 From: Cat Date: Wed, 5 Oct 2022 16:42:13 +0200 Subject: [PATCH] LSP: updates to push parameters Includes: - new buildUI element option 'postSave' - new buildUI element option 'prefix' - validation 'track_selector_parameter' and 'track_selector' in convertBuildOptions now expand help text - new element option 'disable' in convertBuildOptions - new element type 'bool' in convertBuildOptions (equals checkbox) - new element type 'unixtime' in convertBuildOptions - new element option 'format' in convertBuildOptions - UI for scheduling automated pushes based on variables - MistServer: sorting of capabilities.push_parameters - Prevent an empty (null) variable_list to break adding automatic pushes - automatic push config: start and stop if conditions - Fix LSP to hide endVariableValue on boolean expression - Remove references to current evaluation in LSP - Also remove the start variable requirement from the frontend - allow endVariabbles without startVariables, bugfix variable value hint - push target url parameters: dump 'leftover' params in a custom params field; added customizable inputlist inputs - autopushes: when the variable settings are not set, they are '', not 0. Also trigger onchange of comparison operator fields when the edit page loads so the variable value fields are shown or hidden properly. - autopush tab onchange maar nu goed (?) fixup pl0x - autopush: there's fun and joy in making Jaron do multiple fixups - autopush tab: not my fault Balder asks one change at a time D: --- lib/config.cpp | 20 ++ lsp/main.css | 35 +-- lsp/minified.js | 470 +++++++++++++++++---------------- lsp/mist.js | 445 ++++++++++++++++++++++++++----- src/process/process_ffmpeg.cpp | 3 +- 5 files changed, 659 insertions(+), 314 deletions(-) diff --git a/lib/config.cpp b/lib/config.cpp index d0aba75a..f849fc57 100644 --- a/lib/config.cpp +++ b/lib/config.cpp @@ -734,47 +734,56 @@ void Util::Config::addStandardPushCapabilities(JSON::Value &cap){ pp["audio"]["help"] = "Override which audio tracks of the stream should be selected"; pp["audio"]["type"] = "string"; pp["audio"]["validate"][0u] = "track_selector"; + pp["audio"]["sort"] = "aa"; pp["video"]["name"] = "Video track(s)"; pp["video"]["help"] = "Override which video tracks of the stream should be selected"; pp["video"]["type"] = "string"; pp["video"]["validate"][0u] = "track_selector"; + pp["video"]["sort"] = "ab"; pp["subtitle"]["name"] = "Subtitle track(s)"; pp["subtitle"]["help"] = "Override which subtitle tracks of the stream should be selected"; pp["subtitle"]["type"] = "string"; pp["subtitle"]["validate"].append("track_selector"); + pp["subtitle"]["sort"] = "ac"; pp["rate"]["name"] = "Playback rate"; pp["rate"]["help"] = "Multiplier for the playback speed rate, or 0 to not limit"; pp["rate"]["type"] = "int"; pp["rate"]["default"] = "1"; + pp["rate"]["sort"] = "ba"; pp["realtime"]["name"] = "Don't speed up output"; pp["realtime"]["help"] = "If set to any value, removes the rate override to unlimited normally applied to push outputs"; pp["realtime"]["type"] = "bool"; pp["realtime"]["format"] = "set_or_unset"; + pp["realtime"]["sort"] = "bb"; pp["unmask"]["name"] = "Unmask tracks"; pp["unmask"]["help"] = "If set to any value, removes any applied track masking before selecting tracks, acting as if no mask was applied at all"; pp["unmask"]["type"] = "bool"; pp["unmask"]["format"] = "set_or_unset"; + pp["unmask"]["sort"] = "bc"; pp["waittrackcount"]["name"] = "Wait for GOP count"; pp["waittrackcount"]["help"] = "Before starting, wait until this number of GOPs is available in the main selected track"; pp["waittrackcount"]["type"] = "int"; pp["waittrackcount"]["default"] = 2; + pp["waittrackcount"]["sort"] = "bd"; pp["maxwaittrackms"]["name"] = "Max buffer duration for GOP count wait"; pp["maxwaittrackms"]["help"] = "When waiting for GOPs on the main track, give up when this much data is available in the main track buffer"; pp["maxwaittrackms"]["type"] = "int"; pp["maxwaittrackms"]["default"] = "5s, or 120s when using a non-default GOP count"; pp["maxwaittrackms"]["unit"] = "ms"; + pp["maxwaittrackms"]["sort"] = "be"; pp["append"]["name"] = "Append to file"; pp["append"]["help"] = "If set to any value, will (if possible) append to an existing file, rather than overwriting it"; pp["append"]["type"] = "bool"; pp["append"]["format"] = "set_or_unset"; + pp["append"]["sort"] = "bf"; pp["pushdelay"]["name"] = "Push delay"; pp["pushdelay"]["help"] = "Ensures the stream is always delayed by at least this many seconds. Internally overrides the \"realtime\" and \"start\" parameters"; @@ -782,11 +791,13 @@ void Util::Config::addStandardPushCapabilities(JSON::Value &cap){ pp["pushdelay"]["unit"] = "s"; pp["pushdelay"]["disable"].append("realtime"); pp["pushdelay"]["disable"].append("start"); + pp["pushdelay"]["sort"] = "bg"; pp["split"]["name"] = "Split interval"; pp["split"]["help"] = "Performs a gapless restart of the recording every this may seconds. Always aligns to the next keyframe after this duration, to ensure each recording is fully playable"; pp["split"]["type"] = "int"; pp["split"]["unit"] = "s"; + pp["split"]["sort"] = "bh"; pp["duration"]["name"] = "Duration of push"; pp["duration"]["help"] = "How much media time to push, in seconds. Internally overrides \"recstop\""; @@ -794,18 +805,21 @@ void Util::Config::addStandardPushCapabilities(JSON::Value &cap){ pp["duration"]["unit"] = "s"; pp["duration"]["disable"].append("recstop"); pp["duration"]["disable"].append("stop"); + pp["duration"]["sort"] = "bi"; pp["stop"]["name"] = "Media timestamp to stop at"; pp["stop"]["help"] = "What internal media timestamp to stop at"; pp["stop"]["type"] = "int"; pp["stop"]["unit"] = "s"; pp["stop"]["prot_only"] = true; + pp["stop"]["sort"] = "bk"; pp["start"]["name"] = "Media timestamp to start from"; pp["start"]["help"] = "What internal media timestamp to start from"; pp["start"]["type"] = "int"; pp["start"]["unit"] = "s"; pp["start"]["prot_only"] = true; + pp["start"]["sort"] = "bl"; pp["stopunix"]["name"] = "Unix timestamp to stop at"; pp["stopunix"]["help"] = "What unix timestamp to stop at"; @@ -813,6 +827,7 @@ void Util::Config::addStandardPushCapabilities(JSON::Value &cap){ pp["stopunix"]["unit"] = "s"; pp["stopunix"]["prot_only"] = true; pp["stopunix"]["disable"].append("stop"); + pp["stopunix"]["sort"] = "bm"; pp["startunix"]["name"] = "Unix timestamp to start from"; pp["startunix"]["help"] = "What unix timestamp to start from"; @@ -820,18 +835,21 @@ void Util::Config::addStandardPushCapabilities(JSON::Value &cap){ pp["startunix"]["unit"] = "s"; pp["startunix"]["prot_only"] = true; pp["startunix"]["disable"].append("start"); + pp["startunix"]["sort"] = "bn"; pp["recstop"]["name"] = "Media timestamp to stop at"; pp["recstop"]["help"] = "What internal media timestamp to stop at"; pp["recstop"]["type"] = "int"; pp["recstop"]["unit"] = "s"; pp["recstop"]["file_only"] = true; + pp["recstop"]["sort"] = "bo"; pp["recstart"]["name"] = "Media timestamp to start from"; pp["recstart"]["help"] = "What internal media timestamp to start from"; pp["recstart"]["type"] = "int"; pp["recstart"]["unit"] = "s"; pp["recstart"]["file_only"] = true; + pp["recstart"]["sort"] = "bp"; pp["recstopunix"]["name"] = "Unix timestamp to stop at"; pp["recstopunix"]["help"] = "What unix timestamp to stop at"; @@ -839,6 +857,7 @@ void Util::Config::addStandardPushCapabilities(JSON::Value &cap){ pp["recstopunix"]["unit"] = "s"; pp["recstopunix"]["file_only"] = true; pp["recstopunix"]["disable"].append("recstop"); + pp["recstopunix"]["sort"] = "bq"; pp["recstartunix"]["name"] = "Unix timestamp to start from"; pp["recstartunix"]["help"] = "What unix timestamp to start from"; @@ -846,6 +865,7 @@ void Util::Config::addStandardPushCapabilities(JSON::Value &cap){ pp["recstartunix"]["unit"] = "s"; pp["recstartunix"]["file_only"] = true; pp["recstartunix"]["disable"].append("recstart"); + pp["recstartunix"]["sort"] = "br"; } diff --git a/lsp/main.css b/lsp/main.css index 9289d211..a7f34fe3 100644 --- a/lsp/main.css +++ b/lsp/main.css @@ -654,29 +654,6 @@ input[type=radio] { display: none; } -.LTSonly { - overflow: hidden; - position: relative; - outline: 1px solid rgba(0,0,0,0.2); -} -td.LTSonly { outline: none; } -.LTSonly:after { - content: 'Pro'; - font-size: 0.8em; - text-align: center; - white-space: nowrap; - position: absolute; - right: -3em; - top: 0.2em; - width: 8em; - transform: rotate(25deg); - height: 1.5em; - box-shadow: -0.2em 0.2em 0.5em rgba(0,0,0,0.2); - outline: 1px solid rgba(0,0,0,0.2); - color: rgba(255,255,255,0.8); - background-image: linear-gradient(to top,rgb(71, 184, 93),rgb(63, 139, 78)); - text-shadow: -0.2em 0.2em 0.5em rgba(0,0,0,0.2); -} [disabled] { opacity: 0.75; } @@ -980,6 +957,18 @@ button.return:before { .mistvideo-column { flex-direction: column; } +.UIelement .inputlist .field_container { + margin-bottom: 0.2em; +} +.UIelement.custom_url_parameters .field_container .field_container .unit:before { + content: "&"; + width: 0.8em; + display: block; + text-align: center; +} +.UIelement.custom_url_parameters .field_container .field_container:first-child .unit:before { + content: "?"; +} @font-face { font-family: Latin Modern Sans; diff --git a/lsp/minified.js b/lsp/minified.js index cf40330b..7df82400 100644 --- a/lsp/minified.js +++ b/lsp/minified.js @@ -1,11 +1,11 @@ -var MD5=function(a){function b(a,b){var c,d,f,e,g;f=a&2147483648;e=b&2147483648;c=a&1073741824;d=b&1073741824;g=(a&1073741823)+(b&1073741823);return c&d?g^2147483648^f^e:c|d?g&1073741824?g^3221225472^f^e:g^1073741824^f^e:g^f^e}function c(a,c,d,f,g,e,h){a=b(a,b(b(c&d|~c&f,g),h));return b(a<>>32-e,c)}function d(a,c,d,f,e,g,h){a=b(a,b(b(c&f|d&~f,e),h));return b(a<>>32-g,c)}function e(a,c,d,f,g,e,h){a=b(a,b(b(c^d^f,g),h));return b(a<>>32-e,c)}function l(a,c,d,f,e,g,h){a=b(a,b(b(d^(c|~f), -e),h));return b(a<>>32-g,c)}function n(a){var b="",c="",d;for(d=0;3>=d;d++)c=a>>>8*d&255,c="0"+c.toString(16),b+=c.substr(c.length-2,2);return b}var h=[],t,m,k,w,i,f,g,j,h=a.replace(/\r\n/g,"\n"),a="";for(t=0;tm?a+=String.fromCharCode(m):(127m?a+=String.fromCharCode(m>>6|192):(a+=String.fromCharCode(m>>12|224),a+=String.fromCharCode(m>>6&63|128)),a+=String.fromCharCode(m&63|128));h=a;a=h.length;t=a+8;m=16*((t-t%64)/64+1);k=Array(m-1);for(i=w=0;i>>29;h=k;i=1732584193;f=4023233417;g=2562383102;j=271733878;for(a=0;ac?1*d:a .menu"),main:$("main"),header:$("header"),connection:{status:$("#connection"),user_and_host:$("#user_and_host"),msg:$("#message")}};UI.buildMenu();UI.stored.getOpts();try{if("mistLogin"in sessionStorage){var a=JSON.parse(sessionStorage.mistLogin);mist.user.name=a.name;mist.user.password=a.password;mist.user.host=a.host}}catch(b){}location.hash&&(a=decodeURIComponent(location.hash).substring(1).split("@")[0].split("&"),mist.user.name=a[0],a[1]&&(mist.user.host= +var MD5=function(a){function b(a,b){var c,d,g,i,f;g=a&2147483648;i=b&2147483648;c=a&1073741824;d=b&1073741824;f=(a&1073741823)+(b&1073741823);return c&d?f^2147483648^g^i:c|d?f&1073741824?f^3221225472^g^i:f^1073741824^g^i:f^g^i}function c(a,c,d,g,i,f,e){a=b(a,b(b(c&d|~c&g,i),e));return b(a<>>32-f,c)}function d(a,c,d,g,i,f,e){a=b(a,b(b(c&g|d&~g,i),e));return b(a<>>32-f,c)}function f(a,c,d,g,i,f,e){a=b(a,b(b(c^d^g,i),e));return b(a<>>32-f,c)}function l(a,c,d,g,i,f,e){a=b(a,b(b(d^(c|~g), +i),e));return b(a<>>32-f,c)}function m(a){var b="",c="",d;for(d=0;3>=d;d++)c=a>>>8*d&255,c="0"+c.toString(16),b+=c.substr(c.length-2,2);return b}var e=[],t,o,k,x,h,g,i,j,e=a.replace(/\r\n/g,"\n"),a="";for(t=0;to?a+=String.fromCharCode(o):(127o?a+=String.fromCharCode(o>>6|192):(a+=String.fromCharCode(o>>12|224),a+=String.fromCharCode(o>>6&63|128)),a+=String.fromCharCode(o&63|128));e=a;a=e.length;t=a+8;o=16*((t-t%64)/64+1);k=Array(o-1);for(h=x=0;h>>29;e=k;h=1732584193;g=4023233417;i=2562383102;j=271733878;for(a=0;ac?1*d:a .menu"),main:$("main"),header:$("header"),connection:{status:$("#connection"),user_and_host:$("#user_and_host"),msg:$("#message")}};UI.buildMenu();UI.stored.getOpts();try{if("mistLogin"in sessionStorage){var a=JSON.parse(sessionStorage.mistLogin);mist.user.name=a.name;mist.user.password=a.password;mist.user.host=a.host}}catch(b){}location.hash&&(a=decodeURIComponent(location.hash).substring(1).split("@")[0].split("&"),mist.user.name=a[0],a[1]&&(mist.user.host= a[1]));mist.send(function(){$(window).trigger("hashchange")},{},{timeout:5,hide:!0});var c=0;$("body > div.filler").on("scroll",function(){var a=$(this).scrollLeft();a!=c&&UI.elements.header.css("margin-right",-1*a+"px");c=a})});$(window).on("hashchange",function(){var a=decodeURIComponent(location.hash).substring(1).split("@");a[1]||(a[1]="");a=a[1].split("&");""==a[0]&&(a[0]="Overview");UI.showTab(a[0],a[1])}); var MistVideoObject={},otherhost={host:!1,https:!1},UI={debug:!1,elements:{},stored:{getOpts:function(){var a=localStorage.stored;a&&(a=JSON.parse(a));$.extend(!0,this.vars,a);return this.vars},saveOpt:function(a,b){this.vars[a]=b;localStorage.stored=JSON.stringify(this.vars);return this.vars},vars:{helpme:!0}},interval:{clear:function(){"undefined"!=typeof this.opts&&(clearInterval(this.opts.id),delete this.opts)},set:function(a,b){this.opts&&log("[interval]","Set called on interval, but an interval is already active."); this.opts={delay:b,callback:a};this.opts.id=setInterval(a,b)}},returnTab:["Overview"],countrylist:{AF:"Afghanistan",AX:"Åland Islands",AL:"Albania",DZ:"Algeria",AS:"American Samoa",AD:"Andorra",AO:"Angola",AI:"Anguilla",AQ:"Antarctica",AG:"Antigua and Barbuda",AR:"Argentina",AM:"Armenia",AW:"Aruba",AU:"Australia",AT:"Austria",AZ:"Azerbaijan",BS:"Bahamas",BH:"Bahrain",BD:"Bangladesh",BB:"Barbados",BY:"Belarus",BE:"Belgium",BZ:"Belize",BJ:"Benin",BM:"Bermuda",BT:"Bhutan",BO:"Bolivia, Plurinational State of", @@ -21,246 +21,260 @@ clearTimeout(this.hiding);delete this.hiding;var c=$(document).height()-$tooltip "HLS (TS)";break;case "html5/application/vnd.apple.mpegurl;version=7":b="HLS (CMAF)";break;case "html5/video/webm":b="WebM";break;case "html5/video/mp4":b="MP4";break;case "dash/video/mp4":b="DASH";break;case "flash/11":b="HDS";break;case "flash/10":b="RTMP";break;case "flash/7":b="Progressive";break;case "html5/audio/mp3":b="MP3";break;case "html5/audio/wav":b="WAV";break;case "html5/video/mp2t":case "html5/video/mpeg":b="TS";break;case "html5/application/vnd.ms-sstr+xml":case "html5/application/vnd.ms-ss":b= "Smooth Streaming";break;case "html5/text/vtt":b="VTT Subtitles";break;case "html5/text/plain":b="SRT Subtitles";break;case "html5/text/javascript":b="JSON Subtitles";break;case "rtsp":b="RTSP";break;case "webrtc":b="WebRTC"}return b},popup:{element:null,show:function(a){this.element=$("
").attr("id","popup").append($("