Commit c4aaaa11 by xiongziliang

优化hls生成

parent 7f203ce9
...@@ -35,16 +35,6 @@ void MediaSink::addTrack(const Track::Ptr &track_in) { ...@@ -35,16 +35,6 @@ void MediaSink::addTrack(const Track::Ptr &track_in) {
//克隆Track,只拷贝其数据,不拷贝其数据转发关系 //克隆Track,只拷贝其数据,不拷贝其数据转发关系
auto track = track_in->clone(); auto track = track_in->clone();
weak_ptr<MediaSink> weakSelf = shared_from_this();
track->addDelegate(std::make_shared<FrameWriterInterfaceHelper>([weakSelf](const Frame::Ptr &frame){
auto strongSelf = weakSelf.lock();
if(!strongSelf){
return;
}
if(!strongSelf->_anyTrackUnReady){
strongSelf->onTrackFrame(frame);
}
}));
auto codec_id = track->getCodecId(); auto codec_id = track->getCodecId();
_track_map[codec_id] = track; _track_map[codec_id] = track;
auto lam = [this,track](){ auto lam = [this,track](){
...@@ -58,6 +48,17 @@ void MediaSink::addTrack(const Track::Ptr &track_in) { ...@@ -58,6 +48,17 @@ void MediaSink::addTrack(const Track::Ptr &track_in) {
_trackReadyCallback[codec_id] = lam; _trackReadyCallback[codec_id] = lam;
_ticker.resetTime(); _ticker.resetTime();
} }
weak_ptr<MediaSink> weakSelf = shared_from_this();
track->addDelegate(std::make_shared<FrameWriterInterfaceHelper>([weakSelf](const Frame::Ptr &frame){
auto strongSelf = weakSelf.lock();
if(!strongSelf){
return;
}
if(!strongSelf->_anyTrackUnReady){
strongSelf->onTrackFrame(frame);
}
}));
} }
void MediaSink::resetTracks() { void MediaSink::resetTracks() {
......
...@@ -43,11 +43,6 @@ void HlsMaker::makeIndexFile(bool eof) { ...@@ -43,11 +43,6 @@ void HlsMaker::makeIndexFile(bool eof) {
char file_content[1024]; char file_content[1024];
int maxSegmentDuration = 0; int maxSegmentDuration = 0;
//停止写之后将最后的片段也写进m3u8文件中
if (eof && _stampInc > 0) {
_seg_dur_list.push_back(std::make_tuple(_stampInc, _last_file_name));
}
for (auto &tp : _seg_dur_list) { for (auto &tp : _seg_dur_list) {
int dur = std::get<0>(tp); int dur = std::get<0>(tp);
if (dur > maxSegmentDuration) { if (dur > maxSegmentDuration) {
...@@ -83,18 +78,16 @@ void HlsMaker::makeIndexFile(bool eof) { ...@@ -83,18 +78,16 @@ void HlsMaker::makeIndexFile(bool eof) {
void HlsMaker::inputData(void *data, uint32_t len, uint32_t timestamp) { void HlsMaker::inputData(void *data, uint32_t len, uint32_t timestamp) {
//分片数据中断结束 //分片数据中断结束
if (data && len) { if (data && len) {
addNewFile(timestamp); addNewSegment(timestamp);
onWriteFile((char *) data, len); onWriteSegment((char *) data, len);
//记录上次写入数据时间
_ticker_last_data.resetTime();
} else { } else {
_noData = true; flushLastSegment(true);
_stampInc = _ticker.elapsedTime();
_seg_dur_list.push_back(std::make_tuple(_stampInc, _last_file_name));
delOldFile();
makeIndexFile();
} }
} }
void HlsMaker::delOldFile() { void HlsMaker::delOldSegment() {
if(_seg_number == 0){ if(_seg_number == 0){
//如果设置为保留0个切片,则认为是保存为点播 //如果设置为保留0个切片,则认为是保存为点播
return; return;
...@@ -106,28 +99,38 @@ void HlsMaker::delOldFile() { ...@@ -106,28 +99,38 @@ void HlsMaker::delOldFile() {
//但是实际保存的切片个数比m3u8所述多两个,这样做的目的是防止播放器在切片删除前能下载完毕 //但是实际保存的切片个数比m3u8所述多两个,这样做的目的是防止播放器在切片删除前能下载完毕
if (_file_index >= _seg_number + 4) { if (_file_index >= _seg_number + 4) {
onDelFile(_file_index - _seg_number - 4); onDelSegment(_file_index - _seg_number - 4);
} }
} }
void HlsMaker::addNewFile(uint32_t) { void HlsMaker::addNewSegment(uint32_t) {
//上次分片数据中断结束,重置时间避免中途的等待 if(!_last_file_name.empty() && _ticker.elapsedTime() < _seg_duration * 1000){
if (_noData) { //存在上个切片,并且未到分片时间
_ticker.resetTime(); return;
_last_file_name = onOpenFile(_file_index++);
_noData = false;
} }
_stampInc = _ticker.elapsedTime();
if (_file_index == 0 || _stampInc >= _seg_duration * 1000) { //关闭并保存上一个切片
_ticker.resetTime(); flushLastSegment();
auto file_name = onOpenFile(_file_index); //新增切片
if (_file_index++ > 0) { _last_file_name = onOpenSegment(_file_index++);
_seg_dur_list.push_back(std::make_tuple(_stampInc, _last_file_name)); //重置切片计时器
delOldFile(); _ticker.resetTime();
makeIndexFile(); }
}
_last_file_name = file_name; void HlsMaker::flushLastSegment(bool eof){
if(_last_file_name.empty()){
//不存在上个切片
return;
}
//文件创建到最后一次数据写入的时间即为切片长度
auto seg_dur = _ticker.elapsedTime() - _ticker_last_data.elapsedTime();
if(seg_dur <= 0){
seg_dur = 100;
} }
_seg_dur_list.push_back(std::make_tuple(seg_dur, _last_file_name));
delOldSegment();
makeIndexFile(eof);
_last_file_name.clear();
} }
}//namespace mediakit }//namespace mediakit
\ No newline at end of file
...@@ -60,20 +60,20 @@ protected: ...@@ -60,20 +60,20 @@ protected:
* @param index * @param index
* @return * @return
*/ */
virtual string onOpenFile(int index) = 0; virtual string onOpenSegment(int index) = 0;
/** /**
* 删除ts切片文件回调 * 删除ts切片文件回调
* @param index * @param index
*/ */
virtual void onDelFile(int index) = 0; virtual void onDelSegment(int index) = 0;
/** /**
* 写ts切片文件回调 * 写ts切片文件回调
* @param data * @param data
* @param len * @param len
*/ */
virtual void onWriteFile(const char *data, int len) = 0; virtual void onWriteSegment(const char *data, int len) = 0;
/** /**
* 写m3u8文件回调 * 写m3u8文件回调
...@@ -83,20 +83,33 @@ protected: ...@@ -83,20 +83,33 @@ protected:
virtual void onWriteHls(const char *data, int len) = 0; virtual void onWriteHls(const char *data, int len) = 0;
/** /**
* 关闭上个ts切片并且写入m3u8索引
* @param eof
*/
void flushLastSegment(bool eof = false);
private:
/**
* 生成m3u8文件 * 生成m3u8文件
* @param eof true代表点播 * @param eof true代表点播
*/ */
void makeIndexFile(bool eof = false); void makeIndexFile(bool eof = false);
void delOldFile();
void addNewFile(uint32_t timestamp); /**
protected: * 删除旧的ts切片
uint32_t _seg_number = 0; */
void delOldSegment();
/**
* 添加新的ts切片
* @param timestamp
*/
void addNewSegment(uint32_t timestamp);
private: private:
bool _noData = false; uint32_t _seg_number = 0;
int _stampInc = 0;
float _seg_duration = 0; float _seg_duration = 0;
uint64_t _file_index = 0; uint64_t _file_index = 0;
Ticker _ticker; Ticker _ticker;
Ticker _ticker_last_data;
string _last_file_name; string _last_file_name;
std::deque<tuple<int,string> > _seg_dur_list; std::deque<tuple<int,string> > _seg_dur_list;
}; };
......
...@@ -40,6 +40,7 @@ HlsMakerImp::HlsMakerImp(const string &m3u8_file, ...@@ -40,6 +40,7 @@ HlsMakerImp::HlsMakerImp(const string &m3u8_file,
_path_hls = m3u8_file; _path_hls = m3u8_file;
_params = params; _params = params;
_buf_size = bufSize; _buf_size = bufSize;
_is_vod = seg_number == 0;
_file_buf.reset(new char[bufSize],[](char *ptr){ _file_buf.reset(new char[bufSize],[](char *ptr){
delete[] ptr; delete[] ptr;
}); });
...@@ -47,14 +48,14 @@ HlsMakerImp::HlsMakerImp(const string &m3u8_file, ...@@ -47,14 +48,14 @@ HlsMakerImp::HlsMakerImp(const string &m3u8_file,
HlsMakerImp::~HlsMakerImp() { HlsMakerImp::~HlsMakerImp() {
//录制完了 //录制完了
makeIndexFile(true); flushLastSegment(true);
if(_seg_number){ if(!_is_vod){
//hls直播才删除文件 //hls直播才删除文件
File::delete_file(_path_prefix.data()); File::delete_file(_path_prefix.data());
} }
} }
string HlsMakerImp::onOpenFile(int index) { string HlsMakerImp::onOpenSegment(int index) {
auto full_path = fullPath(index); auto full_path = fullPath(index);
_file = makeFile(full_path, true); _file = makeFile(full_path, true);
if(!_file){ if(!_file){
...@@ -67,12 +68,12 @@ string HlsMakerImp::onOpenFile(int index) { ...@@ -67,12 +68,12 @@ string HlsMakerImp::onOpenFile(int index) {
return StrPrinter << index << ".ts" << "?" << _params; return StrPrinter << index << ".ts" << "?" << _params;
} }
void HlsMakerImp::onDelFile(int index) { void HlsMakerImp::onDelSegment(int index) {
//WarnL << index; //WarnL << index;
File::delete_file(fullPath(index).data()); File::delete_file(fullPath(index).data());
} }
void HlsMakerImp::onWriteFile(const char *data, int len) { void HlsMakerImp::onWriteSegment(const char *data, int len) {
if (_file) { if (_file) {
fwrite(data, len, 1, _file.get()); fwrite(data, len, 1, _file.get());
} }
......
...@@ -44,9 +44,9 @@ public: ...@@ -44,9 +44,9 @@ public:
uint32_t seg_number = 3); uint32_t seg_number = 3);
virtual ~HlsMakerImp(); virtual ~HlsMakerImp();
protected: protected:
string onOpenFile(int index) override ; string onOpenSegment(int index) override ;
void onDelFile(int index) override; void onDelSegment(int index) override;
void onWriteFile(const char *data, int len) override; void onWriteSegment(const char *data, int len) override;
void onWriteHls(const char *data, int len) override; void onWriteHls(const char *data, int len) override;
private: private:
string fullPath(int index); string fullPath(int index);
...@@ -58,6 +58,8 @@ private: ...@@ -58,6 +58,8 @@ private:
string _path_hls; string _path_hls;
string _params; string _params;
int _buf_size; int _buf_size;
//是否为点播
bool _is_vod;
}; };
}//namespace mediakit }//namespace mediakit
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论