Commit 0588c47b by xiongziliang

优化HLS延时

parent 45070dbf
......@@ -296,11 +296,11 @@ namespace Hls {
#define HLS_FIELD "hls."
//HLS切片时长,单位秒
#define HLS_SEGMENT_DURATION 5
#define HLS_SEGMENT_DURATION 0
const char kSegmentDuration[] = HLS_FIELD"segDur";
//HLS切片个数
#define HLS_SEGMENT_NUM 3
#define HLS_SEGMENT_NUM 1
const char kSegmentNum[] = HLS_FIELD"segNum";
//HLS文件写缓存大小
......
......@@ -38,14 +38,14 @@ HLSMaker::HLSMaker(const string& strM3u8File, const string& strHttpUrl,
if (ui32BufSize < 16 * 1024) {
ui32BufSize = 16 * 1024;
}
m_ui32BufSize = ui32BufSize;
if (ui32Duration < 5) {
ui32Duration = 5;
if(ui32Duration < 0){
ui32Duration = 0;
}
if (ui32Num < 2) {
ui32Num = 2;
if(ui32Num < 1){
ui32Num = 1;
}
m_ui32BufSize = ui32BufSize;
m_ui64TsCnt = 0;
m_strM3u8File = strM3u8File;
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_strFileName = m_strOutputPrefix.substr(m_strOutputPrefix.find_last_of('/') + 1);
m_strTmpFileName = m_strOutputPrefix + "-0.ts";
m_ts.init(m_strTmpFileName, m_ui32BufSize);
m_ts.init(m_strOutputPrefix + "-0.ts", m_ui32BufSize);
}
......@@ -65,91 +64,90 @@ HLSMaker::~HLSMaker() {
File::delete_file(strDir.data());
}
int HLSMaker::write_index_file(int iFirstSegment, unsigned int uiLastSegment,
int iEnd) {
FILE *pIndexFp;
char *pcWriteBuf;
const char *pcTmpM3u8File = (m_strM3u8File).c_str();
pIndexFp = File::createfile_file(pcTmpM3u8File, "w");
if (pIndexFp == NULL) {
return -1;
bool HLSMaker::write_index_file(int iFirstSegment, unsigned int uiLastSegment, int iEnd) {
char acWriteBuf[1024];
std::shared_ptr<FILE> pM3u8File(File::createfile_file(m_strM3u8File.data(), "w"),[](FILE *fp){
fclose(fp);
});
if (!pM3u8File) {
WarnL << "Could not open temporary m3u8 index file (" << m_strM3u8File << "), no index file will be created";
return false;
}
if (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);
if (!pcWriteBuf) {
WarnL << "Could not allocate write buffer for index file, index file will be invalid";
fclose(pIndexFp);
return -1;
//最少1秒
int maxSegmentDuration = 1;
for (auto dur : m_iDurations) {
dur /=1000;
if(dur > maxSegmentDuration){
maxSegmentDuration = dur;
}
}
if (m_ui32NumSegments) {
snprintf(pcWriteBuf, 1024,
"#EXTM3U\n#EXT-X-TARGETDURATION:%u\n#EXT-X-MEDIA-SEQUENCE:%u\n",
m_ui32SegmentDuration, iFirstSegment);
snprintf(acWriteBuf,
sizeof(acWriteBuf),
"#EXTM3U\n"
"#EXT-X-TARGETDURATION:%u\n"
"#EXT-X-MEDIA-SEQUENCE:%u\n",
maxSegmentDuration,
iFirstSegment);
} else {
snprintf(pcWriteBuf, 1024, "#EXTM3U\n#EXT-X-TARGETDURATION:%u\n",
m_ui32SegmentDuration);
snprintf(acWriteBuf,
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";
free(pcWriteBuf);
fclose(pIndexFp);
return -1;
return false;
}
for (unsigned int i = iFirstSegment; i < uiLastSegment; i++) {
snprintf(pcWriteBuf, 1024, "#EXTINF:%u,\n%s%s-%u.ts\n",
m_ui32SegmentDuration, m_strHttpUrl.c_str(),
m_strFileName.c_str(), i);
//printf(options.output_prefix);
if (fwrite(pcWriteBuf, strlen(pcWriteBuf), 1, pIndexFp) != 1) {
snprintf(acWriteBuf,
sizeof(acWriteBuf),
"#EXTINF:%.3f,\n%s%s-%u.ts\n",
m_iDurations[i-iFirstSegment]/1000.0,
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";
free(pcWriteBuf);
fclose(pIndexFp);
return -1;
return false;
}
}
if (iEnd) {
snprintf(pcWriteBuf, 1024, "#EXT-X-ENDLIST\n");
if (fwrite(pcWriteBuf, strlen(pcWriteBuf), 1, pIndexFp) != 1) {
snprintf(acWriteBuf, sizeof(acWriteBuf), "#EXT-X-ENDLIST\n");
if (fwrite(acWriteBuf, strlen(acWriteBuf), 1, pM3u8File.get()) != 1) {
WarnL << "Could not write last file and endlist tag to m3u8 index file";
free(pcWriteBuf);
fclose(pIndexFp);
return -1;
return false;
}
}
free(pcWriteBuf);
fclose(pIndexFp);
return 1;
return true;
}
void HLSMaker::inputH264(void *data, uint32_t length, uint32_t timeStamp,
int type) {
void HLSMaker::inputH264(void *data, uint32_t length, uint32_t timeStamp, int type) {
switch (type) {
case 7: //SPS
if (m_Timer.elapsedTime() >= m_ui32SegmentDuration * 1000) {
//关闭文件
m_ts.clear();
m_strTmpFileName = StrPrinter << m_strOutputPrefix << '-' << (++m_ui64TsCnt) << ".ts" << endl;
if (!m_ts.init(m_strTmpFileName, m_ui32BufSize)) {
auto strTmpFileName = StrPrinter << m_strOutputPrefix << '-' << (++m_ui64TsCnt) << ".ts" << endl;
if (!m_ts.init(strTmpFileName, m_ui32BufSize)) {
//创建文件失败
return;
}
//记录切片时间
m_iDurations.push_back(m_Timer.elapsedTime());
m_Timer.resetTime();
removets();
if (write_index_file(m_ui64TsCnt - m_ui32NumSegments, m_ui64TsCnt, 0) == -1) {
WarnL << "write_index_file error :" << get_uv_errmsg();
if(removets()){
//删除老的时间戳
m_iDurations.pop_front();
}
write_index_file(m_ui64TsCnt - m_ui32NumSegments, m_ui64TsCnt, 0);
}
case 1: //P
//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);
}
void HLSMaker::removets() {
bool HLSMaker::removets() {
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
<< ".ts" << endl).data());
return true;
}
} /* namespace MediaFile */
......
......@@ -33,6 +33,7 @@
#include "Util/File.h"
#include "Util/util.h"
#include "Util/logger.h"
#include <deque>
using namespace ZL::Util;
......@@ -65,15 +66,15 @@ private:
string m_strHttpUrl;
string m_strFileName;
string m_strOutputPrefix;
string m_strTmpFileName;
uint32_t m_ui32SegmentDuration;
uint32_t m_ui32NumSegments;
uint64_t m_ui64TsCnt;
uint32_t m_ui32BufSize;
Ticker m_Timer;
std::deque<int> m_iDurations;
int write_index_file(int iFirstSegment, unsigned int uiLastSegment, int iEnd);
void removets();
bool write_index_file(int iFirstSegment, unsigned int uiLastSegment, int iEnd);
bool removets();
};
} /* namespace MediaFile */
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论