Fix recstart/recstop parameters

This commit is contained in:
Marco 2021-03-08 10:50:02 +01:00 committed by Thulinma
parent 4a712404ed
commit 8b59c9abe7
2 changed files with 58 additions and 29 deletions

View file

@ -761,6 +761,7 @@ void HTTP::parseVars(const std::string &data, std::map<std::string, std::string>
varval.clear(); varval.clear();
} }
if (varname.size()){ if (varname.size()){
DONTEVEN_MSG("Found key:value pair '%s:%s'", varname.c_str(), varval.c_str());
storage[Encodings::URL::decode(varname)] = Encodings::URL::decode(varval); storage[Encodings::URL::decode(varname)] = Encodings::URL::decode(varval);
} }
if (nextpos == std::string::npos){ if (nextpos == std::string::npos){

View file

@ -721,7 +721,7 @@ namespace Mist{
HIGH_MSG("Seeking for pos %" PRIu64, pos); HIGH_MSG("Seeking for pos %" PRIu64, pos);
if (meta.getLive() && meta.getLastms(tid) < pos){ if (meta.getLive() && meta.getLastms(tid) < pos){
unsigned int maxTime = 0; unsigned int maxTime = 0;
while (meta.getLastms(tid) < pos && myConn && ++maxTime <= 20){ while (meta.getLastms(tid) < pos && myConn && ++maxTime <= 20 && keepGoing()){
Util::wait(500); Util::wait(500);
stats(); stats();
} }
@ -840,14 +840,17 @@ namespace Mist{
} }
/*LTS-START*/ /*LTS-START*/
if (isRecordingToFile){ if (isRecordingToFile){
if (M.getLive()){
MEDIUM_MSG("Stream currently contains data from %lu ms to %lu ms", startTime(), endTime());
}
// Overwrite recstart/recstop with recstartunix/recstopunix if set
if (M.getLive() && if (M.getLive() &&
(targetParams.count("recstartunix") || targetParams.count("recstopunix"))){ (targetParams.count("recstartunix") || targetParams.count("recstopunix"))){
uint64_t unixStreamBegin = Util::epoch() - endTime()/1000; uint64_t unixStreamBegin = Util::epoch() - endTime()/1000;
if (targetParams.count("recstartunix")){ if (targetParams.count("recstartunix")){
uint64_t startUnix = atoll(targetParams["recstartunix"].c_str()); uint64_t startUnix = atoll(targetParams["recstartunix"].c_str());
if (startUnix < unixStreamBegin){ if (startUnix < unixStreamBegin){
WARN_MSG( WARN_MSG("Recording start time is earlier than stream begin - starting earliest possible");
"Recording start time is earlier than stream begin - starting earliest possible");
targetParams["recstart"] = "-1"; targetParams["recstart"] = "-1";
}else{ }else{
targetParams["recstart"] = JSON::Value((startUnix - unixStreamBegin) * 1000).asString(); targetParams["recstart"] = JSON::Value((startUnix - unixStreamBegin) * 1000).asString();
@ -863,59 +866,71 @@ namespace Mist{
} }
} }
} }
// Check recstart/recstop for correctness
if (targetParams.count("recstop")){ if (targetParams.count("recstop")){
uint64_t endRec = atoll(targetParams["recstop"].c_str()); uint64_t endRec = atoll(targetParams["recstop"].c_str());
if (endRec < startTime()){ if (endRec < startTime()){
onFail("Entire recording range is in the past", true); onFail("Entire recording range is in the past", true);
return; return;
} }
INFO_MSG("Recording will stop at %" PRIu64, endRec);
} }
if (targetParams.count("recstart") && atoll(targetParams["recstart"].c_str()) != 0){ if (targetParams.count("recstart") && atoll(targetParams["recstart"].c_str()) != 0){
size_t mainTrack = getMainSelectedTrack();
uint64_t startRec = atoll(targetParams["recstart"].c_str()); uint64_t startRec = atoll(targetParams["recstart"].c_str());
if (startRec > M.getLastms(mainTrack)){ if (startRec > endTime()){
if (M.getVod()){ if (M.getVod()){
onFail("Recording start past end of non-live source", true); onFail("Recording start past end of non-live source", true);
return; return;
} }
uint64_t streamAvail = M.getLastms(mainTrack);
uint64_t lastUpdated = Util::getMS();
while (Util::getMS() - lastUpdated < 5000 && startRec > streamAvail && keepGoing()){
Util::sleep(500);
if (M.getLastms(mainTrack) > streamAvail){
stats();
streamAvail = M.getLastms(mainTrack);
lastUpdated = Util::getMS();
}
}
} }
if (startRec < startTime()){ if (startRec < startTime()){
WARN_MSG("Record begin at %" PRIu64 " ms not available, starting at %" PRIu64
" ms instead",
startRec, startTime());
startRec = startTime(); startRec = startTime();
WARN_MSG("Record begin at %llu ms not available, starting at %" PRIu64
" ms instead", atoll(targetParams["recstart"].c_str()), startRec);
targetParams["recstart"] = JSON::Value(startRec).asString();
} }
INFO_MSG("Recording will start at %" PRIu64, startRec);
seekPos = startRec; seekPos = startRec;
} }
// Duration to record in seconds. Overrides recstop.
if (targetParams.count("split")){ if (targetParams.count("split")){
long long endRec = atoll(targetParams["split"].c_str()) * 1000; long long endRec = atoll(targetParams["split"].c_str()) * 1000;
INFO_MSG("Will split recording every %lld seconds", atoll(targetParams["split"].c_str())); INFO_MSG("Will split recording every %lld seconds", atoll(targetParams["split"].c_str()));
targetParams["nxt-split"] = JSON::Value((int64_t)(seekPos + endRec)).asString(); targetParams["nxt-split"] = JSON::Value((int64_t)(seekPos + endRec)).asString();
} }
// Duration to record in seconds. Overrides recstop.
if (targetParams.count("duration")){ if (targetParams.count("duration")){
long long endRec = atoll(targetParams["duration"].c_str()) * 1000; long long endRec = atoll(targetParams["duration"].c_str()) * 1000;
targetParams["recstop"] = JSON::Value((int64_t)(seekPos + endRec)).asString(); targetParams["recstop"] = JSON::Value((int64_t)(seekPos + endRec)).asString();
} // Recheck recording end time
if (targetParams.count("recstop")){ endRec = atoll(targetParams["recstop"].c_str());
long long endRec = atoll(targetParams["recstop"].c_str());
if (endRec < 0 || endRec < startTime()){ if (endRec < 0 || endRec < startTime()){
onFail("Entire recording range is in the past", true); onFail("Entire recording range is in the past", true);
return; return;
} }
INFO_MSG("Recording will stop at %lld", endRec); }
// Print calculated start and stop time
if (targetParams.count("recstart")){
INFO_MSG("Recording will start at timestamp %llu ms", atoll(targetParams["recstart"].c_str()));
}
else{
INFO_MSG("Recording will start at timestamp %lu ms", endTime());
}
if (targetParams.count("recstop")){
INFO_MSG("Recording will stop at timestamp %llu ms", atoll(targetParams["recstop"].c_str()));
}
// Wait for the stream to catch up to the starttime
uint64_t streamAvail = endTime();
uint64_t lastUpdated = Util::getMS();
if (atoll(targetParams["recstart"].c_str()) > streamAvail){
INFO_MSG("Waiting for stream to reach recording starting point. Recording will start in " PRETTY_PRINT_TIME, PRETTY_ARG_TIME((atoll(targetParams["recstart"].c_str()) - streamAvail) / 1000));
while (Util::getMS() - lastUpdated < 10000 && atoll(targetParams["recstart"].c_str()) > streamAvail && keepGoing()){
Util::sleep(250);
meta.reloadReplacedPagesIfNeeded();
if (endTime() > streamAvail){
stats();
streamAvail = endTime();
lastUpdated = Util::getMS();
}
}
} }
}else{ }else{
if (M.getLive() && targetParams.count("pushdelay")){ if (M.getLive() && targetParams.count("pushdelay")){
@ -925,17 +940,20 @@ namespace Mist{
} }
if (M.getLive() && (targetParams.count("startunix") || targetParams.count("stopunix"))){ if (M.getLive() && (targetParams.count("startunix") || targetParams.count("stopunix"))){
uint64_t unixStreamBegin = Util::epoch() - endTime()/1000; uint64_t unixStreamBegin = Util::epoch() - endTime()/1000;
size_t mainTrack = getMainSelectedTrack();
int64_t streamAvail = M.getLastms(mainTrack);
if (targetParams.count("startunix")){ if (targetParams.count("startunix")){
int64_t startUnix = atoll(targetParams["startunix"].c_str()); int64_t startUnix = atoll(targetParams["startunix"].c_str());
if (startUnix < 0){ if (startUnix < 0){
int64_t origStartUnix = startUnix; int64_t origStartUnix = startUnix;
startUnix += Util::epoch(); startUnix += Util::epoch();
if (startUnix < unixStreamBegin){ if (startUnix < unixStreamBegin){
INFO_MSG("Waiting for stream to reach intended starting point"); INFO_MSG("Waiting for stream to reach playback starting point. Current last ms is '%lu'", streamAvail);
while (startUnix < Util::epoch() - (endTime() / 1000) && keepGoing()){ while (startUnix < Util::epoch() - (endTime() / 1000) && keepGoing()){
Util::wait(1000); Util::wait(1000);
stats(); stats();
startUnix = origStartUnix + Util::epoch(); startUnix = origStartUnix + Util::epoch();
HIGH_MSG("Waiting for stream to reach playback starting point. Current last ms is '%lu'", streamAvail);
} }
} }
} }
@ -974,12 +992,13 @@ namespace Mist{
onFail("Playback start past end of non-live source", true); onFail("Playback start past end of non-live source", true);
return; return;
} }
INFO_MSG("Waiting for stream to reach playback starting point");
int64_t streamAvail = M.getLastms(mainTrack); int64_t streamAvail = M.getLastms(mainTrack);
int64_t lastUpdated = Util::getMS(); int64_t lastUpdated = Util::getMS();
INFO_MSG("Waiting for stream to reach playback starting point. Current last ms is '%lu'", streamAvail);
while (Util::getMS() - lastUpdated < 5000 && startRec > streamAvail && keepGoing()){ while (Util::getMS() - lastUpdated < 5000 && startRec > streamAvail && keepGoing()){
Util::sleep(500); Util::sleep(500);
if (M.getLastms(mainTrack) > streamAvail){ if (M.getLastms(mainTrack) > streamAvail){
HIGH_MSG("Waiting for stream to reach playback starting point. Current last ms is '%lu'", streamAvail);
stats(); stats();
streamAvail = M.getLastms(mainTrack); streamAvail = M.getLastms(mainTrack);
lastUpdated = Util::getMS(); lastUpdated = Util::getMS();
@ -997,8 +1016,16 @@ namespace Mist{
} }
} }
/*LTS-END*/ /*LTS-END*/
MEDIUM_MSG("Initial seek to %" PRIu64 "ms", seekPos); if (!keepGoing()){
seek(seekPos); ERROR_MSG("Aborting seek to %" PRIu64 " since the stream is no longer active", seekPos);
return;
}
if (endTime() >= atoll(targetParams["recstart"].c_str())) {
MEDIUM_MSG("Initial seek to %" PRIu64 "ms", seekPos);
seek(seekPos);
}else{
ERROR_MSG("Aborting seek to %" PRIu64 " since stream only has available from %lu ms to %lu ms", seekPos, startTime(), endTime());
}
} }
/// Returns the highest getMinKeepAway of all selected tracks /// Returns the highest getMinKeepAway of all selected tracks
@ -1805,6 +1832,7 @@ namespace Mist{
} }
close(outFile); close(outFile);
isRecordingToFile = true; isRecordingToFile = true;
realTime = 0;
return true; return true;
} }