优化HLS平滑播放逻辑

This commit is contained in:
xiongziliang 2020-09-06 17:56:45 +08:00
parent faa8786f8f
commit e7ac7fd5f9
2 changed files with 41 additions and 16 deletions

View File

@ -254,14 +254,18 @@ void HlsPlayerImp::onAllTrackReady() {
} }
void HlsPlayerImp::onPlayResult(const SockException &ex) { void HlsPlayerImp::onPlayResult(const SockException &ex) {
if(ex){ if (ex) {
PlayerImp<HlsPlayer, PlayerBase>::onPlayResult(ex); PlayerImp<HlsPlayer, PlayerBase>::onPlayResult(ex);
}else{ } else {
_frame_cache.clear();
_stamp[TrackAudio].setRelativeStamp(0);
_stamp[TrackVideo].setRelativeStamp(0);
_stamp[TrackAudio].syncTo(_stamp[TrackVideo]); _stamp[TrackAudio].syncTo(_stamp[TrackVideo]);
_ticker.resetTime(); setPlayPosition(0);
weak_ptr<HlsPlayerImp> weakSelf = dynamic_pointer_cast<HlsPlayerImp>(shared_from_this()); weak_ptr<HlsPlayerImp> weakSelf = dynamic_pointer_cast<HlsPlayerImp>(shared_from_this());
//每50毫秒执行一次 //每20毫秒执行一次
_timer = std::make_shared<Timer>(0.05, [weakSelf]() { _timer = std::make_shared<Timer>(0.02, [weakSelf]() {
auto strongSelf = weakSelf.lock(); auto strongSelf = weakSelf.lock();
if (!strongSelf) { if (!strongSelf) {
return false; return false;
@ -288,22 +292,37 @@ void HlsPlayerImp::inputFrame(const Frame::Ptr &frame) {
//根据时间戳缓存frame //根据时间戳缓存frame
_frame_cache.emplace(dts, Frame::getCacheAbleFrame(frame)); _frame_cache.emplace(dts, Frame::getCacheAbleFrame(frame));
while (!_frame_cache.empty()) { if (getBufferMS() > 30 * 1000) {
if (_frame_cache.rbegin()->first - _frame_cache.begin()->first > 30 * 1000) { //缓存超过30秒强制消费至15秒(减少延时或内存占用)
//缓存超过30秒强制消费掉 while (getBufferMS() > 15 * 1000) {
MediaSink::inputFrame(_frame_cache.begin()->second); MediaSink::inputFrame(_frame_cache.begin()->second);
_frame_cache.erase(_frame_cache.begin()); _frame_cache.erase(_frame_cache.begin());
continue;
} }
//缓存小于30秒 //接着播放缓存中最早的帧
break; setPlayPosition(_frame_cache.begin()->first);
} }
} }
int64_t HlsPlayerImp::getPlayPosition(){
return _ticker.elapsedTime() + _ticker_offset;
}
int64_t HlsPlayerImp::getBufferMS(){
if(_frame_cache.empty()){
return 0;
}
return _frame_cache.rbegin()->first - _frame_cache.begin()->first;
}
void HlsPlayerImp::setPlayPosition(int64_t pos){
_ticker.resetTime();
_ticker_offset = pos;
}
void HlsPlayerImp::onTick() { void HlsPlayerImp::onTick() {
auto it = _frame_cache.begin(); auto it = _frame_cache.begin();
while (it != _frame_cache.end()) { while (it != _frame_cache.end()) {
if (it->first > _ticker.elapsedTime()) { if (it->first > getPlayPosition()) {
//这些帧还未到时间播放 //这些帧还未到时间播放
break; break;
} }

View File

@ -138,13 +138,19 @@ private:
void inputFrame(const Frame::Ptr &frame) override; void inputFrame(const Frame::Ptr &frame) override;
void onShutdown(const SockException &ex) override; void onShutdown(const SockException &ex) override;
void onTick(); void onTick();
int64_t getPlayPosition();
void setPlayPosition(int64_t pos);
int64_t getBufferMS();
private: private:
TSSegment::onSegment _on_ts; int64_t _ticker_offset = 0;
DecoderImp::Ptr _decoder;
multimap<int64_t, Frame::Ptr> _frame_cache;
Timer::Ptr _timer;
Ticker _ticker; Ticker _ticker;
Stamp _stamp[2]; Stamp _stamp[2];
Timer::Ptr _timer;
DecoderImp::Ptr _decoder;
TSSegment::onSegment _on_ts;
multimap<int64_t, Frame::Ptr> _frame_cache;
}; };
}//namespace mediakit }//namespace mediakit