mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-23 03:10:04 +08:00
优化HLS延时
This commit is contained in:
parent
45070dbfff
commit
0588c47bd2
@ -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文件写缓存大小
|
||||||
|
@ -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 */
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user