Android实现RTSP
RTSP和SIP有些类似,只是起到媒体协商的作用,并不关心媒体流的手法,具体来讲,在协商过程中,采用TCP协议进行一系列交互
具体流程:
-------------------------------
C--->S: DESCRIBE
S--->C: DESCRIBE/SDP
C--->S: SETUP
S--->C: SETUP
C--->S: PLAY
S--->C: PLAY
媒体流传输
C--->S: TEARDOWN
-------------------------------
研究RTSP协议的最好方法 :
- 先去下载一个live555的开源流媒体服务器,手机端则用videoview控件做客户端
- 用wireshark抓取videoview和live555通信时的包,分析live555 response的格式
- 细节不懂的地方参照协议RFC 2326
DESCRIBE
具体到程序里是,客户端采用videoview,需要setVideoURI(rtsp://192.168.2.103:1234/path/stream.sdp); 这里这个uri是说向192.168.2.103端口为1234的rtsp服务器发送播放流媒体文件请求,流媒体文件路径为path,文件为stream.sdp 此时videoview会向server发送两个tcp包, 如下:
第一个包用于连接,第二个包发送的是DESCRIBE,内容如下:
0000 44 45 53 43 52 49 42 45 20 72 74 73 70 3a 2f 2f DESCRIBE rtsp://
0010 31 39 32 2e 31 36 38 2e 32 2e 31 30 33 3a 31 32 192.168.2.103:12
0020 33 34 2f 73 74 72 65 61 6d 2e 73 64 70 20 52 54 34/stream.sdp RT
0030 53 50 2f 31 2e 30 0d 0a 43 53 65 71 3a 20 31 0d SP/1.0..CSeq: 1.
0040 0a 41 63 63 65 70 74 3a 20 61 70 70 6c 69 63 61 .Accept: applica
0050 74 69 6f 6e 2f 73 64 70 0d 0a 41 63 63 65 70 74 tion/sdp..Accept
0060 2d 45 6e 63 6f 64 69 6e 67 3a 20 69 64 65 6e 74 -Encoding: ident
0070 69 74 79 0d 0a 43 6f 6e 74 65 6e 74 2d 45 6e 63 ity..Content-Enc
0080 6f 64 69 6e 67 3a 20 69 64 65 6e 74 69 74 79 0d oding: identity.
0090 0a 43 6f 6e 74 65 6e 74 2d 4c 61 6e 67 75 61 67 .Content-Languag
00a0 65 3a 20 65 6e 2d 55 53 0d 0a 42 61 6e 64 77 69 e: en-US..Bandwi
00b0 64 74 68 3a 20 31 31 30 30 30 30 30 30 0d 0a 55 dth: 11000000..U
00c0 73 65 72 2d 41 67 65 6e 74 3a 20 48 54 43 20 53 ser-Agent: HTC S
00d0 74 72 65 61 6d 69 6e 67 20 50 6c 61 79 65 72 20 treaming Player
00e0 68 74 63 5f 61 73 69 61 5f 77 77 65 20 2f 20 31 htc_asia_wwe / 1
00f0 2e 30 20 2f 20 68 74 63 5f 73 61 67 61 20 2f 20 .0 / htc_saga /
0100 32 2e 33 2e 33 0d 0a 78 2d 6e 65 74 77 6f 72 6b 2.3.3..x-network
0110 2d 74 79 70 65 3a 20 57 49 46 49 0d 0a 78 2d 77 -type: WIFI..x-w
0120 61 70 2d 70 72 6f 66 69 6c 65 3a 20 68 74 74 70 ap-profile: http
0130 3a 2f 2f 77 77 77 2e 68 74 63 6d 6d 73 2e 63 6f ://www.htcmms.co
0140 6d 2e 74 77 2f 41 6e 64 72 6f 69 64 2f 43 6f 6d m.tw/Android/Com
0150 6d 6f 6e 2f 50 47 38 38 2f 75 61 2d 70 72 6f 66 mon/PG88/ua-prof
0160 69 6c 65 2e 78 6d 6c 0d 0a 0d 0a ile.xml....
按照rfc2326的标准格式:
写response时注意几点:
- RTSP版本号要一致
CSeq
要一致content-type
一般是sdp
content-length
是sdp
长度- 一定要把
control
这个属性加上,否则videoview解析不出来 - 一定要注意每个消息头部结尾时的
"\r\n\r\n"
,不写或写错会导致videoview死循环,后面的消息同理
代码如下:
String describe_content = "v=0\r\n"+
"o=- 1234567899876543 1 IN IP4 192.168.1.102\r\n"+
"a=range:npt=0-\r\n"+
"m=video 0 RTP/AVP 96\r\n"+
"c=IN IP4 0.0.0.0\r\n"+
"b=AS:500\r\n"+
"a=rtpmap:96 H264/90000\r\n"+
"a=control:track1";
String descirbe_header = "RTSP/1.0 200 OK\r\n"+
"CSeq: 1\r\n"+
"Date: Fri,12 Aug 2011 18:43:59 GMT\r\n"+
"Content-Base: rtsp://192.168.1.102:554/newStream264.264\r\n"+
"Content-Type: application/sdp\r\n"+
"Content-Length: "+describe_content.length()+"\r\n\r\n";
注意几点:
- 一定要确保
"a=control:track1"
- 对于三星手机下面参数一定要写,具体含义参见RFC3984,其含义是:指定RTP的传输通道是track1,具体含义参考sdp协议
a=fmtp:96 packetization-mode=1;
profile-level-id=42000B;
sprop-parameter-sets=Z0IAC41oLE5A,aM4G8g==
SETUP
此时videoview会发来SETUP请求,同样要给予应答,代码如下:
String setup_header = "RTSP/1.0 200 OK\r\n"+
"CSeq: 2\r\n"+
"Date: Fri,12 Aug 2011 18:43:59 GMT\r\n"+
"Transport: RTP/AVP;unicast;mode=play;destination=192.168.1.101;source:192.168.1.102;" +
"client_port="+port1+"-"+port2+";server_port=6970-6971\r\n"+
"Session: 00004E61\r\n\r\n";
注意文本格式,尤其是空格的位置需要特别注意
PLAY
vidoview收到SETUP回复后会发送PLAY消息,同样要给予应答,代码如下:
String play_header = "RTSP/1.0 200 OK\r\n"+
"CSeq: 3\r\n"+
"Date: Fri,12 Aug 2011 18:43:59 GMT\r\n"+
"Range: npt=0.000-\r\n"+
"Session: 00004E61\r\n"+
"RTP-Info: url=rtsp://192.168.1.102/newStream264.264/track1;seq=1000;rtptime=27000\r\n\r\n";
其中Session的标识符要与SETUP的一致,seq指定了RTP包的起始值,rtptime指定了时间戳的起始值