- 浏览: 873814 次
- 性别:
- 来自: 上海
-
最新评论
-
waterflow:
感谢分享
简单的ChartDirector生成图表例子 -
YQuite:
写到最后一种文件才看到这个,洼的一声哭了出来 - - !
java简单解析docx、pptx、xlsx文档 -
q394469902:
Android通过selector改变界面状态 -
db6623919:
直接粘贴别人帖子还是英文的,有意思?
实现RTSP协议的简单例子 -
ykou314:
请问下,这些超级命令,是否需要android root权限,尤 ...
Android系统在超级终端下必会的命令大全(七)
Creating an RTSP Protocol Handler
Recall that RTSP is the actual protocol over which streaming commands are initiated, through which the RTP packets are received. The RTSP protocol is like a command initiator, a bit like HTTP. For a really good explanation of a typical RTSP session, please see these specifications for a simple RTSP client. For the purposes of this article, I am going to oversimplify the protocol implementation. Figure 1 shows the typical RTSP session between a client and a streaming server.
Figure 1. A typical RTSP session between a RTSP client and a streaming server (click for full-size image).
In a nutshell, an RTSP client initiates a session by sending a DESCRIBE
request to the streaming server which means that the client wants more information about a media file. An example DESCRIBE
request may look like this:
DESCRIBE rtsp://localhost:554/media.3gp rtsp/1.0 CSeq: 1
The URL for the media file is followed by the RTSP version that the client is following, and a carriage return/line feed (CRLF). The next line contains the sequence number of this request and increments for each subsequent request sent to the server. The command is terminated by a single line on its own (as are all RTSP commands).
All client commands that are successful receive a response that starts with RTSP/1.0 200 OK
. For the DESCRIBE
request, the server responds with several parameters, and if the file is present and streamable, this response contains any information for any tracks in special control strings that start with a a=control:trackID=
String. The trackID
is important and is used to create the next requests to the server.
Once described, the media file's separate tracks are set up for streaming using the SETUP
command, and these commands should indicate the transport properties for the subsequent RTP packets. This is shown here:
SETUP rtsp://localhost:554/media.3gp/trackID=3 rtsp/1.0 CSeq: 2 TRANSPORT: UDP;unicast;client_port=8080-8081
The previous command indicates to the server to set up to stream trackID
3 of the media.3gp file, to send the packets via UDP, and to send them to port 8080 on the client (8081 is for RTCP commands). The response to the first SETUP
command (if it is okay) will contain the session information for subsequent commands and must be included as shown here:
SETUP rtsp://localhost:554/media.3gp/trackID=3 rtsp/1.0
CSeq: 3
Session: 556372992204
TRANSPORT: UDP;unicast;client_port=8080-8081
An OK response from the server indicates that you can send the PLAY command, which will make the server start sending the RTP packets:
PLAY rtsp://localhost:554/media.3gp rtsp/1.0 CSeq: 3 Session: 556372992204
Notice that the PLAY
command is issued only on the main media file, and not on any individual tracks. The same is true for the PAUSE
and TEARDOWN
commands, which are identical to the PLAY
command, except for the command itself.
The following listing contains the RTSPProtocolHandler
class. The comments in the code and the brief information so far should help with understanding how this protocol handler works:
import java.util.Vector; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; public class RTSPProtocolHandler { // the address of the media file as an rtsp://... String private String address; // the inputstream to receive response from the server private InputStream is; // the outputstream to write to the server private OutputStream os; // the incrementing sequence number for each request // sent by the client private static int CSeq = 1; // the session id sent by the server after an initial setup private String sessionId; // the number of tracks in a media file private Vector tracks = new Vector(2); // flags to indicate the status of a session private boolean described, setup, playing; private Boolean stopped = true; // constants private static final String CRLF = "\r\n"; private static final String VERSION = "rtsp/1.0"; private static final String TRACK_LINE = "a=control:trackID="; private static final String TRANSPORT_DATA = "TRANSPORT: UDP;unicast;client_port=8080-8081"; private static final String RTSP_OK = "RTSP/1.0 200 OK"; // base constructor, takes the media address, input and output streams public RTSPProtocolHandler( String address, InputStream is, OutputStream Os) { this.address = address; this.is = is; this.os = Os; } // creates, sends and parses a DESCRIBE client request public void doDescribe() throws IOException { // if already described, return if(described) return; // create the base command String baseCommand = getBaseCommand("DESCRIBE " + address); // execute it and read the response String response = doCommand(baseCommand); // the response will contain track information, amongst other things parseTrackInformation(response); // set flag described = true; } // creates, sends and parses a SETUP client request public void doSetup() throws IOException { // if not described if(!described) throw new IOException("Not Described!"); // create the base command for the first SETUP track String baseCommand = getBaseCommand( "SETUP " + address + "/trackID=" + tracks.elementAt(0)); // add the static transport data baseCommand += CRLF + TRANSPORT_DATA; // read response String response = doCommand(baseCommand); // parse it for session information parseSessionInfo(response); // if session information cannot be parsed, it is an error if(sessionId == null) throw new IOException("Could not find session info"); // now, send SETUP commands for each of the tracks int cntOfTracks = tracks.size(); for(int i = 1; i < cntOfTracks; i++) { baseCommand = getBaseCommand( "SETUP " + address + "/trackID=" + tracks.elementAt(i)); baseCommand += CRLF + "Session: " + sessionId + CRLF + TRANSPORT_DATA; doCommand(baseCommand); } // this is now setup setup = true; } // issues a PLAY command public void doPlay() throws IOException { // must be first setup if(!setup) throw new IOException("Not Setup!"); // create base command String baseCommand = getBaseCommand("PLAY " + address); // add session information baseCommand += CRLF + "Session: " + sessionId; // execute it doCommand(baseCommand); // set flags playing = true; stopped = false; } // issues a PAUSE command public void doPause() throws IOException { // if it is not playing, do nothing if(!playing) return; // create base command String baseCommand = getBaseCommand("PAUSE " + address); // add session information baseCommand += CRLF + "Session: " + sessionId; // execute it doCommand(baseCommand); // set flags stopped = true; playing = false; } // issues a TEARDOWN command public void doTeardown() throws IOException { // if not setup, nothing to teardown if(!setup) return; // create base command String baseCommand = getBaseCommand("TEARDOWN " + address); // add session information baseCommand += CRLF + "Session: " + sessionId; // execute it doCommand(baseCommand); // set flags described = setup = playing = false; stopped = true; } // this method is a convenience method to put a RTSP command together private String getBaseCommand(String command) { return( command + " " + VERSION + // version CRLF + "CSeq: " + (CSeq++) // incrementing sequence ); } // executes a command and receives response from server private String doCommand(String fullCommand) throws IOException { // to read the response from the server byte[] buffer = new byte[2048]; // debug System.err.println(" ====== CLIENT REQUEST ====== "); System.err.println(fullCommand + CRLF + CRLF); System.err.println(" ============================ "); // send a command os.write((fullCommand + CRLF + CRLF).getBytes()); // read response int length = is.read(buffer); String response = new String(buffer, 0, length); // empty the buffer buffer = null; // if the response doesn't start with an all clear if(!response.startsWith(RTSP_OK)) throw new IOException("Server returned invalid code: " + response); // debug System.err.println(" ====== SERVER RESPONSE ====== "); System.err.println(response.trim()); System.err.println(" ============================="); return response; } // convenience method to parse a server response to DESCRIBE command // for track information private void parseTrackInformation(String response) { String localRef = response; String trackId = ""; int index = localRef.indexOf(TRACK_LINE); // iterate through the response to find all instances of the // TRACK_LINE, which indicates all the tracks. Add all the // track id's to the tracks vector while(index != -1) { int baseIdx = index + TRACK_LINE.length(); trackId = localRef.substring(baseIdx, baseIdx + 1); localRef = localRef.substring(baseIdx + 1, localRef.length()); index = localRef.indexOf(TRACK_LINE); tracks.addElement(trackId); } } // find out the session information from the first SETUP command private void parseSessionInfo(String response) { sessionId = response.substring( response.indexOf("Session: ") + "Session: ".length(), response.indexOf("Date:")).trim(); } }
发表评论
-
j2me to android 例子源码下载
2009-11-11 12:21 1679推荐下载: iWidsets最新版2.0.0下载(J2ME) ... -
J2ME时间例子
2009-11-04 01:51 2129下面是一个时间例子: Calendar.getInst ... -
MP3Dict应用发布了
2009-11-03 18:33 1733iWidsets发布新用MP3Dict了 ... -
一些很特别的J2ME开源项目
2009-11-03 04:35 2244StrutsME 一个轻量级的序列化协议,使J2ME客户端能调 ... -
基于J2ME平台的Log4j
2009-11-03 03:55 2147J2ME平台并没有提供LOG来获取一些有用的信息,如 ... -
iWidsets公告
2009-10-21 15:16 1874由于前段时间忘记备案,国庆前关闭网站,导致软件无法下载,请见谅 ... -
iWidsets 发布1.8.1版本(20090920)
2009-09-20 21:21 20321.1 iWidsets 发布1.8.1版本,此版本主要修正B ... -
iWidsets J2ME客户端首次发布了
2009-09-13 13:40 1136经过九个月的开发,iWidsets J2ME客户端首次发布了, ... -
iWidsets J2ME客户端首次发布了
2009-09-13 12:20 1260经过九个月的开发,iWidsets J2ME客户端首次发布了, ... -
解决java.lang.SecurityException: Access denied
2009-08-13 15:42 11317NOKIA的一些目录不允许创建文件,所以会抛出java.lan ... -
J2ME FileConnection开发
2009-08-07 00:00 2679下面是对开发J2ME FileConnection的一些总结: ... -
Experiments in Streaming Content in Java ME(源码下载)
2009-08-04 09:38 1359Experiments in Streaming Conten ... -
keyRepeated和keyPressed处理
2009-07-26 21:38 3162今天修改了一个很重要的Bug,这个BUG会不断向服务端请求相同 ... -
Experiments in Streaming Content in Java ME(3)
2009-07-14 11:47 2033Back to RTPSourceStream and Str ... -
Experiments in Streaming Content in Java ME(1)
2009-07-14 11:06 3850Since my book on Mobile Media A ... -
J2ME实现RTSP(只有在支持的手机才能用)
2009-07-12 21:09 2077最近在研究J2ME实现RTSP协议,在索爱开发网站中看到一个类 ... -
少用System.out.println()
2009-07-11 16:13 3550之前就知道System.out.println ... -
读取流最快方式
2009-07-09 11:42 2639读取流最快方式,当你知道流的长度时,如流长度是maxLengt ... -
让你的J2ME安装包跑起来及其优化
2009-07-09 11:21 1308一、无法下载:通过HTTP下载安装包时,可能会出现“未知文件类 ... -
安装Jar提示“jar文件无效”的另一个奇怪原因
2009-06-24 15:29 8858今天在做魔橙推送邮时遇到一个奇怪的问题,在安装jar时总是提示 ...
相关推荐
标题“Experiments in Streaming Content in Java ME(源码下载)”涉及的是在Java ME环境中实现流媒体内容的实验。Java ME(Micro Edition)是Java平台的一个版本,主要用于移动设备和嵌入式系统。这个项目可能专注于...
Kotti 是一个基于 Pyramid 框架的 Python 内容管理系统(CMS),适合用来搭建中小型网站、文档库、企业展示平台、知识库等需要灵活内容结构和权限模型的项目。它本身更像一个可以二次开发的 CMS 框架,比 WordPress、Drupal 这类“一装就用”的系统更倾向于开发者定制和扩展。 这是支持pyramid2.x版本的kotti! tar -xzvf kotti1.0.tar.gz 解压缩 进入目录执行 pip install -e . 来安装, 然后执行pserve app.ini 启动。 用浏览器浏览127.0.0.1:5000 即可浏览。 用户名admin ,口令qwerty
cmd-bat-批处理-脚本-hello world.zip
知识付费系统自动采集V3.0 跳转不卡顿+搭建教程,不和外面的一样跳转卡顿,这个跳转不卡顿,支持三级分销。
在Matlab环境下,对图像进行特征提取时,主要涵盖形状、纹理以及颜色这三大关键特征。其中,对于纹理特征的提取,采用灰度梯度共生矩阵这一方法来实现。通过灰度梯度共生矩阵,可以有效地捕捉图像中像素灰度值之间在不同方向和距离上的相互关系,进而量化地反映出图像的纹理特性,为后续的图像分析、分类等任务提供重要的纹理信息依据。
该数据集为2010-2023年中国A股上市公司管理层情感语调的年度面板数据,覆盖45,320条样本,数据源自年报及半年报的"管理层讨论与分析"部分。通过构建中文金融情感词典(融合《知网情感分析用词典》与L&M金融词汇表),采用文本分析方法计算情感语调指标,包括:正面/负面词汇数量、文本相似度、情感语调1((积极词-消极词)/总词数)和情感语调2((积极词-消极词)/(积极词+消极词))。同时包含盈利预测偏差、审计意见类型等衍生指标,可用于研究信息披露质量、市场反应及代理问题。该数据复刻了《管理世界》《财经研究》等期刊的变量构建方法,被应用于分析语调操纵对债券市场的影响,学术常用度与稀缺度较高。
cmd-bat-批处理-脚本-FTIME.zip
1747829038637.png
2025年自动化X光检查机项目大数据研究报告.docx
在计算机组成原理课程设计中,我全程跟随老师的指导,独立完成了以下两项任务:一是利用Logisim软件进行原码一位乘法器的仿真设计,通过逐步搭建电路、配置逻辑单元,实现了原码乘法运算的完整流程,深入理解了原码乘法的原理和实现机制;二是完成了补码一位乘法器的Logisim仿真,同样按照老师讲解的步骤,精心设计电路,确保补码乘法运算的正确性,进一步掌握了补码乘法的运算规则和电路实现方法。通过这两个项目,我不仅巩固了理论知识,还提升了动手实践能力和逻辑思维能力。
cmd-bat-批处理-脚本-msvc2017.zip
cmd-bat-批处理-脚本-virtualcam-install.zip
二十四节气之立秋介绍.pptx
cmd-bat-批处理-脚本-shift.zip
二十四节气之小雪介绍.pptx
java、SpringBoot面试专题,6页面试题
cmd-bat-批处理-脚本-GenerateUnionWinMD.zip
二十四节气之大暑节气.pptx
python实现五子棋游戏源码
cmd-bat-批处理-脚本-TransparentConsole.zip