From 46842e6f29c6d52d60fb25c805ed75dad23aff11 Mon Sep 17 00:00:00 2001 From: Talus Date: Mon, 20 Feb 2023 16:23:29 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DWebRTC=E6=92=AD=E6=94=BE?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E5=AA=92=E4=BD=93=E5=BB=B6=E8=BF=9F=E6=B3=A8?= =?UTF-8?q?=E9=94=80=E9=97=AE=E9=A2=98=20(#2246)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 因WebRtcPlayer中使用RtspMediaSource的共享指针,特定情况下引起媒体注销无法触发的问题。 - 重现步骤 在ZL的webrtc demo页面推流 浏览器打开如下html webrtc.html 关闭推流器页面,推流器停止推流 webrtc.htm浏览器console->network将观察到:即使推流停止,但webrtc sdp请求一直能成功获取sdp,且流媒体一直不注销 - 原因 因为每个WebRtc 播放 SDP请求都会产生 WebRtcPlayer,产生RtspMediaSource的共享指针,产生强引用。 而DTLS超时释放需要一定的时间,WebRtcPlayer销毁需要超时。如果请求sdp的时间足够短,强引用会一直存在。将永远无法触发媒体注销 - 场景 webrtc播放存在重试,但是udp不通。DTLS无法创建 有人对ZLM执行恶意攻击,短时间内不断请求SDP但是不建立WebRTC通信 --- webrtc/WebRtcPlayer.cpp | 21 +++++++++++++-------- webrtc/WebRtcPlayer.h | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/webrtc/WebRtcPlayer.cpp b/webrtc/WebRtcPlayer.cpp index 6f76bbb8..3b533594 100644 --- a/webrtc/WebRtcPlayer.cpp +++ b/webrtc/WebRtcPlayer.cpp @@ -33,15 +33,19 @@ WebRtcPlayer::WebRtcPlayer(const EventPoller::Ptr &poller, bool preferred_tcp) : WebRtcTransportImp(poller,preferred_tcp) { _media_info = info; _play_src = src; - CHECK(_play_src); + CHECK(src); } void WebRtcPlayer::onStartWebRTC() { - CHECK(_play_src); + auto playSrc = _play_src.lock(); + if(!playSrc){ + onShutdown(SockException(Err_shutdown, "rtsp media source was shutdown")); + return ; + } WebRtcTransportImp::onStartWebRTC(); if (canSendRtp()) { - _play_src->pause(false); - _reader = _play_src->getRing()->attach(getPoller(), true); + playSrc->pause(false); + _reader = playSrc->getRing()->attach(getPoller(), true); weak_ptr weak_self = static_pointer_cast(shared_from_this()); weak_ptr weak_session = getSession(); _reader->setGetInfoCB([weak_session]() { return weak_session.lock(); }); @@ -64,8 +68,6 @@ void WebRtcPlayer::onStartWebRTC() { strong_self->onShutdown(SockException(Err_shutdown, "rtsp ring buffer detached")); }); } - //使用完毕后,释放强引用,这样确保推流器断开后能及时注销媒体 - _play_src = nullptr; } void WebRtcPlayer::onDestory() { WebRtcTransportImp::onDestory(); @@ -86,11 +88,14 @@ void WebRtcPlayer::onDestory() { } void WebRtcPlayer::onRtcConfigure(RtcConfigure &configure) const { - CHECK(_play_src); + auto playSrc = _play_src.lock(); + if(!playSrc){ + return ; + } WebRtcTransportImp::onRtcConfigure(configure); //这是播放 configure.audio.direction = configure.video.direction = RtpDirection::sendonly; - configure.setPlayRtspInfo(_play_src->getSdp()); + configure.setPlayRtspInfo(playSrc->getSdp()); } }// namespace mediakit \ No newline at end of file diff --git a/webrtc/WebRtcPlayer.h b/webrtc/WebRtcPlayer.h index 17e7bcf0..fbe168b2 100644 --- a/webrtc/WebRtcPlayer.h +++ b/webrtc/WebRtcPlayer.h @@ -36,7 +36,7 @@ private: //媒体相关元数据 MediaInfo _media_info; //播放的rtsp源 - RtspMediaSource::Ptr _play_src; + std::weak_ptr _play_src; //播放rtsp源的reader对象 RtspMediaSource::RingType::RingReader::Ptr _reader; };