diff --git a/src/buffer/player.cpp b/src/buffer/player.cpp index a995c8af..2c1169cd 100644 --- a/src/buffer/player.cpp +++ b/src/buffer/player.cpp @@ -10,6 +10,7 @@ #include #include #include +#include //under cygwin, recv blocks for ~15ms if no data is available. //This is a hack to keep performance decent with that bug present. @@ -70,9 +71,23 @@ int main(int argc, char** argv){ conf.activate(); int playing = 0; - DTSC::File source = DTSC::File(conf.getString("filename")); Socket::Connection in_out = Socket::Connection(fileno(stdout), fileno(stdin)); + + DTSC::File source = DTSC::File(conf.getString("filename")); JSON::Value meta = source.getMeta(); + + if ( !(meta.isMember("keytime") && meta.isMember("keybpos") && meta.isMember("keynum") && meta.isMember("keylen") && meta.isMember("frags")) && meta.isMember("video")){ + //file needs to be DTSCFix'ed! Run MistDTSCFix executable on it first + std::cerr << "Calculating / writing / updating VoD metadata..." << std::endl; + Util::Procs::Start("Fixer", Util::getMyPath() + "MistDTSCFix "+conf.getString("filename")); + while (Util::Procs::isActive("Fixer")){ + Util::sleep(5000); + } + std::cerr << "Done!" << std::endl; + source = DTSC::File(conf.getString("filename")); + meta = source.getMeta(); + } + JSON::Value pausemark; pausemark["datatype"] = "pause_marker"; pausemark["time"] = (long long int)0; @@ -83,6 +98,8 @@ int main(int argc, char** argv){ //send the header std::string meta_str = meta.toNetPacked(); in_out.Send(meta_str); + + if (meta.isMember("keytime")) if (meta["video"]["keyms"].asInt() < 11){ meta["video"]["keyms"] = (long long int)1000; diff --git a/src/connectors/conn_http_dynamic.cpp b/src/connectors/conn_http_dynamic.cpp index 4ea0d3e4..e8a1570b 100644 --- a/src/connectors/conn_http_dynamic.cpp +++ b/src/connectors/conn_http_dynamic.cpp @@ -62,18 +62,10 @@ namespace Connector_HTTP { afrt.setFragmentRun(afrtrun, count++); } }else{ - for (int i = 0; i < metadata["keytime"].size(); i++){ - afrtrun.firstFragment = i + 1; + for (int i = 0; i < metadata["keynum"].size(); i++){ + afrtrun.firstFragment = metadata["keynum"][i].asInt(); afrtrun.firstTimestamp = metadata["keytime"][i].asInt(); - if (i + 1 < metadata["keytime"].size()){ - afrtrun.duration = metadata["keytime"][i + 1].asInt() - metadata["keytime"][i].asInt(); - }else{ - if (metadata["lastms"].asInt()){ - afrtrun.duration = metadata["lastms"].asInt() - metadata["keytime"][i].asInt(); - }else{ - afrtrun.duration = 3000; //guess 3 seconds if unknown - } - } + afrtrun.duration = metadata["keylen"][i].asInt(); afrt.setFragmentRun(afrtrun, i); } } @@ -92,23 +84,10 @@ namespace Connector_HTTP { abst.setUpdate(true); } abst.setTimeScale(1000); - if (metadata.isMember("vod")){ - abst.setLive(false); - if (metadata["lastms"].asInt()){ - abst.setCurrentMediaTime(metadata["lastms"].asInt()); - }else{ - abst.setCurrentMediaTime(1000 * metadata["length"].asInt()); - } - }else{ - abst.setLive(false); - abst.setCurrentMediaTime(metadata["lastms"].asInt()); - } + abst.setLive(false); + abst.setCurrentMediaTime(metadata["lastms"].asInt()); abst.setSmpteTimeCodeOffset(0); abst.setMovieIdentifier(MovieId); - //abst.setServerEntry(empty, 0); - //abst.setQualityEntry(empty, 0); - //abst.setDrmData(empty); - //abst.setMetaData(empty); abst.setSegmentRunTable(asrt, 0); abst.setFragmentRunTable(afrt, 0); diff --git a/src/connectors/conn_http_live.cpp b/src/connectors/conn_http_live.cpp index ac05057f..da91442b 100644 --- a/src/connectors/conn_http_live.cpp +++ b/src/connectors/conn_http_live.cpp @@ -25,52 +25,22 @@ /// Holds everything unique to HTTP Connectors. namespace Connector_HTTP { - /// Parses the list of keyframes into 10 second fragments - std::vector keyframesToFragments(JSON::Value & metadata){ - std::vector result; - if (metadata.isNull()){ - return result; - } - if (metadata.isMember("keynum")){ - for (int i = 0; i < metadata["keynum"].size(); i++){ - result.push_back(metadata["keynum"][i].asInt()); - } - }else{ - result.push_back(0); - int currentBase = metadata["keytime"][0u].asInt(); - for (int i = 0; i < metadata["keytime"].size(); i++){ - if ((metadata["keytime"][i].asInt() - currentBase) > 10000){ - currentBase = metadata["keytime"][i].asInt(); - result.push_back(i); - } - } - } - return result; - } /// Returns a m3u or m3u8 index file std::string BuildIndex(std::string & MovieId, JSON::Value & metadata){ std::stringstream Result; if ( !metadata.isMember("live")){ - std::vector fragIndices = keyframesToFragments(metadata); int longestFragment = 0; - for (int i = 1; i < fragIndices.size(); i++){ - int fragDuration = metadata["keytime"][fragIndices[i]].asInt() - metadata["keytime"][fragIndices[i - 1]].asInt(); - if (fragDuration > longestFragment){ - longestFragment = fragDuration; + for (JSON::ArrIter ai = metadata["frags"].ArrBegin(); ai != metadata["frags"].ArrEnd(); ai++){ + if ((*ai)["dur"].asInt() > longestFragment){ + longestFragment = (*ai)["dur"].asInt(); } } Result << "#EXTM3U\r\n" - //"#EXT-X-VERSION:1\r\n" - //"#EXT-X-ALLOW-CACHE:YES\r\n" - "#EXT-X-TARGETDURATION:" << (longestFragment / 1000) + 1 << "\r\n" + "#EXT-X-TARGETDURATION:" << (longestFragment / 1000) + 1 << "\r\n" "#EXT-X-MEDIA-SEQUENCE:0\r\n"; - //"#EXT-X-PLAYLIST-TYPE:VOD\r\n"; - int lastDuration = 0; - for (int i = 0; i < fragIndices.size() - 1; i++){ - Result << "#EXTINF:" << (metadata["keytime"][fragIndices[i + 1]].asInt() - lastDuration) / 1000 << ", no desc\r\n" << fragIndices[i] + 1 - << "_" << fragIndices[i + 1] - fragIndices[i] << ".ts\r\n"; - lastDuration = metadata["keytime"][fragIndices[i + 1]].asInt(); + for (JSON::ArrIter ai = metadata["frags"].ArrBegin(); ai != metadata["frags"].ArrEnd(); ai++){ + Result << "#EXTINF:" << (*ai)["dur"].asInt() / 1000 << ", no desc\r\n" << (*ai)["num"].asInt() << "_" << (*ai)["len"].asInt() << ".ts\r\n"; } Result << "#EXT-X-ENDLIST"; }else{ diff --git a/src/connectors/conn_http_smooth.cpp b/src/connectors/conn_http_smooth.cpp index 9d0548ec..e7b7e6f3 100644 --- a/src/connectors/conn_http_smooth.cpp +++ b/src/connectors/conn_http_smooth.cpp @@ -222,21 +222,8 @@ namespace Connector_HTTP { MP4::MFHD mfhd_box; for (int i = 0; i < Strm.metadata["keytime"].size(); i++){ if (Strm.metadata["keytime"][i].asInt() >= (ReqFragment / 10000)){ - if (Strm.metadata.isMember("keynum")){ - mfhd_box.setSequenceNumber(Strm.metadata["keynum"][i].asInt()); - }else{ - mfhd_box.setSequenceNumber(i + 1); - } - if (Strm.metadata.isMember("keylen")){ - myDuration = Strm.metadata["keylen"][i].asInt() * 10000; - }else{ - if (i != Strm.metadata["keytime"].size()){ - myDuration = Strm.metadata["keytime"][i + 1].asInt() - Strm.metadata["keytime"][i].asInt(); - }else{ - myDuration = Strm.metadata["lastms"].asInt() - Strm.metadata["keytime"][i].asInt(); - } - myDuration = myDuration * 10000; - } + mfhd_box.setSequenceNumber(Strm.metadata["keynum"][i].asInt()); + myDuration = Strm.metadata["keylen"][i].asInt() * 10000; break; } } diff --git a/src/converters/flv2dtsc.cpp b/src/converters/flv2dtsc.cpp index b8f90daa..5f396863 100644 --- a/src/converters/flv2dtsc.cpp +++ b/src/converters/flv2dtsc.cpp @@ -68,7 +68,7 @@ namespace Converters { std::cout << std::string(DTSC::Magic_Header, 4) << std::string((char*) &size, 4) << packed_header; std::cout << prebuffer.rdbuf(); } - std::cerr << "Done! If you output this data to a file, don't forget to run MistDTSCFix next." << std::endl; + std::cerr << "Done!" << std::endl; return 0; } //FLV2DTSC