RTSP支持强制协商RTP传输方式 (#2572)

当客户端发起RTSP SETUP的时候,如果rtp传输类型和配置不一致则返回461 Unsupported
transport。迫使客户端切换到对应rtp传输协议并重新SETUP;目前支持FFMPEG和VLC。
This commit is contained in:
Talus 2023-06-21 15:35:27 +08:00 committed by GitHub
parent 7e117b1c7f
commit 9f753b5e5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 9 deletions

View File

@ -362,6 +362,10 @@ port=554
sslport=0 sslport=0
#rtsp 转发是否使用低延迟模式当开启时不会缓存rtp包来提高并发可以降低一帧的延迟 #rtsp 转发是否使用低延迟模式当开启时不会缓存rtp包来提高并发可以降低一帧的延迟
lowLatency=0 lowLatency=0
#强制协商rtp传输方式 (0:TCP,1:UDP,2:MULTICAST,-1:不限制)
#当客户端发起RTSP SETUP的时候如果传输类型和此配置不一致则返回461 Unsupported transport
#迫使客户端重新SETUP并切换到对应协议。目前支持FFMPEG和VLC
rtpTransportType=-1
[shell] [shell]
#调试telnet服务器接受最大bufffer大小 #调试telnet服务器接受最大bufffer大小
maxReqSize=1024 maxReqSize=1024

View File

@ -209,6 +209,7 @@ const string kHandshakeSecond = RTSP_FIELD "handshakeSecond";
const string kKeepAliveSecond = RTSP_FIELD "keepAliveSecond"; const string kKeepAliveSecond = RTSP_FIELD "keepAliveSecond";
const string kDirectProxy = RTSP_FIELD "directProxy"; const string kDirectProxy = RTSP_FIELD "directProxy";
const string kLowLatency = RTSP_FIELD"lowLatency"; const string kLowLatency = RTSP_FIELD"lowLatency";
const string kRtpTransportType = RTSP_FIELD"rtpTransportType";
static onceToken token([]() { static onceToken token([]() {
// 默认Md5方式认证 // 默认Md5方式认证
@ -217,6 +218,7 @@ static onceToken token([]() {
mINI::Instance()[kKeepAliveSecond] = 15; mINI::Instance()[kKeepAliveSecond] = 15;
mINI::Instance()[kDirectProxy] = 1; mINI::Instance()[kDirectProxy] = 1;
mINI::Instance()[kLowLatency] = 0; mINI::Instance()[kLowLatency] = 0;
mINI::Instance()[kRtpTransportType] = -1;
}); });
} // namespace Rtsp } // namespace Rtsp

View File

@ -273,6 +273,11 @@ extern const std::string kDirectProxy;
// rtsp 转发是否使用低延迟模式当开启时不会缓存rtp包来提高并发可以降低一帧的延迟 // rtsp 转发是否使用低延迟模式当开启时不会缓存rtp包来提高并发可以降低一帧的延迟
extern const std::string kLowLatency; extern const std::string kLowLatency;
//强制协商rtp传输方式 (0:TCP,1:UDP,2:MULTICAST,-1:不限制)
//当客户端发起RTSP SETUP的时候如果传输类型和此配置不一致则返回461 Unsupport Transport
//迫使客户端重新SETUP并切换到对应协议。目前支持FFMPEG和VLC
extern const std::string kRtpTransportType;
} // namespace Rtsp } // namespace Rtsp
////////////RTMP服务器配置/////////// ////////////RTMP服务器配置///////////

View File

@ -634,18 +634,43 @@ void RtspSession::handleReq_Setup(const Parser &parser) {
//已经初始化过该Track //已经初始化过该Track
throw SockException(Err_shutdown, "can not setup one track twice"); throw SockException(Err_shutdown, "can not setup one track twice");
} }
trackRef->_inited = true; //现在初始化
if(_rtp_type == Rtsp::RTP_Invalid){ static auto getRtpTypeStr = [](const int type) {
switch (type)
{
case Rtsp::RTP_TCP:
return "TCP";
case Rtsp::RTP_UDP:
return "UDP";
case Rtsp::RTP_MULTICAST:
return "MULTICAST";
default:
return "Invalid";
}
};
if (_rtp_type == Rtsp::RTP_Invalid) {
auto &strTransport = parser["Transport"]; auto &strTransport = parser["Transport"];
if(strTransport.find("TCP") != string::npos){ auto rtpType = Rtsp::RTP_Invalid;
_rtp_type = Rtsp::RTP_TCP; if (strTransport.find("TCP") != string::npos) {
}else if(strTransport.find("multicast") != string::npos){ rtpType = Rtsp::RTP_TCP;
_rtp_type = Rtsp::RTP_MULTICAST; } else if (strTransport.find("multicast") != string::npos) {
}else{ rtpType = Rtsp::RTP_MULTICAST;
_rtp_type = Rtsp::RTP_UDP; } else {
rtpType = Rtsp::RTP_UDP;
} }
//检查RTP传输类型限制
GET_CONFIG(int, transport, Rtsp::kRtpTransportType);
if (transport != Rtsp::RTP_Invalid && transport != rtpType) {
WarnL << "rtsp client setup transport " << getRtpTypeStr(rtpType) << " but config force transport " << getRtpTypeStr(transport);
//配置限定RTSP传输方式但是客户端握手方式不一致返回461
sendRtspResponse("461 Unsupported transport");
return;
} }
_rtp_type = rtpType;
}
trackRef->_inited = true; //现在初始化
//允许接收rtp、rtcp包 //允许接收rtp、rtcp包
RtspSplitter::enableRecvRtp(_rtp_type == Rtsp::RTP_TCP); RtspSplitter::enableRecvRtp(_rtp_type == Rtsp::RTP_TCP);