收藏 分享(赏)

利用JMF进行多媒体编程67159new.doc

上传人:dreamzhangning 文档编号:2308537 上传时间:2018-09-10 格式:DOC 页数:15 大小:142KB
下载 相关 举报
利用JMF进行多媒体编程67159new.doc_第1页
第1页 / 共15页
利用JMF进行多媒体编程67159new.doc_第2页
第2页 / 共15页
利用JMF进行多媒体编程67159new.doc_第3页
第3页 / 共15页
利用JMF进行多媒体编程67159new.doc_第4页
第4页 / 共15页
利用JMF进行多媒体编程67159new.doc_第5页
第5页 / 共15页
点击查看更多>>
资源描述

1、利用 JMF进行多媒体编程 聚生网管 2.2禁一切 P2P下载,限带宽,封 QQ聊天国内最强!Tags: 作者:BitsCN 整理 来源:中国网管联盟 点击: 1258 日期:2002-10-02Java媒体框架(JMF)使你能够编写出功能强大的多媒体程序,却不用关心底层复杂的实现细节。JMF API 的使用相对比较简单,但是能够满足几乎所有多媒体编程的需求。在这篇文章中,我将向你介绍如何用很少的代码就编写出多媒体程序。 Java多媒体框架(JMF)中包含了许多用于处理多媒体的 API。它是一个相当复杂的系统,完全了解这个系统可能需要花上几周的时间,但是这篇文章将主要介绍 JMF的几个核心接口

2、和类,然后通过一个简单的例子向你展示如何利用该接口进行编程。 JMF目前的最新版本是 2.1,Sun 通过它向 Java中引入处理多媒体的能力。下面是 JMF所支持的功能的一个概述: 可以在 Java Applet和应用程序中播放各种媒体文件,例如AU、AVI、MIDI、MPEG、QuickTime 和 WAV等文件。 可以播放从互联网上下载的媒体流。 可以利用麦克风和摄像机一类的设备截取音频和视频,并保存成多媒体文件。 处理多媒体文件,转换文件格式。 向互联网上传音频和视频数据流。 在互联网上广播音频和视频数据。 JMF的结构为了更好地说明 JMF的结构,让我们用立体声音响做一个简单的比喻。

3、当你 CD机播放 CD唱片的时候,CD 唱片向系统提供音乐信号。这些数据是在录音棚中用麦克风和其他类似的设备记录下来的。CD 播放机将音乐信号传送到系统的音箱上。在这个例子中,麦克风就是一个音频截取设备,CD 唱片是数据源,而音箱是输出设备。 JMF的结构和立体声音响系统非常相似,在后面的文章中,你会遇到下面的这些术语: 数据源(Data source) 截取设备(Capture Device,包括视频和音频截取设备) 播放器(Player) 处理器(Processor) 数据格式(Format) 管理器(Manager) 下面让我们来看一看这些术语到底代表什么意思。 1数据源 就像 CD中保

4、存了歌曲一样,数据源中包含了媒体数据流。在 JMF中,DataSource对象就是数据源,它可以是一个多媒体文件,也可以是从互联网上下载的数据流。对于 DataSource对象,一旦你确定了它的位置和类型,对象中就包含了多媒体的位置信息和能够播放该多媒体的软件信息。当创建了DataSource对象后,可以将它送入 Player对象中,而 Player对象不需要关心DataSource中的多媒体是如何获得的,以及格式是什么。 在某些情况下,你需要将多个数据源合并成一个数据源。例如当你在制作一段录像时,你需要将音频数据源和视频数据源合并在一起。JMF 支持数据源合并,在后面的例子中我们将提到这一点

5、。 2截取设备 截取设备指的是可以截取到音频或视频数据的硬件,如麦克风、摄像机等。截取到的数据可以被送入 Player对象中进行处理。 3播放器 在 JMF中对应播放器的接口是 Player。Player 对象将音频视频数据流作为输入,然后将数据流输出到音箱或屏幕上,就像 CD播放机读取 CD唱片中的歌曲,然后将信号送到音箱上一样。Player 对象有多种状态,JMF 中定义了 JMF的六种状态,在正常情况下 Player对象需要经历每个状态,然后才能播放多媒体。下面是对这些状态的说明。 Unrealized:在这种状态下,Player 对象已经被实例化,但是并不知道它需要播放的多媒体的任何信

6、息。 Realizing:当调用 realize()方法时,Player 对象的状态从 Unrealized转变为 Realizing。在这种状态下,Player 对象正在确定它需要占用哪些资源。 Realized:在这种状态下 Player对象已经确定了它需要哪些资源,并且也知道需要播放的多媒体的类型。 Prefetching:当调用 prefectch()方法时,Player 对象的状态从Realized变为 Prefetching。在该状态下的 Player对象正在为播放多媒体做一些准备工作,其中包括加载多媒体数据,获得需要独占的资源等。这个过程被称为预取(Prefetch)。 Pref

7、etched:当 Player对象完成了预取操作后就到达了该状态。 Started:当调用 start()方法后,Player 对象就进入了该状态并播放多媒体。 4处理器 处理器对应的接口是 Processor,它一种播放器。在 JMF API中,Processor 接口继承了 Player接口。 Processor 对象除了支持支持 Player对象支持的所有功能,还可以控制对于输入的多媒体数据流进行何种处理以及通过数据源向其他的 Player对象或 Processor对象输出数据。 除了在播放器中提到了六种状态外,Processor 对象还包括两种新的状态,这两种状态是在 Unrealiz

8、ed状态之后,但是在 Realizing状态之前。 Configuring:当调用 configure()方法后,Processor 对象进入该状态。在该状态下,Processor 对象连接到数据源并获取输入数据的格式信息。 Configured:当完成数据源连接,获得输入数据格式的信息后,Processor对象就处于 Configured状态。 5数据格式 Format对象中保存了多媒体的格式信息。该对象中本身没有记录多媒体编码的相关信息,但是它保存了编码的名称。Format 的子类包括 AudioFormat和VideoFormat类,ViedeoFomat 又有六个子类:H261Form

9、at、H263Format、IndexedColorFormat、JPEGFormat、RGBFormat 和YUVFormat类。 6管理器 JMF提供了下面四种管理器: Manager:Manager 相当于两个类之间的接口。例如当你需要播放一个DataSource对象,你可以通过使用 Manager对象创建一个 Player对象来播放它。使用 Manager对象可以创建 Player、Processor、DataSource 和 DataSink对象。 bitsCN.nET 中国网管博客 PackageManager:该管理器中保存了 JMF类注册信息。 CaptureDeviceMan

10、ager:该管理器中保存了截取设备的注册信息。 PlugInManager:该管理器中保存了 JMF插件的注册信息。 创建一个 Player对象在 JMF编程中,最常见的工作就是创建一个 Player对象。你可以通过 Manager类的 createPlayer()方法创建 Player对象。Manager 对象使用多媒体的 URL或 MediaLocator对象来创建 Player对象。当你获得了一个 Player对象后,你可以通过调用 getVisualComponent()方法得到 Player对象的图像部件(Visual Component,在图像部件上可以播放多媒体的图像)。然后将图

11、像部件加入到应用程序或 Applet的界面上。Player 对象还包含一个控制面板,在上面可以控制媒体的播放、停止和暂停等。 Player类中的很多方法只有在 Player对象处于 Realized的状态下才会被调用。为了保证 Player对象已经到达了该状态,你需要使用 Manager的createRealizePlayer()方法来获得 Player对象。但是对于 start()方法来说,你可以在 Player对象到达 Prefetched状态之前调用它,它可以自动将Player的状态转换到 Started状态。 截取多媒体数据多媒体数据的截取是 JMF程序中另一个非常重要的功能。你可以按

12、照下面的步骤截取数据: 通过查询 CaptureDevieceManager获得你希望使用的截取设备。 获得设备对应的 CaptureDeviceInfo对象。 从 CaptureDeviecInfo对象中获得 MediaLocator对象,然后用它创建一个DataSource对象。 使用 DataSource对象创建 Player对象或 Processor对象。 调用 start()方法,开始截取多媒体数据。 你可以使用 CaptureDeviceManager对象获得系统中可用的视频和音频截取设备。通过调用 getDeviceList()方法你可以获得设备的列表。每个设备都对应一个 Cap

13、trueDeviceInfo对象。也可以通过调用 CaptureDevieceManager对象的getDevice()方法来获得特定的 CaptureDeviceInfo对象。在使用设备截取多媒体数据前,还需要从 CaptureDeviceInfo对象中获得设备对应的MediaLocator对象。然后你可以直接使用 MediaLocator来构造 Player或Processor的实例,也可以用 MediaLocator构造一个 DataSource对象,然后将 DataSource对象送入 Player或 Processor对象中。最后调用 start()方法来截取多媒体数据。 BBS.b

14、itsCN.com 国内最早的网管论坛 一个 JMF例子当你使用 JMF进行编程以前,你需要安装 JMF。同时在硬件上也有一些要求。由于本文的代码是在 Windows 2000下编写和测试,因此文章中提到的操作系统需要的软件都是与 Windows有关的。虽然 Java是跨平台的,但是 JMF是个例外并不是所有的平台上都实现了 JMF。 硬件和软件要求 硬件方面你需要与 SoundBlaster兼容的声卡,芯片最好使用奔腾 III以上的芯片。内存最好不小于 64MB。同时你需要安装下面的软件: Windows95/98,Windows NT 4.0, Windows2000 或 WindowsX

15、P。 JDK1.1.6 或以上的 Windows版本。 JMF 类和动态库 在 Windows下安装 JMF2.1 当下载了 JMF2.1以后,运行 jmf-2_1_1b-windows-i586.exe。该程序会将JMF2.1安装到你指定的目录下。当安装成功后,你需要确认一下安装程序正确设定了 CLASSPATH和 PATH环境变量。在 CLASSPATH中需要包含 jmf.jar和sound.jar;在 PATH中需要包含 JMF动态库的路径。 网管求职 JMFRegistry如果你希望使用视频和音频截取的设备,你需要确认安装了这些设备的驱动程序。除此之外,你还需要运行 JMFRegist

16、ry应用程序。JMFRegistry 可以向 JMF注册新的数据源、媒体处理器、插件、视频和音频截取设备,然后你才能够在你的程序中使用它们。你只需要运行一次 JMFRegistry就能注册系统中所有的视频和音频截取设备。 当你运行了 JMFRegistry后,会弹出图一所示的窗口: DL.bitsCN.com网管软件下载 图一 通过 JMFRegistry注册视频和音频截取设备选择“Capture Devices”标签,然后按下“Detect Capture Devices”按钮,程序将自动检测出系统中的视频和音频截取设备。在左边的类表框中会列出所有检测到的设备的名称。在图一中我们看到 JMF

17、Regsitery发现了 JavaSound audio capture、vfw:Logitech USB Video Camera:0 和 vfw:Microsoft WDM Image Capture (Win32):1。单击某个设备可以看到该设备支持的视频或音频格式。如果 JMFRegistry无法检测到设备,有可能是没有正常安装设备的驱动程序。 例子程序由于 JMF2.1比较复杂,我不可能在在例子中包含 JMF2.1支持的所有功能。因此我选择了下面几个在 JMF中比较常用的功能:播放多媒体、注册音频和视频截取设备、截取视频和音频。 1播放多媒体 在 JMF.java中有一个 play(

18、)方法。该方法可以播放用户选择的多媒体文件。当播放多媒体文件时,你需要一个 Player对象。在例子中,dualPlayer 就是Player接口的实现对象。 Player dualPlayer; 在 Play()方法中,通过使用 FileDialog获得媒体文件的路径和文件名,并保存在 filename中。 try FileDialog fd = new FileDialog(this, Select File, FileDialog.LOAD);fd.show();String filename = fd.getDirectory() + fd.getFile();.catch (Exce

19、ption e) System.out.println(e.toString(); 然后你需要通过媒体管理器 Manager间接创建一个 Player对象。你可以使用Manager类的 createPlayer()方法或者 createProcessor()方法来获得一个 Player对象或 Processor对象。在 play()方法中,我使用的是createPlayer()方法。 dualPlayer = Manager.createPlayer(new MediaLocator(file:/ + filename); BBS.bitsCN.com国内最早的网管论坛 有时你需要使用一个 P

20、layer对象来控制多个其他的 Player和 Controller对象,我们把这个 Player对象称为主对象,并把这些对象组成一个组。通过调用主对象中的 start()、stop()、setMediaTime()等方法就可以激活组中所有成员的相应方法。主对象控制所有的状态变化和事件发布。然后使用addControllerListerner()方法来将一个 ControllerListener对象绑定到Player对象上,Controller 对象将向该 ControllerListener对象发送事件消息。 dualPlayer.addControllerListener(this); 最

21、后需要调用 start()方法来启动 Player对象。start()方法将 Player对象的状态设置为 Started。如果 Player没有被实体化(Realize)或预取(Prefetch),start()方法会自动执行这些操作。 dualPlayer.start(); 由于 JMF类实现了 ControllerLister接口,因此需要实现该接口中的controllerUpdate()方法,该方法在 Controller对象产生一个事件时被调用。public synchronized void controllerUpdate(ControllerEvent event) if (e

22、vent instanceof RealizeCompleteEvent) Component comp;if (comp = dualPlayer.getVisualComponent() != null)add (Center, comp);if (comp = dualPlayer.getControlPanelComponent() != null)add(South, comp);validate(); 当 JMF类产生了一个 RealizeCompleteEvent事件后,controllerUpdate()方法在界面上增加两个 Component对象,一个用于播放媒体,一个用于放

23、置控制按钮,例如播放、停止等。 在运行程序的过程中,程序会产生下面的输出。 Starting player .javax.media.TransitionEventsource=com.sun.media.content.video.mpeg.Handler71bb78,previous=Unrealized,current=Realizing,target=StartedOpen log file: C:testJavaJMFJMFjmf.logjavax.media.DurationUpdateEventsource=com.sun.media.content.video.mpeg.Han

24、dler71bb78,duration=javax.media.Time2a37a6javax.media.RealizeCompleteEventsource=com.sun.media.content.video.mpeg.Handler71bb78,previous=Realizing,current=Realized,target=StartedAdding visual componentAdding control paneljavax.media.TransitionEventsource=com.sun.media.content.video.mpeg.Handler71bb7

25、8,previous=Realized,current=Prefetching,target=Startedjavax.media.PrefetchCompleteEventsource=com.sun.media.content.video.mpeg.Handler71bb78,previous=Prefetching,current=Prefetched,target=Startedjavax.media.StartEventsource=com.sun.media.content.video.mpeg.Handler71bb78,previous=Prefetched,current=S

26、tarted,target=Started,mediaTime=javax.media.Time56a05e,timeBaseTime=javax.media.Time3a8602javax.media.EndOfMediaEventsource=com.sun.media.content.video.mpeg.Handler71bb78,previous=Started,current=Prefetched,target=Prefetched,mediaTime=javax.media.Time1d332b 前面提到,当调用 start()方法的时候,Player 会切换到 Started状

27、态。从上面列出的信息中可以看到 Player对象的状态从 Unrealized变成了Started。当 EndOfMedia事件被激活时(这时 Player对象完成了媒体文件的播放),状态从 Started变成了 Prefetched。图二显示了程序正在播放多媒体文件时的情况。 图二 程序正在播放媒体文件2注册音频和视频截取设备 在例子中,注册音频和视频截取设备的方法只在程序的内部注册这些设备,在程序外则不起作用。该方法的作用是当用户的计算机上存在多和音频和视频截取设备时,告诉程序因该使用哪个设备和这些设备支持的音频和视频格式。因此在进行截取处理之前需要获得设备的配置信息。在例子中,当在 Co

28、nfigure菜单上按下 Capture Device命令后,会弹出 CaptureDeviceDialog对话框。如果在截取音频或视频前没有设定设备的配置,也会弹出该对话框。图三显示了该对话框。 图三 设备注册对话框让我们来看一下 CaptureDeviceDialog类中的 init()方法:在初始化了界面之后,通过调用 CaptureDeviceManager类的 getDeviceList()方法: devices = CaptureDeviceManager.getDeviceList ( null ); CaptureDeviceManager类使用查询机制和一个注册表来定位设备,

29、然后将设备的信息放入 CaptureDeviceInfo对象中返回。我们还可以利用CaptureDeviceManager类来注册新的设备。通过调用 getDeviceList()方法程序获取了一个支持指定格式的设备的列表。在例子中,我将格式参数设定为null,这意味着设备可以使用任何格式。返回值被放入 device变量中。如果getDeviceList()方法返回的是一个非空值,程序会将包含在其中的音频设备名称和视频设备名称分别放入两个下拉列表中中,但是到目前为止我们还不知道哪些设备是音频设备,哪些是视频设备。 我们可以通过 CaptureDeviceInfo的 getFormat()方法获

30、得 Format对象组数,在 Format对象中保存了设备支持的媒体格式。Format 类间接被 AudioFormat和 VideoFormat类所继承。因此我们可以利用设备支持的格式类型来区分设备的类型: if (devices!=null #38;#38; devices.size()0) int deviceCount = devices.size();audioDevices = new Vector();videoDevices = new Vector();Format formats;for ( int i = 0; i deviceCount; i+ ) cdi = (Cap

31、tureDeviceInfo) devices.elementAt ( i );formats = cdi.getFormats();for ( int j=0; jformats.length; j+ ) if ( formatsj instanceof AudioFormat ) audioDevices.addElement(cdi);break;else if (formatsj instanceof VideoFormat ) videoDevices.addElement(cdi);break;. . . 上面的程序运行后,audioDevices()中将包含所有的音频设备,vid

32、eoDevices()中将保存所有的视频设备。其中 cdi是 CaptureDeviceInfo对象。然后将设备名称填入下拉列表中: / 将音频设备显示在下拉列表中for (int i=0; iaudioDevices.size(); i+) cdi = (CaptureDeviceInfo) audioDevices.elementAt(i);audioDeviceCombo.addItem(cdi.getName();/ 将视频设备显示在下拉列表中for (int i=0; ivideoDevices.size(); i+) cdi = (CaptureDeviceInfo) videoD

33、evices.elementAt(i);videoDeviceCombo.addItem(cdi.getName(); 然后程序显示出当前选中的设备支持的格式: displayAudioFormats();displayVideoFormats(); 下一步需要获取用户选中的音频设备和视频设备以及它们支持的格式,相关的方法是 JMF类中的 getAudioDevice()、getVideoDevice()、getAudioFormat()和 getVideoFormat()方法。然后将获取的对象分别保存到 audioCDI,videoCDI,audioFormat 和 videoFormat中

34、: 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: + videoDeviceNa

35、me);/ 获得选中的多媒体格式videoFormat = cdDialog.getVideoFormat();audioFormat = cdDialog.getAudioFormat(); 3截取视频和音频 使用 capture()方法可以截取音频和视频数据。但是在使用该方法前需要确定是否已经选中了视频和音频截取设备: if (audioCDI=null #38;#38; videoCDI=null)registerDevices(); 和 play()方法类似,可以通过使用 Manger类中的静态方法createPlayer()创建一个 Player对象,该对象可以播放一个 DataSo

36、urce对象中的数据流。 Player createPlayer(MediaLocator sourceLocator) 在例子中,我首先通过调用 audioCDI和 videoCDI的 getLocator()方法来获得 MediaLocator对象,然后利用 Manager类的 createPlayer()方法创建Player对象。最后将一个 ControllerListener对象绑定到视频 Player对象上并开始播放。 videoPlayer = Manager.createPlayer(videoCDI.getLocator();audioPlayer = Manager.crea

37、tePlayer(audioCDI.getLocator();videoPlayer.addControllerListener(this);videoPlayer.start();audioPlayer.start(); 使用这种方法导致最后获得了两个 Player对象。我们也可以使用 Manager类中的 createDataSource()方法从视频和音频 CaptureDeviceInfo对象(audioCID 和 videoCDI)中获得视频和音频数据源(DataSource 对象),然后调用 createMergingDataSource()方法将两个数据源合并成一个数据源(ds)

38、: DataSource dataSources = new DataSource2;dataSources0 =Manager.createDataSource(audioCDI.getLocator();dataSources1 =Manager.createDataSource(videoCDI.getLocator();DataSource ds = Manager.createMergingDataSource(dataSources); 然后可以使用 ds作为 createPlayer()方法的参数来获得一个 Player对象dualPlayer。调用 addControllerL

39、istener()就可以进行播放了。 dualPlayer = Manager.createPlayer(ds);dualPlayer.addControllerListener(this);dualPlayer.start(); bitsCN.nET中国网管博客 小结Java多媒体框架是一个很好的多媒体编程工具。在这篇文章中我只是简单介绍了 JMF的一些基本功能。如果有兴趣的话可以仔细阅读一下 Sun公司的 Java网站上提供的 JMStudio的例子。在 JMStudio中不仅实现了简单的播放和视频音频截取功能,还实现了从互联网下载和向互联网上传多媒体数据流的功能。而且它还包含了 JMFRegistry的源代码,将相应的代码移植到你的应用程序中后,你就不需要在运行程序前运行 JMFRegistry来向 JMF注册设备了。 作者简介:冯睿,2000 年毕业于美国 Northern Illinois大学电气工程系,获硕士学位。随后在 New Monics软件公司工作了一年,其间参加了 Java虚拟机的开发和优化工作。目前在国内一家 GIS公司担任项目经理,主要从事应急指挥系统的交通 GIS系统的开发。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 大学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报