Generalize DTSH header reading and writing; generalize input override prefixes; support external writer targets for pushing
This commit is contained in:
parent
2b18a414b4
commit
0f692233e8
26 changed files with 193 additions and 146 deletions
|
@ -785,6 +785,28 @@ void Util::Config::addStandardPushCapabilities(JSON::Value &cap){
|
|||
pp["append"]["format"] = "set_or_unset";
|
||||
pp["append"]["sort"] = "bf";
|
||||
|
||||
pp["split"]["name"] = "Split interval";
|
||||
pp["split"]["help"] = "Performs a gapless restart of the recording every this many seconds. Always aligns to the next keyframe after this duration, to ensure each recording is fully playable. When set to zero (the default) will not split at all.";
|
||||
pp["split"]["type"] = "int";
|
||||
pp["split"]["unit"] = "s";
|
||||
pp["split"]["sort"] = "bh";
|
||||
|
||||
pp["m3u8"]["name"] = "Playlist path (relative to segments)";
|
||||
pp["m3u8"]["help"] = "If set, will write a m3u8 playlist file for the segments to the given path (relative from the first segment path). When this parameter is used, at least one of the variables $segmentCounter or $currentMediaTime must be part of the segment path (to keep segments from overwriting each other). The \"Split interval\" parameter will default to 60 seconds when using this option.";
|
||||
pp["m3u8"]["type"] = "string";
|
||||
pp["m3u8"]["sort"] = "apa";
|
||||
|
||||
pp["targetAge"]["name"] = "Playlist target age";
|
||||
pp["targetAge"]["help"] = "When writing a playlist, delete segment entries that are more than this many seconds old from the playlist (and, if possible, also delete said segments themselves). When set to 0 or left empty, does not delete.";
|
||||
pp["targetAge"]["type"] = "int";
|
||||
pp["targetAge"]["unit"] = "s";
|
||||
pp["targetAge"]["sort"] = "apb";
|
||||
|
||||
pp["maxEntries"]["name"] = "Playlist max entries";
|
||||
pp["maxEntries"]["help"] = "When writing a playlist, delete oldest segment entries once this entry count has been reached (and, if possible, also delete said segments themselves). When set to 0 or left empty, does not delete.";
|
||||
pp["maxEntries"]["type"] = "int";
|
||||
pp["maxEntries"]["sort"] = "apc";
|
||||
|
||||
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";
|
||||
|
@ -793,12 +815,6 @@ void Util::Config::addStandardPushCapabilities(JSON::Value &cap){
|
|||
pp["pushdelay"]["disable"].append("start");
|
||||
pp["pushdelay"]["sort"] = "bg";
|
||||
|
||||
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["split"]["sort"] = "bh";
|
||||
|
||||
pp["duration"]["name"] = "Duration of push";
|
||||
pp["duration"]["help"] = "How much media time to push, in seconds. Internally overrides \"recstop\"";
|
||||
pp["duration"]["type"] = "int";
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "procs.h"
|
||||
#include "shared_memory.h"
|
||||
#include "socket.h"
|
||||
#include "url.h"
|
||||
#include "stream.h"
|
||||
#include "triggers.h" //LTS
|
||||
#include <semaphore.h>
|
||||
|
@ -673,6 +674,25 @@ JSON::Value Util::getInputBySource(const std::string &filename, bool isProvider)
|
|||
for (unsigned int i = 0; i < input_size; ++i){
|
||||
DTSC::Scan tmp_input = inputs.getIndice(i);
|
||||
|
||||
// if name prefix based match, always force 99 priority
|
||||
if (tmp_input.getMember("name")){
|
||||
std::string inPrefix = tmp_input.getMember("name").asString() + ":";
|
||||
if (tmpFn.size() > inPrefix.size()){
|
||||
Util::stringToLower(inPrefix);
|
||||
std::string fnPrefix = tmpFn.substr(0, inPrefix.size());
|
||||
Util::stringToLower(fnPrefix);
|
||||
if (inPrefix == fnPrefix){
|
||||
if (tmp_input.getMember("non-provider") && !isProvider){
|
||||
noProviderNoPick = true;
|
||||
continue;
|
||||
}
|
||||
curPrio = 99;
|
||||
selected = true;
|
||||
input = tmp_input;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if match voor current stream && priority is hoger dan wat we al hebben
|
||||
if (tmp_input.getMember("source_match") && curPrio < tmp_input.getMember("priority").asInt()){
|
||||
if (tmp_input.getMember("source_match").getSize()){
|
||||
|
@ -769,18 +789,43 @@ pid_t Util::startPush(const std::string &streamname, std::string &target, int de
|
|||
std::string back = tar_match.substr(tar_match.find('*') + 1);
|
||||
MEDIUM_MSG("Checking output %s: %s (%s)", outputs.getIndiceName(i).c_str(),
|
||||
output.getMember("name").asString().c_str(), checkTarget.c_str());
|
||||
|
||||
if (checkTarget.substr(0, front.size()) == front &&
|
||||
checkTarget.substr(checkTarget.size() - back.size()) == back){
|
||||
output_bin = Util::getMyPath() + "MistOut" + output.getMember("name").asString();
|
||||
break;
|
||||
}
|
||||
//Check for external writer support
|
||||
if (front == "/" && back.size() && checkTarget.substr(checkTarget.size() - back.size()) == back){
|
||||
HTTP::URL tUri(target);
|
||||
// If it is a remote target, we might need to spawn an external binary
|
||||
if (tUri.isLocalPath()){continue;}
|
||||
// Read configured external writers
|
||||
IPC::sharedPage extwriPage(EXTWRITERS, 0, false, false);
|
||||
if (extwriPage.mapped){
|
||||
Util::RelAccX extWri(extwriPage.mapped, false);
|
||||
if (extWri.isReady()){
|
||||
for (uint64_t i = 0; i < extWri.getEndPos(); i++){
|
||||
Util::RelAccX protocols = Util::RelAccX(extWri.getPointer("protocols", i));
|
||||
uint8_t protocolCount = protocols.getPresent();
|
||||
JSON::Value protocolArray;
|
||||
for (uint8_t idx = 0; idx < protocolCount; idx++){
|
||||
if (tUri.protocol == protocols.getPointer("protocol", idx)){
|
||||
output_bin = Util::getMyPath() + "MistOut" + output.getMember("name").asString();
|
||||
break;
|
||||
}
|
||||
if (output_bin.size()){break;}
|
||||
}
|
||||
if (output_bin.size()){break;}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (output_bin == ""){
|
||||
if (!output_bin.size()){
|
||||
FAIL_MSG("No output found for target %s, aborting push.", target.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue