利用JMF進行多媒體編程26067_第1頁
利用JMF進行多媒體編程26067_第2頁
利用JMF進行多媒體編程26067_第3頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

1、僅供個人參考利用 JMF進行多媒體編程Java 媒體框架( JMF)使你能夠編寫出功能強大的多媒體程序,卻不用關心底層復雜的實現(xiàn)細節(jié)。JMF API 的使用相對比較簡單,但是能夠滿足幾乎所有多媒體編程的需求。在這篇文章中,我將向你介紹如何用很少的代碼就編寫出多媒體程序。Java 多媒體框架( JMF)中包含了許多用于處理多媒體的API。它是一個相當復雜的系統(tǒng),完全了解這個系統(tǒng)可能需要花上幾周的時間,但是這篇文章將主要介紹JMF的幾個核心接口和類,然后通過一個簡單的例子向你展示如何利用該接口進行編程。JMF目前的最新版本是2.1 ,Sun 通過它向 Java 中引入處理多媒體的能力。下面是JMF

2、所支持的功能的一個概述: 可以在 Java Applet和應用程序中播放各種媒體文件,例如AU、AVI、 MIDI 、MPEG、 QuickTime 和 WAV等文件。 可以播放從互聯(lián)網(wǎng)上下載的媒體流。 可以利用麥克風和攝像機一類的設備截取音頻和視頻,并保存成多媒體文件。 處理多媒體文件,轉(zhuǎn)換文件格式。 向互聯(lián)網(wǎng)上傳音頻和視頻數(shù)據(jù)流。 在互聯(lián)網(wǎng)上廣播音頻和視頻數(shù)據(jù)。JMF的結(jié)構為了更好地說明JMF的結(jié)構,讓我們用立體聲音響做一個簡單的比喻。當你 CD機播放 CD唱片的時候, CD唱片向系統(tǒng)提供音樂信號。這些數(shù)據(jù)是在錄音棚中用麥克風和其他類似的設備記錄下來的。CD播放機將音樂信號傳送到系統(tǒng)的音箱

3、上。在這個例子中,麥克風就是一個音頻截取設備,CD唱片是數(shù)據(jù)源,而音箱是輸出設備。JMF的結(jié)構和立體聲音響系統(tǒng)非常相似,在后面的文章中,你會遇到下面的這些術語: 數(shù)據(jù)源( Data source) 截取設備( Capture Device,包括視頻和音頻截取設備) 播放器( Player ) 處理器( Processor ) 數(shù)據(jù)格式( Format ) 管理器( Manager)下面讓我們來看一看這些術語到底代表什么意思。1數(shù)據(jù)源就像 CD中保存了歌曲一樣,數(shù)據(jù)源中包含了媒體數(shù)據(jù)流。在JMF中, DataSource 對象就是數(shù)據(jù)源,它可以是一個多媒體文件,也可以是從互聯(lián)網(wǎng)上下載的數(shù)據(jù)流。對

4、于DataSource 對象,一旦你確定了它的位置和類型,對象中就包含了多媒體的位置信息和能夠播放該多媒體的軟件信息。當創(chuàng)建了DataSource 對象后,可以將它送入Player對象中,而Player對象不需要關心DataSource 中的多媒體是如何獲得的,以及格式是什么。在某些情況下,你需要將多個數(shù)據(jù)源合并成一個數(shù)據(jù)源。例如當你在制作一段錄像時,你需要將音頻數(shù)據(jù)源和視頻數(shù)據(jù)源合并在一起。 JMF支持數(shù)據(jù)源合并,在后面的例子中我們將提到這一點。2截取設備截取設備指的是可以截取到音頻或視頻數(shù)據(jù)的硬件,如麥克風、攝像機等。截取到的數(shù)據(jù)可以被送入Player對象中進行處理。3播放器在 JMF中對

5、應播放器的接口是Player 。Player對象將音頻視頻數(shù)據(jù)流作為輸入,然后將數(shù)據(jù)流輸出到音箱或屏幕上,就像不得用于商業(yè)用途僅供個人參考CD播放機讀取 CD唱片中的歌曲,然后將信號送到音箱上一樣。Player 對象有多種狀態(tài), JMF中定義了 JMF的六種狀態(tài),在正常情況下 Player 對象需要經(jīng)歷每個狀態(tài),然后才能播放多媒體。下面是對這些狀態(tài)的說明。 Unrealized:在這種狀態(tài)下, Player 對象已經(jīng)被實例化,但是并不知道它需要播放的多媒體的任何信息。 Realizing:當調(diào)用 realize ()方法時, Player 對象的狀態(tài)從 Unrealized 轉(zhuǎn)變?yōu)?Reali

6、zing 。在這種狀態(tài)下, Player對象正在確定它需要占用哪些資源。 Realized :在這種狀態(tài)下 Player對象已經(jīng)確定了它需要哪些資源,并且也知道需要播放的多媒體的類型。 Prefetching:當調(diào)用 prefectch()方法時, Player 對象的狀態(tài)從 Realized 變?yōu)?Prefetching 。在該狀態(tài)下的 Player對象正在為播放多媒體做一些準備工作,其中包括加載多媒體數(shù)據(jù),獲得需要獨占的資源等。 這個過程被稱為預取 (Prefetch)。 Prefetched :當 Player 對象完成了預取操作后就到達了該狀態(tài)。 Started :當調(diào)用 start

7、()方法后, Player 對象就進入了該狀態(tài)并播放多媒體。4處理器處理器對應的接口是Processor ,它一種播放器。在JMFAPI 中, Processor接口繼承了Player接口。 Processor對象除了支持支持 Player對象支持的所有功能,還可以控制對于輸入的多媒體數(shù)據(jù)流進行何種處理以及通過數(shù)據(jù)源向其他的Player對象或 Processor對象輸出數(shù)據(jù)。除了在播放器中提到了六種狀態(tài)外,Processor對象還包括兩種新的狀態(tài),這兩種狀態(tài)是在Unrealized狀態(tài)之后,但是在Realizing狀態(tài)之前。 Configuring:當調(diào)用 configure()方法后, Pr

8、ocessor 對象進入該狀態(tài)。在該狀態(tài)下,Processor對象連接到數(shù)據(jù)源并獲取輸入數(shù)據(jù)的格式信息。 Configured:當完成數(shù)據(jù)源連接,獲得輸入數(shù)據(jù)格式的信息后,Processor 對象就處于Configured狀態(tài)。5數(shù)據(jù)格式Format 對象中保存了多媒體的格式信息。該對象中本身沒有記錄多媒體編碼的相關信息,但是它保存了編碼的名稱。Format的子類包括 AudioFormat 和 VideoFormat 類, ViedeoFomat 又有六個子類: H261Format、 H263Format、 IndexedColorFormat 、JPEGFormat、RGBFormat和

9、 YUVFormat 類。6管理器JMF提供了下面四種管理器: Manager :Manager 相當于兩個類之間的接口。例如當你需要播放一個DataSource 對象,你可以通過使用Manager 對象創(chuàng)建一個 Player對象來播放它。使用Manager 對象可以創(chuàng)建Player 、 Processor 、DataSource 和 DataSink 對象。 PackageManager :該管理器中保存了 JMF類注冊信息。 CaptureDeviceManager :該管理器中保存了截取設備的注冊信息。 PlugInManager :該管理器中保存了 JMF插件的注冊信息。創(chuàng)建一個 Pl

10、ayer對象在 JMF編程中,最常見的工作就是創(chuàng)建一個 Player 對象。你可以通過 Manager 類的 createPlayer ()方法創(chuàng)建 Player 對象。Manager對象使用多媒體的 URL或 MediaLocator 對象來創(chuàng)建 Player 對象。當你獲得了一個 Player 對象后,你可以通過調(diào)用 getVisualComponent ()方法得到 Player 對象的圖像部件( Visual Component,在圖像部件上可以播放多媒體的圖像)。然后將圖像部件加入到應用程序或 Applet 的界面上。 Player 對象還包含一個控制面板,在上面可以控制媒體的播放、

11、停止和暫停等。Player類中的很多方法只有在Player對象處于 Realized的狀態(tài)下才會被調(diào)用。為了保證Player對象已經(jīng)到達了該狀態(tài),你需要使用 Manager 的 createRealizePlayer()方法來獲得Player對象。但是對于start ()方法來說,你可以在Player對象到達Prefetched狀態(tài)之前調(diào)用它,它可以自動將Player的狀態(tài)轉(zhuǎn)換到Started狀態(tài)。不得用于商業(yè)用途僅供個人參考截取多媒體數(shù)據(jù)多媒體數(shù)據(jù)的截取是 JMF程序中另一個非常重要的功能。你可以按照下面的步驟截取數(shù)據(jù): 通過查詢 CaptureDevieceManager獲得你希望使用的截

12、取設備。 獲得設備對應的 CaptureDeviceInfo對象。 從 CaptureDeviecInfo對象中獲得MediaLocator 對象,然后用它創(chuàng)建一個DataSource 對象。 使用 DataSource 對象創(chuàng)建 Player對象或 Processor 對象。 調(diào)用 start()方法,開始截取多媒體數(shù)據(jù)。你可以使用CaptureDeviceManager對象獲得系統(tǒng)中可用的視頻和音頻截取設備。通過調(diào)用getDeviceList()方法你可以獲得設備的列表。每個設備都對應一個CaptrueDeviceInfo對象。也可通過調(diào)用CaptureDevieceManager對象的

13、getDevice ()方法來獲得特定的CaptureDeviceInfo對象。在使用設備截取多媒體數(shù)據(jù)前,還需要從CaptureDeviceInfo對象中獲得設備對應的 MediaLocator 對象。然后你可以直接使用 MediaLocator 來構造 Player 或 Processor 的實例,也可以用 MediaLocator 構造一個 DataSource 對象,然后將 DataSource 對象送入 Player 或 Processor 對象中。最后調(diào)用 start ()方法來截取多媒體數(shù)據(jù)。一個 JMF例子當你使用JMF進行編程以前, 你需要安裝JMF。同時在硬件上也有一些要求

14、。由于本文的代碼是在Windows 2000 下編寫和測試,因此文章中提到的操作系統(tǒng)需要的軟件都是與Windows有關的。雖然Java 是跨平臺的,但是JMF是個例外并不是所有的平臺上都實現(xiàn)了JMF。硬件和軟件要求硬件方面你需要與SoundBlaster兼容的聲卡,芯片最好使用奔騰III以上的芯片。內(nèi)存最好不小于64MB。同時你需要安裝下面的軟件: Windows95/98 ,Windows NT 4.0, Windows2000或 WindowsXP。 JMF 類和動態(tài)庫在 Windows 下安裝 JMF2.1當下載了JMF2.1 以后,運行jmf-2_1_1b-windows-i586.e

15、xe。該程序會將JMF2.1 安裝到你指定的目錄下。當安裝成功后,你需要確認一下安裝程序正確設定了CLASSPATH和 PATH環(huán)境變量。在CLASSPATH中需要包含jmf.jar和 sound.jar;在 PATH中需要包含JMF動態(tài)庫的路徑。JMFRegistry如果你希望使用視頻和音頻截取的設備,你需要確認安裝了這些設備的驅(qū)動程序。除此之外,你還需要運行JMFRegistry應用程序。 JMFRegistry 可以向 JMF注冊新的數(shù)據(jù)源、媒體處理器、插件、視頻和音頻截取設備,然后你才能夠在你的程序中使用它們。你只需要運行一次JMFRegistry就能注冊系統(tǒng)中所有的視頻和音頻截取設備

16、。當你運行了JMFRegistry后,會彈出圖一所示的窗口:不得用于商業(yè)用途僅供個人參考圖一通過 JMFRegistry注冊視頻和音頻截取設備選擇“ Capture Devices”標簽,然后按下“Detect Capture Devices”按鈕,程序?qū)⒆詣訖z測出系統(tǒng)中的視頻和音頻截取設備。在左邊的類表框中會列出所有檢測到的設備的名稱。在圖一中我們看到JMFRegsitery發(fā)現(xiàn)了 JavaSound audio capture、vfw:Logitech USB Video Camera:0和 vfw:Microsoft WDM Image Capture (Win32):1。單擊某個設備可

17、以看到該設備支持的視頻或音頻格式。如果JMFRegistry 無法檢測到設備,有可能是沒有正常安裝設備的驅(qū)動程序。例子程序由于 JMF2.1 比較復雜,我不可能在在例子中包含JMF2.1 支持的所有功能。因此我選擇了下面幾個在JMF中比較常用的功能:播放多媒體、注冊音頻和視頻截取設備、截取視頻和音頻。1播放多媒體在 JMF.java 中有一個 play ()方法。該方法可以播放用戶選擇的多媒體文件。 當播放多媒體文件時, 你需要一個 Player 對象。在例子中, dualPlayer 就是 Player 接口的實現(xiàn)對象。Player dualPlayer;在 Play ()方法中,通過使用F

18、ileDialog獲得媒體文件的路徑和文件名,并保存在filename中。try FileDialog fd =new FileDialog(this, "Select File", FileDialog.LOAD);fd.show();String filename = fd.getDirectory() + fd.getFile();.catch (Exception e) ;然后你需要通過媒體管理器Manager 間接創(chuàng)建一個Player對象。你可以使用Manager 類的 createPlayer()方法或者createProcessor()方法來獲得一個Playe

19、r對象或 Processor對象。在 play ()方法中,我使用的是createPlayer()方法。不得用于商業(yè)用途僅供個人參考dualPlayer = Manager.createPlayer(new MediaLocator(" + filename);有時你需要使用一個Player對象來控制多個其他的Player和 Controller對象,我們把這個Player對象稱為主對象,并把這些對象組成一個組。通過調(diào)用主對象中的start ()、 stop ()、 setMediaTime ()等方法就可以激活組中所有成員的相應方法。主對象控制所有的狀態(tài)變化和事件發(fā)布。然后使用ad

20、dControllerListerner()方法來將一個ControllerListener對象綁定到 Player對象上, Controller對象將向該ControllerListener對象發(fā)送事件消息。dualPlayer.addControllerListener(this);最后需要調(diào)用start ()方法來啟動Player對象。 start ()方法將Player對象的狀態(tài)設置為Started 。如果 Player沒有被實體化( Realize )或預取( Prefetch ), start()方法會自動執(zhí)行這些操作。dualPlayer.start();由于 JMF類實現(xiàn)了Co

21、ntrollerLister接口,因此需要實現(xiàn)該接口中的controllerUpdate()方法,該方法在Controller對象產(chǎn)生一個事件時被調(diào)用。public synchronized void controllerUpdate(ControllerEvent event) if (event instanceof RealizeCompleteEvent) Component comp;if (comp = dualPlayer.getVisualComponent() != null)add ("Center", comp);if (comp = dualPlay

22、er.getControlPanelComponent() != null)add("South", comp);validate();當 JMF類產(chǎn)生了一個RealizeCompleteEvent事件后, controllerUpdate()方法在界面上增加兩個Component對象,一個用于播放媒體,一個用于放置控制按鈕,例如播放、停止等。在運行程序的過程中,程序會產(chǎn)生下面的輸出。Starting player .source=,previous=Unrealized,current=Realizing,target=StartedOpen log file: C:te

23、stJavaJMFJMFjmf.logsource=,duration=不得用于商業(yè)用途僅供個人參考source=,previous=Realizing,current=Realized,target=StartedAdding visual componentAdding control panelsource=,previous=Realized,current=Prefetching,target=Startedsource=,previous=Prefetching,current=Prefetched,target=Startedsource=,previous=Prefetched

24、,current=Started,target=Started,mediaTime=,timeBaseTime=source=,previous=Started,current=Prefetched,target=Prefetched,mediaTime=前面提到,當調(diào)用start ()方法的時候,Player會切換到Started狀態(tài)。從上面列出的信息中可以看到Player對象的狀態(tài)從 Unrealized變成了 Started 。當 EndOfMedia 事件被激活時(這時Player對象完成了媒體文件的播放),狀態(tài)從Started變成了 Prefetched。圖二顯示了程序正在播放多媒體

25、文件時的情況。不得用于商業(yè)用途僅供個人參考圖二程序正在播放媒體文件2注冊音頻和視頻截取設備在例子中,注冊音頻和視頻截取設備的方法只在程序的內(nèi)部注冊這些設備,在程序外則不起作用。該方法的作用是當用戶的計算機上存在多和音頻和視頻截取設備時,告訴程序因該使用哪個設備和這些設備支持的音頻和視頻格式。因此在進行截取處理之前需要獲得設備的配置信息。在例子中,當在 Configure 菜單上按下 Capture Device 命令后,會彈出 CaptureDeviceDialog 對話框。如果在截取音頻或視頻前沒有設定設備的配置,也會彈出該對話框。圖三顯示了該對話框。圖三設備注冊對話框讓我們來看一下Capt

26、ureDeviceDialog類中的 init()方法:在初始化了界面之后,通過調(diào)用CaptureDeviceManager類的getDeviceList()方法:devices = CaptureDeviceManager.getDeviceList ( null );CaptureDeviceManager類使用查詢機制和一個注冊表來定位設備,然后將設備的信息放入CaptureDeviceInfo對象中返回。 我們還可以利用CaptureDeviceManager類來注冊新的設備。通過調(diào)用 getDeviceList()方法程序獲取了一個支持指定格式的設備的列表。在例子中,我將格式參數(shù)設定

27、為null ,這意味著設備可以使用任何格式。返回值被放入device變量中。如果getDeviceList()方法返回的是一個非空值,程序會將包含在其中的音頻設備名稱和視頻設備名稱分別放入兩個下拉列表中中,但是到目前為止我們還不知道哪些設備是音頻設備,哪些是視頻設備。我們可以通過CaptureDeviceInfo的 getFormat ()方法獲得 Format 對象組數(shù), 在 Format 對象中保存了設備支持的媒體格式。Format 類間接被AudioFormat 和 VideoFormat 類所繼承。因此我們可以利用設備支持的格式類型來區(qū)分設備的類型:不得用于商業(yè)用途僅供個人參考if (

28、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 = (CaptureDeviceInfo) devices.elementAt ( i );formats = cdi.getFormats();for ( int j=0; j<for

29、mats.length; j+ ) if ( formatsj instanceof AudioFormat ) audioDevices.addElement(cdi);break;else if (formatsj instanceof VideoFormat ) videoDevices.addElement(cdi);break;. . .上面的程序運行后,audioDevices ()中將包含所有的音頻設備,videoDevices ()中將保存所有的視頻設備。其中cdi 是CaptureDeviceInfo對象。然后將設備名稱填入下拉列表中:/ 將音頻設備顯示在下拉列表中for (

30、int i=0; i<audioDevices.size(); i+) cdi = (CaptureDeviceInfo) audioDevices.elementAt(i); audioDeviceCombo.addItem(cdi.getName();/ 將視頻設備顯示在下拉列表中for (int i=0; i<videoDevices.size(); i+) cdi = (CaptureDeviceInfo) videoDevices.elementAt(i);videoDeviceCombo.addItem(cdi.getName();然后程序顯示出當前選中的設備支持的格式

31、:displayAudioFormats();displayVideoFormats();下一步需要獲取用戶選中的音頻設備和視頻設備以及它們支持的格式,相關的方法是JMF類中的 getAudioDevice()、getVideoDevice()、 getAudioFormat ()和 getVideoFormat ()方法。然后將獲取的對象分別保存到audioCDI , videoCDI ,audioFormat和 videoFormat 中:不得用于商業(yè)用途僅供個人參考audioCDI = cdDialog.getAudioDevice();if (audioCDI!=null) audio

32、DeviceName = audioCDI.getName();Audio Device Name: " + audioDeviceName);videoCDI = cdDialog.getVideoDevice();if (videoCDI!=null) videoDeviceName = videoCDI.getName();Video Device Name: " + videoDeviceName);/ 獲得選中的多媒體格式videoFormat = cdDialog.getVideoFormat();audioFormat = cdDialog.getAudioF

33、ormat();3截取視頻和音頻使用 capture ()方法可以截取音頻和視頻數(shù)據(jù)。但是在使用該方法前需要確定是否已經(jīng)選中了視頻和音頻截取設備:if (audioCDI=null &#38;&#38; videoCDI=null)registerDevices();和 play ()方法類似,可以通過使用Manger 類中的靜態(tài)方法createPlayer()創(chuàng)建一個Player對象,該對象可以播放一個DataSource 對象中的數(shù)據(jù)流。Player createPlayer(MediaLocator sourceLocator)在例子中,我首先通過調(diào)用audioCDI 和

34、 videoCDI 的 getLocator()方法來獲得MediaLocator對象,然后利用Manager 類的createPlayer()方法創(chuàng)建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 )中獲得視頻和音頻數(shù)據(jù)源(DataSource 對象

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論