- 浏览: 231399 次
- 性别:
- 来自: 南京
最新评论
-
baby8117628:
vc下mp3 IDv1和IDV2的读取 -
gezexu:
你好,我按照你的步骤一步步进行但是安装libvorbis的时候 ...
linux如何搭建强大的FFMPEG环境 -
ini_always:
帅哥,转载也把格式做好点,另外出处也要注明一下吧。。。
MP3文件格式解析
参考资料
1. 《RTSP简单命令》:http://blog.csdn.net/feidragon319/archive/2007/08/14/1742357.aspx
2. http://bbs.21eic.com/dispbbs.asp?boardid=15&Id=22948
3. 《RTSP客户端的Java实现》:http://hi.baidu.com/ssyuan/blog/item/566df6defac1dc5094ee37eb.html
二. RTSP的常用命令与解释
其中C是客户端,S是服务端。
2.1 OPTIONS
C->S: OPTION request //询问S有哪些方法可用
S->C: OPTION response //S回应信息中包括提供的所有可用方法
使用举例:
客户端到服务端:
Java代码
OPTIONS rtsp://218.207.101.236:554/mobile/3/67A451E937422331 RTSP/1.0
Cseq: 1
OPTIONS rtsp://218.207.101.236:554/mobile/3/67A451E937422331 RTSP/1.0
Cseq: 1 服务端对OPTIONS的回应:
Java代码
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 1
Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, OPTIONS, ANNOUNCE, RECORD
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 1
Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, OPTIONS, ANNOUNCE, RECORD
2.2 DESCRIBE
C->S: DESCRIBE request //要求得到S提供的媒体初始化描述信息
S->C: DESCRIBE response //S回应媒体初始化描述信息,主要是sdp
使用举例:
客户端到服务端:
Java代码
DESCRIBE
DESCRIBE Java代码
rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0
Cseq: 2
rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0
Cseq: 2 服务端对OPTIONS的回应:
Java代码
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 2
Content-length: 421
Date: Mon, 03 Aug 2009 08:21:33 GMT
Expires: Mon, 03 Aug 2009 08:21:33 GMT
Content-Type: application/sdp
x-Accept-Retransmit: our-retransmit
x-Accept-Dynamic-Rate: 1
Content-Base: rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/
v=0
o=MediaBox 127992 137813 IN IP4 0.0.0.0
s=RTSP Session
i=Starv Box Live Cast
c=IN IP4 218.207.101.236
t=0 0
a=range:npt=now-
a=control:*
m=video 0 RTP/AVP 96
b=AS:20
a=rtpmap:96 MP4V-ES/1000
a=fmtp:96 profile-level-id=8; config=000001b008000001b5090000010000000120008440fa282c2090a31f; decode_buf=12586
a=range:npt=now-
a=framerate:5
a=framesize:96 176-144
a=cliprect:0,0,144,176
a=control:trackID=1
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 2
Content-length: 421
Date: Mon, 03 Aug 2009 08:21:33 GMT
Expires: Mon, 03 Aug 2009 08:21:33 GMT
Content-Type: application/sdp
x-Accept-Retransmit: our-retransmit
x-Accept-Dynamic-Rate: 1
Content-Base: rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/
v=0
o=MediaBox 127992 137813 IN IP4 0.0.0.0
s=RTSP Session
i=Starv Box Live Cast
c=IN IP4 218.207.101.236
t=0 0
a=range:npt=now-
a=control:*
m=video 0 RTP/AVP 96
b=AS:20
a=rtpmap:96 MP4V-ES/1000
a=fmtp:96 profile-level-id=8; config=000001b008000001b5090000010000000120008440fa282c2090a31f; decode_buf=12586
a=range:npt=now-
a=framerate:5
a=framesize:96 176-144
a=cliprect:0,0,144,176
a=control:trackID=1 2.3 SETUP
C->S: SETUP request //设置会话的属性,以及传输模式,提醒S建立会话
S->C: SETUP response //S建立会话,返回会话标识符,以及会话相关信息
客户端到服务端的请求举例:
Java代码
SETUP rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1
RTSP/1.0
Cseq: 3
Transport: RTP/AVP;UNICAST;client_port=16264-16265;mode=play
SETUP rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1
RTSP/1.0
Cseq: 3
Transport: RTP/AVP;UNICAST;client_port=16264-16265;mode=play 服务端对客户端的回应举例:
Java代码
RTSP/1.0 200 OK
Server: PVSS/1.4.8(Build/20090111;Platform/Win32;Release/StarValley; )
Cseq: 3
Session: 26633092229589
Date: Mon, 03 Aug 2009 08:21:33 GMT
Expires: Mon, 03 Aug 2009 08:21:33 GMT
Transport: RTP/AVP;UNICAST;mode=play;client_port=16264-16265;server_port=20026-20027
RTSP/1.0 200 OK
Server: PVSS/1.4.8(Build/20090111;Platform/Win32;Release/StarValley; )
Cseq: 3
Session: 26633092229589
Date: Mon, 03 Aug 2009 08:21:33 GMT
Expires: Mon, 03 Aug 2009 08:21:33 GMT
Transport: RTP/AVP;UNICAST;mode=play;client_port=16264-16265;server_port=20026-20027 2.4 PLAY
C->S: PLAY request //C请求播放
S->C: PLAY response //S回应该请求的信息
客户端到服务端的请求举例:
Java代码
PLAY rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0
Session: 26633092229589
Cseq: 4
PLAY rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0
Session: 26633092229589
Cseq: 4 服务端对客户端的回应举例:
Java代码
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 4
Session: 26633092229589
RTP-Info: url=rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1;seq=0;rtptime=0
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 4
Session: 26633092229589
RTP-Info: url=rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1;seq=0;rtptime=0
2.5 PAUSE
C->S: PAUSE request //C请求暂停播放
S->C: PAUSE response //S回应该请求的信息
客户端到服务端的请求举例:
Java代码
PAUSE rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0
Cseq: 5
Session: 26633092229589
PAUSE rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0
Cseq: 5
Session: 26633092229589 服务端对客户端的回应举例:
Java代码
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 5
Session: 26633092229589
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 5
Session: 266330922295892.6 TEARDOWN
C->S: TEARDOWN request //C请求关闭会话
S->C: TEARDOWN response //S回应该请求
客户端到服务端的请求举例:
Java代码
TEARDOWN rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0
Cseq: 6
User-Agent: RealMedia Player HelixDNAClient/10.0.0.11279 (win32)
Session: 26633092229589
TEARDOWN rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0
Cseq: 6
User-Agent: RealMedia Player HelixDNAClient/10.0.0.11279 (win32)
Session: 26633092229589 服务端对客户端的回应举例:
Java代码
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 6
Session: 26633092229589
Connection: Close
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 6
Session: 26633092229589
Connection: Close 三. RTSP客户端的Java实现
3.1 接口IEvent.java
接口IEvent.java的代码如下:
3.2 RTSP的测试类:RTSPClient.java
RTSP的测试类RTSPClient.java类的代码如下所示:
其中:rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp为我在网上找到的一个rtsp的sdp地址,读者可自行更换,RTSP的默认端口为554.
3.3 运行结果
运行RTSPClient.java,运行结果如下所示:
1. 《RTSP简单命令》:http://blog.csdn.net/feidragon319/archive/2007/08/14/1742357.aspx
2. http://bbs.21eic.com/dispbbs.asp?boardid=15&Id=22948
3. 《RTSP客户端的Java实现》:http://hi.baidu.com/ssyuan/blog/item/566df6defac1dc5094ee37eb.html
二. RTSP的常用命令与解释
其中C是客户端,S是服务端。
2.1 OPTIONS
C->S: OPTION request //询问S有哪些方法可用
S->C: OPTION response //S回应信息中包括提供的所有可用方法
使用举例:
客户端到服务端:
Java代码
OPTIONS rtsp://218.207.101.236:554/mobile/3/67A451E937422331 RTSP/1.0
Cseq: 1
OPTIONS rtsp://218.207.101.236:554/mobile/3/67A451E937422331 RTSP/1.0
Cseq: 1 服务端对OPTIONS的回应:
Java代码
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 1
Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, OPTIONS, ANNOUNCE, RECORD
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 1
Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, OPTIONS, ANNOUNCE, RECORD
2.2 DESCRIBE
C->S: DESCRIBE request //要求得到S提供的媒体初始化描述信息
S->C: DESCRIBE response //S回应媒体初始化描述信息,主要是sdp
使用举例:
客户端到服务端:
Java代码
DESCRIBE
DESCRIBE Java代码
rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0
Cseq: 2
rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0
Cseq: 2 服务端对OPTIONS的回应:
Java代码
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 2
Content-length: 421
Date: Mon, 03 Aug 2009 08:21:33 GMT
Expires: Mon, 03 Aug 2009 08:21:33 GMT
Content-Type: application/sdp
x-Accept-Retransmit: our-retransmit
x-Accept-Dynamic-Rate: 1
Content-Base: rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/
v=0
o=MediaBox 127992 137813 IN IP4 0.0.0.0
s=RTSP Session
i=Starv Box Live Cast
c=IN IP4 218.207.101.236
t=0 0
a=range:npt=now-
a=control:*
m=video 0 RTP/AVP 96
b=AS:20
a=rtpmap:96 MP4V-ES/1000
a=fmtp:96 profile-level-id=8; config=000001b008000001b5090000010000000120008440fa282c2090a31f; decode_buf=12586
a=range:npt=now-
a=framerate:5
a=framesize:96 176-144
a=cliprect:0,0,144,176
a=control:trackID=1
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 2
Content-length: 421
Date: Mon, 03 Aug 2009 08:21:33 GMT
Expires: Mon, 03 Aug 2009 08:21:33 GMT
Content-Type: application/sdp
x-Accept-Retransmit: our-retransmit
x-Accept-Dynamic-Rate: 1
Content-Base: rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/
v=0
o=MediaBox 127992 137813 IN IP4 0.0.0.0
s=RTSP Session
i=Starv Box Live Cast
c=IN IP4 218.207.101.236
t=0 0
a=range:npt=now-
a=control:*
m=video 0 RTP/AVP 96
b=AS:20
a=rtpmap:96 MP4V-ES/1000
a=fmtp:96 profile-level-id=8; config=000001b008000001b5090000010000000120008440fa282c2090a31f; decode_buf=12586
a=range:npt=now-
a=framerate:5
a=framesize:96 176-144
a=cliprect:0,0,144,176
a=control:trackID=1 2.3 SETUP
C->S: SETUP request //设置会话的属性,以及传输模式,提醒S建立会话
S->C: SETUP response //S建立会话,返回会话标识符,以及会话相关信息
客户端到服务端的请求举例:
Java代码
SETUP rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1
RTSP/1.0
Cseq: 3
Transport: RTP/AVP;UNICAST;client_port=16264-16265;mode=play
SETUP rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1
RTSP/1.0
Cseq: 3
Transport: RTP/AVP;UNICAST;client_port=16264-16265;mode=play 服务端对客户端的回应举例:
Java代码
RTSP/1.0 200 OK
Server: PVSS/1.4.8(Build/20090111;Platform/Win32;Release/StarValley; )
Cseq: 3
Session: 26633092229589
Date: Mon, 03 Aug 2009 08:21:33 GMT
Expires: Mon, 03 Aug 2009 08:21:33 GMT
Transport: RTP/AVP;UNICAST;mode=play;client_port=16264-16265;server_port=20026-20027
RTSP/1.0 200 OK
Server: PVSS/1.4.8(Build/20090111;Platform/Win32;Release/StarValley; )
Cseq: 3
Session: 26633092229589
Date: Mon, 03 Aug 2009 08:21:33 GMT
Expires: Mon, 03 Aug 2009 08:21:33 GMT
Transport: RTP/AVP;UNICAST;mode=play;client_port=16264-16265;server_port=20026-20027 2.4 PLAY
C->S: PLAY request //C请求播放
S->C: PLAY response //S回应该请求的信息
客户端到服务端的请求举例:
Java代码
PLAY rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0
Session: 26633092229589
Cseq: 4
PLAY rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0
Session: 26633092229589
Cseq: 4 服务端对客户端的回应举例:
Java代码
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 4
Session: 26633092229589
RTP-Info: url=rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1;seq=0;rtptime=0
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 4
Session: 26633092229589
RTP-Info: url=rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1;seq=0;rtptime=0
2.5 PAUSE
C->S: PAUSE request //C请求暂停播放
S->C: PAUSE response //S回应该请求的信息
客户端到服务端的请求举例:
Java代码
PAUSE rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0
Cseq: 5
Session: 26633092229589
PAUSE rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0
Cseq: 5
Session: 26633092229589 服务端对客户端的回应举例:
Java代码
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 5
Session: 26633092229589
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 5
Session: 266330922295892.6 TEARDOWN
C->S: TEARDOWN request //C请求关闭会话
S->C: TEARDOWN response //S回应该请求
客户端到服务端的请求举例:
Java代码
TEARDOWN rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0
Cseq: 6
User-Agent: RealMedia Player HelixDNAClient/10.0.0.11279 (win32)
Session: 26633092229589
TEARDOWN rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0
Cseq: 6
User-Agent: RealMedia Player HelixDNAClient/10.0.0.11279 (win32)
Session: 26633092229589 服务端对客户端的回应举例:
Java代码
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 6
Session: 26633092229589
Connection: Close
RTSP/1.0 200 OK
Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; )
Cseq: 6
Session: 26633092229589
Connection: Close 三. RTSP客户端的Java实现
3.1 接口IEvent.java
接口IEvent.java的代码如下:
package com.amigo.rtsp; import java.io.IOException; import java.nio.channels.SelectionKey; /** *//** * IEvent.java 网络事件处理器,当Selector可以进行操作时,调用这个接口中的方法. * 2007-3-22 下午03:35:51 * @author sycheng * @version 1.0 */ public interface IEvent { /** *//** * 当channel得到connect事件时调用这个方法. * @param key * @throws IOException */ void connect(SelectionKey key) throws IOException; /** *//** * 当channel可读时调用这个方法. * @param key * @throws IOException */ void read(SelectionKey key) throws IOException; /** *//** * 当channel可写时调用这个方法. * @throws IOException */ void write() throws IOException; /** *//** * 当channel发生错误时调用. * @param e */ void error(Exception e); }
3.2 RTSP的测试类:RTSPClient.java
RTSP的测试类RTSPClient.java类的代码如下所示:
package com.amigo.rtsp; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.concurrent.atomic.AtomicBoolean; public class RTSPClient extends Thread implements IEvent { private static final String VERSION = " RTSP/1.0\r\n"; private static final String RTSP_OK = "RTSP/1.0 200 OK"; /** *//** 远程地址 */ private final InetSocketAddress remoteAddress; /** *//** * 本地地址 */ private final InetSocketAddress localAddress; /** *//** * 连接通道 */ private SocketChannel socketChannel; /** *//** 发送缓冲区 */ private final ByteBuffer sendBuf; /** *//** 接收缓冲区 */ private final ByteBuffer receiveBuf; private static final int BUFFER_SIZE = 8192; /** *//** 端口选择器 */ private Selector selector; private String address; private Status sysStatus; private String sessionid; /** *//** 线程是否结束的标志 */ private AtomicBoolean shutdown; private int seq=1; private boolean isSended; private String trackInfo; private enum Status { init, options, describe, setup, play, pause, teardown } public RTSPClient(InetSocketAddress remoteAddress, InetSocketAddress localAddress, String address) { this.remoteAddress = remoteAddress; this.localAddress = localAddress; this.address = address; // 初始化缓冲区 sendBuf = ByteBuffer.allocateDirect(BUFFER_SIZE); receiveBuf = ByteBuffer.allocateDirect(BUFFER_SIZE); if (selector == null) { // 创建新的Selector try { selector = Selector.open(); } catch (final IOException e) { e.printStackTrace(); } } startup(); sysStatus = Status.init; shutdown=new AtomicBoolean(false); isSended=false; } public void startup() { try { // 打开通道 socketChannel = SocketChannel.open(); // 绑定到本地端口 socketChannel.socket().setSoTimeout(30000); socketChannel.configureBlocking(false); socketChannel.socket().bind(localAddress); if (socketChannel.connect(remoteAddress)) { System.out.println("开始建立连接:" + remoteAddress); } socketChannel.register(selector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ | SelectionKey.OP_WRITE, this); System.out.println("端口打开成功"); } catch (final IOException e1) { e1.printStackTrace(); } } public void send(byte[] out) { if (out == null || out.length < 1) { return; } synchronized (sendBuf) { sendBuf.clear(); sendBuf.put(out); sendBuf.flip(); } // 发送出去 try { write(); isSended=true; } catch (final IOException e) { e.printStackTrace(); } } public void write() throws IOException { if (isConnected()) { try { socketChannel.write(sendBuf); } catch (final IOException e) { } } else { System.out.println("通道为空或者没有连接上"); } } public byte[] recieve() { if (isConnected()) { try { int len = 0; int readBytes = 0; synchronized (receiveBuf) { receiveBuf.clear(); try { while ((len = socketChannel.read(receiveBuf)) > 0) { readBytes += len; } } finally { receiveBuf.flip(); } if (readBytes > 0) { final byte[] tmp = new byte[readBytes]; receiveBuf.get(tmp); return tmp; } else { System.out.println("接收到数据为空,重新启动连接"); return null; } } } catch (final IOException e) { System.out.println("接收消息错误:"); } } else { System.out.println("端口没有连接"); } return null; } public boolean isConnected() { return socketChannel != null && socketChannel.isConnected(); } private void select() { int n = 0; try { if (selector == null) { return; } n = selector.select(1000); } catch (final Exception e) { e.printStackTrace(); } // 如果select返回大于0,处理事件 if (n > 0) { for (final Iterator<SelectionKey> i = selector.selectedKeys() .iterator(); i.hasNext();) { // 得到下一个Key final SelectionKey sk = i.next(); i.remove(); // 检查其是否还有效 if (!sk.isValid()) { continue; } // 处理事件 final IEvent handler = (IEvent) sk.attachment(); try { if (sk.isConnectable()) { handler.connect(sk); } else if (sk.isReadable()) { handler.read(sk); } else { // System.err.println("Ooops"); } } catch (final Exception e) { handler.error(e); sk.cancel(); } } } } public void shutdown() { if (isConnected()) { try { socketChannel.close(); System.out.println("端口关闭成功"); } catch (final IOException e) { System.out.println("端口关闭错误:"); } finally { socketChannel = null; } } else { System.out.println("通道为空或者没有连接"); } } @Override public void run() { // 启动主循环流程 while (!shutdown.get()) { try { if (isConnected()&&(!isSended)) { switch (sysStatus) { case init: doOption(); break; case options: doDescribe(); break; case describe: doSetup(); break; case setup: if(sessionid==null&&sessionid.length()>0){ System.out.println("setup还没有正常返回"); }else{ doPlay(); } break; case play: doPause(); break; case pause: doTeardown(); break; default: break; } } // do select select(); try { Thread.sleep(1000); } catch (final Exception e) { } } catch (final Exception e) { e.printStackTrace(); } } shutdown(); } public void connect(SelectionKey key) throws IOException { if (isConnected()) { return; } // 完成SocketChannel的连接 socketChannel.finishConnect(); while (!socketChannel.isConnected()) { try { Thread.sleep(300); } catch (final InterruptedException e) { e.printStackTrace(); } socketChannel.finishConnect(); } } public void error(Exception e) { e.printStackTrace(); } public void read(SelectionKey key) throws IOException { // 接收消息 final byte[] msg = recieve(); if (msg != null) { handle(msg); } else { key.cancel(); } } private void handle(byte[] msg) { String tmp = new String(msg); System.out.println("返回内容:"); System.out.println(tmp); if (tmp.startsWith(RTSP_OK)) { switch (sysStatus) { case init: sysStatus = Status.options; break; case options: sysStatus = Status.describe; trackInfo=tmp.substring(tmp.indexOf("trackID")); break; case describe: sessionid = tmp.substring(tmp.indexOf("Session: ") + 9, tmp .indexOf("Date:")); if(sessionid!=null&&sessionid.length()>0){ sysStatus = Status.setup; } break; case setup: sysStatus = Status.play; break; case play: sysStatus = Status.pause; break; case pause: sysStatus = Status.teardown; shutdown.set(true); break; case teardown: sysStatus = Status.init; break; default: break; } isSended=false; } else { System.out.println("返回错误:" + tmp); } } private void doTeardown() { StringBuilder sb = new StringBuilder(); sb.append("TEARDOWN "); sb.append(this.address); sb.append("/"); sb.append(VERSION); sb.append("Cseq: "); sb.append(seq++); sb.append("\r\n"); sb.append("User-Agent: RealMedia Player HelixDNAClient/10.0.0.11279 (win32)\r\n"); sb.append("Session: "); sb.append(sessionid); sb.append("\r\n"); send(sb.toString().getBytes()); System.out.println(sb.toString()); } private void doPlay() { StringBuilder sb = new StringBuilder(); sb.append("PLAY "); sb.append(this.address); sb.append(VERSION); sb.append("Session: "); sb.append(sessionid); sb.append("Cseq: "); sb.append(seq++); sb.append("\r\n"); sb.append("\r\n"); System.out.println(sb.toString()); send(sb.toString().getBytes()); } private void doSetup() { StringBuilder sb = new StringBuilder(); sb.append("SETUP "); sb.append(this.address); sb.append("/"); sb.append(trackInfo); sb.append(VERSION); sb.append("Cseq: "); sb.append(seq++); sb.append("\r\n"); sb.append("Transport: RTP/AVP;UNICAST;client_port=16264-16265;mode=play\r\n"); sb.append("\r\n"); System.out.println(sb.toString()); send(sb.toString().getBytes()); } private void doOption() { StringBuilder sb = new StringBuilder(); sb.append("OPTIONS "); sb.append(this.address.substring(0, address.lastIndexOf("/"))); sb.append(VERSION); sb.append("Cseq: "); sb.append(seq++); sb.append("\r\n"); sb.append("\r\n"); System.out.println(sb.toString()); send(sb.toString().getBytes()); } private void doDescribe() { StringBuilder sb = new StringBuilder(); sb.append("DESCRIBE "); sb.append(this.address); sb.append(VERSION); sb.append("Cseq: "); sb.append(seq++); sb.append("\r\n"); sb.append("\r\n"); System.out.println(sb.toString()); send(sb.toString().getBytes()); } private void doPause() { StringBuilder sb = new StringBuilder(); sb.append("PAUSE "); sb.append(this.address); sb.append("/"); sb.append(VERSION); sb.append("Cseq: "); sb.append(seq++); sb.append("\r\n"); sb.append("Session: "); sb.append(sessionid); sb.append("\r\n"); send(sb.toString().getBytes()); System.out.println(sb.toString()); } public static void main(String[] args) { try { // RTSPClient(InetSocketAddress remoteAddress, // InetSocketAddress localAddress, String address) RTSPClient client = new RTSPClient( new InetSocketAddress("218.207.101.236", 554), new InetSocketAddress("192.168.2.28", 0), "rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp"); client.start(); } catch (Exception e) { e.printStackTrace(); } } }
其中:rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp为我在网上找到的一个rtsp的sdp地址,读者可自行更换,RTSP的默认端口为554.
3.3 运行结果
运行RTSPClient.java,运行结果如下所示:
端口打开成功 OPTIONS rtsp://218.207.101.236:554/mobile/3/67A451E937422331 RTSP/1.0 Cseq: 1 返回内容: RTSP/1.0 200 OK Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; ) Cseq: 1 Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, OPTIONS, ANNOUNCE, RECORD DESCRIBE rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0 Cseq: 2 返回内容: RTSP/1.0 200 OK Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; ) Cseq: 2 Content-length: 421 Date: Mon, 03 Aug 2009 08:50:36 GMT Expires: Mon, 03 Aug 2009 08:50:36 GMT Content-Type: application/sdp x-Accept-Retransmit: our-retransmit x-Accept-Dynamic-Rate: 1 Content-Base: rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ v=0 o=MediaBox 127992 137813 IN IP4 0.0.0.0 s=RTSP Session i=Starv Box Live Cast c=IN IP4 218.207.101.236 t=0 0 a=range:npt=now- a=control:* m=video 0 RTP/AVP 96 b=AS:20 a=rtpmap:96 MP4V-ES/1000 a=fmtp:96 profile-level-id=8; config=000001b008000001b5090000010000000120008440fa282c2090a31f; decode_buf=12586 a=range:npt=now- a=framerate:5 a=framesize:96 176-144 a=cliprect:0,0,144,176 a=control:trackID=1 SETUP rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1 RTSP/1.0 Cseq: 3 Transport: RTP/AVP;UNICAST;client_port=16264-16265;mode=play 返回内容: RTSP/1.0 200 OK Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; ) Cseq: 3 Session: 15470472221769 Date: Mon, 03 Aug 2009 08:50:36 GMT Expires: Mon, 03 Aug 2009 08:50:36 GMT Transport: RTP/AVP;UNICAST;mode=play;client_port=16264-16265;server_port=20080-20081 PLAY rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp RTSP/1.0 Session: 15470472221769 Cseq: 4 返回内容: RTSP/1.0 200 OK Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; ) Cseq: 4 Session: 15470472221769 RTP-Info: url=rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/trackID=1;seq=0;rtptime=0 PAUSE rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0 Cseq: 5 Session: 15470472221769 返回内容: RTSP/1.0 200 OK Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; ) Cseq: 5 Session: 15470472221769 TEARDOWN rtsp://218.207.101.236:554/mobile/3/67A451E937422331/8jH5QPU5GWS07Ugn.sdp/ RTSP/1.0 Cseq: 6 User-Agent: RealMedia Player HelixDNAClient/10.0.0.11279 (win32) Session: 15470472221769 返回内容: RTSP/1.0 200 OK Server: PVSS/1.4.8 (Build/20090111; Platform/Win32; Release/StarValley; ) Cseq: 6 Session: 15470472221769 Connection: Close 端口关闭成功
发表评论
-
vc下mp3 IDv1和IDV2的读取
2010-01-25 10:52 2379/*这是修改后的代码,VC下读ID3v2 & ID3v ... -
使用ffmpeg为库编写的小型多媒体播放器源代码
2010-01-21 16:52 4332今天突发奇想,就在以前音频播放器(详细情况请看这里——http ... -
ffmpeg提取音频播放器总结
2010-01-21 16:31 5963ffmpeg提取音频播放器总 ... -
ffmpeg开发指南
2010-01-20 17:26 3370ffmpeg 中的Libavformat 和 li ... -
linux下安装ffmpeg过程
2010-01-18 15:48 1882最近互联网视频共享的 ... -
【PNG overview】PNG专题!
2010-01-18 13:39 3347【PNG overview】PNG专题! 作者 鼯鼠 ... -
Big Endian 和 Little Endian
2010-01-18 13:29 1542Peter Lee 2008-04-20 一、字节序 ... -
MediaInfo开源工程
2010-01-18 13:22 2354一、简介 MediaInfo 用来 ... -
MP3文件格式解析
2010-01-18 10:58 3541MP3文件格式解析 Peter Lee 2008-06-0 ... -
LAME-mp3
2010-01-18 10:40 2010LAME - 压缩 MP3 的最佳利 ... -
FLV文件格式分析(图示讲解的清楚)
2010-01-14 15:56 5090FLV是一个二进制文件, ... -
我对FLV 文件格式的理解
2010-01-14 15:52 3345我对FLV 文件格式的理解 ----------------- ... -
常用的音频文件介绍
2010-01-13 10:56 1364MP3全称是动态影像专家压缩标准音频层面3(Moving Pi ... -
国外嵌入式、音视频处理等重要网站
2010-01-08 10:07 2017嵌入式方面: 1.关于嵌入式开发的站点,提供非常多关于嵌入 ... -
RTSP点播——消息流程实例
2010-01-08 09:44 5096RTSP点播消息流程实例(客户端:VLC, RTSP服务器:L ... -
live555代码解读之三:SETUP和PLAY请求消息处理过程
2010-01-08 09:43 3442SETUP请求消息处理过程 ... -
live555代码解读之二:DESCRIBE请求消息处理过程
2010-01-08 09:42 3776ve555代码解读之二:DESCRIBE请求消息处理过程 ... -
live555代码解读之一:RTSP连接的建立过程
2010-01-08 09:42 4431TSPServer类用于构建一个RTSP服务器,该类同时在其内 ... -
live555源代码概述
2010-01-08 09:41 3862述 liveMedia项目(http://www ... -
浅议SDP(会话描述协议)
2010-01-04 15:25 3532因为最近常常使用到SDP(会话描述协议Session Desc ...
相关推荐
这是rtsp转流到rtmp服务器客户端-javafx客户端
原生JAVA编写RTSP客户端与服务端通讯协议流程
使用netty进行rtsp服务端开发 一个使用netty写的rtsp服务器。 目前支持H264、H265、 AAC格式的流文件上传与存储。 H264、H265、AAC格式流文件的播放
rtmp-rtsp-stream-client-java Library for stream in RTMP and RTSP. All code in Java. If you need a player see this project: https://github.com/pedroSG94/vlc-example-streamplayer Wiki ...
Android rtmp rtsp 推流客户端.zip,用于Android的RTMP和RTSP流媒体库。Java中的所有代码
rtsp-web-converter转码RTSP,RTMP或其他格式的流用于h5播放成品下载:SpringBootJavacv测试页面:前端使用flvjs播放转码接口 url=base64(视频流地址)(该接口直接响应flv格式视频流)示列var flvPlayer = flvjs....
JAVA实现的流服务(直播,点播),JAVA实现的RTSP协议,可以实现与网络客户端的交互
java socket nginx tcp转发 用户真实IP测试,文章请看我的博客
rtsp地址转websocket去网页显示 其中需要ffmpeg jsmpeg等。利用ffmpeg转码灌输给websocket,客户端通过websocket接收流,然后使用jsmpeg播放
webrtc-java 基于免费、开放的项目的 Java 原生接口实现。 该项目的目标是为运行 Java 的桌面平台开发 RTC 应用程序。...演示客户端演示实现了信号协议,该协议允许 JavaFX 演示应用程序与浏览器中
Android rtmp rtsp 推流客户端
用java实现的摄像头RTSP拉流客户端,测试海康威视摄像头,拉流成功!
采用各种Java Media API,软件开发商人员就能容易、快速地为他们已有的各种应用程序和客户端Java小程序增添丰富的媒体功能,如流式视频、3D图像和影像处理等。就是 说,各种Java Media API发挥了Java平台的固有优势...
LIBONVIF 将您的程序连接到 IP 摄像机 libonvif 是一个开源项目,它实现客户端 ONVIF 以与兼容的 IP 摄像机通信。 在 Windows、Linux、Mac、mingw 上从源代码轻松编译。 libonvif 附带了一个示例程序,该程序在本地...
最好的实现该软件的方法是,借助Android的MediaRecorder实时提取出H263/H264数据,然后经过RTP封装传给RTSP服务器,这种实现方式最理想,通过获取onPrewFrame来获取预览帧编码,无论怎么弄,不可避免的,延时,丢帧...
拉流播放器采用b站的ijkplayer,推流rtmp协议代码封装完全java代码实现,除了使用yuv图片操作的一个第三方c库来提高效率。全部开源,全部免费。不需要任何商业付费。 运行环境:win10+android studio 3.4.1 服务器端...
作为一款无需下载安装即可使用的应用,【小程序名称】依托于微信庞大的生态系统,让用户在微信内就能轻松实现各种功能操作。 【小程序名称】的核心功能主要集中在【具体服务领域】,例如在线购物、本地生活服务、...
LiveView-udp-> RtspServer-udp / tcp-> MyRtsp 摄像机/音频记录-> MediaCodec-> H264 / AAC-> RTP MyRtsp(RtspPlayer)建立在ExoPlayer上。 由于像素格式的原因,目前唯一支持的已知设备是Nexus 5!
CatchCameraActivity视频通话页面,仅完成获取前置摄像头预览及获取网络RTSP视频流播放; ConnetServer连接服务器类,单例模式; FormatTools简单工具类,用于各种类型数据间的转换; ChatActivity聊天页面,实现...
MineSweeper由java实现.zip miniTwitter登录界面.rar MyAppWeixin(仿微信界面) MyBrowser(简单网页浏览器) Myjob3(图片剪辑功能).rar OPENG开发的示例代码.rar OpenSudoku一个简单的九宫格数独游戏.zip OssSystem...