diff --git a/lib/util.cpp b/lib/util.cpp index 0c8b932f..839e44ae 100644 --- a/lib/util.cpp +++ b/lib/util.cpp @@ -8,6 +8,7 @@ #include "timing.h" #include "util.h" #include "url.h" +#include "urireader.h" #include // errno, ENOENT, EEXIST #include #include @@ -215,7 +216,7 @@ namespace Util{ /// \param outFile file descriptor which will be used to send data /// \param append whether to open this connection in truncate or append mode bool externalWriter(const std::string & uri, int &outFile, bool append){ - HTTP::URL target(uri); + HTTP::URL target = HTTP::localURIResolver().link(uri); // If it is a remote target, we might need to spawn an external binary if (!target.isLocalPath()){ bool matchedProtocol = false; diff --git a/src/input/input.cpp b/src/input/input.cpp index ec75da5e..4bb77092 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -227,38 +227,45 @@ namespace Mist{ lastStats = 0; } - void Input::checkHeaderTimes(std::string streamFile){ - struct stat bufStream; - struct stat bufHeader; - struct stat srtStream; + void Input::checkHeaderTimes(const HTTP::URL & streamFile){ - std::string srtFile = streamFile + ".srt"; - if (stat(srtFile.c_str(), &srtStream) == 0){ - hasSrt = true; - srtSource.open(srtFile.c_str()); - INFO_MSG("File %s opened as srt source", srtFile.c_str()); + /// \TODO Implement remote URLs? + + if (streamFile.isLocalPath()){ + const std::string & f = streamFile.getFilePath(); + + struct stat bufStream; + struct stat bufHeader; + struct stat srtStream; + std::string srtFile = f + ".srt"; + if (stat(srtFile.c_str(), &srtStream) == 0){ + hasSrt = true; + srtSource.open(srtFile.c_str()); + INFO_MSG("File %s opened as srt source", srtFile.c_str()); + } + + if (stat(f.c_str(), &bufStream) != 0){ + INSANE_MSG("Source is not a file - ignoring header check"); + return; + } + std::string headerFile = f + ".dtsh"; + if (stat(headerFile.c_str(), &bufHeader) != 0){ + INSANE_MSG("No header exists to compare - ignoring header check"); + return; + } + // the same second is not enough - add a 15 second window where we consider it too old + if (bufHeader.st_mtime < bufStream.st_mtime + 15){ + INFO_MSG("Overwriting outdated DTSH header file: %s ", headerFile.c_str()); + remove(headerFile.c_str()); + } + + // the same second is not enough - add a 15 second window where we consider it too old + if (hasSrt && bufHeader.st_mtime < srtStream.st_mtime + 15){ + INFO_MSG("Overwriting outdated DTSH header file: %s ", headerFile.c_str()); + remove(headerFile.c_str()); + } } - if (stat(streamFile.c_str(), &bufStream) != 0){ - INSANE_MSG("Source is not a file - ignoring header check"); - return; - } - std::string headerFile = streamFile + ".dtsh"; - if (stat(headerFile.c_str(), &bufHeader) != 0){ - INSANE_MSG("No header exists to compare - ignoring header check"); - return; - } - // the same second is not enough - add a 15 second window where we consider it too old - if (bufHeader.st_mtime < bufStream.st_mtime + 15){ - INFO_MSG("Overwriting outdated DTSH header file: %s ", headerFile.c_str()); - remove(headerFile.c_str()); - } - - // the same second is not enough - add a 15 second window where we consider it too old - if (hasSrt && bufHeader.st_mtime < srtStream.st_mtime + 15){ - INFO_MSG("Overwriting outdated DTSH header file: %s ", headerFile.c_str()); - remove(headerFile.c_str()); - } } void Input::readSrtHeader(){ @@ -586,7 +593,7 @@ namespace Mist{ int Input::run(){ Comms::sessionConfigCache(); if (streamStatus){streamStatus.mapped[0] = STRMSTAT_BOOT;} - checkHeaderTimes(config->getString("input")); + checkHeaderTimes(HTTP::localURIResolver().link(config->getString("input"))); //needHeader internally calls readExistingHeader which in turn attempts to read header cache if (needHeader()){ uint64_t timer = Util::getMicros(); @@ -597,7 +604,7 @@ namespace Mist{ timer = Util::getMicros(timer); INFO_MSG("Created header in %.3f ms (%zu tracks)", (double)timer/1000.0, M?M.trackCount():(size_t)0); //Write header to file for caching purposes - M.toFile(config->getString("input") + ".dtsh"); + M.toFile(HTTP::localURIResolver().link(config->getString("input") + ".dtsh").getUrl()); } postHeader(); if (config->getBool("headeronly")){return 0;} diff --git a/src/input/input.h b/src/input/input.h index 6b2b56ad..63ada152 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "../io.h" @@ -73,7 +74,7 @@ namespace Mist{ virtual bool openStreamSource(){return readHeader();} virtual void closeStreamSource(){} virtual void parseStreamHeader(){} - void checkHeaderTimes(std::string streamFile); + void checkHeaderTimes(const HTTP::URL & streamFile); virtual void removeUnused(); virtual void convert(); virtual void serve(); diff --git a/src/output/output.cpp b/src/output/output.cpp index 114086e7..f8fb51bf 100644 --- a/src/output/output.cpp +++ b/src/output/output.cpp @@ -1417,7 +1417,7 @@ namespace Mist{ if (!plsConn){ std::string plsRel = targetParams["m3u8"]; Util::streamVariables(plsRel, streamName); - playlistLocation = HTTP::URL(config->getString("target")).link(plsRel); + playlistLocation = HTTP::localURIResolver().link(config->getString("target")).link(plsRel); if (playlistLocation.isLocalPath()){ playlistLocationString = playlistLocation.getFilePath(); INFO_MSG("Segmenting to local playlist '%s'", playlistLocationString.c_str()); @@ -1551,7 +1551,6 @@ namespace Mist{ Util::replace(newTarget, "$segmentCounter", JSON::Value(segmentCount).asString()); Util::streamVariables(newTarget, streamName); currentTarget = newTarget; - config->getOption("target", true).append(currentTarget); if (newTarget == "-"){ INFO_MSG("Outputting %s to stdout with %s format", streamName.c_str(), capa["name"].asString().c_str()); @@ -1668,7 +1667,7 @@ namespace Mist{ Util::logExitReason("Lost connection to playlist file `%s` during segmenting", playlistLocationString.c_str()); break; } - std::string segment = HTTP::URL(currentTarget).getLinkFrom(playlistLocation); + std::string segment = HTTP::localURIResolver().link(currentTarget).getLinkFrom(playlistLocation); if (M.getLive()){ uint64_t unixMs = M.getBootMsOffset() + systemBoot + currentStartTime; playlistBuffer += "#EXT-X-PROGRAM-DATE-TIME:" + Util::getUTCStringMillis(unixMs) + "\n"; @@ -1800,7 +1799,7 @@ namespace Mist{ // If this is a non-live source, we can finally open up the connection to the playlist file if (!M.getLive()){connectToFile(playlistLocationString, false, &plsConn);} if (plsConn){ - std::string segment = HTTP::URL(currentTarget).getLinkFrom(playlistLocation); + std::string segment = HTTP::localURIResolver().link(currentTarget).getLinkFrom(playlistLocation); if (M.getLive()){ uint64_t unixMs = M.getBootMsOffset() + systemBoot + currentStartTime; playlistBuffer += "#EXT-X-PROGRAM-DATE-TIME:" + Util::getUTCStringMillis(unixMs) + "\n"; @@ -2296,7 +2295,7 @@ namespace Mist{ bool Output::connectToFile(std::string file, bool append, Socket::Connection *conn){ int outFile = -1; if (!conn) {conn = &myConn;} - bool isFileTarget = HTTP::URL(file).isLocalPath(); + bool isFileTarget = HTTP::localURIResolver().link(file).isLocalPath(); if (!Util::externalWriter(file, outFile, append)){return false;} if (*conn && isFileTarget) { flock(conn->getSocket(), LOCK_UN | LOCK_NB);