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;
}
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<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;
}
//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<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;
}
if (URL.substr(0, 1) == "/"){

View file

@ -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";

View file

@ -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;