From c2b0f3c07bae62e6f68d5ce3a58ff3e96bbe4c58 Mon Sep 17 00:00:00 2001 From: ziyue <1213642868@qq.com> Date: Wed, 1 Dec 2021 22:09:05 +0800 Subject: [PATCH] =?UTF-8?q?Refine:=20=E4=BF=AE=E5=A4=8Dhls=E6=92=AD?= =?UTF-8?q?=E6=94=BE=E5=99=A8=E4=B8=A2=E5=A4=B1=E9=A6=96=E5=B8=A7=E5=85=B3?= =?UTF-8?q?=E9=94=AE=E5=B8=A7=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Http/HlsPlayer.cpp | 147 ++++++++++++++++++++++++++--------------- src/Http/HlsPlayer.h | 33 +++++---- 2 files changed, 109 insertions(+), 71 deletions(-) diff --git a/src/Http/HlsPlayer.cpp b/src/Http/HlsPlayer.cpp index 882e7207..b88c8243 100644 --- a/src/Http/HlsPlayer.cpp +++ b/src/Http/HlsPlayer.cpp @@ -238,65 +238,68 @@ void HlsPlayer::onPacket_l(const char *data, size_t len){ ////////////////////////////////////////////////////////////////////////// -HlsPlayerImp::HlsPlayerImp(const EventPoller::Ptr &poller) : PlayerImp(poller) { +class HlsDemuxer : public MediaSinkInterface, public TrackSource, public std::enable_shared_from_this { +public: + HlsDemuxer() = default; + ~HlsDemuxer() override { _timer = nullptr; } -} + void start(const EventPoller::Ptr &poller, TrackListener *listener); -void HlsPlayerImp::setOnPacket(const TSSegment::onSegment &cb){ - _on_ts = cb; -} + bool inputFrame(const Frame::Ptr &frame) override; -void HlsPlayerImp::onPacket(const char *data,size_t len) { - if (_on_ts) { - _on_ts(data, len); + bool addTrack(const Track::Ptr &track) override { + return _delegate.addTrack(track); } - if (!_decoder) { - _decoder = DecoderImp::createDecoder(DecoderImp::decoder_ts, this); + void addTrackCompleted() override { + _delegate.addTrackCompleted(); } - if (_decoder) { - _decoder->input((uint8_t *) data, len); + void resetTracks() override { + ((MediaSink &)_delegate).resetTracks(); } -} -void HlsPlayerImp::onAllTrackReady() { - PlayerImp::onPlayResult(SockException(Err_success,"play hls success")); -} - -void HlsPlayerImp::onPlayResult(const SockException &ex) { - if (ex) { - PlayerImp::onPlayResult(ex); - } else { - _frame_cache.clear(); - _stamp[TrackAudio].setRelativeStamp(0); - _stamp[TrackVideo].setRelativeStamp(0); - _stamp[TrackAudio].syncTo(_stamp[TrackVideo]); - setPlayPosition(0); - - weak_ptr weakSelf = dynamic_pointer_cast(shared_from_this()); - //每50毫秒执行一次 - _timer = std::make_shared(0.05f, [weakSelf]() { - auto strongSelf = weakSelf.lock(); - if (!strongSelf) { - return false; - } - strongSelf->onTick(); - return true; - }, getPoller()); + vector getTracks(bool ready = true) const override { + return _delegate.getTracks(ready); } + +private: + void onTick(); + int64_t getBufferMS(); + int64_t getPlayPosition(); + void setPlayPosition(int64_t pos); + +private: + int64_t _ticker_offset = 0; + Ticker _ticker; + Stamp _stamp[2]; + Timer::Ptr _timer; + MediaSinkDelegate _delegate; + multimap _frame_cache; +}; + +void HlsDemuxer::start(const EventPoller::Ptr &poller, TrackListener *listener) { + _frame_cache.clear(); + _stamp[TrackAudio].setRelativeStamp(0); + _stamp[TrackVideo].setRelativeStamp(0); + _stamp[TrackAudio].syncTo(_stamp[TrackVideo]); + setPlayPosition(0); + + _delegate.setTrackListener(listener); + + //每50毫秒执行一次 + weak_ptr weak_self = shared_from_this(); + _timer = std::make_shared(0.05f, [weak_self]() { + auto strong_self = weak_self.lock(); + if (!strong_self) { + return false; + } + strong_self->onTick(); + return true; + }, poller); } -void HlsPlayerImp::onShutdown(const SockException &ex) { - PlayerImp::onShutdown(ex); - _timer = nullptr; -} - -vector HlsPlayerImp::getTracks(bool trackReady) const { - return MediaSink::getTracks(trackReady); -} - -bool HlsPlayerImp::inputFrame(const Frame::Ptr &frame) { +bool HlsDemuxer::inputFrame(const Frame::Ptr &frame) { //计算相对时间戳 int64_t dts, pts; _stamp[frame->getTrackType()].revise(frame->dts(), frame->pts(), dts, pts); @@ -306,7 +309,7 @@ bool HlsPlayerImp::inputFrame(const Frame::Ptr &frame) { if (getBufferMS() > 30 * 1000) { //缓存超过30秒,强制消费至15秒(减少延时或内存占用) while (getBufferMS() > 15 * 1000) { - MediaSink::inputFrame(_frame_cache.begin()->second); + _delegate.inputFrame(_frame_cache.begin()->second); _frame_cache.erase(_frame_cache.begin()); } //接着播放缓存中最早的帧 @@ -315,23 +318,23 @@ bool HlsPlayerImp::inputFrame(const Frame::Ptr &frame) { return true; } -int64_t HlsPlayerImp::getPlayPosition(){ +int64_t HlsDemuxer::getPlayPosition() { return _ticker.elapsedTime() + _ticker_offset; } -int64_t HlsPlayerImp::getBufferMS(){ - if(_frame_cache.empty()){ +int64_t HlsDemuxer::getBufferMS() { + if (_frame_cache.empty()) { return 0; } return _frame_cache.rbegin()->first - _frame_cache.begin()->first; } -void HlsPlayerImp::setPlayPosition(int64_t pos){ +void HlsDemuxer::setPlayPosition(int64_t pos) { _ticker.resetTime(); _ticker_offset = pos; } -void HlsPlayerImp::onTick() { +void HlsDemuxer::onTick() { auto it = _frame_cache.begin(); while (it != _frame_cache.end()) { if (it->first > getPlayPosition()) { @@ -346,10 +349,46 @@ void HlsPlayerImp::onTick() { } //消费掉已经到期的帧 - MediaSink::inputFrame(it->second); + _delegate.inputFrame(it->second); it = _frame_cache.erase(it); } } +////////////////////////////////////////////////////////////////////////// + +HlsPlayerImp::HlsPlayerImp(const EventPoller::Ptr &poller) : PlayerImp(poller) {} + +void HlsPlayerImp::onPacket(const char *data,size_t len) { + if (!_decoder) { + _decoder = DecoderImp::createDecoder(DecoderImp::decoder_ts, _demuxer.get()); + } + + if (_decoder && _demuxer) { + _decoder->input((uint8_t *) data, len); + } +} + +void HlsPlayerImp::addTrackCompleted() { + PlayerImp::onPlayResult(SockException(Err_success, "play hls success")); +} + +void HlsPlayerImp::onPlayResult(const SockException &ex) { + if (ex) { + PlayerImp::onPlayResult(ex); + } else { + auto demuxer = std::make_shared(); + demuxer->start(getPoller(), this); + _demuxer = std::move(demuxer); + } +} + +void HlsPlayerImp::onShutdown(const SockException &ex) { + PlayerImp::onShutdown(ex); + _demuxer = nullptr; +} + +vector HlsPlayerImp::getTracks(bool ready) const { + return static_pointer_cast(_demuxer)->getTracks(ready); +} }//namespace mediakit \ No newline at end of file diff --git a/src/Http/HlsPlayer.h b/src/Http/HlsPlayer.h index 93e586ec..fdafb279 100644 --- a/src/Http/HlsPlayer.h +++ b/src/Http/HlsPlayer.h @@ -22,6 +22,7 @@ #include "Rtp/TSDecoder.h" using namespace toolkit; + namespace mediakit { class HlsPlayer : public HttpClientImp , public PlayerBase , public HlsParser{ @@ -123,34 +124,32 @@ private: TSSegment _segment; }; -class HlsPlayerImp : public PlayerImp , public MediaSink{ +class HlsPlayerImp : public PlayerImp, private TrackListener { public: typedef std::shared_ptr Ptr; HlsPlayerImp(const EventPoller::Ptr &poller = nullptr); ~HlsPlayerImp() override {}; + void setOnPacket(const TSSegment::onSegment &cb); private: + //// HlsPlayer override//// void onPacket(const char *data, size_t len) override; - void onAllTrackReady() override; - void onPlayResult(const SockException &ex) override; - vector getTracks(bool trackReady = true) const override; - bool inputFrame(const Frame::Ptr &frame) override; - void onShutdown(const SockException &ex) override; - void onTick(); - - int64_t getPlayPosition(); - void setPlayPosition(int64_t pos); - int64_t getBufferMS(); private: - int64_t _ticker_offset = 0; - Ticker _ticker; - Stamp _stamp[2]; - Timer::Ptr _timer; + //// PlayerBase override//// + void onPlayResult(const SockException &ex) override; + vector getTracks(bool ready = true) const override; + void onShutdown(const SockException &ex) override; + +private: + //// TrackListener override//// + bool addTrack(const Track::Ptr &track) override { return true; }; + void addTrackCompleted() override; + +private: DecoderImp::Ptr _decoder; - TSSegment::onSegment _on_ts; - multimap _frame_cache; + MediaSinkInterface::Ptr _demuxer; }; }//namespace mediakit