mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-26 12:37:09 +08:00
优化HLS平滑播放逻辑
This commit is contained in:
parent
faa8786f8f
commit
e7ac7fd5f9
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user