- 浏览: 103676 次
- 性别:
- 来自: 南京
文章分类
最新评论
Since my book on Mobile Media API (MMAPI), Pro Java ME MMAPI: Mobile Media API for Java Micro Edition, was published in May, I have been inundated with requests to help readers with streaming content via MMAPI for Java-enabled mobile devices. This topic was an important omission from the book, but one that was simply not feasible to include because of the lack of support for it within various MMAPI implementations. In this article, I will show you the results of experiments I have conducted since the publication of the book to stream content via MMAPI using a custom datasource.
DISCLAIMER: Before I commence, I would like to point out that even though I was able to stream data from a streaming server and receive it successfully in a MIDlet using a custom datasource, I wasn't able to utilize this data in any meaningful manner because of limitations in the way this data is read by the MMAPI implementation at my disposal. You may have more success if you have access to a MMAPI implementation that doesn't read its data fully. Even if you don't, this article still provides a good study of the issues involved in streaming media data. At the very least, it shows you how to create and utilize your own custom datasource.
For a background on Java ME please see my previous tutorial series on getting started. For an introduction to MMAPI, tutorial 4 is a good start, or you can always buy the book.
Background to the streaming problem
MMAPI is a format- and protocol-agnostic API, which means that the API doesn't dictate mandatory support from device manufacturers for any particular format or protocol. One of the protocols that is widely requested by application developers is the Real Time Streaming Protocol (RTSP) and the associated Real-time Transport Protocol (RTP) for streaming audio/video content. The advantage of streaming content is that it provides a fast turnaround time for the user, control over the content distribution to the distributor, and an overall richer user experience.
However, hardly any manufacturer supports this protocol through Java ME. Some new phones provide support for RTSP, but that support is only on a smattering of devices. A majority of devices still do not support this protocol, therefore limiting useful application development in the streaming media department. A majority of questions in the MMAPI forums of various device manufacturers revolve around this very issue, that is, how to provide streaming data when RTSP is not supported. This article aims to point you in the right direction. I'll start by cutting through the clutter to try to provide an understanding of what streaming means.
What is streaming?
Streaming is the process of transferring data via a channel to its destination, where it is decoded and consumed via the user or device in real time, that is, as the data is being delivered. It differs from non-streaming processes because it doesn't require the data to be fully downloaded before it can be seen or used. Streaming is not the property of the data that is being delivered, but is an attribute of the distribution channel. This means, technically, that most media can be streamed.
HTTP and RTSP
HTTP and RTSP are application-level protocols that allow remote retrieval of data. So why can't you use HTTP for streaming media content? The truth is, you can. When you click on a Web page link to play an audio file, in most cases the media data is streamed to your machine. However, streaming content over HTTP is inherently inefficient. This is because HTTP is based on the Transmission Control Protocol (TCP), which makes sure that media packets are delivered to their destination reliably without worrying about when they are delivered. On the other hand, RTSP can be based on both User Datagram Protocol (UDP), which is a connectionless protocol ensuring faster delivery over reliability, and on TCP. Besides, RTSP has control mechanisms built in that allow random access to the media data, allowing you to seek, pause, and play.
Making sense of RTSP, RTP, and RTCP
There is a lot of confusion among newcomers over the acronyms RTSP, RTP, and RTCP. All three represent different protocols related to streaming of media content. An RTSP session initiates both Real-time Transport Protocol (RTP) and RTP Control Protocol (RTCP) sessions. RTSP is only the control protocol, a bit like a remote control for a DVD player, in that it allows you to start, stop, resume, and seek data remotely. The actual data delivery is done via RTP, and RTCP is a partner protocol to RTP providing feedback to both the sender and receiver on the quality of media data that is being transferred.
With this basic introduction about RTSP and streaming out of the way, let's set up our own streaming server to conduct some experiments. You can read more about RTSP, RTP, and RTCP at http://www.rtsp.org.
Set up a streaming server
To conduct experiments for the purposes of this article, you will need access to a specialty streaming server that can create RTSP streams for media objects. One such server is the Darwin Streaming Server, which is an open-source streaming server based on the same source code as Apple's commercial QuickTime streaming server. Implementations of this free server are available for Mac OS, Linux, and Windows. Download the version that is suitable for your OS and run the installer. You can also choose to download the source code and build it in your environment. I have run the examples in this article on a Windows XP machine, and the server is installed in C:/Program Files/Darwin Streaming Server .
For the purposes of this article, you will also need to have Perl installed on your computer, to administer the Darwin server. For Windows, you can download ActivePerl.
As part of the installation, you will be asked to provide an administrator username and password, but make sure that you run the administration server after the installation (by running the streamingadminserver.pl file). This starts an administration server on port 1220 with which you can monitor the current activity within the streaming server. More importantly, you will need to supply a username/password combination the first time you log into the administrative console (by navigating to http://localhost:1220 in your browser) for running the movie and MP3 broadcast service. It is important to set this (even though you never really need to supply this username/password combination anywhere when running the examples in this article).
Note: On Windows, if you download the latest version of ActivePerl, streamingadminserver.pl is likely to fail with the following error:
ActivePerl 5.8.0 or higher is required
in order to run the Darwin Streaming Server web-based administration. Please
download it from http://www.activeperl.com/ and install it.
This is because of an incorrect configuration check in this script, and you can easily fix it by commenting out lines 33 and 34 (put a #
in front of these lines).
The streaming server starts on port 554 and comes with a few sample movie files, ready for streaming in the installation folder under the Movies directory. The Darwin server can stream MPEG-4, 3GPP, and QuickTime movie files natively. This means that these files don't need to be "hinted" in order to be streamed. Hinting is a process by which media files are prepared with track information for streaming using the professional version of QuickTime. For the purposes of this article, I will work with natively streamable files like 3GPP and MPEG-4 only.
To test that your streaming server is working correctly, use the QuickTime player to launch a file via RTSP. For example, if you can open the URL rtsp://localhost:554/sample_50kbit.3gp correctly in the Quicktime player and view the file, pause it, stop it, and seek it, then your streaming server is working correctly.
Model an RTP packet
As I said earlier, RTP is the actual delivery protocol for streaming data. Each streaming session involves the streaming server sending RTP packets to its destination based on the client request (requests that are delivered via the RTSP protocol). A full knowledge of the RTP RFC is not required for the purposes of this article, so the following base class will model an RTP packet to its best possible approximation.
Note: I have used the Java ME Wireless Toolkit 2.3 (beta) to create and run the examples in this article. You can start by creating a project called "StreamingData" (or whatever you prefer) in this toolkit to place your code in. The J2ME tutorial part 1 gives more details on the process of creating projects in this toolkit.
//usedtoidentifyseparatestreamsthatmaycontributetothispacket
privatelongSSRC;
//incrementingidentifierforeachpacketthatissent
privatelongsequenceNumber;
//usedtoplacethispacketinthecorrecttimingorder
//thatis,wherethispacketfitsintimebasedmedia
privatelongtimeStamp;
//thetypeofthemediadata,orthepayloadtype
privatelongpayloadType;
//theactualmediadata,alsocalledthepayload
privatebytedata[];
//thegetandsetmethods
publiclonggetSSRC()...{returnthis.SSRC;}
publicvoidsetSSRC(longSSRC)...{this.SSRC=SSRC;}
publiclonggetSequenceNumber()...{returnthis.sequenceNumber;}
publicvoidsetSequenceNumber(longsequenceNumber)
...{this.sequenceNumber=sequenceNumber;}
publiclonggetTimeStamp()...{returnthis.timeStamp;}
publicvoidsetTimeStamp(longtimeStamp)...{this.timeStamp=timeStamp;}
publiclonggetPayloadType()...{returnthis.payloadType;}
publicvoidsetPayloadType(longpayloadType)
...{this.payloadType=payloadType;}
publicbyte[]getData()...{returnthis.data;}
publicvoidsetData(byte[]data)...{this.data=data;}
publicStringtoString()...{
return
"RTPPacket"+sequenceNumber+
":["+
"ssrc=0x"+SSRC+
",timestamp="+timeStamp+
",payloadtype="+payloadType+
"]";
}
}
The comments within the code should offer you some idea about the various features of an RTP packet. Since you won't be building a complete RTP client and will be running this code within the confines of this example, the main feature of the above class is the data, or the payload contained within such a packet. Note that an RTP packet contains other information as well, which is not modeled by this class.
Create a custom DataSource
A DataSource
is a MMAPI abstract class, implementations of which encapsulate the task of media data location and retrieval. Device manufacturers provide their own implementations in the Java ME toolkit for most sources. Developers don't need to create their own custom datasources because the task of locating data over file or network is rudimentary and fulfilled by the device manufacturer's implementation. However, in cases where the developer needs to do data retrieval from a custom source, a custom datasource is the answer, and media data fetched from a streaming server is a perfect example.
Data retrieval is one thing, while data consumption is another. Since MMAPI doesn't allow you to create custom media players, will a custom datasource suffice in this example? Let's proceed further with the creation of the custom datasource before I answer that question. The following listing shows the starting of the custom datasource class that I will use for talking to the streaming server:
importjavax.microedition.media.protocol.DataSource;
importjavax.microedition.media.protocol.SourceStream;
publicclassStreamingDataSourceextendsDataSource...{
//thefullURLlikelocatortothedestination
privateStringlocator;
//theinternalstreamthatconnectstothesource
privateSourceStream[]streams;
publicStreamingDataSource(Stringlocator)...{
super(locator);
setLocator(locator);
}
publicvoidsetLocator(Stringlocator)...{this.locator=locator;}
publicStringgetLocator()...{returnlocator;}
publicvoidconnect()...{}
publicvoidstop()...{}
publicvoidstart()...{}
publicvoiddisconnect()...{}
publicStringgetContentType()...{return"";}
publicControl[]getControls()...{returnnull;}
publicControlgetControl(StringcontrolType)...{returnnull;}
publicSourceStream[]getStreams()...{returnstreams;}
}
This class contains only placeholder methods at the moment. Internally, each datasource uses a SourceStream
implementation to read individual streams of data from; therefore, let's create a simple SourceStream
implementation for reading RTP packets:
importjavax.microedition.media.Control;
importjavax.microedition.media.protocol.SourceStream;
importjavax.microedition.media.protocol.ContentDescriptor;
publicclassRTPSourceStreamimplementsSourceStream...{
publicRTPSourceStream(Stringaddress)throwsIOException...{}
publicvoidclose()...{}
publicintread(byte[]buffer,intoffset,intlength)
throwsIOException...{
return0;
}
publiclongseek(longwhere)throwsIOException...{
thrownewIOException("cannotseek");
}
publiclongtell()...{return-1;}
publicintgetSeekType()...{returnNOT_SEEKABLE;}
publicControl[]getControls()...{returnnull;}
publicControlgetControl(StringcontrolType)...{returnnull;}
publiclonggetContentLength()...{return-1;}
publicintgetTransferSize()...{return-1;}
publicContentDescriptorgetContentDescriptor()...{
returnnewContentDescriptor("audio/rtp");
}
}
As with the previous listing, this class only contains placeholder methods for the moment. However, all listings so far should compile and preverify successfully.
发表评论
-
规范的模板化项目架构管理
2012-05-03 23:31 850总在寻找项目开发简单化、标准化、统一化的开发管理方法,在项目 ... -
Java的ftp上传下载工具
2012-04-05 22:17 1724自己写的利用apache的net包写的ftp的上传、下 ... -
SmartGWT学习注意事项(一)
2012-03-31 20:42 1537首先表明,我 ... -
J2ME程序开发全方位基础讲解汇总
2007-08-03 14:19 620一、J2ME中需要的Java基础知识现在有大部分人,都是从零开 ... -
使用J2ME技术开发RPG游戏
2007-08-03 14:24 550RPG(角色扮演游戏)是手机游戏中的一类主要类型,也是相对来说 ... -
移动视频: QuickTime for Java API 入门
2007-08-05 12:45 620在 Java 平台上创建 iPod 视频内容 ... -
技术交流:QuickTime流媒体和Java(图)
2007-08-05 12:46 631这并不是即将问世的Quic ... -
JMF下载安装与支持格式
2007-08-05 12:47 854JMF开发进度不是很快,所以目前还是比较薄弱。 JMF,全名 ... -
搭建J2ME开发环境
2007-08-05 12:48 566由于WTK并没有提供代码编辑的功能,因此本文讲述如何使用Ecl ... -
JMF系统介绍
2007-08-09 15:18 701一.简介 1.1JMF 体系结构 ... -
Experiments in Streaming Content in Java ME(二)----Creating an RTSP Protocol Handler
2007-08-13 13:44 1446Recall that RTSP is the actual ... -
Experiments in Streaming Content in Java ME(三)-----Back to RTPSourceStream and StreamingDataSource
2007-08-13 13:46 1029With the protocol handler in pl ... -
java中文件操作大全
2007-08-22 15:40 554一.获得控制台用户输入的信息 /***//**获得控 ... -
Pocket PC、Pocket PC Phone、Smartphone的区别
2007-08-23 16:59 653首先说明几个概念: 1、什么是Pocket PC?Pocket ... -
Windows mobile Install the Tools
2007-08-23 17:39 577Install Visual Studio 2005 ... -
windows mobile 5.0 模拟器上网的设置
2007-08-28 14:31 644在确保主机已连上互联网的情况下,按以下步骤设置: 1、打 ... -
使用 Windows Mobile 5.0 中的图片、视频和照相机
2007-08-29 15:47 816使用 Windows Mobile 5.0 中的图片、视频和照 ... -
Windows Mobile的安装与流媒体的安装设置
2007-09-05 17:29 853本文重点描述了在Windows Mobile下使用流媒体服务 ... -
Windows Mobile中的WebService应用
2007-09-07 15:03 634Web Service对于开发者来说已经不再是一个陌生概念了。 ... -
Struts配置文件详解(来自csdn)
2007-11-30 08:35 497Struts应用采用两个基于X ...
相关推荐
标题“Experiments in Streaming Content in Java ME(源码下载)”涉及的是在Java ME环境中实现流媒体内容的实验。Java ME(Micro Edition)是Java平台的一个版本,主要用于移动设备和嵌入式系统。这个项目可能专注于...
这本书对反应式机器人和行为式机器人有各种介绍,对智能机器人的爱好者是一个很不错的启发学习。
《车辆:合成心理学的实验》是由Valentino Braitenberg所著的一本经典著作,它深入探讨了人工生命和智能机器人的概念,特别是在心理学视角下的机器行为。这本书的核心是Braitenberg小车,这是一种简单的机器人设计,...
根据提供的文件信息,我们可以深入探讨《实验设计与分析第一门课程》所涉及的关键知识点,并结合计算机科学领域的应用进行解析。 ### 实验设计基础 实验设计是科学研究中的一个重要组成部分,尤其在计算机科学领域...
通过构建一个新颖的元理论框架,该框架将语言理论构建视为一种可能性论证的过程,我们试图解决这一难题。解决方案的关键在于,通过动态反馈机制——即信息的循环、棱镜式和回顾式的再评估过程——思维实验可以在概念...
java8流源码java-flow-experiments 在这个存储库中,我正在试验 ,它将成为 Java 8 应用程序java.util.concurrent包中的 Java 9 的一部分。 这个存储库是为我的主题为 java.util.concurrent.Flow 做好准备的演讲准备...
ideally, intermediate-level data analysts and data scientists with experience in Java. Preferably, you will have experience with the fundamentals of machine learning and now have a desire to explore ...
图像分割是计算机视觉、图像处理及模式识别领域的一个关键步骤,其目的是将一幅数字图像划分为若干个具有相似特性的区域,以便进行后续的特征提取和分类工作。 #### 图像分割的重要性 图像分割是图像处理和模式识别...
1 the fruit-fly experiments described in Carl Zimmer’s piece in the Science Times on Tuesday. Fruit flies who were taught to be smarter than the average fruit fly 2 to live shorter lives. This ...
The release of Java 9 has brought many subtle and not-so-subtle changes to the way in which Java programmers approach their code. The most important ones are definitely the availability of a REPL, ...
Design of Experiments for Engineers and Scientists Second Edition Design of Experiments (DOE) is a powerful technique used for both exploring new processes and gaining increased knowledge of existing ...
"gradle_java_experiments"项目是一个专注于探索Gradle与Java结合使用的实验性项目,旨在帮助开发者深入理解这两个工具的协同工作方式。 **Gradle特性与优势** 1. **灵活的构建模型**:Gradle基于Groovy或Kotlin ...
从以上内容可以推断出,本书《Design and Analysis of Experiments vol.2.pdf》是一本专注于高级实验设计和分析的学术书籍,主要受众为已经具备一定实验设计基础的读者,特别是在生物学领域的研究者。书中不仅介绍了...
In conclusion, this Java laboratory report covers fundamental programming structures in Java, including data types, variables, assignments, and operators. The three experiments demonstrate the ...
根据给定文件的信息,我们可以深入探讨Java编程语言的关键知识点,这些知识点主要集中在“SUN - SL-275 Java Programming Language.pdf”这一资料中,它被认为是SCJP(Sun Certified Java Programmer)不可或缺的...
在IT领域,Prolog(Programming in Logic)是一种专门用于逻辑编程的高级编程语言,常用于人工智能领域的研究与开发。 在本书的介绍部分,作者首先带领读者入门Prolog语言,随后以一系列实验加深对离散数学、逻辑...
### 云冷存储服务实验研究报告 ...总的来说,《Yoshida_Hiroshi_Experiments_in_Storing_Data__Cold_Storage_Services.pdf》是一份全面介绍云冷存储服务的重要文献,对于理解和应用云冷存储技术具有很高的参考价值。
David S. Lee:Randomized Experiments from Non-random Selection in U.S. House Elections._ Journal of Econometrics,
Java8实验 酿什么呢? Java8是! 这个实验项目深入到Java8中,并探讨了其中引入的一些非常酷的功能。 该代码包含以下Java8功能: 内置功能接口 谓词 职能 溪流 map() reduce filter collect 自定义功能界面 ...
在“JavaScript-Experiments”项目中,我们看到的是一系列针对JavaScript语言特性和应用的实验性实践。这个项目可能是为了探索、学习或者测试JavaScript的各种特性,包括但不限于DOM操作、事件处理、函数编程、异步...