如何强制客户端将RTP传输从UDP切换到TCP?

7
如果客户端想观看我RTSP服务器上的流,它首先尝试通过UDP协议设置流。我如何告诉它我的服务器仅支持RTP / AVP / TCP,并且应该切换传输方式?
我想在我的服务器上终止UDP支持,但所有客户端都会首先尝试通过UDP设置会话,然后再通过TCP进行设置... 我想尽快在RTSP协议中将它们切换到TCP。我该怎么做?
6个回答

8
据我所知,服务器端没有传输类型优先的控制。服务器应该是通用的,支持UDP上的RTP、TCP上的RTP、RTSP上的RTP以及HTTP(S)上的RTSP上的RTP。而客户端可以选择使用哪种传输方式。传输字段首先在SETUP请求中发送。
1)UDP
 C->A: SETUP rtsp://audio.example.com/twister/audio.en RTSP/1.0
               CSeq: 1
               Transport: RTP/AVP/UDP;unicast;client_port=3056-3057

2) TCP

    C->A: SETUP rtsp://audio.example.com/twister/audio.en RTSP/1.0
               CSeq: 1
               Transport: RTP/AVP/TCP;unicast;client_port=3056-3057

3) RTP通过RTSP和RTP通过RTSP通过HTTP(S)

S->C: RTSP/1.0 200 OK
           CSeq: 2
           Date: 05 Jun 1997 18:57:18 GMT
           Transport: RTP/AVP/TCP;interleaved=0-1

我们可以看到,“传输类型”请求是由客户端发送的。

如果您想支持仅TCP服务器,则可以像您建议的那样,在SETUP请求的响应中发送“400 Bad Request”或“461 Unsupported transport”,或者另一种方法是发送200 OK,但不传输任何RTP数据包。客户端将超时并知道它在代理后面,并再次发送带有RTP / AVP / TCP参数的SETUP请求(这不是理想情况)。


@Alam 先生,我正在使用两个 live555 程序:“testMpeg2transportstreamer” 在 live555 的 test 目录中和代理服务器在 live555 的 proxy server 目录中。对于代理服务器程序,我正在提供“testMpeg2transportstreamer” rtsp 服务器的 url,并且现在我可以从代理服务器发送 C->A: SETUP rtsp://audio.example.com/twister/audio.en RTSP/1.0 CSeq: 1 Transport: RTP/AVP/TCP;unicast;client_port=3056-3057 到“testMpeg2transportstreamer”,请指导。 - Ajinkya
@Alam,我想让testMpeg2transportstreamer只流传TCP数据包,因为现在当我在wireshark中查看时,它会流传UDP数据包,我希望它能够流传我可以在wireshark中看到的TCP数据包。 - Ajinkya
示例2过于肤浅,应该与示例3完全一致,并且示例3需要包含HTTP头并进行Base64编码以适用于HTTP变体。 - Jay
@Alam 此外,服务器仅控制此事而非客户端... 客户端可以请求 foo 传输,服务器将响应 UnsupportedTransport。你提供的几乎所有信息都是不正确的! - Jay
这听起来像是很好的建议,我只是想知道你从哪里获取信息以及为什么你认为它是你所描述的那样。 - Jay
显示剩余7条评论

7
针对Android的问题,为了更详细地说明,Android客户端总是首先尝试建立UDP连接。
对于OpenCore和StageFright,如果我在响应第一个UDP传输SETUP请求时从我的服务器返回“461不支持的传输协议”,这两个客户端将立即尝试通过RTSP端口建立基于TCP的连接。
所有其他响应都在此处详细介绍:http://www.ietf.org/rfc/rfc2326.txt

4

如果您使用的是ffmpeg,您可以强制切换rtsp传输层协议。

av_dict_set(&format_opts, "rtsp_transport", "tcp", 0);
err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts);

4

好的,一种方法是向客户端的SETUP请求发送“400 Bad Request”作为响应...然后它会自动切换到TCP协议。这适用于RealOne和QuickTime。

但我不确定它是否适用于所有其他播放器,因为这是一种hack方法。

还有其他想法吗?=|


这方面有文档吗?BadRequest会导致QuickTime进入“配置”状态,然后再也不发送其他请求并显示“BadRequest”或“连接失败”。UnsupportedTranport只会让QuickTime显示“UnsupportedTransport”。我可以让Vlc切换,但无法让QuickTime或Real One切换。邮件列表似乎表明QuickTime不支持http tunneles http://lists.apple.com/archives/streaming-server-dev/2007/Feb/msg00033.html,只支持http。 - Jay
你什么时候发送BadRequest?QuickTime尝试启动哪种协议? - Cipi
在设置期间,使用x-rtsp-tunneled头进行Http请求。 - Jay
1
有一个特殊的响应代码适用于此情况。461 - 传输不支持。http://www.websitepulse.com/kb/rtsp_status_codes.html - LawfulEvil

1
您可以尝试在响应中传递“transport”头,并在其中声明您的服务器仅支持 RTP/AVP/TCP 传输,客户端应知道 UDP 不受支持。

我正在使用2个live555程序,一个是位于live555测试目录下的“testMpeg2transportstreamer”,另一个是位于live555代理服务器目录下的代理服务器。对于代理服务器程序,我会提供“testMpeg2transportstreamer” RTSP服务器的URL,并且现在我可以从代理服务器发送C->A: SETUP rtsp://audio.example.com/twister/audio.en RTSP/1.0 CSeq: 1 Transport: RTP/AVP/TCP;unicast;client_port=3056-3057到“testMpeg2transportstreamer”。请指导。 - Ajinkya

1

什么客户端连接到您的服务器?一些客户端可以通过URL中的URI方法触发。例如,您可以指定rtspt://myhost/path.sdp。

如果您对客户端/服务器有控制权,则可以在客户端上使用Require标头,在服务器上使用Unsupported标头来指示不支持UDP;但我见过的大多数客户端都没有使用此功能。


支持RTSP的多媒体播放器,例如RealOne、QuickTime、VLC、Media Player Classic... 我不明白你的意思是什么方法?我无法控制客户端,我只编写了服务器,所以这是我唯一拥有的控制权。我不能发送“不支持传输”头文件。 =\ - Cipi
如果我明白你的意思,我只需要在 "rtspt" 中添加字母 "t",是吗? =| - Cipi
@J.FritzBarnes 先生,请在此回复 http://stackoverflow.com/questions/14337755/how-to-create-and-destroy-rtsp-server-again-and-again-live-555 - Ajinkya
@J.FritzBarnes 有没有办法从代理服务器向后端服务器发送拆除请求? - Ajinkya
顺便提一下,如果要强制VLC(似乎使用Live555库)在客户端使用TCP来处理此类流,请参见http://www.wowza.com/forums/content.php?64-How-to-configure-VLC-media-player-for-RTSP-RTP-playback-(RTSP-RTP-interleaved-and-tuning)。 - George Birbilis
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接