From af59fdeb8629cf07d0d62a7016ffdce210788e63 Mon Sep 17 00:00:00 2001 From: xia-chu <771730766@qq.com> Date: Fri, 30 Apr 2021 18:01:48 +0800 Subject: [PATCH 1/3] =?UTF-8?q?addStreamProxy=E6=8E=A5=E5=8F=A3=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=B6=85=E6=97=B6=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- postman/ZLMediaKit.postman_collection.json | 6 ++++++ server/WebApi.cpp | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/postman/ZLMediaKit.postman_collection.json b/postman/ZLMediaKit.postman_collection.json index 75d9cbb9..93fd341e 100644 --- a/postman/ZLMediaKit.postman_collection.json +++ b/postman/ZLMediaKit.postman_collection.json @@ -512,6 +512,12 @@ "value": null, "description": "rtsp拉流时,拉流方式,0:tcp,1:udp,2:组播", "disabled": true + }, + { + "key": "timeout_sec", + "value": "10", + "description": "拉流超时时间,单位秒,float类型", + "disabled": true } ] } diff --git a/server/WebApi.cpp b/server/WebApi.cpp index 6c88f4f5..9160c559 100755 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -600,6 +600,7 @@ void installWebApi() { bool enable_hls, bool enable_mp4, int rtp_type, + float timeoutSec, const function &cb){ auto key = getProxyKey(vhost,app,stream); lock_guard lck(s_proxyMapMtx); @@ -614,6 +615,12 @@ void installWebApi() { //指定RTP over TCP(播放rtsp时有效) (*player)[kRtpType] = rtp_type; + + if (timeoutSec > 0.1) { + //播放握手超时时间 + (*player)[kTimeoutMS] = timeoutSec * 1000; + } + //开始播放,如果播放失败或者播放中止,将会自动重试若干次,默认一直重试 player->setPlayCallbackOnce([cb,key](const SockException &ex){ if(ex){ @@ -643,6 +650,7 @@ void installWebApi() { allArgs["enable_hls"],/* 是否hls转发 */ allArgs["enable_mp4"],/* 是否MP4录制 */ allArgs["rtp_type"], + allArgs["timeout_sec"], [invoker,val,headerOut](const SockException &ex,const string &key) mutable{ if (ex) { val["code"] = API::OtherFailed; @@ -1133,6 +1141,7 @@ void installWebApi() { true,/* 开启hls转发 */ false,/* 禁用MP4录制 */ 0,//rtp over tcp方式拉流 + 10,//10秒超时 [invoker,val,headerOut](const SockException &ex,const string &key) mutable{ if(ex){ val["code"] = API::OtherFailed; From e807a08f2edc6692c3b4368e330ed7562cd7f8e7 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Sat, 15 May 2021 09:56:35 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=8D=95track=20rtsp=E6=8E=A8=E6=B5=81?= =?UTF-8?q?=E5=8A=A0=E5=BF=AB=E5=AA=92=E4=BD=93=E6=B3=A8=E5=86=8C=E9=80=9F?= =?UTF-8?q?=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Rtsp/RtspSession.cpp | 107 +++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index 4c413a6b..a8d3c8ac 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -202,81 +202,57 @@ void RtspSession::handleReq_ANNOUNCE(const Parser &parser) { _media_info._vhost, _media_info._app, _media_info._streamid)); - if(src){ + if (src) { sendRtspResponse("406 Not Acceptable", {"Content-Type", "text/plain"}, "Already publishing."); string err = StrPrinter << "ANNOUNCE:" << "Already publishing:" << _media_info._vhost << " " << _media_info._app << " " << _media_info._streamid << endl; - throw SockException(Err_shutdown,err); + throw SockException(Err_shutdown, err); } auto full_url = parser.FullUrl(); - if(end_with(full_url,".sdp")){ + if (end_with(full_url, ".sdp")) { //去除.sdp后缀,防止EasyDarwin推流器强制添加.sdp后缀 - full_url = full_url.substr(0,full_url.length() - 4); + full_url = full_url.substr(0, full_url.length() - 4); _media_info.parse(full_url); } - if(_media_info._app.empty() || _media_info._streamid.empty()){ + if (_media_info._app.empty() || _media_info._streamid.empty()) { //推流rtsp url必须最少两级(rtsp://host/app/stream_id),不允许莫名其妙的推流url static constexpr auto err = "rtsp推流url非法,最少确保两级rtsp url"; sendRtspResponse("403 Forbidden", {"Content-Type", "text/plain"}, err); throw SockException(Err_shutdown, StrPrinter << err << ":" << full_url); } - SdpParser sdpParser(parser.Content()); - _sessionid = makeRandStr(12); - _sdp_track = sdpParser.getAvailableTrack(); - if (_sdp_track.empty()) { - //sdp无效 - static constexpr auto err = "sdp中无有效track"; - sendRtspResponse("403 Forbidden", {"Content-Type", "text/plain"}, err); - throw SockException(Err_shutdown,StrPrinter << err << ":" << full_url); - } - _rtcp_context.clear(); - for (auto &track : _sdp_track) { - _rtcp_context.emplace_back(std::make_shared(track->_samplerate, true)); - } - _push_src = std::make_shared(_media_info._vhost, _media_info._app, _media_info._streamid); - _push_src->setListener(dynamic_pointer_cast(shared_from_this())); - _push_src->setSdp(sdpParser.toString()); - sendRtspResponse("200 OK",{"Content-Base", _content_base + "/"}); -} - -void RtspSession::handleReq_RECORD(const Parser &parser){ - if (_sdp_track.empty() || parser["Session"] != _sessionid) { - send_SessionNotFound(); - throw SockException(Err_shutdown, _sdp_track.empty() ? "can not find any availabe track when record" : "session not found when record"); - } - auto onRes = [this](const string &err, bool enableHls, bool enableMP4){ + auto onRes = [this, parser, full_url](const string &err, bool enableHls, bool enableMP4){ bool authSuccess = err.empty(); - if(!authSuccess){ + if (!authSuccess) { sendRtspResponse("401 Unauthorized", {"Content-Type", "text/plain"}, err); - shutdown(SockException(Err_shutdown,StrPrinter << "401 Unauthorized:" << err)); + shutdown(SockException(Err_shutdown, StrPrinter << "401 Unauthorized:" << err)); return; } - //设置转协议 + SdpParser sdpParser(parser.Content()); + _sessionid = makeRandStr(12); + _sdp_track = sdpParser.getAvailableTrack(); + if (_sdp_track.empty()) { + //sdp无效 + static constexpr auto err = "sdp中无有效track"; + sendRtspResponse("403 Forbidden", {"Content-Type", "text/plain"}, err); + shutdown(SockException(Err_shutdown, StrPrinter << err << ":" << full_url)); + return; + } + _rtcp_context.clear(); + for (auto &track : _sdp_track) { + _rtcp_context.emplace_back(std::make_shared(track->_samplerate, true)); + } + _push_src = std::make_shared(_media_info._vhost, _media_info._app, _media_info._streamid); + _push_src->setListener(dynamic_pointer_cast(shared_from_this())); _push_src->setProtocolTranslation(enableHls, enableMP4); - - _StrPrinter rtp_info; - for(auto &track : _sdp_track){ - if (track->_inited == false) { - //还有track没有setup - shutdown(SockException(Err_shutdown,"track not setuped")); - return; - } - rtp_info << "url=" << track->getControlUrl(_content_base) << ","; - } - - rtp_info.pop_back(); - sendRtspResponse("200 OK", {"RTP-Info",rtp_info}); - if(_rtp_type == Rtsp::RTP_TCP){ - //如果是rtsp推流服务器,并且是TCP推流,设置socket flags,,这样能提升接收性能 - setSocketFlags(); - } + _push_src->setSdp(sdpParser.toString()); + sendRtspResponse("200 OK", {"Content-Base", _content_base + "/"}); }; weak_ptr weakSelf = dynamic_pointer_cast(shared_from_this()); @@ -296,11 +272,34 @@ void RtspSession::handleReq_RECORD(const Parser &parser){ //rtsp推流需要鉴权 auto flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPublish, _media_info, invoker, static_cast(*this)); - if(!flag){ + if (!flag) { //该事件无人监听,默认不鉴权 - GET_CONFIG(bool,toHls,General::kPublishToHls); - GET_CONFIG(bool,toMP4,General::kPublishToMP4); - onRes("",toHls,toMP4); + GET_CONFIG(bool, toHls, General::kPublishToHls); + GET_CONFIG(bool, toMP4, General::kPublishToMP4); + onRes("", toHls, toMP4); + } +} + +void RtspSession::handleReq_RECORD(const Parser &parser){ + if (_sdp_track.empty() || parser["Session"] != _sessionid) { + send_SessionNotFound(); + throw SockException(Err_shutdown, _sdp_track.empty() ? "can not find any availabe track when record" : "session not found when record"); + } + + _StrPrinter rtp_info; + for (auto &track : _sdp_track) { + if (track->_inited == false) { + //还有track没有setup + shutdown(SockException(Err_shutdown, "track not setuped")); + return; + } + rtp_info << "url=" << track->getControlUrl(_content_base) << ","; + } + rtp_info.pop_back(); + sendRtspResponse("200 OK", {"RTP-Info", rtp_info}); + if (_rtp_type == Rtsp::RTP_TCP) { + //如果是rtsp推流服务器,并且是TCP推流,设置socket flags,,这样能提升接收性能 + setSocketFlags(); } } From 259e9dab0751697a6840072e1528ec06afe6097e Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Sat, 15 May 2021 09:59:36 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E6=9B=B4=E6=96=B0ZLToolKit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3rdpart/ZLToolKit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdpart/ZLToolKit b/3rdpart/ZLToolKit index d5de1d4f..b678e474 160000 --- a/3rdpart/ZLToolKit +++ b/3rdpart/ZLToolKit @@ -1 +1 @@ -Subproject commit d5de1d4f0c86139fe8f0b6d956e45dee3b151783 +Subproject commit b678e474f8ba8c9f3e6efd9cec6e4c517e80209d