用Java多媒体框架设计自动播放机.doc
上传人:sy****28 上传时间:2024-09-14 格式:DOC 页数:6 大小:35KB 金币:18 举报 版权申诉
预览加载中,请您耐心等待几秒...

用Java多媒体框架设计自动播放机.doc

用Java多媒体框架设计自动播放机.doc

预览

在线预览结束,喜欢就下载吧,查找使用更方便

18 金币

下载此文档

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

用Java多媒体框架设计自动播放机如果把Java媒体框架(http://java.sun.com/jmf)看作客户端安装的媒体播放机的话,那么这种框架并不是非常激动人心。它只支持少量媒体类型,并且事实上这些媒体类型都被象Windows媒体播放机以及QuickTime等其它的应用程序支持。但是从内容供应商的观点来看,下面这个事实更加有意义:JMF在所有的Java类型中都可用,这使在客户端上不必要有任何特定的媒体技术就可以部署媒体--所需要的只是J2SEJava运行时间。更重要的是它能利用.jar文件格式的一些性能把解码器和媒体组成到一个文件中,创建一个"自我播放电影",使用了象WinZip和StuffIt这样的压缩应用程序大致相同的方式来创建自我展开文档。我们把此分为三个阶段:1.使JMF能够播放.jar文件中的媒体。2.只使用需要播放本地媒体所需的JMF的一部分创建一个轻量级.jar文件。3.将代码和媒体放入.jar文件,并且创建一个合适的manifest文档以使它可以双击。基本的JMF播放的关键是获得Player,能解码和渲染你的媒体。一般来说,这通过使用Manager获得合适的DataSource来完成,在一个播放实例中提供了媒体流和流元数据,例如媒体格式。Manager然后找到一个Player来处理DataSource。在两种情况下,Manager结合一个带有程序包前缀列表(象javax.media、com.ibm.media等等)的反射方案来试图寻找合适的类,例如如果一个计划的播放程序不能接受提供给它的DataSource,那么它就会抛出异常。Manager没有太多事要做,只是察看一下URL中的协议和文件扩展名,所以虽然它可以很容易的知道如何处理file:///Users/cadamson/mymp3stash/some.mp3,但是它不知道如何处理象jar:file:/Users/cadamson/dev/jmftests/spmovie-old/src/gatsbymovie.jar!/movie/themovie.mov这样的URL。为了缓和这种情况,我们可以写一个DataSource,说得更准确一点就是一个PullDataSource,担负为Manager描述细节的责任。JarEntryDataSource中没有一个方法特别难;我们提供的PullSourceStream还需要实现几个超级接口。它有些不够完美,但是这个类依靠文件扩展名来返回"内容类型"。这多多少少有点象一个MIME类型,除了使用句号代替斜线符号来格式化以外,所以它可被用于程序包名称(例如video/mpegMIME类型变成video.mpeg,所以Manager可以找到com.sun.media.codec.video.mpeg包)。下面是我们的简单的实现:publicStringgetContentType(){try{URLurl=getLocator().getURL();StringurlFile=url.getFile();if(urlFile.endsWith(".mov"))return"video.quicktime";elseif(urlFile.endsWith(".mpg"))return"video.mpeg";elseif(urlFile.endsWith(".avi"))//Managerneeds'_'instedof'-'return"video.x_msvideo";elsereturn"unknown";}catch(MalformedURLExceptionmurle){return"unknown";}}另一个烦恼是JMF源代码表明如果提供的流是Seekable的话(这是一个提供随机存取seek()方法的接口),默认Player只能播放一个QuickTimeDataSource。如果寻找点在流的非常上流的地方,那么JarEntryDataSource中的策略是使用InputStream.skip()。如果寻找点在当前读取点之后(调用tellPoint,因为它的值通过Seekable.tell()方法返回),然后它必须关闭InputStream,再重新打开,跳到寻找点。它使用一个内部的thoroughSkip()方法来确定我们实际上停在哪里。publiclongseek(longposition){try{if(position>tellPoint){thoroughSkip(position-t