New style of always-on inputs. Still needs interface updates

This commit is contained in:
Thulinma 2016-09-15 17:05:20 +02:00
parent eccd3d2949
commit 172bdabf36
3 changed files with 71 additions and 98 deletions

View file

@ -59,35 +59,38 @@ namespace Controller {
return; return;
} }
if (URL.substr(0, 1) != "/"){ if (URL.substr(0, 1) != "/"){
//push-style stream //non-file stream
if (data["udpport"].asInt()){ //Old style always on
std::string udpPort = data["udpport"].asString(); if (data.isMember("udpport") && data["udpport"].asStringRef().size() && (!inputProcesses.count(name) || !Util::Procs::isRunning(inputProcesses[name]))){
//Check running const std::string & udpPort = data["udpport"].asStringRef();
if (!inputProcesses.count(name) || !Util::Procs::isRunning(inputProcesses[name])){ const std::string & multicast = data["multicastinterface"].asStringRef();
std::string multicast = data["multicastinterface"].asString(); URL = "tsudp://"+udpPort;
// False: start TS input if (multicast.size()){
INFO_MSG("No TS Input running on port %s for stream %s, starting it", udpPort.c_str(), name.c_str()); URL.append("/"+multicast);
std::deque<std::string> 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;
}
} }
//Check hasViewers // False: start TS input
// True: data["online"] = 2; INFO_MSG("No TS input for stream %s, starting it: %s", name.c_str(), URL.c_str());
// False: data["online"] =11; std::deque<std::string> 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; return;
} }
if (URL.substr(0, 1) == "/"){ if (URL.substr(0, 1) == "/"){

View file

@ -33,7 +33,7 @@ namespace Mist {
option["value"].append(50000LL); option["value"].append(50000LL);
config->addOption("bufferTime", option); config->addOption("bufferTime", option);
capa["optional"]["DVR"]["name"] = "Buffer time (ms)"; 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"]["option"] = "--buffer";
capa["optional"]["DVR"]["type"] = "uint"; capa["optional"]["DVR"]["type"] = "uint";
capa["optional"]["DVR"]["default"] = 50000LL; capa["optional"]["DVR"]["default"] = 50000LL;
@ -81,35 +81,8 @@ namespace Mist {
capa["optional"]["segmentsize"]["type"] = "uint"; capa["optional"]["segmentsize"]["type"] = "uint";
capa["optional"]["segmentsize"]["default"] = 5000LL; capa["optional"]["segmentsize"]["default"] = 5000LL;
option.null(); 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*/ /*LTS-end*/
capa["source_match"] = "push://*"; capa["source_match"] = "push://*";
capa["priority"] = 9ll; capa["priority"] = 9ll;
capa["desc"] = "Provides buffered live input"; capa["desc"] = "Provides buffered live input";

View file

@ -101,28 +101,15 @@ namespace Mist {
capa["decs"] = "MPEG2-TS input from static files, streamed files, or multicast/unicast UDP socket"; capa["decs"] = "MPEG2-TS input from static files, streamed files, or multicast/unicast UDP socket";
capa["source_match"].append("/*.ts"); capa["source_match"].append("/*.ts");
capa["source_match"].append("stream://*.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["priority"] = 9ll;
capa["codecs"][0u][0u].append("H264"); capa["codecs"][0u][0u].append("H264");
capa["codecs"][0u][0u].append("HEVC"); capa["codecs"][0u][0u].append("HEVC");
capa["codecs"][0u][1u].append("AAC"); capa["codecs"][0u][1u].append("AAC");
capa["codecs"][0u][1u].append("AC3"); 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; inFile = NULL;
} }
@ -146,32 +133,42 @@ namespace Mist {
///Live Setup of TS Input ///Live Setup of TS Input
bool inputTS::setup() { bool inputTS::setup() {
const std::string & inpt = config->getString("input"); const std::string & inpt = config->getString("input");
if (inpt.size() && (inpt != "-" || inpt.substr(0,9) == "stream://")){ //streamed standard input
if (inpt.substr(0,9) == "stream://"){ if (inpt == "-") {
inFile = fopen(inpt.c_str()+9, "r");
standAlone = false;
}else{
inFile = fopen(inpt.c_str(), "r");
}
if (!inFile) {
return false;
}
}else{
standAlone = false; standAlone = false;
if (inpt == "-") { inFile = stdin;
inFile = stdin; return true;
} 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"));
}
}
} }
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;} if (!standAlone){return false;}
//otherwise, check input param //otherwise, check input param
const std::string & inpt = config->getString("input"); 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; return true;
}else{ }else{
return false; return false;