优化HLS延时

This commit is contained in:
xiongziliang 2017-11-09 18:14:16 +08:00
parent 45070dbfff
commit 0588c47bd2
3 changed files with 78 additions and 78 deletions

View File

@ -296,11 +296,11 @@ namespace Hls {
#define HLS_FIELD "hls." #define HLS_FIELD "hls."
//HLS切片时长,单位秒 //HLS切片时长,单位秒
#define HLS_SEGMENT_DURATION 5 #define HLS_SEGMENT_DURATION 0
const char kSegmentDuration[] = HLS_FIELD"segDur"; const char kSegmentDuration[] = HLS_FIELD"segDur";
//HLS切片个数 //HLS切片个数
#define HLS_SEGMENT_NUM 3 #define HLS_SEGMENT_NUM 1
const char kSegmentNum[] = HLS_FIELD"segNum"; const char kSegmentNum[] = HLS_FIELD"segNum";
//HLS文件写缓存大小 //HLS文件写缓存大小

View File

@ -38,14 +38,14 @@ HLSMaker::HLSMaker(const string& strM3u8File, const string& strHttpUrl,
if (ui32BufSize < 16 * 1024) { if (ui32BufSize < 16 * 1024) {
ui32BufSize = 16 * 1024; ui32BufSize = 16 * 1024;
} }
m_ui32BufSize = ui32BufSize;
if (ui32Duration < 5) {
ui32Duration = 5;
}
if (ui32Num < 2) {
ui32Num = 2;
}
if(ui32Duration < 0){
ui32Duration = 0;
}
if(ui32Num < 1){
ui32Num = 1;
}
m_ui32BufSize = ui32BufSize;
m_ui64TsCnt = 0; m_ui64TsCnt = 0;
m_strM3u8File = strM3u8File; m_strM3u8File = strM3u8File;
m_strHttpUrl = strHttpUrl.substr(0, strHttpUrl.find_last_of('/') + 1); m_strHttpUrl = strHttpUrl.substr(0, strHttpUrl.find_last_of('/') + 1);
@ -54,8 +54,7 @@ HLSMaker::HLSMaker(const string& strM3u8File, const string& strHttpUrl,
m_strOutputPrefix = strM3u8File.substr(0, strM3u8File.find_last_of('.')); m_strOutputPrefix = strM3u8File.substr(0, strM3u8File.find_last_of('.'));
m_strFileName = m_strOutputPrefix.substr(m_strOutputPrefix.find_last_of('/') + 1); m_strFileName = m_strOutputPrefix.substr(m_strOutputPrefix.find_last_of('/') + 1);
m_strTmpFileName = m_strOutputPrefix + "-0.ts"; m_ts.init(m_strOutputPrefix + "-0.ts", m_ui32BufSize);
m_ts.init(m_strTmpFileName, m_ui32BufSize);
} }
@ -65,91 +64,90 @@ HLSMaker::~HLSMaker() {
File::delete_file(strDir.data()); File::delete_file(strDir.data());
} }
int HLSMaker::write_index_file(int iFirstSegment, unsigned int uiLastSegment, bool HLSMaker::write_index_file(int iFirstSegment, unsigned int uiLastSegment, int iEnd) {
int iEnd) { char acWriteBuf[1024];
FILE *pIndexFp; std::shared_ptr<FILE> pM3u8File(File::createfile_file(m_strM3u8File.data(), "w"),[](FILE *fp){
char *pcWriteBuf; fclose(fp);
const char *pcTmpM3u8File = (m_strM3u8File).c_str(); });
pIndexFp = File::createfile_file(pcTmpM3u8File, "w"); if (!pM3u8File) {
if (pIndexFp == NULL) { WarnL << "Could not open temporary m3u8 index file (" << m_strM3u8File << "), no index file will be created";
return -1; return false;
} }
if (iFirstSegment < 0) { if (iFirstSegment < 0) {
iFirstSegment = 0; iFirstSegment = 0;
} }
if (!pIndexFp) {
WarnL << "Could not open temporary m3u8 index file (" << pcTmpM3u8File
<< "), no index file will be created";
return -1;
}
pcWriteBuf = (char *) malloc(sizeof(char) * 1024); //最少1秒
if (!pcWriteBuf) { int maxSegmentDuration = 1;
WarnL << "Could not allocate write buffer for index file, index file will be invalid"; for (auto dur : m_iDurations) {
fclose(pIndexFp); dur /=1000;
return -1; if(dur > maxSegmentDuration){
maxSegmentDuration = dur;
}
} }
if (m_ui32NumSegments) { if (m_ui32NumSegments) {
snprintf(pcWriteBuf, 1024, snprintf(acWriteBuf,
"#EXTM3U\n#EXT-X-TARGETDURATION:%u\n#EXT-X-MEDIA-SEQUENCE:%u\n", sizeof(acWriteBuf),
m_ui32SegmentDuration, iFirstSegment); "#EXTM3U\n"
"#EXT-X-TARGETDURATION:%u\n"
"#EXT-X-MEDIA-SEQUENCE:%u\n",
maxSegmentDuration,
iFirstSegment);
} else { } else {
snprintf(pcWriteBuf, 1024, "#EXTM3U\n#EXT-X-TARGETDURATION:%u\n", snprintf(acWriteBuf,
m_ui32SegmentDuration); sizeof(acWriteBuf),
"#EXTM3U\n"
"#EXT-X-TARGETDURATION:%u\n",
maxSegmentDuration);
} }
if (fwrite(pcWriteBuf, strlen(pcWriteBuf), 1, pIndexFp) != 1) { if (fwrite(acWriteBuf, strlen(acWriteBuf), 1, pM3u8File.get()) != 1) {
WarnL << "Could not write to m3u8 index file, will not continue writing to index file"; WarnL << "Could not write to m3u8 index file, will not continue writing to index file";
free(pcWriteBuf); return false;
fclose(pIndexFp);
return -1;
} }
for (unsigned int i = iFirstSegment; i < uiLastSegment; i++) { for (unsigned int i = iFirstSegment; i < uiLastSegment; i++) {
snprintf(pcWriteBuf, 1024, "#EXTINF:%u,\n%s%s-%u.ts\n", snprintf(acWriteBuf,
m_ui32SegmentDuration, m_strHttpUrl.c_str(), sizeof(acWriteBuf),
m_strFileName.c_str(), i); "#EXTINF:%.3f,\n%s%s-%u.ts\n",
//printf(options.output_prefix); m_iDurations[i-iFirstSegment]/1000.0,
if (fwrite(pcWriteBuf, strlen(pcWriteBuf), 1, pIndexFp) != 1) { m_strHttpUrl.c_str(),
m_strFileName.c_str(),
i);
if (fwrite(acWriteBuf, strlen(acWriteBuf), 1, pM3u8File.get()) != 1) {
WarnL << "Could not write to m3u8 index file, will not continue writing to index file"; WarnL << "Could not write to m3u8 index file, will not continue writing to index file";
free(pcWriteBuf); return false;
fclose(pIndexFp);
return -1;
} }
} }
if (iEnd) { if (iEnd) {
snprintf(pcWriteBuf, 1024, "#EXT-X-ENDLIST\n"); snprintf(acWriteBuf, sizeof(acWriteBuf), "#EXT-X-ENDLIST\n");
if (fwrite(pcWriteBuf, strlen(pcWriteBuf), 1, pIndexFp) != 1) { if (fwrite(acWriteBuf, strlen(acWriteBuf), 1, pM3u8File.get()) != 1) {
WarnL << "Could not write last file and endlist tag to m3u8 index file"; WarnL << "Could not write last file and endlist tag to m3u8 index file";
free(pcWriteBuf); return false;
fclose(pIndexFp);
return -1;
} }
} }
return true;
free(pcWriteBuf);
fclose(pIndexFp);
return 1;
} }
void HLSMaker::inputH264(void *data, uint32_t length, uint32_t timeStamp, void HLSMaker::inputH264(void *data, uint32_t length, uint32_t timeStamp, int type) {
int type) {
switch (type) { switch (type) {
case 7: //SPS case 7: //SPS
if (m_Timer.elapsedTime() >= m_ui32SegmentDuration * 1000) { if (m_Timer.elapsedTime() >= m_ui32SegmentDuration * 1000) {
//关闭文件
m_ts.clear(); m_ts.clear();
m_strTmpFileName = StrPrinter << m_strOutputPrefix << '-' << (++m_ui64TsCnt) << ".ts" << endl; auto strTmpFileName = StrPrinter << m_strOutputPrefix << '-' << (++m_ui64TsCnt) << ".ts" << endl;
if (!m_ts.init(m_strTmpFileName, m_ui32BufSize)) { if (!m_ts.init(strTmpFileName, m_ui32BufSize)) {
//创建文件失败 //创建文件失败
return; return;
} }
//记录切片时间
m_iDurations.push_back(m_Timer.elapsedTime());
m_Timer.resetTime(); m_Timer.resetTime();
removets(); if(removets()){
if (write_index_file(m_ui64TsCnt - m_ui32NumSegments, m_ui64TsCnt, 0) == -1) { //删除老的时间戳
WarnL << "write_index_file error :" << get_uv_errmsg(); m_iDurations.pop_front();
} }
write_index_file(m_ui64TsCnt - m_ui32NumSegments, m_ui64TsCnt, 0);
} }
case 1: //P case 1: //P
//insert aud frame before p and SPS frame //insert aud frame before p and SPS frame
@ -167,13 +165,14 @@ void HLSMaker::inputAAC(void *data, uint32_t length, uint32_t timeStamp) {
m_ts.inputAAC((char *) data, length, timeStamp); m_ts.inputAAC((char *) data, length, timeStamp);
} }
void HLSMaker::removets() { bool HLSMaker::removets() {
if (m_ui64TsCnt <= m_ui32NumSegments) { if (m_ui64TsCnt <= m_ui32NumSegments) {
return; return false;
} }
File::delete_file( (StrPrinter << m_strOutputPrefix << "-" File::delete_file((StrPrinter << m_strOutputPrefix << "-"
<< m_ui64TsCnt - m_ui32NumSegments - 1 << m_ui64TsCnt - m_ui32NumSegments - 1
<< ".ts" << endl).data()); << ".ts" << endl).data());
return true;
} }
} /* namespace MediaFile */ } /* namespace MediaFile */

View File

@ -33,6 +33,7 @@
#include "Util/File.h" #include "Util/File.h"
#include "Util/util.h" #include "Util/util.h"
#include "Util/logger.h" #include "Util/logger.h"
#include <deque>
using namespace ZL::Util; using namespace ZL::Util;
@ -65,15 +66,15 @@ private:
string m_strHttpUrl; string m_strHttpUrl;
string m_strFileName; string m_strFileName;
string m_strOutputPrefix; string m_strOutputPrefix;
string m_strTmpFileName;
uint32_t m_ui32SegmentDuration; uint32_t m_ui32SegmentDuration;
uint32_t m_ui32NumSegments; uint32_t m_ui32NumSegments;
uint64_t m_ui64TsCnt; uint64_t m_ui64TsCnt;
uint32_t m_ui32BufSize; uint32_t m_ui32BufSize;
Ticker m_Timer; Ticker m_Timer;
std::deque<int> m_iDurations;
int write_index_file(int iFirstSegment, unsigned int uiLastSegment, int iEnd); bool write_index_file(int iFirstSegment, unsigned int uiLastSegment, int iEnd);
void removets(); bool removets();
}; };
} /* namespace MediaFile */ } /* namespace MediaFile */