From 50ca789c0c617e2b3593352e6b008e26ecdf9b9c Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Mon, 5 Apr 2021 11:32:38 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A2=84=E7=95=99=E5=90=8C=E6=97=B6=E6=8E=A8?= =?UTF-8?q?=E6=B5=81=E6=8B=89=E6=B5=81=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/WebApi.cpp | 4 ++-- webrtc/WebRtcTransport.cpp | 40 +++++++++++++++++++++++--------------- webrtc/WebRtcTransport.h | 10 +++++++--- 3 files changed, 33 insertions(+), 21 deletions(-) diff --git a/server/WebApi.cpp b/server/WebApi.cpp index 1ae2b0cd..f94d0d59 100755 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -1105,7 +1105,7 @@ void installWebApi() { throw runtime_error(StrPrinter << "播放鉴权失败:" << err); } auto rtc = WebRtcTransportImp::create(EventPollerPool::Instance().getPoller()); - rtc->attach(src); + rtc->attach(src, true); val["sdp"] = rtc->getAnswerSdp(offer_sdp); val["type"] = "answer"; rtcs.emplace_back(rtc); @@ -1139,7 +1139,7 @@ void installWebApi() { auto push_src = std::make_shared(info._vhost, info._app, info._streamid); push_src->setProtocolTranslation(enableHls, enableMP4); auto rtc = WebRtcTransportImp::create(EventPollerPool::Instance().getPoller()); - rtc->attach(push_src); + rtc->attach(push_src, false); val["sdp"] = rtc->getAnswerSdp(offer_sdp); val["type"] = "answer"; rtcs.emplace_back(rtc); diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index bf79e477..ee0558f9 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -224,9 +224,13 @@ void WebRtcTransportImp::onDestory() { WebRtcTransport::onDestory(); } -void WebRtcTransportImp::attach(const RtspMediaSource::Ptr &src) { +void WebRtcTransportImp::attach(const RtspMediaSource::Ptr &src, bool is_play) { assert(src); - _src = src; + if (is_play) { + _play_src = src; + } else { + _push_src = src; + } } void WebRtcTransportImp::onSendSockData(const char *buf, size_t len, struct sockaddr_in *dst, bool flush) { @@ -239,12 +243,12 @@ void WebRtcTransportImp::onSendSockData(const char *buf, size_t len, struct sock bool WebRtcTransportImp::canSendRtp() const{ auto &sdp = getSdp(SdpType::answer); - return sdp.media[0].direction == RtpDirection::sendrecv || sdp.media[0].direction == RtpDirection::sendonly; + return _play_src && (sdp.media[0].direction == RtpDirection::sendrecv || sdp.media[0].direction == RtpDirection::sendonly); } bool WebRtcTransportImp::canRecvRtp() const{ auto &sdp = getSdp(SdpType::answer); - return sdp.media[0].direction == RtpDirection::sendrecv || sdp.media[0].direction == RtpDirection::recvonly; + return _push_src && (sdp.media[0].direction == RtpDirection::sendrecv || sdp.media[0].direction == RtpDirection::recvonly); } void WebRtcTransportImp::onStartWebRTC() { @@ -274,10 +278,10 @@ void WebRtcTransportImp::onStartWebRTC() { } if (canRecvRtp()) { - _src->setSdp(getSdp(SdpType::answer).toRtspSdp()); + _push_src->setSdp(getSdp(SdpType::answer).toRtspSdp()); } if (canSendRtp()) { - _reader = _src->getRing()->attach(_socket->getPoller(), true); + _reader = _play_src->getRing()->attach(_socket->getPoller(), true); weak_ptr weak_self = shared_from_this(); _reader->setReadCB([weak_self](const RtspMediaSource::RingDataType &pkt) { auto strongSelf = weak_self.lock(); @@ -299,14 +303,14 @@ void WebRtcTransportImp::onCheckSdp(SdpType type, RtcSession &sdp){ } RtcSession rtsp_send_sdp; - rtsp_send_sdp.loadFrom(_src->getSdp(), false); + rtsp_send_sdp.loadFrom(_play_src->getSdp(), false); for (auto &m : sdp.media) { if (m.type == TrackApplication) { continue; } //添加answer sdp的ssrc信息 - m.rtp_ssrc.ssrc = _src->getSsrc(m.type); + m.rtp_ssrc.ssrc = _play_src->getSsrc(m.type); m.rtp_ssrc.cname = RTP_CNAME; //todo 先屏蔽rtx,因为chrome报错 if (false && m.getRelatedRtxPlan(m.plan[0].pt)) { @@ -324,15 +328,17 @@ void WebRtcTransportImp::onCheckSdp(SdpType type, RtcSession &sdp){ void WebRtcTransportImp::onRtcConfigure(RtcConfigure &configure) const { WebRtcTransport::onRtcConfigure(configure); - if (!_src->getSdp().empty()) { - //这是播放 - configure.video.direction = RtpDirection::sendonly; - configure.audio.direction = RtpDirection::sendonly; - configure.setPlayRtspInfo(_src->getSdp()); - } else { - //这是推流 + if (_play_src) { + //这是播放,同时也可能有推流 + configure.video.direction = _push_src ? RtpDirection::sendrecv : RtpDirection::sendonly; + configure.audio.direction = configure.video.direction; + configure.setPlayRtspInfo(_play_src->getSdp()); + } else if (_push_src) { + //这只是推流 configure.video.direction = RtpDirection::recvonly; configure.audio.direction = RtpDirection::recvonly; + } else { + throw std::invalid_argument("未设置播放或推流的媒体源"); } //添加接收端口candidate信息 @@ -455,7 +461,9 @@ void WebRtcTransportImp::onSortedRtp(const RtpPayloadInfo &info, RtpPacket::Ptr sendRtcpPacket((char *) pli.get(), sizeof(RtcpPli), true); InfoL << "send pli"; } - _src->onWrite(std::move(rtp), false); + if (_push_src) { + _push_src->onWrite(std::move(rtp), false); + } } void WebRtcTransportImp::onBeforeSortedRtp(const RtpPayloadInfo &info, const RtpPacket::Ptr &rtp) { diff --git a/webrtc/WebRtcTransport.h b/webrtc/WebRtcTransport.h index 6ba2cb4e..125771d8 100644 --- a/webrtc/WebRtcTransport.h +++ b/webrtc/WebRtcTransport.h @@ -119,8 +119,9 @@ public: /** * 绑定rtsp媒体源 * @param src 媒体源 + * @param is_play 是播放还是推流 */ - void attach(const RtspMediaSource::Ptr &src); + void attach(const RtspMediaSource::Ptr &src, bool is_play = true); protected: void onStartWebRTC() override; @@ -161,8 +162,11 @@ private: uint8_t _send_rtp_pt[2] = {0, 0}; //复合udp端口,接收一切rtp与rtcp Socket::Ptr _socket; - //推流或播放的rtsp源 - RtspMediaSource::Ptr _src; + //推流的rtsp源 + RtspMediaSource::Ptr _push_src; + //播放的rtsp源 + RtspMediaSource::Ptr _play_src; + //播放rtsp源的reader对象 RtspMediaSource::RingType::RingReader::Ptr _reader; //根据rtp的pt获取相关信息 unordered_map _rtp_info_pt;