From 92f879d703c64826b7f2734d5846e1c4e984d77e Mon Sep 17 00:00:00 2001 From: ziyue <1213642868@qq.com> Date: Wed, 9 Jun 2021 15:01:45 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84PlayerProxy=E5=85=B3=E9=97=AD?= =?UTF-8?q?=E6=9C=BA=E5=88=B6,=E9=87=8D=E8=AF=95=E6=AC=A1=E6=95=B0?= =?UTF-8?q?=E8=B6=85=E9=99=90=E5=90=8E=E8=87=AA=E5=8A=A8=E5=85=B3=E9=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/include/mk_proxyplayer.h | 2 +- api/source/mk_proxyplayer.cpp | 4 +- server/WebApi.cpp | 2 +- src/Player/PlayerProxy.cpp | 85 ++++++++++++++++++----------------- src/Player/PlayerProxy.h | 8 ++-- 5 files changed, 53 insertions(+), 48 deletions(-) diff --git a/api/include/mk_proxyplayer.h b/api/include/mk_proxyplayer.h index 82844fdf..0dcc0923 100644 --- a/api/include/mk_proxyplayer.h +++ b/api/include/mk_proxyplayer.h @@ -59,7 +59,7 @@ API_EXPORT void API_CALL mk_proxy_player_play(mk_proxy_player ctx, const char *u * 如果你不调用mk_proxy_player_release函数,那么MediaSource.close()操作将无效 * @param user_data 用户数据指针,通过mk_proxy_player_set_on_close函数设置 */ -typedef void(API_CALL *on_mk_proxy_player_close)(void *user_data); +typedef void(API_CALL *on_mk_proxy_player_close)(void *user_data, int err, const char *what, int sys_err); /** * 监听MediaSource.close()事件 diff --git a/api/source/mk_proxyplayer.cpp b/api/source/mk_proxyplayer.cpp index 97f31567..f151ceb8 100644 --- a/api/source/mk_proxyplayer.cpp +++ b/api/source/mk_proxyplayer.cpp @@ -51,9 +51,9 @@ API_EXPORT void API_CALL mk_proxy_player_set_on_close(mk_proxy_player ctx, on_mk PlayerProxy::Ptr &obj = *((PlayerProxy::Ptr *) ctx); obj->getPoller()->async([obj,cb,user_data](){ //切换线程再操作 - obj->setOnClose([cb,user_data](){ + obj->setOnClose([cb,user_data](const SockException &ex){ if(cb){ - cb(user_data); + cb(user_data, ex.getErrCode(), ex.what(), ex.getCustomCode()); } }); }); diff --git a/server/WebApi.cpp b/server/WebApi.cpp index 2ccb077b..969c3636 100755 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -634,7 +634,7 @@ void installWebApi() { }); //被主动关闭拉流 - player->setOnClose([key](){ + player->setOnClose([key](const SockException &ex){ lock_guard lck(s_proxyMapMtx); s_proxyMap.erase(key); }); diff --git a/src/Player/PlayerProxy.cpp b/src/Player/PlayerProxy.cpp index 40ffa33b..5dbb1b55 100644 --- a/src/Player/PlayerProxy.cpp +++ b/src/Player/PlayerProxy.cpp @@ -48,62 +48,66 @@ static uint8_t s_mute_adts[] = {0xff, 0xf1, 0x6c, 0x40, 0x2d, 0x3f, 0xfc, 0x00, PlayerProxy::PlayerProxy(const string &vhost, const string &app, const string &stream_id, bool enable_hls, bool enable_mp4, int retry_count, const EventPoller::Ptr &poller) - : MediaPlayer(poller) { + : MediaPlayer(poller) { _vhost = vhost; _app = app; _stream_id = stream_id; _enable_hls = enable_hls; _enable_mp4 = enable_mp4; _retry_count = retry_count; + _on_close = [](const SockException &) {}; } -void PlayerProxy::setPlayCallbackOnce(const function &cb){ +void PlayerProxy::setPlayCallbackOnce(const function &cb) { _on_play = cb; } -void PlayerProxy::setOnClose(const function &cb){ - _on_close = cb; +void PlayerProxy::setOnClose(const function &cb) { + _on_close = cb ? cb : [](const SockException &) {}; } void PlayerProxy::play(const string &strUrlTmp) { weak_ptr weakSelf = shared_from_this(); std::shared_ptr piFailedCnt(new int(0)); //连续播放失败次数 - setOnPlayResult([weakSelf,strUrlTmp,piFailedCnt](const SockException &err) { + setOnPlayResult([weakSelf, strUrlTmp, piFailedCnt](const SockException &err) { auto strongSelf = weakSelf.lock(); - if(!strongSelf) { + if (!strongSelf) { return; } - if(strongSelf->_on_play) { + if (strongSelf->_on_play) { strongSelf->_on_play(err); strongSelf->_on_play = nullptr; } - if(!err) { + if (!err) { // 播放成功 *piFailedCnt = 0;//连续播放失败次数清0 strongSelf->onPlaySuccess(); - }else if(*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) { + } else if (*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) { // 播放失败,延时重试播放 - strongSelf->rePlay(strUrlTmp,(*piFailedCnt)++); + strongSelf->rePlay(strUrlTmp, (*piFailedCnt)++); + } else { + //达到了最大重试次数,回调关闭 + strongSelf->_on_close(err); } }); - setOnShutdown([weakSelf,strUrlTmp,piFailedCnt](const SockException &err) { + setOnShutdown([weakSelf, strUrlTmp, piFailedCnt](const SockException &err) { auto strongSelf = weakSelf.lock(); - if(!strongSelf) { + if (!strongSelf) { return; } //注销直接拉流代理产生的流:#532 strongSelf->setMediaSource(nullptr); - if(strongSelf->_muxer) { + if (strongSelf->_muxer) { auto tracks = strongSelf->MediaPlayer::getTracks(false); - for (auto & track : tracks){ + for (auto &track : tracks) { track->delDelegate(strongSelf->_muxer.get()); } - GET_CONFIG(bool,resetWhenRePlay,General::kResetWhenRePlay); + GET_CONFIG(bool, resetWhenRePlay, General::kResetWhenRePlay); if (resetWhenRePlay) { strongSelf->_muxer.reset(); } else { @@ -111,8 +115,11 @@ void PlayerProxy::play(const string &strUrlTmp) { } } //播放异常中断,延时重试播放 - if(*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) { - strongSelf->rePlay(strUrlTmp,(*piFailedCnt)++); + if (*piFailedCnt < strongSelf->_retry_count || strongSelf->_retry_count < 0) { + strongSelf->rePlay(strUrlTmp, (*piFailedCnt)++); + } else { + //达到了最大重试次数,回调关闭 + strongSelf->_on_close(err); } }); MediaPlayer::play(strUrlTmp); @@ -120,7 +127,7 @@ void PlayerProxy::play(const string &strUrlTmp) { setDirectProxy(); } -void PlayerProxy::setDirectProxy(){ +void PlayerProxy::setDirectProxy() { MediaSource::Ptr mediaSource; if (dynamic_pointer_cast(_delegate)) { //rtsp拉流 @@ -142,24 +149,24 @@ PlayerProxy::~PlayerProxy() { _timer.reset(); } -void PlayerProxy::rePlay(const string &strUrl,int iFailedCnt){ - auto iDelay = MAX(2 * 1000, MIN(iFailedCnt * 3000, 60*1000)); +void PlayerProxy::rePlay(const string &strUrl, int iFailedCnt) { + auto iDelay = MAX(2 * 1000, MIN(iFailedCnt * 3000, 60 * 1000)); weak_ptr weakSelf = shared_from_this(); - _timer = std::make_shared(iDelay / 1000.0f,[weakSelf,strUrl,iFailedCnt]() { + _timer = std::make_shared(iDelay / 1000.0f, [weakSelf, strUrl, iFailedCnt]() { //播放失败次数越多,则延时越长 auto strongPlayer = weakSelf.lock(); - if(!strongPlayer) { + if (!strongPlayer) { return false; } - WarnL << "重试播放[" << iFailedCnt << "]:" << strUrl; + WarnL << "重试播放[" << iFailedCnt << "]:" << strUrl; strongPlayer->MediaPlayer::play(strUrl); strongPlayer->setDirectProxy(); return false; }, getPoller()); } -bool PlayerProxy::close(MediaSource &sender,bool force) { - if(!force && totalReaderCount()){ +bool PlayerProxy::close(MediaSource &sender, bool force) { + if (!force && totalReaderCount()) { return false; } @@ -174,14 +181,12 @@ bool PlayerProxy::close(MediaSource &sender,bool force) { strongSelf->setMediaSource(nullptr); strongSelf->teardown(); }); - if (_on_close) { - _on_close(); - } + _on_close(SockException(Err_shutdown, "closed by user")); WarnL << sender.getSchema() << "/" << sender.getVhost() << "/" << sender.getApp() << "/" << sender.getId() << " " << force; return true; } -int PlayerProxy::totalReaderCount(){ +int PlayerProxy::totalReaderCount() { return (_muxer ? _muxer->totalReaderCount() : 0) + (_pMediaSrc ? _pMediaSrc->readerCount() : 0); } @@ -189,29 +194,29 @@ int PlayerProxy::totalReaderCount(MediaSource &sender) { return totalReaderCount(); } -MediaOriginType PlayerProxy::getOriginType(MediaSource &sender) const{ +MediaOriginType PlayerProxy::getOriginType(MediaSource &sender) const { return MediaOriginType::pull; } -string PlayerProxy::getOriginUrl(MediaSource &sender) const{ +string PlayerProxy::getOriginUrl(MediaSource &sender) const { return _pull_url; } -std::shared_ptr PlayerProxy::getOriginSock(MediaSource &sender) const{ +std::shared_ptr PlayerProxy::getOriginSock(MediaSource &sender) const { return getSockInfo(); } -class MuteAudioMaker : public FrameDispatcher{ +class MuteAudioMaker : public FrameDispatcher { public: typedef std::shared_ptr Ptr; - MuteAudioMaker(){}; + MuteAudioMaker() {}; ~MuteAudioMaker() override {} void inputFrame(const Frame::Ptr &frame) override { - if(frame->getTrackType() == TrackVideo){ + if (frame->getTrackType() == TrackVideo) { auto audio_idx = frame->dts() / MUTE_ADTS_DATA_MS; - if(_audio_idx != audio_idx){ + if (_audio_idx != audio_idx) { _audio_idx = audio_idx; auto aacFrame = std::make_shared(CodecAAC, (char *)MUTE_ADTS_DATA, MUTE_ADTS_DATA_LEN, _audio_idx * MUTE_ADTS_DATA_MS, 0 ,ADTS_HEADER_LEN); FrameDispatcher::inputFrame(aacFrame); @@ -220,10 +225,10 @@ public: } private: - class FrameFromStaticPtr : public FrameFromPtr{ + class FrameFromStaticPtr : public FrameFromPtr { public: - template - FrameFromStaticPtr(ARGS && ...args) : FrameFromPtr(std::forward(args)...) {}; + template + FrameFromStaticPtr(ARGS &&...args) : FrameFromPtr(std::forward(args)...) {}; ~FrameFromStaticPtr() override = default; bool cacheAble() const override { @@ -236,7 +241,7 @@ private: }; void PlayerProxy::onPlaySuccess() { - GET_CONFIG(bool,resetWhenRePlay,General::kResetWhenRePlay); + GET_CONFIG(bool, resetWhenRePlay, General::kResetWhenRePlay); if (dynamic_pointer_cast(_pMediaSrc)) { //rtsp拉流代理 if (resetWhenRePlay || !_muxer) { diff --git a/src/Player/PlayerProxy.h b/src/Player/PlayerProxy.h index 3d41d55a..613afe4f 100644 --- a/src/Player/PlayerProxy.h +++ b/src/Player/PlayerProxy.h @@ -34,15 +34,15 @@ public: /** * 设置play结果回调,只触发一次;在play执行之前有效 - * @param cb + * @param cb 回调对象 */ void setPlayCallbackOnce(const function &cb); /** * 设置主动关闭回调 - * @param cb + * @param cb 回调对象 */ - void setOnClose(const function &cb); + void setOnClose(const function &cb); /** * 开始拉流播放 @@ -76,7 +76,7 @@ private: string _stream_id; string _pull_url; Timer::Ptr _timer; - function _on_close; + function _on_close; function _on_play; MultiMediaSourceMuxer::Ptr _muxer; };