New style of always-on inputs. Still needs interface updates
This commit is contained in:
parent
eccd3d2949
commit
172bdabf36
3 changed files with 71 additions and 98 deletions
|
@ -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) == "/"){
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Reference in a new issue