用Java多媒体框架实现自播放
2008-01-05 08:19:11 来源:WEB开发网核心提示:作为客户端安装的媒体播放器,java Media Framework并没有给人很深的印象,用Java多媒体框架实现自播放,它仅仅支持一部分媒体类型,而这些类型只是其他播放系统比如说Windows Media Player和QuickTime支持类型的子集,重开,然后跳到寻找点,
作为客户端安装的媒体播放器,java Media Framework并没有给人很深的印象。它仅仅支持一部分媒体类型,而这些类型只是其他播放系统比如说Windows Media Player和QuickTime支持类型的子集。
但是从内容供给商的观点来看,故事就变的有趣多了:JMF在所有的java模式下都可以适用,这样我们在部署媒体的时候客户端不需要任何媒体播放技术――只需要一个J2SE的运行环境就可以了。举例来说,工程巨人Robert X. Cringely最近公布一项计划: 他们将提供一个被称为"NerdTV"的纯java的MPEG-4 系统,这个系统不需要任何客户端的预安装。
更进一步来说,我们还可以利用.jar格式来把解码器和媒体文件打包成一个文件,以此,从效果上来说创建了一个"自播放电影",与压缩系统WinZip和StuffIt可以创建自扩展归档文件的方式相似。
实现的策略分三步走:
1.使JMF可以播放在.jar文件里的媒体文件。
2.创建一个精简型的.jar 文件,只包括JMF里必须播放本地媒体文件的部分。
3.把代码和媒体文件都放进.jar里,创建一个合适的manifest 文件来支持双击。
JMF基本放像功能的要害在于得到一个可以解码和播放媒体文件的播放器。一般来说,这个动作通过使用治理器来得到一个合适的数据源,这个数据源在放像模式下同时提供媒体流和关于媒体流的元数据,比如说媒体文件的格式。治理器接着找到一个播放器来处理这个数据源。在两种情形下,治理器把一系列的包前缀(javax.media,com.ibm.media等等)绑定在反射机制上来寻找合适的类,在某种情形下抛出错误,比如说当找到的播放器不能接受提供的数据源。
接下来治理器没有更多的办法,通常只是查看URL里的协议和文件扩展名,所以它可以很轻易的知道如何处理file&:///Users/cadamson/mymp3stash/some.mp3 ,却不知道如何处理jar:file&:/Users/cadamson/dev/jmftests/spmovie-old/src/gatsbymovie.jar!/movie/themovie.mov。
为了让事情变得更简单,我们来写一个数据源,或者更确切的说,写一个牵引式数据源。它的职责是为治理器描速数据源本身。JarEntryDataSource里的方法都很简单;但是有很多,因为我们提供的PullSourceStream需要使用很多接口的实现。
这种做法看起来有些不妥――类是通过文件的扩展名来返回"内容类型"的。它类似于MIME类型,只是它用句点而不是用斜杠来构建(MIME类型video/mpeg 转换为video.mpeg,这样治理器可以找到包com.sun.media.codec.video.mpeg )。下面是简单的实现:
public String getContentType() {
try {
URL url = getLocator().getURL();
String urlFile = url.getFile();
if (urlFile.endsWith(".mov"))
return "video.quicktime";
else if (urlFile.endsWith(".mpg"))
return "video.mpeg";
else if (urlFile.endsWith(".avi"))
// Manager needs '_' insted of '-'
return "video.x_msvideo";
else
return "unknown";
} catch (MalformedURLException murle) {
return "unknown";
}
}
另一个令人头疼的问题是JMF的源代码(目前从Sun的网站拿走了不过很快就会放上去)表明假如提供的流是Seekable,(一个提供随机访问方法seek()的接口) 缺省的播放器只能播放一个QuickTime的数据源。JarEntryDataSource的解决策略是在寻找点在媒介流前面的情况下使用InputStream.skip()。假如寻找点在当前读取点(被称为tellPoint因为这个值是由方法Seekable.tell()返回的)的后面,必须关闭InputStream,重开,然后跳到寻找点。它使用一个内部的thoroughSkip()方法来保证我们是真正的结束。
更多精彩
赞助商链接