预留同时推流拉流的接口

This commit is contained in:
xiongziliang 2021-04-05 11:32:38 +08:00
parent 606f251311
commit 50ca789c0c
3 changed files with 33 additions and 21 deletions

View File

@ -1105,7 +1105,7 @@ void installWebApi() {
throw runtime_error(StrPrinter << "播放鉴权失败:" << err); throw runtime_error(StrPrinter << "播放鉴权失败:" << err);
} }
auto rtc = WebRtcTransportImp::create(EventPollerPool::Instance().getPoller()); auto rtc = WebRtcTransportImp::create(EventPollerPool::Instance().getPoller());
rtc->attach(src); rtc->attach(src, true);
val["sdp"] = rtc->getAnswerSdp(offer_sdp); val["sdp"] = rtc->getAnswerSdp(offer_sdp);
val["type"] = "answer"; val["type"] = "answer";
rtcs.emplace_back(rtc); rtcs.emplace_back(rtc);
@ -1139,7 +1139,7 @@ void installWebApi() {
auto push_src = std::make_shared<RtspMediaSourceImp>(info._vhost, info._app, info._streamid); auto push_src = std::make_shared<RtspMediaSourceImp>(info._vhost, info._app, info._streamid);
push_src->setProtocolTranslation(enableHls, enableMP4); push_src->setProtocolTranslation(enableHls, enableMP4);
auto rtc = WebRtcTransportImp::create(EventPollerPool::Instance().getPoller()); auto rtc = WebRtcTransportImp::create(EventPollerPool::Instance().getPoller());
rtc->attach(push_src); rtc->attach(push_src, false);
val["sdp"] = rtc->getAnswerSdp(offer_sdp); val["sdp"] = rtc->getAnswerSdp(offer_sdp);
val["type"] = "answer"; val["type"] = "answer";
rtcs.emplace_back(rtc); rtcs.emplace_back(rtc);

View File

@ -224,9 +224,13 @@ void WebRtcTransportImp::onDestory() {
WebRtcTransport::onDestory(); WebRtcTransport::onDestory();
} }
void WebRtcTransportImp::attach(const RtspMediaSource::Ptr &src) { void WebRtcTransportImp::attach(const RtspMediaSource::Ptr &src, bool is_play) {
assert(src); 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) { 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{ bool WebRtcTransportImp::canSendRtp() const{
auto &sdp = getSdp(SdpType::answer); 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{ bool WebRtcTransportImp::canRecvRtp() const{
auto &sdp = getSdp(SdpType::answer); 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() { void WebRtcTransportImp::onStartWebRTC() {
@ -274,10 +278,10 @@ void WebRtcTransportImp::onStartWebRTC() {
} }
if (canRecvRtp()) { if (canRecvRtp()) {
_src->setSdp(getSdp(SdpType::answer).toRtspSdp()); _push_src->setSdp(getSdp(SdpType::answer).toRtspSdp());
} }
if (canSendRtp()) { if (canSendRtp()) {
_reader = _src->getRing()->attach(_socket->getPoller(), true); _reader = _play_src->getRing()->attach(_socket->getPoller(), true);
weak_ptr<WebRtcTransportImp> weak_self = shared_from_this(); weak_ptr<WebRtcTransportImp> weak_self = shared_from_this();
_reader->setReadCB([weak_self](const RtspMediaSource::RingDataType &pkt) { _reader->setReadCB([weak_self](const RtspMediaSource::RingDataType &pkt) {
auto strongSelf = weak_self.lock(); auto strongSelf = weak_self.lock();
@ -299,14 +303,14 @@ void WebRtcTransportImp::onCheckSdp(SdpType type, RtcSession &sdp){
} }
RtcSession rtsp_send_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) { for (auto &m : sdp.media) {
if (m.type == TrackApplication) { if (m.type == TrackApplication) {
continue; continue;
} }
//添加answer sdp的ssrc信息 //添加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; m.rtp_ssrc.cname = RTP_CNAME;
//todo 先屏蔽rtx因为chrome报错 //todo 先屏蔽rtx因为chrome报错
if (false && m.getRelatedRtxPlan(m.plan[0].pt)) { 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 { void WebRtcTransportImp::onRtcConfigure(RtcConfigure &configure) const {
WebRtcTransport::onRtcConfigure(configure); WebRtcTransport::onRtcConfigure(configure);
if (!_src->getSdp().empty()) { if (_play_src) {
//这是播放 //这是播放,同时也可能有推流
configure.video.direction = RtpDirection::sendonly; configure.video.direction = _push_src ? RtpDirection::sendrecv : RtpDirection::sendonly;
configure.audio.direction = RtpDirection::sendonly; configure.audio.direction = configure.video.direction;
configure.setPlayRtspInfo(_src->getSdp()); configure.setPlayRtspInfo(_play_src->getSdp());
} else { } else if (_push_src) {
//这是推流 //这是推流
configure.video.direction = RtpDirection::recvonly; configure.video.direction = RtpDirection::recvonly;
configure.audio.direction = RtpDirection::recvonly; configure.audio.direction = RtpDirection::recvonly;
} else {
throw std::invalid_argument("未设置播放或推流的媒体源");
} }
//添加接收端口candidate信息 //添加接收端口candidate信息
@ -455,7 +461,9 @@ void WebRtcTransportImp::onSortedRtp(const RtpPayloadInfo &info, RtpPacket::Ptr
sendRtcpPacket((char *) pli.get(), sizeof(RtcpPli), true); sendRtcpPacket((char *) pli.get(), sizeof(RtcpPli), true);
InfoL << "send pli"; 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) { void WebRtcTransportImp::onBeforeSortedRtp(const RtpPayloadInfo &info, const RtpPacket::Ptr &rtp) {

View File

@ -119,8 +119,9 @@ public:
/** /**
* rtsp媒体源 * rtsp媒体源
* @param src * @param src
* @param is_play
*/ */
void attach(const RtspMediaSource::Ptr &src); void attach(const RtspMediaSource::Ptr &src, bool is_play = true);
protected: protected:
void onStartWebRTC() override; void onStartWebRTC() override;
@ -161,8 +162,11 @@ private:
uint8_t _send_rtp_pt[2] = {0, 0}; uint8_t _send_rtp_pt[2] = {0, 0};
//复合udp端口接收一切rtp与rtcp //复合udp端口接收一切rtp与rtcp
Socket::Ptr _socket; Socket::Ptr _socket;
//推流或播放的rtsp源 //推流的rtsp源
RtspMediaSource::Ptr _src; RtspMediaSource::Ptr _push_src;
//播放的rtsp源
RtspMediaSource::Ptr _play_src;
//播放rtsp源的reader对象
RtspMediaSource::RingType::RingReader::Ptr _reader; RtspMediaSource::RingType::RingReader::Ptr _reader;
//根据rtp的pt获取相关信息 //根据rtp的pt获取相关信息
unordered_map<uint8_t, RtpPayloadInfo> _rtp_info_pt; unordered_map<uint8_t, RtpPayloadInfo> _rtp_info_pt;