预留同时推流拉流的接口

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);
}
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<RtspMediaSourceImp>(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);

View File

@ -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<WebRtcTransportImp> 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) {

View File

@ -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<uint8_t, RtpPayloadInfo> _rtp_info_pt;