- 浏览: 237701 次
- 性别:
- 来自: 南京
-
最新评论
-
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 2452/*这是修改后的代码,VC下读ID3v2 & ID3v ... -
使用ffmpeg为库编写的小型多媒体播放器源代码
2010-01-21 16:52 4401今天突发奇想,就在以前音频播放器(详细情况请看这里——http ... -
ffmpeg提取音频播放器总结
2010-01-21 16:31 6057ffmpeg提取音频播放器总 ... -
ffmpeg开发指南
2010-01-20 17:26 3414ffmpeg 中的Libavformat 和 li ... -
linux下安装ffmpeg过程
2010-01-18 15:48 1924最近互联网视频共享的 ... -
【PNG overview】PNG专题!
2010-01-18 13:39 3426【PNG overview】PNG专题! 作者 鼯鼠 ... -
Big Endian 和 Little Endian
2010-01-18 13:29 1575Peter Lee 2008-04-20 一、字节序 ... -
MediaInfo开源工程
2010-01-18 13:22 2420一、简介 MediaInfo 用来 ... -
MP3文件格式解析
2010-01-18 10:58 3585MP3文件格式解析 Peter Lee 2008-06-0 ... -
LAME-mp3
2010-01-18 10:40 2077LAME - 压缩 MP3 的最佳利 ... -
FLV文件格式分析(图示讲解的清楚)
2010-01-14 15:56 5136FLV是一个二进制文件, ... -
我对FLV 文件格式的理解
2010-01-14 15:52 3405我对FLV 文件格式的理解 ----------------- ... -
常用的音频文件介绍
2010-01-13 10:56 1430MP3全称是动态影像专家压缩标准音频层面3(Moving Pi ... -
国外嵌入式、音视频处理等重要网站
2010-01-08 10:07 2062嵌入式方面: 1.关于嵌入式开发的站点,提供非常多关于嵌入 ... -
RTSP点播——消息流程实例
2010-01-08 09:44 5141RTSP点播消息流程实例(客户端:VLC, RTSP服务器:L ... -
live555代码解读之三:SETUP和PLAY请求消息处理过程
2010-01-08 09:43 3514SETUP请求消息处理过程 ... -
live555代码解读之二:DESCRIBE请求消息处理过程
2010-01-08 09:42 3836ve555代码解读之二:DESCRIBE请求消息处理过程 ... -
live555代码解读之一:RTSP连接的建立过程
2010-01-08 09:42 4469TSPServer类用于构建一个RTSP服务器,该类同时在其内 ... -
live555源代码概述
2010-01-08 09:41 3916述 liveMedia项目(http://www ... -
浅议SDP(会话描述协议)
2010-01-04 15:25 3609因为最近常常使用到SDP(会话描述协议Session Desc ...
相关推荐
4. **DirectShow或GStreamer**:这些是更底层的多媒体框架,通常在C++或Python中使用,但也可以通过JNI(Java Native Interface)在Java中调用,实现RTSP客户端。 实现RTSP客户端时,你可能会遇到的问题包括网络...
该项目为基于Java语言的RTSP客户端设计实现源码,包含58个文件,其中包括49个Java源代码文件、5个XML配置文件、2个Git忽略文件以及1个LICENSE文件。
这是rtsp转流到rtmp服务器客户端-javafx客户端
本文将深入探讨基于Java实现RTSP服务的相关知识点,并以“基于Java的RTSP服务源码”为例进行分析。 1. RTSP协议基础 RTSP协议由IETF定义,主要目的是为了解决多媒体数据的实时传输问题。它允许客户端通过发送指令来...
在这个"基于Java的RTSP服务源代码"中,我们主要关注的是如何利用Java实现RTSP(Real-Time Streaming Protocol)服务,这是一种用于控制实时媒体流传输的协议。RTSP常用于流式音频和视频,比如在线直播或者vod(视频...
综上所述,这个项目融合了多个高级IT技术,展示了如何在Java环境中集成FFmpeg和JavaCV来实现复杂的实时视频处理功能,同时利用RTSP协议和WebSocket提供无控件的HTML5视频预览和录像服务。这样的技术组合在物联网、...
原生JAVA编写RTSP客户端与服务端通讯协议流程
这个库是为了解决在不同操作系统和网络环境下的多媒体流传输问题而设计的,特别适合于在嵌入式设备如Android手机上实现RTSP客户端。 创建RTSP客户端的第一步是获取并编译Live555库。你需要下载Live555源代码,然后...
- `video.jar` 可能是一个包含Java实现的流处理服务,负责接收RTSP/RTMP流并进行转换。 - `ffmpeg-4.4-essentials_build.zip` 包含了FFmpeg的编译版本,供Java服务调用。 - `nginx-1.7.11.zip` 是Nginx的一个版本...
总之,Java实现RTSP/RTMP到M3U8/FLV/HLS/MP4的转换是一项复杂但至关重要的工作,涵盖了音视频处理、网络协议、流媒体技术和Web开发等多个领域,它为用户提供了一种灵活且适应性强的在线直播和回放解决方案。
这段代码展示了如何使用Java实现一个简单的RTSP客户端,它与服务器进行交互以请求流媒体资源。以下是对代码中关键知识点的详细解释: 1. **RTSP协议**:RTSP是一种应用层协议,用于控制多媒体数据的传输。它允许...
当客户端通过RTSP协议将流文件上传到服务器时,你需要在Netty的服务器端实现文件接收和存储逻辑。这可能涉及到创建一个特殊的Handler来处理上传请求,将接收到的数据写入到磁盘,并保持文件系统的同步。 6. 播放...
在Java平台上实现RTSP,对于开发多媒体应用程序非常关键。这个"RTSP.rar"压缩包包含了一些核心的Java类,用于理解和实现RTSP相关的功能。 首先,`RTSPProtocolHandler.java`是处理RTSP协议的核心类。它可能包含了...
3. Java实现RTSP对接: Java提供了JMF(Java Media Framework)和VLCJ库来处理RTSP流。然而,JMF已经较旧且支持有限,VLCJ则基于开源的VLC播放器,提供了更全面的多媒体支持。 使用VLCJ,你可以创建一个...
RTSP客户端(RTSP Client)是实现RTSP协议的应用程序,它负责与RTSP服务器通信,发起播放、停止、暂停等控制命令。"rtspclient"和"RTSPClient"可能是这个项目中的客户端实现,可能是一个C++或Java库,或者是一个...
本项目标题为“通过rtmp/rtsp,openCV进行人脸识别并截图,Java版本”,它结合了实时传输协议(RTMP)、实时流协议(RTSP)以及开源计算机视觉库OpenCV,用Java语言实现了一个简单的人脸识别和截图功能。下面将详细...
然而,由于浏览器本身并不支持RTSP直接播放,我们需要借助外部工具来实现网页播放。这就引出了我们的主角——WebSocket。 WebSocket是一种在客户端和服务器之间建立长连接的协议,能够提供双向通信,非常适合实时...
在Java中,利用RTSP协议可以实现与远程摄像头的连接,以及媒体文件的自动化播放和控制。以下是对RTSP协议及其在Java中的应用进行的详细解释: 1. **RTSP协议基础**: - RTSP是IETF定义的标准,它的主要目的是为...
在IT行业中,视频编码与转换是一项关键的技术,尤其是在多媒体内容分发和服务...为了详细了解和学习这个纯Java实现,建议解压后仔细研究其中的文件,理解代码逻辑和工作流程,以便进一步应用或改进这个视频转码工具。