java JMF 多媒体
JMF:(JavaTM Media Framework)是处理多媒体的程序接口。
JMF框架主要有三种模型,分别是时间模型,事件模型以及数据模型。时间模型定义了JMF的处理媒体流的时间数据的结构。事件模型定义了JMF框架的事件类型以及各个事件类型之间的关系。数据类型定义了JMF处理的媒体流数据的类型。
时间模型
JMF中时间的最小单位是纳秒。所有持JMF的时间模型的类都实现了Clock接口。Clock接口定义了基本的计时和同步操作,以控制媒体数据的呈现。
Clock接口使用TimeBase来跟踪媒体流的时间。
Clock接口中的media time表示媒体流中的当前位置。媒体流的初始media time是0,媒体流的末尾是流的最大media time.Duration表示的媒体流的时间长度。TimeBaseStartTime表示播放媒体流的Time-base time.MediaStartTime表示播放媒体流的起始时间。Rate表示Clock相对TimeBase的速度。比如Rate为1代表正常的播放速度,如果为2代表是正常速度的2倍。
换算关系为:MediaTime=MediaStartTime+Rate*(Time-Basetime - TimeBaseStartTime)
事件模型
JMF使用结构化的事件报告机制来跟踪基于JMF开发的程序的当前状态。基于JMF的程序可以响应媒体驱动的事件,如out-of data和resource unavailable事件。所有媒体事件都继承自MediaEvent类。可以通过调用addListener方法将该接口注册到发布事件的对象上,即可在事件发生后获得事件通知。
数据模型
JMF媒体播放器通常用DataSources类来处理媒体数据的传输。DataSources类封装了媒体的位置信息、协议信息以及传送媒体的软件。DataSource类可以通过JMF的MediaLocator类或者一个URL(Universal Resource Locator)类来标识。MediaLocator类似于URL类并且可以通过URL类来构造,同时MediaLocator可以在相应的协议处理器没有安装的情况下被构造,而URL不行。
一个DataSource对象管理一系列的SourceStream对象。标准的数据源及字节序列为单位进行传输,缓冲数据源使用Buffer对象作为阐述对象。
Processor与Player
在JMF API中,Processor 接口继承了Player接口。Processor对象除了支持Player对象支持的所有功能之外,还可以控制对于输入的多媒体数据流进行何种处理以及通过数据源向其他的Player对象或Processor对象输出数据。
Processor与Player的一个不同点在于,Player处理媒体数据的方式是被Processor内部实现代码事先定义好的,而不能在处理过程中更改。Processor则允许开发者在处理媒体数据的同时根据需要改变处理方式。Processor的这种方式使应用程序更加高效,更加适合处理复杂的数据。
数据源(Data Source)
截取设备(Capture Device)
播放器(Player)
处理器(Processor)
数据格式(Format)
管理器(Manager)
1.数据源
就像CD中保存了歌曲一样,数据源中包含了媒体数据流。在JMF中,DataSource对象就是数据源,它可以是一个多媒体文件,也可以是从互联网上下载的数据流。对于DataSource对象,一旦你确定了它的位置和类型,对象中就包含了多媒体的位置信息和能够播放该多媒体的软件信息。当创建了DataSource对象后,可以将它送入Player对象中,而Player对象不需要关心DataSource中的多媒体是如何获得的,以及格式是什么。
在某些情况下,你需要将多个数据源合并成一个数据源。例如当你在制作一段录像时,你需要将音频数据源和视频数据源合并在一起。JMF支持数据源合并,在后面的例子中我们将提到这一点。
2.截取设备
截取设备指的是可以截取到音频或视频数据的硬件,如麦克风、摄像机等。截取到的数据可以被送入Player对象中进行处理。
3.播放器
在JMF中对应播放器的接口是Player。Player对象将音频/视频数据流作为输入,然后将数据流输出到音箱或屏幕上,就像CD播放机读取CD唱片中的歌曲,然后将信号送到音箱上一样。Player对象有多种状态,JMF中定义了JMF的六种状态,在正常情况下Player对象需要经历每个状态,然后才能播放多媒体。下面是对这些状态的说明。
● Unrealized:在这种状态下,Player对象已经被实例化,但是并不知道它需要播放的多媒体的任何信息。
● Realizing:当调用realize()方法时,Player对象的状态从Unrealized转变为Realizing。在这种状态下,Player对象正在确定它需要占用哪些资源。
● Realized:在这种状态下Player对象已经确定了它需要哪些资源,并且也知道需要播放的多媒体的类型。
● Prefetching:当调用prefectch()方法时,Player对象的状态从Realized变为Prefetching。在该状态下的Player对象正在为播放多媒体做一些准备工作,其中包括加载多媒体数据,获得需要独占的资源等。这个过程被称为预取(Prefetch)。
● Prefetched:当Player对象完成了预取操作后就到达了该状态。
● Started:当调用start()方法后,Player对象就进入了该状态并播放多媒体。
4.处理器
处理器对应的接口是Processor,它一种播放器。在JMF API中,Processor接口继承了Player接口。 Processor对象除了支持支持Player对象支持的所有功能,还可以控制对于输入的多媒体数据流进行何种处理以及通过数据源向其他的Player对象或Processor对象输出数据。
除了在播放器中提到了六种状态外,Processor 对象还包括两种新的状态,这两种状态是在Unrealized状态之后,但是在Realizing状态之前。
● Configuring:当调用configure()方法后,Processor对象进入该状态。在该状态下,Processor对象连接到数据源并获取输入数据的格式信息。
● Configured:当完成数据源连接,获得输入数据格式的信息后,Processor对象就处于Configured状态。
5.数据格式
Format对象中保存了多媒体的格式信息。该对象中本身没有记录多媒体编码的相关信息,但是它保存了编码的名称。Format的子类包括AudioFormat和VideoFormat类,ViedeoFomat又有六个子类:H261Format、H263Format、IndexedColorFormat、JPEGFormat、RGBFormat和YUVFormat类。
6.管理器
JMF提供了下面四种管理器:
● Manager:Manager相当于两个类之间的接口。例如当你需要播放一个DataSource对象,你可以通过使用Manager对象创建一个Player对象来播放它。使用Manager对象可以创建Player、Processor、DataSource和DataSink对象。
● PackageManager:该管理器中保存了JMF类注册信息。
● CaptureDeviceManager:该管理器中保存了截取设备的注册信息。
● PlugInManager:该管理器中保存了JMF插件的注册信息。 创建一个Player对象
在JMF编程中,最常见的工作就是创建一个Player对象。你可以通过Manager类的createPlayer()方法创建Player对象。Manager对象使用多媒体的URL或MediaLocator对象来创建Player对象。当你获得了一个Player对象后,你可以通过调用getVisualComponent()方法得到Player对象的图像部件(Visual Component,在图像部件上可以播放多媒体的图像)。然后将图像部件加入到应用程序或Applet的界面上。Player对象还包含一个控制面板,在上面可以控制媒体的播放、停止和暂停等。
Player类中的很多方法只有在Player对象处于Realized的状态下才会被调用。为了保证Player对象已经到达了该状态,你需要使用Manager的createRealizePlayer()方法来获得Player对象。但是对于start()方法来说,你可以在Player对象到达Prefetched状态之前调用它,它可以自动将Player的状态转换到Started状态。
截取多媒体数据
多媒体数据的截取是JMF程序中另一个非常重要的功能。你可以按照下面的步骤截取数据:
● 通过查询CaptureDevieceManager获得你希望使用的截取设备。
● 获得设备对应的CaptureDeviceInfo对象。
● 从CaptureDeviecInfo对象中获得MediaLocator对象,然后用它创建一个DataSource对象。
● 使用DataSource对象创建Player对象或Processor对象。
● 调用start()方法,开始截取多媒体数据。
你可以使用CaptureDeviceManager对象获得系统中可用的视频和音频截取设备。通过调用getDeviceList()方法你可以获得设备的列表。每个设备都对应一个CaptrueDeviceInfo对象。也可以通过调用CaptureDevieceManager对象的getDevice()方法来获得特定的CaptureDeviceInfo对象。在使用设备截取多媒体数据前,还需要从CaptureDeviceInfo对象中获得设备对应的MediaLocator对象。然后你可以直接使用MediaLocator来构造Player或Processor的实例,也可以用MediaLocator构造一个DataSource对象,然后将DataSource对象送入Player或Processor对象中。最后调用start()方法来截取多媒体数据。