From 172bdabf36cadfa9e42ac066edbe434520ec6723 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 15 Sep 2016 17:05:20 +0200 Subject: [PATCH] New style of always-on inputs. Still needs interface updates --- src/controller/controller_streams.cpp | 57 ++++++++++--------- src/input/input_buffer.cpp | 31 +--------- src/input/input_ts.cpp | 81 +++++++++++++-------------- 3 files changed, 71 insertions(+), 98 deletions(-) diff --git a/src/controller/controller_streams.cpp b/src/controller/controller_streams.cpp index fa32badf..895fd486 100644 --- a/src/controller/controller_streams.cpp +++ b/src/controller/controller_streams.cpp @@ -59,35 +59,38 @@ namespace Controller { return; } if (URL.substr(0, 1) != "/"){ - //push-style stream - if (data["udpport"].asInt()){ - std::string udpPort = data["udpport"].asString(); - //Check running - if (!inputProcesses.count(name) || !Util::Procs::isRunning(inputProcesses[name])){ - std::string multicast = data["multicastinterface"].asString(); - // False: start TS input - INFO_MSG("No TS Input running on port %s for stream %s, starting it", udpPort.c_str(), name.c_str()); - std::deque command; - command.push_back(Util::getMyPath() + "MistInTS"); - command.push_back("-s"); - command.push_back(name); - command.push_back("-p"); - command.push_back(udpPort); - command.push_back("-M"); - command.push_back(multicast); - command.push_back(URL); - int stdIn = 0; - int stdOut = 1; - int stdErr = 2; - pid_t program = Util::Procs::StartPiped(command, &stdIn, &stdOut, &stdErr); - if (program){ - inputProcesses[name] = program; - } + //non-file stream + //Old style always on + if (data.isMember("udpport") && data["udpport"].asStringRef().size() && (!inputProcesses.count(name) || !Util::Procs::isRunning(inputProcesses[name]))){ + const std::string & udpPort = data["udpport"].asStringRef(); + const std::string & multicast = data["multicastinterface"].asStringRef(); + URL = "tsudp://"+udpPort; + if (multicast.size()){ + URL.append("/"+multicast); } - //Check hasViewers - // True: data["online"] = 2; - // False: data["online"] =11; + // False: start TS input + INFO_MSG("No TS input for stream %s, starting it: %s", name.c_str(), URL.c_str()); + std::deque command; + command.push_back(Util::getMyPath() + "MistInTS"); + command.push_back("-s"); + command.push_back(name); + command.push_back(URL); + int stdIn = 0; + int stdOut = 1; + int stdErr = 2; + pid_t program = Util::Procs::StartPiped(command, &stdIn, &stdOut, &stdErr); + if (program){ + inputProcesses[name] = program; + } + return; } + //new style always on + if (data.isMember("always_on") && !Util::streamAlive(name)){ + INFO_MSG("Starting always-on input %s: %s", name.c_str(), URL.c_str()); + Util::startInput(name, URL); + return; + } + //non-automatics simply return return; } if (URL.substr(0, 1) == "/"){ diff --git a/src/input/input_buffer.cpp b/src/input/input_buffer.cpp index 9f3a3359..d5299fa7 100644 --- a/src/input/input_buffer.cpp +++ b/src/input/input_buffer.cpp @@ -33,7 +33,7 @@ namespace Mist { option["value"].append(50000LL); config->addOption("bufferTime", option); capa["optional"]["DVR"]["name"] = "Buffer time (ms)"; - capa["optional"]["DVR"]["help"] = "The target available buffer time for this live stream, in milliseconds. This is the time available to seek around in, and will automatically be extended to fit whole keyframes."; + capa["optional"]["DVR"]["help"] = "The target available buffer time for this live stream, in milliseconds. This is the time available to seek around in, and will automatically be extended to fit whole keyframes as well as the minimum duration needed for stable playback."; capa["optional"]["DVR"]["option"] = "--buffer"; capa["optional"]["DVR"]["type"] = "uint"; capa["optional"]["DVR"]["default"] = 50000LL; @@ -81,35 +81,8 @@ namespace Mist { capa["optional"]["segmentsize"]["type"] = "uint"; capa["optional"]["segmentsize"]["default"] = 5000LL; option.null(); - - option["arg"] = "string"; - option["long"] = "udp-port"; - option["short"] = "U"; - option["help"] = "The UDP port on which to listen for TS Packets"; - option["value"].append(""); - config->addOption("udpport", option); - capa["optional"]["udpport"]["name"] = "TS/UDP port"; - capa["optional"]["udpport"]["help"] = "The UDP port on which to listen for TS Packets, or 0 for disabling TS Input, optionally prefixed with the interface IP to listen on."; - capa["optional"]["udpport"]["option"] = "--udp-port"; - capa["optional"]["udpport"]["type"] = "str"; - capa["optional"]["udpport"]["default"] = ""; - option.null(); - - option["arg"] = "string"; - option["long"] = "multicast-interface"; - option["short"] = "M"; - option["help"] = "The interface(s)s on which to listen for UDP Multicast packets, space separated."; - option["value"].append(""); - config->addOption("multicastinterface", option); - capa["optional"]["multicastinterface"]["name"] = "TS Multicast interface"; - capa["optional"]["multicastinterface"]["help"] = "The interface(s) on which to listen for UDP Multicast packets, comma separated."; - capa["optional"]["multicastinterface"]["option"] = "--multicast-interface"; - capa["optional"]["multicastinterface"]["type"] = "str"; - capa["optional"]["multicastinterface"]["default"] = ""; - option.null(); - - /*LTS-end*/ + capa["source_match"] = "push://*"; capa["priority"] = 9ll; capa["desc"] = "Provides buffered live input"; diff --git a/src/input/input_ts.cpp b/src/input/input_ts.cpp index b0b8d799..c55cdd3e 100755 --- a/src/input/input_ts.cpp +++ b/src/input/input_ts.cpp @@ -101,28 +101,15 @@ namespace Mist { capa["decs"] = "MPEG2-TS input from static files, streamed files, or multicast/unicast UDP socket"; capa["source_match"].append("/*.ts"); capa["source_match"].append("stream://*.ts"); + capa["source_match"].append("tsudp://*"); + //These two can/may be set to always-on mode + capa["always_match"].append("stream://*.ts"); + capa["always_match"].append("tsudp://*"); capa["priority"] = 9ll; capa["codecs"][0u][0u].append("H264"); capa["codecs"][0u][0u].append("HEVC"); capa["codecs"][0u][1u].append("AAC"); capa["codecs"][0u][1u].append("AC3"); - - capa["optional"]["port"]["name"] = "UDP Port"; - capa["optional"]["port"]["help"] = "The UDP port on which to listen for incoming UDP Packets, optionally prefixed by the interface IP."; - capa["optional"]["port"]["type"] = "string"; - capa["optional"]["port"]["default"] = "9876"; - capa["optional"]["port"]["option"] = "--port"; - cfg->addOption("port", - JSON::fromString("{\"arg\":\"string\",\"value\":9876,\"short\":\"p\",\"long\":\"port\",\"help\":\"The UDP port on which to listen for incoming UDP Packets, optionally prefixed by the interface IP.\"}")); - - capa["optional"]["multicastinterface"]["name"] = "TS Multicast interface"; - capa["optional"]["multicastinterface"]["help"] = "The interface(s) on which to listen for UDP Multicast packets, comma separated."; - capa["optional"]["multicastinterface"]["option"] = "--multicast-interface"; - capa["optional"]["multicastinterface"]["type"] = "str"; - capa["optional"]["multicastinterface"]["default"] = ""; - cfg->addOption("multicastinterface", - JSON::fromString("{\"arg\":\"string\",\"value\":\"\",\"short\":\"M\",\"long\":\"multicast-interface\",\"help\":\"The interfaces on which to listen for UDP Multicast packets, space separated.\"}")); - inFile = NULL; } @@ -146,32 +133,42 @@ namespace Mist { ///Live Setup of TS Input bool inputTS::setup() { const std::string & inpt = config->getString("input"); - if (inpt.size() && (inpt != "-" || inpt.substr(0,9) == "stream://")){ - if (inpt.substr(0,9) == "stream://"){ - inFile = fopen(inpt.c_str()+9, "r"); - standAlone = false; - }else{ - inFile = fopen(inpt.c_str(), "r"); - } - if (!inFile) { - return false; - } - }else{ + //streamed standard input + if (inpt == "-") { standAlone = false; - if (inpt == "-") { - inFile = stdin; - } else { - udpCon.setBlocking(false); - std::string ipPort = config->getString("port"); - size_t colon = ipPort.rfind(':'); - if (colon != std::string::npos) { - udpCon.bind(JSON::Value(ipPort.substr(colon + 1)).asInt(), ipPort.substr(0, colon), config->getString("multicastinterface")); - } else { - udpCon.bind(JSON::Value(ipPort).asInt(), "", config->getString("multicastinterface")); - } - } + inFile = stdin; + return true; } - return true; + //streamed file + if (inpt.substr(0,9) == "stream://"){ + inFile = fopen(inpt.c_str()+9, "r"); + standAlone = false; + return inFile; + } + //UDP input (tsudp://[host:]port[/iface[,iface[,...]]]) + if (inpt.substr(0, 8) == "tsudp://"){ + standAlone = false; + udpCon.setBlocking(false); + uint32_t port; + std::string host; + std::string ifaces; + size_t colon = inpt.find(':', 8); + if (colon != std::string::npos){ + port = atoi(inpt.c_str()+colon+1);//skip to colon + host = inpt.substr(8, colon-8); + }else{ + port = atoi(inpt.c_str()+8);//skip udpts:// + } + size_t slash = inpt.find('/', 8); + if (slash != std::string::npos){ + ifaces = inpt.substr(slash+1); + } + udpCon.bind(port, host, ifaces); + return true; + } + //plain VoD file + inFile = fopen(inpt.c_str(), "r"); + return inFile; } @@ -442,7 +439,7 @@ namespace Mist { if (!standAlone){return false;} //otherwise, check input param const std::string & inpt = config->getString("input"); - if (inpt.size() && inpt != "-" && inpt.substr(0,9) != "stream://"){ + if (inpt.size() && inpt != "-" && inpt.substr(0,9) != "stream://" && inpt.substr(0,8) != "tsudp://"){ return true; }else{ return false;