diff --git a/postman/ZLMediaKit.postman_collection.json b/postman/ZLMediaKit.postman_collection.json index fdda9d2a..d8a49900 100644 --- a/postman/ZLMediaKit.postman_collection.json +++ b/postman/ZLMediaKit.postman_collection.json @@ -1710,10 +1710,16 @@ "value": "obs", "description": "流id,例如 obs" }, + { + "key": "ssrc_multi_send", + "value": "0", + "description": "是否支持同ssrc推流到多个上级服务器,该参数非必选参数 默认false", + "disabled": true + }, { "key": "ssrc", "value": "1", - "description": "rtp推流的ssrc,ssrc不同时,可以推流到多个上级服务器" + "description": "rtp推流的ssrc" }, { "key": "dst_url", diff --git a/server/WebApi.cpp b/server/WebApi.cpp index 5c63c943..1ddc0c0f 100755 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -1245,6 +1245,7 @@ void installWebApi() { args.passive = false; args.dst_url = allArgs["dst_url"]; args.dst_port = allArgs["dst_port"]; + args.ssrc_multi_send = allArgs["ssrc_multi_send"].empty() ? false : allArgs["ssrc_multi_send"].as(); args.ssrc = allArgs["ssrc"]; args.is_udp = allArgs["is_udp"]; args.src_port = allArgs["src_port"]; diff --git a/src/Common/MediaSource.h b/src/Common/MediaSource.h index ffced627..73306385 100644 --- a/src/Common/MediaSource.h +++ b/src/Common/MediaSource.h @@ -104,6 +104,8 @@ public: bool passive = false; // rtp payload type uint8_t pt = 96; + //是否支持同ssrc多服务器发送 + bool ssrc_multi_send = false; // 指定rtp ssrc std::string ssrc; // 指定本地发送端口 diff --git a/src/Common/MultiMediaSourceMuxer.cpp b/src/Common/MultiMediaSourceMuxer.cpp index e3151093..99898b95 100644 --- a/src/Common/MultiMediaSourceMuxer.cpp +++ b/src/Common/MultiMediaSourceMuxer.cpp @@ -291,12 +291,14 @@ void MultiMediaSourceMuxer::startSendRtp(MediaSource &sender, const MediaSourceE auto ring = _ring; auto ssrc = args.ssrc; + auto ssrc_multi_send = args.ssrc_multi_send; auto tracks = getTracks(false); auto poller = getOwnerPoller(sender); auto rtp_sender = std::make_shared(poller); + weak_ptr weak_self = shared_from_this(); - rtp_sender->startSend(args, [ssrc, weak_self, rtp_sender, cb, tracks, ring, poller](uint16_t local_port, const SockException &ex) mutable { + rtp_sender->startSend(args, [ssrc,ssrc_multi_send, weak_self, rtp_sender, cb, tracks, ring, poller](uint16_t local_port, const SockException &ex) mutable { cb(local_port, ex); auto strong_self = weak_self.lock(); if (!strong_self || ex) { @@ -325,7 +327,10 @@ void MultiMediaSourceMuxer::startSendRtp(MediaSource &sender, const MediaSourceE // 可能归属线程发生变更 strong_self->getOwnerPoller(MediaSource::NullMediaSource())->async([=]() { - strong_self->_rtp_sender[ssrc] = std::move(reader); + if(!ssrc_multi_send) { + strong_self->_rtp_sender.erase(ssrc); + } + strong_self->_rtp_sender.emplace(ssrc,reader); }); }); #else diff --git a/src/Common/MultiMediaSourceMuxer.h b/src/Common/MultiMediaSourceMuxer.h index 4db34d42..45ab7623 100644 --- a/src/Common/MultiMediaSourceMuxer.h +++ b/src/Common/MultiMediaSourceMuxer.h @@ -168,7 +168,7 @@ private: toolkit::Ticker _last_check; Stamp _stamp[2]; std::weak_ptr _track_listener; - std::unordered_map _rtp_sender; + std::unordered_multimap _rtp_sender; FMP4MediaSourceMuxer::Ptr _fmp4; RtmpMediaSourceMuxer::Ptr _rtmp; RtspMediaSourceMuxer::Ptr _rtsp;