MistPlayer will now auto-run DTSCFix, updated connectors to use the now guaranteed consistent metadata.

This commit is contained in:
Thulinma 2013-03-21 14:22:22 +01:00
parent e2ef8c45d8
commit 78886239e1
5 changed files with 32 additions and 79 deletions

View file

@ -10,6 +10,7 @@
#include <mist/config.h>
#include <mist/socket.h>
#include <mist/timing.h>
#include <mist/procs.h>
//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;

View file

@ -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);

View file

@ -25,52 +25,22 @@
/// Holds everything unique to HTTP Connectors.
namespace Connector_HTTP {
/// Parses the list of keyframes into 10 second fragments
std::vector<int> keyframesToFragments(JSON::Value & metadata){
std::vector<int> 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<int> 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{

View file

@ -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;
}
}

View file

@ -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