利用JMF进行多媒体编程(4)

来源:百度文库 编辑:神马文学网 时间:2024/06/03 10:24:10
myeclipse 转贴  (参与分:19378,专家分:811)   发表:2005-07-26 10:40   版本:1.0   阅读:1829次
作者:冯睿    本文选自:赛迪网  2002年09月29日
2.注册音频和视频截取设备
在例子中,注册音频和视频截取设备的方法只在程序的内部注册这些设备,在程序外则不起作用。该方法的作用是当用户的计算机上存在多和音频和视频截取设备时,告诉程序因该使用哪个设备和这些设备支持的音频和视频格式。因此在进行截取处理之前需要获得设备的配置信息。在例子中,当在Configure菜单上按下Capture Device命令后,会弹出CaptureDeviceDialog对话框。如果在截取音频或视频前没有设定设备的配置,也会弹出该对话框。图三显示了该对话框。

图三 设备注册对话框
让我们来看一下CaptureDeviceDialog类中的init()方法:在初始化了界面之后,通过调用CaptureDeviceManager类的getDeviceList()方法:
devices = CaptureDeviceManager.getDeviceList ( null );
CaptureDeviceManager类使用查询机制和一个注册表来定位设备,然后将设备的信息放入CaptureDeviceInfo对象中返回。我们还可以利用CaptureDeviceManager类来注册新的设备。通过调用getDeviceList()方法程序获取了一个支持指定格式的设备的列表。在例子中,我将格式参数设定为null,这意味着设备可以使用任何格式。返回值被放入device变量中。如果getDeviceList()方法返回的是一个非空值,程序会将包含在其中的音频设备名称和视频设备名称分别放入两个下拉列表中中,但是到目前为止我们还不知道哪些设备是音频设备,哪些是视频设备。
我们可以通过CaptureDeviceInfo的getFormat()方法获得Format对象组数,在Format对象中保存了设备支持的媒体格式。Format类间接被AudioFormat和VideoFormat类所继承。因此我们可以利用设备支持的格式类型来区分设备的类型:
if (devices!=null && devices.size()>0) {
int deviceCount = devices.size();
audioDevices = new Vector();
videoDevices = new Vector();
Format[] formats;
for ( int i = 0;  i < deviceCount;  i++ ) {
cdi = (CaptureDeviceInfo) devices.elementAt ( i );
formats = cdi.getFormats();
for ( int j=0;  jif ( formats[j] instanceof AudioFormat ) {
audioDevices.addElement(cdi);
break;
}
else if (formats[j] instanceof VideoFormat ) {
videoDevices.addElement(cdi);
break;
}
}
}
. . .
}
上面的程序运行后,audioDevices()中将包含所有的音频设备,videoDevices()中将保存所有的视频设备。其中cdi是CaptureDeviceInfo对象。然后将设备名称填入下拉列表中:
// 将音频设备显示在下拉列表中
for (int i=0; icdi  = (CaptureDeviceInfo) audioDevices.elementAt(i);
audioDeviceCombo.addItem(cdi.getName());
}
// 将视频设备显示在下拉列表中
for (int i=0; icdi  = (CaptureDeviceInfo) videoDevices.elementAt(i);
videoDeviceCombo.addItem(cdi.getName());
}
然后程序显示出当前选中的设备支持的格式:
displayAudioFormats();
displayVideoFormats();
下一步需要获取用户选中的音频设备和视频设备以及它们支持的格式,相关的方法是JMF类中的getAudioDevice()、getVideoDevice()、getAudioFormat()和getVideoFormat()方法。然后将获取的对象分别保存到audioCDI,videoCDI,audioFormat和videoFormat中:
audioCDI = cdDialog.getAudioDevice();
if (audioCDI!=null) {
audioDeviceName = audioCDI.getName();
System.out.println("Audio Device Name: " + audioDeviceName);
}
videoCDI = cdDialog.getVideoDevice();
if (videoCDI!=null) {
videoDeviceName = videoCDI.getName();
System.out.println("Video Device Name: " + videoDeviceName);
}
// 获得选中的多媒体格式
videoFormat = cdDialog.getVideoFormat();
audioFormat = cdDialog.getAudioFormat();
3.截取视频和音频
使用capture()方法可以截取音频和视频数据。但是在使用该方法前需要确定是否已经选中了视频和音频截取设备:
if (audioCDI==null && videoCDI==null)
registerDevices();
和play()方法类似,可以通过使用Manger类中的静态方法createPlayer()创建一个Player对象,该对象可以播放一个DataSource对象中的数据流。
Player createPlayer(MediaLocator sourceLocator)
在例子中,我首先通过调用audioCDI和videoCDI的getLocator()方法来获得MediaLocator对象,然后利用Manager类的createPlayer()方法创建Player对象。最后将一个ControllerListener对象绑定到视频Player对象上并开始播放。
videoPlayer = Manager.createPlayer(videoCDI.getLocator());
audioPlayer = Manager.createPlayer(audioCDI.getLocator());
videoPlayer.addControllerListener(this);
videoPlayer.start();
audioPlayer.start();
使用这种方法导致最后获得了两个Player对象。我们也可以使用Manager类中的createDataSource()方法从视频和音频CaptureDeviceInfo对象(audioCID和videoCDI)中获得视频和音频数据源(DataSource对象),然后调用createMergingDataSource()方法将两个数据源合并成一个数据源(ds):
DataSource[] dataSources = new DataSource[2];
dataSources[0] =
Manager.createDataSource(audioCDI.getLocator());
dataSources[1] =
Manager.createDataSource(videoCDI.getLocator());
DataSource ds = Manager.createMergingDataSource(dataSources);
然后可以使用ds作为createPlayer()方法的参数来获得一个Player对象dualPlayer。调用addControllerListener()就可以进行播放了。
dualPlayer = Manager.createPlayer(ds);
dualPlayer.addControllerListener(this);
dualPlayer.start();
小结
Java多媒体框架是一个很好的多媒体编程工具。在这篇文章中我只是简单介绍了JMF的一些基本功能。如果有兴趣的话可以仔细阅读一下Sun公司的Java网站上提供的JMStudio的例子。在JMStudio中不仅实现了简单的播放和视频/音频截取功能,还实现了从互联网下载和向互联网上传多媒体数据流的功能。而且它还包含了JMFRegistry的源代码,将相应的代码移植到你的应用程序中后,你就不需要在运行程序前运行JMFRegistry来向JMF注册设备了。
_xyz