diff --git a/src/Http/HlsPlayer.cpp b/src/Http/HlsPlayer.cpp index 0e5b55c9..519297b6 100644 --- a/src/Http/HlsPlayer.cpp +++ b/src/Http/HlsPlayer.cpp @@ -256,12 +256,62 @@ void HlsPlayerImp::onAllTrackReady() { void HlsPlayerImp::onPlayResult(const SockException &ex) { if(ex){ PlayerImp::onPlayResult(ex); + }else{ + _stamp[TrackAudio].syncTo(_stamp[TrackVideo]); + _ticker.resetTime(); + weak_ptr weakSelf = dynamic_pointer_cast(shared_from_this()); + //每50毫秒执行一次 + _timer = std::make_shared(0.05, [weakSelf]() { + auto strongSelf = weakSelf.lock(); + if (!strongSelf) { + return false; + } + strongSelf->onTick(); + return true; + }, getPoller()); } } +void HlsPlayerImp::onShutdown(const SockException &ex) { + PlayerImp::onShutdown(ex); + _timer = nullptr; +} + vector HlsPlayerImp::getTracks(bool trackReady) const { return MediaSink::getTracks(trackReady); } +void HlsPlayerImp::inputFrame(const Frame::Ptr &frame) { + //计算相对时间戳 + int64_t dts, pts; + _stamp[frame->getTrackType()].revise(frame->dts(), frame->pts(), dts, pts); + //根据时间戳缓存frame + _frame_cache.emplace(dts, Frame::getCacheAbleFrame(frame)); + + while (!_frame_cache.empty()) { + if (_frame_cache.rbegin()->first - _frame_cache.begin()->first > 30 * 1000) { + //缓存超过30秒,强制消费掉 + MediaSink::inputFrame(_frame_cache.begin()->second); + _frame_cache.erase(_frame_cache.begin()); + continue; + } + //缓存小于30秒 + break; + } +} + +void HlsPlayerImp::onTick() { + auto it = _frame_cache.begin(); + while (it != _frame_cache.end()) { + if (it->first > _ticker.elapsedTime()) { + //这些帧还未到时间播放 + break; + } + //消费掉已经到期的帧 + MediaSink::inputFrame(it->second); + it = _frame_cache.erase(it); + } +} + }//namespace mediakit \ No newline at end of file diff --git a/src/Http/HlsPlayer.h b/src/Http/HlsPlayer.h index bfeed863..bda64a77 100644 --- a/src/Http/HlsPlayer.h +++ b/src/Http/HlsPlayer.h @@ -135,9 +135,16 @@ private: void onAllTrackReady() override; void onPlayResult(const SockException &ex) override; vector getTracks(bool trackReady = true) const override; + void inputFrame(const Frame::Ptr &frame) override; + void onShutdown(const SockException &ex) override; + void onTick(); private: TSSegment::onSegment _on_ts; DecoderImp::Ptr _decoder; + multimap _frame_cache; + Timer::Ptr _timer; + Ticker _ticker; + Stamp _stamp[2]; }; }//namespace mediakit