diff --git a/src/output/output_hls.cpp b/src/output/output_hls.cpp index a472639c..194367c1 100644 --- a/src/output/output_hls.cpp +++ b/src/output/output_hls.cpp @@ -13,6 +13,16 @@ namespace Mist { return false; } + std::string OutHLS::h264init(const std::string & initData){ + std::stringstream r; + MP4::AVCC avccBox; + avccBox.setPayload(initData); + r << std::hex << std::setw(2) << std::setfill('0') << (int)initData[1] << std::dec; + r << std::hex << std::setw(2) << std::setfill('0') << (int)initData[2] << std::dec; + r << std::hex << std::setw(2) << std::setfill('0') << (int)initData[3] << std::dec; + return r.str(); + } + ///\brief Builds an index file for HTTP Live streaming. ///\return The index file for HTTP Live Streaming. std::string OutHLS::liveIndex() { @@ -43,11 +53,26 @@ namespace Mist { if (audioId != -1) { bWidth += myMeta.tracks[audioId].bps; } - if (!hasSubs){ - result << "#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" << (bWidth * 8) << "\r\n"; - }else{ - result << "#EXT-X-STREAM-INF:PROGRAM-ID=1,SUBTITLES=\"sub1\",BANDWIDTH=" << (bWidth * 8) << "\r\n"; + result << "#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" << (bWidth * 8); + result << ",RESOLUTION=" << it->second.width << "x" << it->second.height; + if (it->second.fpks){ + result << ",FRAME-RATE=" << (float)it->second.fpks / 1000; } + if (it->second.codec == "H264"){ + result << ",CODECS=\""; + if (it->second.codec == "H264"){ + result << "avc1." << h264init(it->second.init); + } + if (audioId != -1){ + if (myMeta.tracks[audioId].codec == "AAC"){ + result << ",mp4a.40.2"; + }else if (myMeta.tracks[audioId].codec == "MP3" ){ + result << ",mp4a.40.34"; + } + } + result << "\""; + } + result <<"\r\n"; result << it->first; if (audioId != -1) { result << "_" << audioId; @@ -63,7 +88,13 @@ namespace Mist { } } if (!vidTracks && audioId) { - result << "#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" << (myMeta.tracks[audioId].bps * 8) << "\r\n"; + result << "#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=" << (myMeta.tracks[audioId].bps * 8); + if (myMeta.tracks[audioId].codec == "AAC"){ + result << ",CODECS=\"mp4a.40.2\""; + }else if (myMeta.tracks[audioId].codec == "MP3" ){ + result << ",CODECS=\"mp4a.40.34\""; + } + result << "\r\n"; result << audioId << "/index.m3u8\r\n"; } DEBUG_MSG(DLVL_HIGH, "Sending this index: %s", result.str().c_str()); @@ -165,15 +196,7 @@ namespace Mist { } char lineBuf[400]; - if(myMeta.tracks[tid].codec == "subtitle"){ - snprintf(lineBuf, 400, "#EXTINF:%f,\r\n../../../%s.vtt?track=%d&from=%lld&to=%lld\r\n", streamName.c_str(),(double)duration/1000,tid, starttime, starttime + duration); - }else{ - if (sessId.size()){ - snprintf(lineBuf, 400, "#EXTINF:%f,\r\n%lld_%lld.ts?sessId=%s\r\n", (double)duration/1000, starttime, starttime + duration, sessId.c_str()); - }else{ - snprintf(lineBuf, 400, "#EXTINF:%f,\r\n%lld_%lld.ts\r\n", (double)duration/1000, starttime, starttime + duration); - } - } + snprintf(lineBuf, 400, "#EXTINF:%f,\r\n%lld_%lld.ts\r\n", (double)duration/1000, starttime, starttime + duration); durs.push_back(duration); total_dur += duration; lines.push_back(lineBuf); diff --git a/src/output/output_hls.h b/src/output/output_hls.h index 2ddd123b..746a648a 100644 --- a/src/output/output_hls.h +++ b/src/output/output_hls.h @@ -12,6 +12,8 @@ namespace Mist { void onHTTP(); bool isReadyForPlay(); protected: + std::string h264init(const std::string & initData); + bool hasSessionIDs(){return true;} std::string liveIndex(); std::string liveIndex(int tid, std::string & sessId);