From 3af710e30dee4e29d25d1be4407822a788e0475b Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 18 Jul 2013 16:40:46 +0200 Subject: [PATCH] Fixed FLV MP3 audio, some fixes for live support. --- lib/dtsc.cpp | 26 ++++++++++++++++++++++++-- lib/dtsc.h | 7 +++++++ lib/flv_tag.cpp | 2 +- 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/lib/dtsc.cpp b/lib/dtsc.cpp index dc7d7e60..2f191573 100644 --- a/lib/dtsc.cpp +++ b/lib/dtsc.cpp @@ -173,11 +173,32 @@ bool DTSC::Stream::parsePacket(Socket::Buffer & buffer){ return false; } +/// Adds a keyframe packet to all tracks, so the stream can be fully played. +void DTSC::Stream::endStream(){ + if (metadata.isMember("tracks")){ + for (JSON::ObjIter it = metadata["tracks"].ObjBegin(); it != metadata["tracks"].ObjEnd(); it++){ + JSON::Value newPack; + newPack["time"] = it->second["lastms"]; + newPack["trackid"] = it->second["trackid"]; + newPack["keyframe"] = 1ll; + newPack["data"] = ""; + addPacket(newPack); + addPacket(newPack); + } + } +} + void DTSC::Stream::addPacket(JSON::Value & newPack){ long long unsigned int now = Util::getMS(); livePos newPos; newPos.trackID = newPack["trackid"].asInt(); newPos.seekTime = newPack["time"].asInt(); + if (buffers.size() > 0){ + livePos lastPos = buffers.rbegin()->first; + if (newPos < lastPos){ + newPos.seekTime = lastPos.seekTime+1; + } + } std::string newTrack = trackMapping[newPos.trackID]; while (buffers.count(newPos) > 0){ newPos.seekTime++; @@ -208,8 +229,9 @@ void DTSC::Stream::addPacket(JSON::Value & newPack){ } int keySize = metadata["tracks"][newTrack]["keys"].size(); if (buffercount > 1){ + metadata["tracks"][newTrack]["lastms"] = newPack["time"]; #define prevKey metadata["tracks"][newTrack]["keys"][keySize - 1] - if (newPack.isMember("keyframe") || !keySize || newPack["time"].asInt() - 2000 > prevKey["time"].asInt()){ + if (newPack.isMember("keyframe") || !keySize || (datapointertype != VIDEO && newPack["time"].asInt() - 2000 > prevKey["time"].asInt())){ keyframes[newPos.trackID].insert(newPos); JSON::Value key; key["time"] = newPack["time"]; @@ -255,7 +277,7 @@ void DTSC::Stream::addPacket(JSON::Value & newPack){ newFrag["len"] = newFrag["len"].asInt() + 1; newFrag["dur"] = newFrag["dur"].asInt() + (*fragIt)["len"].asInt(); //more than 10 seconds? store the new fragment - if (newFrag["dur"].asInt() >= 10000){ + if (newFrag["dur"].asInt() >= 10000 || (*fragIt)["len"].asInt() < 2){ /// \todo Make this variable instead of hardcoded 10 seconds? metadata["tracks"][newTrack]["frags"].append(newFrag); break; diff --git a/lib/dtsc.h b/lib/dtsc.h index dc4bfbfb..3a1e9f18 100644 --- a/lib/dtsc.h +++ b/lib/dtsc.h @@ -149,6 +149,12 @@ namespace DTSC { seekTime = rhs.seekTime; trackID = rhs.trackID; } + bool operator == (const livePos& rhs) { + return seekTime == rhs.seekTime && trackID == rhs.trackID; + } + bool operator != (const livePos& rhs) { + return seekTime != rhs.seekTime || trackID != rhs.trackID; + } bool operator < (const livePos& rhs) const { if (seekTime < rhs.seekTime){ return true; @@ -207,6 +213,7 @@ namespace DTSC { void setBufferTime(unsigned int ms); bool isNewest(DTSC::livePos & pos); DTSC::livePos getNext(DTSC::livePos & pos, std::set & allowedTracks); + void endStream(); private: std::map buffers; std::map > keyframes; diff --git a/lib/flv_tag.cpp b/lib/flv_tag.cpp index d093459a..c712881d 100644 --- a/lib/flv_tag.cpp +++ b/lib/flv_tag.cpp @@ -1075,7 +1075,7 @@ JSON::Value FLV::Tag::toJSON(JSON::Value & metadata){ metadata["tracks"]["track2"]["trackid"] = 2; metadata["tracks"]["track2"]["type"] = "audio"; if ( !metadata["tracks"]["track2"].isMember("codec") || metadata["tracks"]["track2"]["codec"].asString() == "?" || metadata["tracks"]["track2"]["codec"].asString() == ""){ - metadata["audio"]["codec"] = getAudioCodec(); + metadata["tracks"]["track2"]["codec"] = getAudioCodec(); } if ( !metadata["tracks"]["track2"].isMember("rate") || metadata["tracks"]["track2"]["rate"].asInt() < 1){ switch (audiodata & 0x0C){