diff --git a/lib/config.cpp b/lib/config.cpp index df7895e3..d0aba75a 100644 --- a/lib/config.cpp +++ b/lib/config.cpp @@ -726,6 +726,129 @@ void Util::Config::addBasicConnectorOptions(JSON::Value &capabilities){ addOption("json", option); } +void Util::Config::addStandardPushCapabilities(JSON::Value &cap){ + //Set up fast access to the push_parameters + JSON::Value & pp = cap["push_parameters"]; + + pp["audio"]["name"] = "Audio track(s)"; + pp["audio"]["help"] = "Override which audio tracks of the stream should be selected"; + pp["audio"]["type"] = "string"; + pp["audio"]["validate"][0u] = "track_selector"; + + 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["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["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["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["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["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["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["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["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"; + pp["pushdelay"]["type"] = "int"; + pp["pushdelay"]["unit"] = "s"; + pp["pushdelay"]["disable"].append("realtime"); + pp["pushdelay"]["disable"].append("start"); + + 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["duration"]["name"] = "Duration of push"; + pp["duration"]["help"] = "How much media time to push, in seconds. Internally overrides \"recstop\""; + pp["duration"]["type"] = "int"; + pp["duration"]["unit"] = "s"; + pp["duration"]["disable"].append("recstop"); + pp["duration"]["disable"].append("stop"); + + 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["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["stopunix"]["name"] = "Unix timestamp to stop at"; + pp["stopunix"]["help"] = "What unix timestamp to stop at"; + pp["stopunix"]["type"] = "unixtime"; + pp["stopunix"]["unit"] = "s"; + pp["stopunix"]["prot_only"] = true; + pp["stopunix"]["disable"].append("stop"); + + pp["startunix"]["name"] = "Unix timestamp to start from"; + pp["startunix"]["help"] = "What unix timestamp to start from"; + pp["startunix"]["type"] = "unixtime"; + pp["startunix"]["unit"] = "s"; + pp["startunix"]["prot_only"] = true; + pp["startunix"]["disable"].append("start"); + + 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["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["recstopunix"]["name"] = "Unix timestamp to stop at"; + pp["recstopunix"]["help"] = "What unix timestamp to stop at"; + pp["recstopunix"]["type"] = "unixtime"; + pp["recstopunix"]["unit"] = "s"; + pp["recstopunix"]["file_only"] = true; + pp["recstopunix"]["disable"].append("recstop"); + + pp["recstartunix"]["name"] = "Unix timestamp to start from"; + pp["recstartunix"]["help"] = "What unix timestamp to start from"; + pp["recstartunix"]["type"] = "unixtime"; + pp["recstartunix"]["unit"] = "s"; + pp["recstartunix"]["file_only"] = true; + pp["recstartunix"]["disable"].append("recstart"); + +} + /// Gets directory the current executable is stored in. std::string Util::getMyPath(){ char mypath[500]; diff --git a/lib/config.h b/lib/config.h index 2b1f5163..7c04a253 100644 --- a/lib/config.h +++ b/lib/config.h @@ -49,6 +49,7 @@ namespace Util{ int servePlainSocket(int (*callback)(Socket::Connection &S)); void addOptionsFromCapabilities(const JSON::Value &capabilities); void addBasicConnectorOptions(JSON::Value &capabilities); + void addStandardPushCapabilities(JSON::Value &capabilities); void addConnectorOptions(int port, JSON::Value &capabilities); }; diff --git a/src/output/output_cmaf.cpp b/src/output/output_cmaf.cpp index 4d2636cf..77d1b410 100644 --- a/src/output/output_cmaf.cpp +++ b/src/output/output_cmaf.cpp @@ -203,6 +203,7 @@ namespace Mist{ capa["optional"]["chunkpath"]["short"] = "e"; capa["optional"]["chunkpath"]["default"] = ""; + config->addStandardPushCapabilities(capa); capa["push_urls"].append("cmaf://*"); capa["push_urls"].append("cmafs://*"); diff --git a/src/output/output_dtsc.cpp b/src/output/output_dtsc.cpp index 03e26601..2f4c5380 100644 --- a/src/output/output_dtsc.cpp +++ b/src/output/output_dtsc.cpp @@ -96,6 +96,7 @@ namespace Mist{ capa["desc"] = "Real time streaming over DTSC (proprietary protocol for efficient inter-server streaming)"; capa["deps"] = ""; capa["codecs"][0u][0u].append("+*"); + config->addStandardPushCapabilities(capa); capa["push_urls"].append("dtsc://*"); capa["incoming_push_url"] = "dtsc://$host:$port/$stream?pass=$password"; diff --git a/src/output/output_ebml.cpp b/src/output/output_ebml.cpp index f1bf7e3d..9ac330ca 100644 --- a/src/output/output_ebml.cpp +++ b/src/output/output_ebml.cpp @@ -100,6 +100,7 @@ namespace Mist{ capa["exceptions"]["codec:FLOAT"] = blacklistNonChrome; capa["exceptions"]["codec:AC3"] = blacklistNonChrome; capa["exceptions"]["codec:DTS"] = blacklistNonChrome; + config->addStandardPushCapabilities(capa); capa["push_urls"].append("/*.mkv"); capa["push_urls"].append("/*.webm"); capa["push_urls"].append("mkv-exec:*"); diff --git a/src/output/output_flv.cpp b/src/output/output_flv.cpp index 33ba45cc..beff2735 100644 --- a/src/output/output_flv.cpp +++ b/src/output/output_flv.cpp @@ -31,6 +31,7 @@ namespace Mist{ capa["methods"][0u]["hrn"] = "FLV progressive"; capa["methods"][0u]["priority"] = 5; capa["methods"][0u]["player_url"] = "/oldflashplayer.swf"; + config->addStandardPushCapabilities(capa); capa["push_urls"].append("/*.flv"); JSON::Value opt; diff --git a/src/output/output_httpts.cpp b/src/output/output_httpts.cpp index 7d710db4..c9d28b26 100644 --- a/src/output/output_httpts.cpp +++ b/src/output/output_httpts.cpp @@ -79,6 +79,7 @@ namespace Mist{ capa["methods"][0u]["type"] = "html5/video/mpeg"; capa["methods"][0u]["hrn"] = "TS HTTP progressive"; capa["methods"][0u]["priority"] = 1; + config->addStandardPushCapabilities(capa); capa["push_urls"].append("/*.ts"); capa["push_urls"].append("ts-exec:*"); diff --git a/src/output/output_jpg.cpp b/src/output/output_jpg.cpp index 9c685957..8da17ed0 100644 --- a/src/output/output_jpg.cpp +++ b/src/output/output_jpg.cpp @@ -107,6 +107,7 @@ namespace Mist{ capa["methods"][0u]["type"] = "html5/image/jpeg"; capa["methods"][0u]["hrn"] = "JPEG"; capa["methods"][0u]["priority"] = 0; + config->addStandardPushCapabilities(capa); capa["push_urls"].append("/*.jpg"); capa["optional"]["cachedir"]["name"] = "Cache directory"; diff --git a/src/output/output_rtmp.cpp b/src/output/output_rtmp.cpp index 41cf2191..bac766ad 100644 --- a/src/output/output_rtmp.cpp +++ b/src/output/output_rtmp.cpp @@ -251,6 +251,7 @@ namespace Mist{ capa["optional"]["maxkbps"]["type"] = "uint"; cfg->addConnectorOptions(1935, capa); config = cfg; + config->addStandardPushCapabilities(capa); capa["push_urls"].append("rtmp://*"); capa["push_urls"].append("rtmps://*"); diff --git a/src/output/output_sdp.cpp b/src/output/output_sdp.cpp index 50d491e8..7049defe 100644 --- a/src/output/output_sdp.cpp +++ b/src/output/output_sdp.cpp @@ -119,6 +119,7 @@ namespace Mist{ capa["methods"][0u]["url_rel"] = "/$.sdp"; capa["methods"][0u]["priority"] = 11; + config->addStandardPushCapabilities(capa); capa["push_urls"].append("/*.sdp"); JSON::Value opt; diff --git a/src/output/output_ts.cpp b/src/output/output_ts.cpp index cec6eee4..6ab2d84f 100644 --- a/src/output/output_ts.cpp +++ b/src/output/output_ts.cpp @@ -183,6 +183,7 @@ namespace Mist{ capa["codecs"][1u][0u].append("rawts"); cfg->addConnectorOptions(8888, capa); config = cfg; + config->addStandardPushCapabilities(capa); capa["push_urls"].append("tsudp://*"); capa["push_urls"].append("tsrtp://*"); capa["push_urls"].append("tstcp://*"); diff --git a/src/output/output_tsrist.cpp b/src/output/output_tsrist.cpp index 38ef410e..ebed34a9 100644 --- a/src/output/output_tsrist.cpp +++ b/src/output/output_tsrist.cpp @@ -232,6 +232,7 @@ namespace Mist{ cfg->addBasicConnectorOptions(capa); config = cfg; + config->addStandardPushCapabilities(capa); capa["push_urls"].append("rist://*"); // JSON::Value & pp = capa["push_parameters"]; diff --git a/src/output/output_tssrt.cpp b/src/output/output_tssrt.cpp index 9a945287..3a3402e1 100644 --- a/src/output/output_tssrt.cpp +++ b/src/output/output_tssrt.cpp @@ -209,6 +209,8 @@ namespace Mist{ cfg->addConnectorOptions(8889, capa); config = cfg; capa["push_urls"].append("srt://*"); + + config->addStandardPushCapabilities(capa); JSON::Value & pp = capa["push_parameters"]; pp["mode"]["name"] = "Mode"; diff --git a/src/output/output_wav.cpp b/src/output/output_wav.cpp index f1bbf899..177b9796 100644 --- a/src/output/output_wav.cpp +++ b/src/output/output_wav.cpp @@ -21,6 +21,7 @@ namespace Mist{ capa["methods"][0u]["type"] = "html5/audio/wav"; capa["methods"][0u]["hrn"] = "WAV progressive"; capa["methods"][0u]["priority"] = 1; + config->addStandardPushCapabilities(capa); capa["push_urls"].append("/*.wav"); JSON::Value opt;