文章詳情頁
Java Media Framework 基礎教程
瀏覽:82日期:2024-06-13 13:36:00
內容: Java媒體架構基礎developerWorks出版,你主要資源的來源ibm.com/developerWorks作者:Eric Olson;pawenwen版權聲明:可以任意轉載,轉載時請務必以超鏈接形式標明文章原始出處和作者信息及本聲明作者:Eric Olson;pawenwen地址:http://www.matrix.org.cn/resource/article/43/43883_JMF.html關鍵詞: Java Media Framework內容表格1. 關于此指南2. 一個簡單的音頻播放器3. JMF用戶接口組件4. JMF概念5. 傳播和接收媒體6. 總結以及資源第一節. 關于此指南此指南包含的內容?Java媒體架構(JMF)是一個令人激動的通用的API,它允許Java開發者用許多不同的方法處理媒體。本指南主要通過使用工作的例子提供一個JMF的一些主要的特征的概述。閱讀完本指南后,你將會明白JMF體系結構中的主要播放功能。你同樣能正確的使用JMF,使用現存的例子和可為更多特殊功能擴展的源代碼。本指南包含著以下主題:· 下載和安裝JMF· 主要的JMF類以及它們在JMF體系結構中的應用· 播放本地的媒體文件· 為媒體的存取和操作制作以和圖形用戶界面(GUI)· 通過網絡傳播媒體· 通過網絡接收媒體幾乎所有的媒體類型的操作和處理都可以通過JMF來實現。全面的討論JMF所提供的所有特征已經超過了本指南的范圍,我們將使用三個簡單的媒體應用程序來學習此框架的構建模塊。通過這個方法,本指南將為你未來學習和實施更多特殊的應用提供準備。我應該使用此指南嗎?本指南會帶你學習使用JMF工作的基礎。為完成這些,我們會創建三個的獨立工作的例程序。每個例子都會建立前一個例子的基礎上,顯示JMF功能性的不同方面。在本指南中的例子假定你曾經使用過并且已經熟悉了Java程序語言。除了Java核心和JMF的類之外,我們會使用一些Java AWT和Swing類(用于創建GUI),也會有一些Java網絡類(用于在網絡中傳輸媒體)。對GUI和網絡類一些熟悉有助于你更快的明白觀點和這里的例子,但并非是閱讀本指南必須的。我們將學習的例程序如下· 一個簡單的音頻播放器(JMF的HelloWorld應用):這個字符界面的播放器通過在命令行中簡單的輸入媒體文件的名字就可以播放大多數的音頻類型。此音頻播放器的演示大體上顯示了JMF的特有的類。· 一個圖形界面的媒體播放器:我們將使用JMF內置的接口組件來建立圖形界面,所以在此練習中必須有一些圖形界面的編程經驗。這個媒體閱覽器演示使用了一些Java AWT和Swing類來為用戶顯示圖形組件。· 一個媒體廣播應用:此應用程序允許一個本地媒體文件通過網絡傳播。此程序能靈活的使媒體只傳輸到指定的網絡節點,或者傳輸到一個子網絡中的所有節點。此演示使用了一些Java的網絡APIs來在網絡中傳輸媒體。作為第三個練習的一部分,我們將修改圖形界面的播放器,讓其能接收并且播放媒體。跳至23頁觀看Resources,文章,指南,和其他參考書目的列表,這會幫助你學習到更到關于此指南包括的主題。安裝需求要運行此指南中的例程序,你需要如下的工具和組件:· Java 2 平臺,標準版,編譯和運行演示程序· Java媒體框架,版本2.1.1a或者更高· 一塊已經安裝并且配置號的適當的聲卡· 一臺或者多臺測試機器· 演示的源代碼文件在mediaplayer.jar中最后的一個演示應用顯示了JMF在網絡中的應用。如果需要,此演示能運行在一個獨立的機器上,使用此機器即是傳輸方也是接收方。可是要觀察到在網絡中使用JMF的所有功能,你仍然需要至少兩臺聯網的機器。在23頁中的Resources可下載Java 2平臺,完整的源代碼文件,以及其他一些完成本指南所需要的工具。下載安裝文件將JMF安裝到你的計算機中的第一步是在JMF的主頁中下載安裝文件,它同樣包括了JMF源代碼和API文檔的鏈接。23頁的Resources中有下載JMF的鏈接。目前,JMF有Windows, Solaris, Linux等版本,以及可運行在任何裝有虛擬機的計算機上一個純Java版本。為了增加性能,你需要下載一個與你操作系統所適應的版本。任何在一個操作系統JMF版本下書寫和編譯的代碼都可以方便的移植到另外的操作系統上。例如,如果你下載了一個Solaris版本的JMF并且編譯了一個類,這些類就可以在Linux上使用,不會有任何問題。作為選擇,你可以選擇下載純Java版本,或者跨平臺版本的JMF。這些版本沒有使用操作系統特有的庫文件。如果沒有合適的JMF版本適合的操作系統,那么跨平臺版本就是一個不錯的選擇。安裝JMF下載完JMF安裝程序后,雙擊安裝程序的圖標。大部分安裝程序都會有個選項,安裝本地庫到系統目錄中;例如,Windows版本安裝程序會有一個選項“Move DLLs to Windows/System directory.。最好將此選項選中,因為它能確保這些操作系統的庫文件能正確的安裝在安裝的過程中,你還需要選擇項目來更新系統的CLASSPATH和PATH變量。如果這些選項被關閉,那么在你編譯和運行本指南的例程序的時候就需要在classpath中引入JMF的jar文件。關于作者Eric Olson在Retek Inc工作的軟件工程師。它在Java平臺上有四年的工作經驗,并且在不同的基于Java的技術上富有經驗,包括JMF, Jini, Jiro, JSP, servlets, and EJBs。Eric畢業于St. Paul, MN的St. Thomas大學,獲得計算機科學的學位。他在IBM的SanFrancisco項目組工作,負責WebSphere商業組件。他同時再為Imation Corp.工作,負責存儲應用。現在,他正在開發零售行業的基于web的軟件解決方案。再業余的時間,Eric和PaulMonday在Stereo Beacon上合作—一個分布式的點對點的基于JMF的媒體播放器。聯系Eric [email protected].第二節. 一個簡單的音頻播放器瀏覽在本節中,我們將進行創建一個簡單的音頻播放器的第一個練習。本例將介紹Manager類和Player接口,中兩個都是建立大多數基于JMF應用的重要部分。本例的功能目標是在字符界面下播放本地的音頻文件。我們將學習此源代碼,并了解每一行所做的任務。完成本節后,你將會有一個基于JMF的可播放包括MP3, WAV, AU等多種音頻文件的演示程序。在本練習后的源代碼分類種可查詢文件SimpleAudioPlayer.java。引入必要的類SimpleAudioPlayer類中包括了一些調用,在其前幾行中需要引入所有必要的類:import javax.media.*;import java.io.File;import java.io.IOException;import java.net.URL;import java.net.MalformedURLException;The javax.media包是由JMF定義的多個包之一。javax.media是一個核心包,包括了定義Manager類和Player接口等。本節中,我們主要學習Manager類和Player接口,其余的javax.media類放在后面的章節中。除了引入javax.media聲明外,以上的代碼片斷引入了一些創建媒體播放器的輸入的聲明。Player接口在下面的代碼片斷中,創建一個公共類SimpleAudioPlayer并舉例定義一個Player變量:public class SimpleAudioPlayer {private Player audioPlayer = null;術語Player聽起來由點熟悉,因為它是建立在我們公用的音頻或者視頻播放器的基礎上的。事實上,這個接口的例子就像是當作它們的真實的副本。Players揭示了一個實體上的媒體播放器(如立體音箱系統或者VCR)涉及到功能上的方法。例如,一個JMF媒體播放器可以開始和結束一個媒體流。在本節種,我們將使用Player的開始和結束功能。在一個文件上創建一個Player使用JMF獲得一個特定媒體文件的Player實例非常簡單。Manager類在JMF中如同一個工廠制作許多的特殊接口類型,包括Player接口。因此,Manager類的責任就是創建Player實例,如下例:public SimpleAudioPlayer(URL url) throws IOException,NoPlayerException,CannotRealizeException {audioPlayer = Manager.createRealizedPlayer(url);}public SimpleAudioPlayer(File file) throws IOException,NoPlayerException,CannotRealizeException {this(file.toURL());}如果你看完本節的代碼,你可以注意到Manager類包含了創建一個Player實例的其他方法。我們會研究其中的一些,如在后面的章節中的DataSource或者MediaLocator的實例化。Player的狀態JMF定義了大量的一個Player實例可能存在的不同狀態。如下:· Prefetched· Prefetching· Realized· Realizing· Started· Unrealized使用這些狀態因為使用媒體常常是資源非常密集的,由JMF對象揭示的許多方法都是不閉塞的,允許一系列事件監聽的狀態改變的異步通知。例如,一個Player在它可以啟動之前,必須經過Prefetched和Realized狀態。由于這些狀態的改變都需要一些時間來完成,JMF媒體應用可以分配一個線程來初始化創建Player實例,然后再繼續其他的操作。當Player準備就緒的時候,它會通知應用程序其狀態已經改變。在一個如同我們的這樣簡單的程序中,多功能性的類型并不是很重要。處于這個原因,Manager類也提供了一些創建Realized player的有用方法。調用一個createRealizedPlayer()方法來阻塞調用線程,直到player達到Realized狀態。為了調用一個無阻塞的創建player的方法,我們在Manager類中使用了一個createPlayer()方法。下面的一行代碼中創建了一個我們需要在例程序中使用的Realized player:audioPlayer = Manager.createRealizedPlayer(url);啟動和停止Player設定一個Player實例的啟動或是停止就如同調用Player的一個簡單的認證方法,如下所示:public void play() {audioPlayer.start();}public void stop() {audioPlayer.stop();audioPlayer.close();}調用SimpleAudioPlayer類中的play()方法來實現調用Player實例的start()方法。調用此方法后,你能聽到本地的喇叭的聲音文件。同樣的,stop()方法使player停止并且關閉掉Player對象。對于讀取和或者播放本地媒體文件來說,關閉Player實例釋放所有資源是一個有用的方法。因為這是一個簡單的例子,關閉Player是終止一個會話可接受的方法。但是在實際的應用中,你需要小心的確認在除掉Player之前必須要關閉掉。一但你已經關閉掉player,在再次播放一個媒體之前你必須要創建一個新的Player實例(等待它的狀態改變)。建立一個SimpleAudioPlayer最后,這個媒體播放應用程序要包含一個可以從命令提示行中輸入命令而調用的main()方法。在此main()方法中,我們將調用創建SimpleAudioPlayer的方法:File audioFile = new File(args[0]);SimpleAudioPlayer player = new SimpleAudioPlayer(audioFile);在播放音頻文件之前的唯一的一些事情就是調用已經創建的音頻player的方法play(),如下所示:player.play();要停止和清除掉音頻player,在main()方法中也應該有如下調用:player.stop();編譯和運行SimpleAudioPlayer通過在命令提示行輸入javac SimpleAudioPlayer.java來編譯例程序。所創建的文件SimpleAudioPlayer.class在當前工作目錄中。然后在命令提示行中鍵入如下命令來運行例程序:java SimpleAudioPlayer audioFile將audioFile替換成你本地機器上的音頻文件。所有的相對文件名都試相對于當前的工作目錄。你會看到一些當前正在播放文件的標志信息。要終止播放,按下回車鍵。如果編譯失敗,確認JMF的jar文件已經正確的包含在CLASSPATH環境變量中。第三節. JMF用戶界面組件播放視頻在前一節中,我們學習了建立一個通過字符界面播放音頻文件的應用程序。JMF中一個最重要的特點就是你不需要為了配置媒體播放器而去了解媒體文件的格式;一切都內置了。舉一個例子,再我們前面的例子中,需要使用MP3格式的時候,我們不需要讓應用程序為一個MP3文件建立一個特殊的Player。如同你將會再本節所見到的,對于視頻文件的操作同樣有效。JMF有所有媒體文件類型接口的詳細資料。處理視頻媒體與音頻最大的不同就是,我們必須建立一個能播放視頻的顯示屏幕。幸運的是,JMF能處理許多的這些資料。如同再上例一樣我們會建立一個Player對象,并且使用很多的可視組件來直接從JMF對象中創建我們的可視的媒體瀏覽器。本節中,我們將學習兩個例程序。In this section, we'll walk through the second example application. 請再后面的練習的源代碼分布中查閱MediaPlayerFrame.java。關于例子在本節中,我們將創建一個能顯示和運行本地音頻和視頻媒體的應用程序。作為練習的一部分,我們將研究JMF內置的一些GUI組件。熟悉AWT和Swing將有助于你理解本例,但這并不是必須的。除非需要直接涉及到JMF的GUI組件,或者我們是不會詳細介紹源代碼的。你可以在源代碼的注釋中找到這里未涉及的詳細說明。本例中我們使用的許多概念,類和方法都和第一個例子的類似。建立Player的基本操作大都一樣。最大的不同就是我們需要對Player對象專研更深一點,特別當需要從Player獲取媒體信息的時候。如何開始視頻播放器例子被設計得如同音頻播放例子一樣通過命令行來運行,但是本例需要建立在GUI基礎上。如同在上節一樣,我們先通過媒體文件名調用應用。然后,應用程序顯示一個帶有可操作媒體組件的窗體。在MediaPlayerFrame開始的一行中我們定義了類并擴展自,javax.swing.Jframe類。這就是使媒體播放器如同一個在桌面上的單獨窗體的方法。任何客戶機程序創建了本媒體播放對象后都可以通過調用Jframe類中定義的show()方法來顯示。下面是一個MediaPlayerFrame正在播放MPEG電影的屏幕截圖:獲取GUI組件Player界面有一些方法來獲取已選擇可視組件的涉及。在MediaPlayerFrame中,我們使用如下組件:· player.getVisualComponent()是一個播放所有視頻媒體的可視組件。· player.getControlPanelComponent() 是一個操作時間軸的可視組件(包括開始,停止,回放),也包含了一些媒體流的有用信息。· player.getGainControl().getControlComponent() 是操作音量(增加)的可視組件。getGainControl()方法返回一個GainControl實例,可用于改變節目的增加等級。使用可視化組件上面的界面方法都返回一個java.awt.Component類的實例。沒個實例都視可加載到我們窗體上的可視組件。這些組件都與Player有直接的聯系,所以在這些組件上的所有可視元素的處理都會產生Player播放媒體后相應的變化。在我們將這些組件加入到我們的窗體的之前,必須要保證它們不為空。因為并不是所有的媒體播放器包括每一種可視組件,我們只需添加相關播放器類型的組件。比如,一般來說一個音頻播放器沒有可視組件,所以getVisualComponent()就要返回空。你不會想在音頻播放器窗體上添加可視組件的。獲得媒體的特殊控制一個Player實例也可以通過getControl()和getControls()方法來暴露其控制,getControls()返回一個控制對象集,而getControl()返回一個控制。不同的播放器類型可選擇為特殊的操作來暴露控制集去指定的媒體類型,或者用于獲取該媒體的傳輸機制。如果你在寫一個只支持某些媒體類型的播放器,你需要依靠某些在Player實例中可用Control對象。由于我們的播放器是非常抽象的,被設計于播放多種不同媒體類型,我們簡單的為用戶暴露所有的Control對象。如果找到任何擴展的控制集,我們就可使用getControlComponent()方法來增加相應的可視控件到標簽面板上。通過這個辦法,用戶就可以觀察播放器上的所有組件。以下代碼片斷將所有的控制對象暴露給用戶:Control[] controls = player.getControls();for (int i = 0; i < controls.length; i++) {if (controls[i].getControlComponent() != null) {tabPane.add(controls[i].getControlComponent());}}為了使一個真實的應用程序能用Control實例做一些有用的事(除了能顯示可視組件之外),應用程序需要知道該Control的特殊類型,并分配它。此后,應用程序就可使用這些control來控制媒體節目了。例如,如果你知道你經常使用的媒體暴露javax.media.control.QualityControl類型的Control,你能使用QualityControl界面,之后在QualityControl界面上通過調用各種方法來改變性質設定。使用一個MediaLocator在我們新的基于GUI的媒體播放器和我們的第一個簡單播放器之間最大的不同就是,我們使用一個MediaLocator對象而不是URL來創建Player實例,如下所示:public void setMediaLocator(MediaLocator locator) throws IOException,NoPlayerException, CannotRealizeException {setPlayer(Manager.createRealizedPlayer(locator));}我們將在稍后的章節中討論這個變化的原因。目前,在網絡上資源站點上,關于MediaLocator對象和URL的描述被認為是非常相似的。事實上,你可以從一個URL創建一個MediaLocator,也可以從MediaLocator獲取到URL。我們的新媒體播放器一個URL中創建一個MediaLocator,并使用該MediaLocator通過文件創建了一個Player。編譯和運行MediaPlayerFrame通過在命令提示行輸入javac MediaPlayerFrame.java來編譯例程序。在工作目錄下將創建一個名為MediaPlayerFrame.class的文件。在命令提示行中鍵入如下來運行例程序:java MediaPlayerFrame mediaFile你需要用你本機上的一個媒體文件來替換掉mediaFile(音頻或者視頻文件都可以)。所有的相對文件名都是相對于當前工作目錄。你會看見一個顯示控制媒體文件的GUI控制集的窗口。欲了解JMF支持的音頻和視頻文件列表,在23頁的資源。如果初始編譯時失敗,請確認JMF的jar文件已經包含在當前的CLASSPATH環境變量中。MediaPlayerFrame在行動在本節前你看見的一個視頻播放器正在播放MPEG視頻文件的屏幕截圖。下面的屏幕截圖顯示了一個音頻播放器正在播放一個MP3文件:要更多的學習本練習中的例子,查看完成的MediaPlayerFrame源代碼。第四節. JMF概念JMF體系結構你曾見過了使用JMF播放本地媒體文件是多么的容易,現在我們將后退一步,來看看一幅是如何通過JMF創建了如此成熟的基于媒體的應用程序的大的畫面,是如何通過JMF創建了如此成熟的基于媒體的應用程序。全面的了解JMF體系結構是沒有意義的,本節將給你一個大體的概念,關于高級的JMF組件是如何組合起來創建想得到的東西。JMF的組件結構非常的靈活,它的組件一般可以分成三個部分:· Input描述某種被用于在進程休息的時候作為一個輸入的媒體。· process執行某些輸入上的活動。一個過程有一個明確的輸入和輸出。大量的過程可用, 能被用于一個輸入或者一批輸入。這些過程能被聯系起來,一個過程的輸出被用于另外一個過程的輸入。在這種風格中,大量的過程可能被應用于一個輸入。(這段期間是可選擇的——我們開始的兩個例子沒有包含真正的數據過程,只有一個來自文件的輸入和一個通過Player的輸出。)· Output 描述了媒體的某些目的地。從這些描述中,你可以想象到JMF組件體系結構聽起來就好像在一個典型的立體聲系統或者VCR之后。很容易設想到,使用JMF就如同打開電視或者在立體聲音箱系統下調節聲音的風格。例如,錄制喜愛的電視節目的簡單的動作能在這些組件的基礎中:· Input 是電視廣播流,在同一個頻道運輸音頻和視頻。· Process 是一個記錄設備(就是,一個VCR或者許多的數字設備)轉換模擬或者數字音頻視頻廣播流成適合復制到磁帶或其他媒體上的格式。· Output 是記錄已格式化軌跡(音頻和視頻)到某些類型的媒體上。JMF資料處理模式以下圖片說明了JMF數據處理模塊并對每個類型給出了例子:使用此模式,很容易明白我們前面的兩個例子,從文件中輸入音頻和視頻并輸出到本地計算機上。在后面的章節中,我們也會談論一些通過傳播和接收音頻媒體的JMF網絡功能。處理模型例子將JMF的輸入,處理和輸出模式聯系起來,我們能開始想象許多基于媒體的操作都可能通過JMF完成。一個例子,轉換一種媒體類型為其他類型并將其輸出存儲到一個新的文件。舉一個例子,我們想要在不損壞原始文件的前提下轉化一個WAV格式的音頻文件為MP3格式。以下的過程模式插圖,就是我們將開始執行轉換的步驟:本例的輸入是一個WAV文件。它被一個媒體格式轉換工具加工,并輸出到一個新的文件。現在,讓我們看看JMF API中的這個模式的每一步。我們使用輸入,處理和輸出模式作為概念上的路標。JMF輸入再JMF中,一般由一個MediaLocator對象來描述一個輸入。如先前規定的,MediaLocator的外觀和行為都非常象一個URL,這樣它可以唯一確定網絡上的一個資源。事實上,使用一個URL來創建一個MediaLocator是完全可能的;我們在前面的兩個例子中就是這樣做的。為了我們的媒體轉換例子,我們需要建立一個MediaLocator來描述最初的WAV文件。如同我們將在后面的章節中見到的,一個MediaLocator也可以用于描述一個跨越網絡中媒體流。在這個案例中,MediaLocator會描述傳播的URL――很像一個被URL指定的在Web上的資源,用于取代指定一個本地文件系統的文件來建立MediaLocator。一個MediaLocator和一個URL之間的不同要成功的建立一個URL對象,需要適當的java.net.URLStreamHandler安裝于系統中。這個流處理的用途是能夠處理被URL描述的流類型。一個MediaLocator對象并沒有這個需要。例如,我們的下個應用程序將使用實時傳輸協議(RTP)在網絡上傳輸音頻。由于多數的系統都未為RTP協議安裝一個URLStreamHandler,所以創建一個URL對象會失敗。在這個應用中,只有MediaLocator對象會成功。要理解更多關于URL對象以及創建和注冊一個URLStreamHandler的信息,查閱JDK幫助文檔(查看23頁資源)。JMF處理機當我們使用JMF的時候,應用程序的處理機組件被Processor接口實例描述。你需要已有些熟悉Processor,它擴展至Player接口。由于Processor繼承直Player接口,它同樣也從Player繼承所有可用屬性。另外,Processor增加了兩個屬性:Configuring和Configured。這些擴展的屬性(和與之關聯的方法)用于Processor從輸入流收集信息時的通信。在我們的最后的例程序中,我們將建立一個Processor用于將MP3編碼格式的音頻轉換成適合在網絡上傳播的格式。在稍后的板塊中我們會討論創建一個簡單的Processor的步驟。JMF輸出有少許的方法用于描述JMF中處理模式的輸出狀態。最簡單的(并且我們將在最后一個例子中使用的)是javax.media.DataSink接口。一個DataSink讀取媒體內容并且將其傳送到一些目的地。本節中最開始的音頻格式轉換過程中,MP3(輸出)文件將被DataSink描述。在我們最后一個例子中,我們將使用一個DataSink在實際上完成網絡中傳播音頻媒體的工作。一個DataSink是在Manager類中,由指定一個DataSource(輸入到DataSink)和一個MediaLocator(輸出到DataSink)完成的。一個DataSource實例描述可用于Players,Processors和DataSinks的輸入數據。一個處理機的輸出也被描述成一個DataSource對象。這就是為什么處理器能彼此聯系起來,在同一媒體數據中完成多種操作。這也是來自Processor的輸出能作為輸入被Player或者DataSink使用的原因(它可將媒體傳遞到輸出目的地)。一個DataSink的最后目的文件由一個MediaLocator對象說明。如同前面一樣,MediaLocator描述一個網絡資源;這就是媒體流將被傳遞的地方。第五節.傳播接收媒體JMF和實時傳輸協議(RTP)許多的友善網絡的特征直接建立在JMF中,這些使為客戶端程序通過網絡傳輸和接收媒體非常容易。當在一個網絡上的一個用戶想要接收任何種類的媒體流的時候,它不需要在觀看媒體前等待全部的廣播下載到機器上;用戶可以實時的觀看廣播。在流媒體中些提出了這個概念。通過流媒體,一個網絡客戶端能接收到其他機器上廣播的音頻,甚至獲取正在發生的實況視頻廣播。在IETF RFC 1889中定義了實時傳輸協議(RTP)。發展在快速和可靠的狀態下通過網絡傳輸時間極其敏感的數據,RTP在JMF中用于提供給用戶向其他網絡節點中傳輸媒體流的方法。在本節中,我們將學習我們的最后一個例程序。這里,你將學習到如何傳輸一個存儲在一臺機器上的MP3文件到另外的在同一個網絡的機器上去。實際的MP3源文件并不從主計算機上移除,它也不使復制到其他機器上去;事實上它將會轉換成能使用RTP傳輸的文件格式并通過網絡發送。一旦被一個客戶端接收到,源文件(現在是RTP信息包的形式)可以再次傳輸,這一次是在接收機器上可播放的一種格式。在MediaTransmitter.java文件中源代碼查看學習以下練習。設置處理模式我們可以在前面的章節中定義的處理模式的基礎下來討論我們的最終的例子。在傳輸機器上,處理模式看起來像這樣:事實上,MediaTransmitter對象源代碼包括了以下三行:private MediaLocator mediaLocator = null;private DataSink dataSink = null;private Processor mediaProcessor = null;這三個實例變量可以直接映射到前面的處理模式圖表,如下:· mediaProcessor變量是我們的處理器;它將負責轉換音頻文件從MP3文件模式到一個適合通過RTP協議傳輸的格式。· dataSink變量是我們的輸出塊。· 當我們建立DataSink時我們需要指定一個MediaLocator,它是DataSink的目的文件。當我們通過運行DataSink我們的處理過的媒體,它將傳輸到我們在MediaLocator中指定的地點。RTP MediaLocator在前面的兩個練習中,我們通過從文件中獲得的一個URL建立了MediaLocator實例。 在本練習中,我們必須建立一個MediaLocator來描述網絡上媒體傳播輸出流;換句話說,我們必須創建一個能我們的音頻傳播的目的地的MediaLocator。一個RTP MediaLocator符合如下規則,看起來就像一個典型的URL:rtp://address:port/content-type讓我們看看上面URL規范的每一段:· address 是將傳輸的媒體的地址。以單播的模式傳輸(一個專用IP地址),地址將會是有意接收的機器的IP地址。以廣播的模式傳播(到子網中的所有機器),地址將會是以255作為最后的一塊的子網地址。舉個例子,如果我再子網中可指定地址為192.168.1和想要傳播到子網中的所有節點,我可以指定192.168.1.255作為地址;這樣允許子網中的每個節點監聽廣播媒體。· port 必須是被傳輸者和接收者都允許的一個端口。· content-type 是媒體流類型。在我們的案子中,這個將會是音頻。下面的一個簡單的RTP傳播MediaLocator例子會讓所有在指定網絡中的機器接收到媒體流:rtp://192.168.1.255:49150/audio創建一個處理機在setDataSource()方法中我們首先要做的就是創建一個Processor實例。下面的Processor的職責是轉換MP3音頻媒體為一個RTP來表示:public void setDataSource(DataSource ds) throws IOException,NoProcessorException, CannotRealizeException, NoDataSinkException {mediaProcessor = Manager.createRealizedProcessor(new ProcessorModel(ds, FORMATS, CONTENT_DESCRIPTOR));在Manager類中,我們能創建一個Processor對象,通過兩種方法中的一種:createProcessor()或者createRealizedProcessor()。你很可能會注意到這兩個方法樣式的顯示和前面例子中創建一個Player的方法很相似。在目前的例子中,我們將創建一個已實現的Processor。我們這樣做是因為我們使用的應用非常簡單,在Processo處于Realized狀態時我們不需要關心任何真實的工作。創建一個ProcessorModel創建一個已實現的Processor,我們需要創建一個為Processor描述輸入和輸出媒體類型的ProcessorModel實例。為了創建ProcessorModel,我們需要下面的一些:· 一個DataSource,將被處理的媒體(輸入文件)。· 一個javax.media.Format數組,描述輸入媒體的格式。· 一個javax.media.protocol.ContentDescriptor實例,為我們的處理機描述輸出格式。傳送者的DataSource是通過一個參數傳遞到此方法。定義輸入和輸出格式因為我們的MediaTransmitter類會被時常用于將輸入媒體格式(MP3)轉換成一種輸出格式(音頻RTP),中學對象被定義成靜態。我們創建一個新的javax.media.format.AudioFormat實例用于描述媒體輸入類型(在java幫助文檔中查看可用格式)。這就是我們的處理機可以獲取MP3音頻文件的原因。我們也創建一個javax.media.protocol.ContentDescriptor實例來描述想要處理機輸出的。在我們的案子中,這是一個RTP媒體流。這就是為什么我們的處理機可以只制造RTP流。下面的代碼片斷顯示了我們如何設置格式和內容描述符變量,用于創建ProcessorModel對象:private static final Format[] FORMATS = new Format[] {new AudioFormat(AudioFormat.MPEG_RTP)};private static final ContentDescriptor CONTENT_DESCRIPTOR =new ContentDescriptor(ContentDescriptor.RAW_RTP);連接輸入,處理機和輸出現在我們有一個處于Realized狀態的Processor,我們需要設置DataSink以能實際上傳播RTP媒體。創建DataSink是簡單的大概使用另外一個調用給Manager對象,如下所示:dataSink = Manager.createDataSink(mediaProcessor.getDataOutput(),mediaLocator);createDataSink()方法獲取新Processor的輸出(作為一個DataSource參數)和MediaLocator對象,我們和MediaTransmitter對象同時建立的。通過這樣,你能開始我們的不同的組件是如何在處理模式中聯系起來的:我們從一個Processor中獲取輸出并使用他們作為輸入到其他組件。在這個特殊的應用中,Processor輸出用于傳輸媒體的DataSink的一個輸入。創建一個DataSource實例在這點上,我們全部都是做和設置我們的媒體播放器的廣播傳輸。我們需要創建DataSource對象,我們用于創建處理機(就是,在我們的MediaTransmitter中,參數傳遞到setDataSource()方法)。下面是創建一個DataSource實例的代碼:File mediaFile = new File(args[1]);DataSource source = Manager.createDataSource(new MediaLocator(mediaFile.toURL()));這段代碼是在MediaTransmitter對象中的vmain()方法。這里我們通過從命令行輸入的第二個參數創建一個File對象。我們通過文件創建一個MediaLocator,而后通過位置創建一個DataSource。這個新近創建的DataSource是一個涉及到傳送者的輸入文件。我們能使用這個DataSource初始化傳輸者。開始和停止MediaTransmitter我們通過調用其中的startTransmitting()方法來開始MediaTransmitter,如下所示:public void startTransmitting() throws IOException {mediaProcessor.start();dataSink.open();dataSink.start();}這個方法首先開啟處理機,然后打開并啟動DataSink。在這個調用后,接收機器就可在媒體傳送者上監聽。停止傳輸者是非常簡單的。以下代碼將DataSink和Processor都停止和關閉掉:public void stopTransmitting() throws IOException {dataSink.stop();dataSink.close();mediaProcessor.stop();mediaProcessor.close();}編譯和運行MediaTransmitter通過在命令行中輸入javac MediaTransmitter.java來編譯例程序,可在你的工作目錄中生成一個同名的.class文件。要運行例程序,在命令提示行中輸入以下代碼:java MediaTransmitter rtpMediaLocator audioFile此例將創建一個myAudio.mp3文件的媒體廣播。不要忘記將rtpMediaLocator替換成一個媒體傳輸的RTP URL,如同先前討論的。你同樣也需要將audioFile替換成你本機的音頻文件名。所有的相對文件名都是相對于當前工作目錄的。你會看見一些信息標志正在播放的文件。按下Enter鍵來停止播放。為傳送者的一個例命令行交互如下:java MediaTransmitter rtp://192.168.1.255:49150/audio myAudio.mp3如果初始編輯失敗,確定JMF的jar文件包含CLASSPATH環境變量中。要近一步探索本程序和練習,請查閱MediaTransmitter源代碼。接收傳輸的媒體現在你可能會問,“如果沒有人可以看或者收聽的話,這個傳播媒體有什么好的?幸運的是,設定一個接收傳播媒體的客戶端只需要對我們在第二個例程序的MediaPlayerFrame源代碼做很小的改動。MediaPlayerFrame類需要一個很小的調節來接收和播放音頻文件。在main()方法中,你需要注釋掉如下的一行:mpf.setMediaLocator(new MediaLocator(new File(args[0]).toURL()));并且輸入如下的一行:mpf.setMediaLocator(new MediaLocator(args[0]));這個簡單的改動允許我們通過String來創建一個MediaLocator對象,而不是通過創建一個File來創建MediaLocator。其他代碼都一樣。指定RTP URL在12頁的說明編譯和運行MediaPlayerFrame介紹了如何編譯和運行MediaPlayerFrame例程序。這唯一的不同就是你需要為傳輸者指定RTP URL。為接收者的例命令行交互如下:java MediaPlayerFrame rtp://192.168.1.255:49150/audio運行網絡媒體傳送者的注意事項如果你在網絡上只有權使用一臺機器,你仍然可以運行傳輸程序。當你啟動傳送程序的時候,你可以即使用RTP URL傳輸地址,也可指定你工作的機器的機器地址。為了能夠調節傳輸,在開始前接收者必須使用精確的同樣的RTP URL。如果你運行本例真實的網絡版本,每臺你使用的機器都需要安裝JMF,不論是傳輸還是接收媒體流。這是必須的,因為不論是傳送程序還是接收程序都大量的使用了JMF的API。在任一個案子中,確認在指定的RTP URL中使用了相同的地址和端口;否則媒體傳輸是不會工作的。第六節. 約束和資源摘要我希望本指南能給你提供如何使用JMF的API的有用的瀏覽。我們建立了三個小的應用程序來播放本地的音頻和視頻,也通過網絡傳播和接收媒體。這些應用程序的源代碼中包含了很多的javadoc樣式的注釋。這就有助于你理解你剩余的問題。許多JMF的主題在本指南中并沒有涉及。實際上,我們更關注JMF的基本概念和應用;在此基礎上,我們能輕易地擴展學習的其他范圍。要更深入JMF的應用程序,你可能想要學習下面的面板中所提到的主題。更近一步的閱讀本指南中的主題,查閱23頁的資源。高級主題大量的值得做的練習在本指南的范圍之上。在簡單的說明之下自己更進一步的學習,你可以擴展我們的應用程序代碼,也可以反展你的JMF相關知識。使用以下的練習開始:· 媒體捕獲:JMF包含了豐富的API來捕獲媒體數據。如果你對使用JMF捕獲媒體感興趣,你可以使用javax.media.CaptureDeviceManager類和javax.media.protocol.CaptureDevice接口的API來學習。對于一個高級的練習,考慮使用CaptureDeviceManager和CaptureDevice接口來增加媒體捕獲功能到媒體播放應用程序的GUI版本上。· 會話管理:由于本指南是一個JMF的說明,我們使輸出表現非常的簡單,僅僅實現了javax.media.DataSink輸出。另外的輸出表示是使用javax.media.rtp.SessionManager。這個管理類允許客戶端創建并監視他們的RTP流和連接。通過SessionManager并隨后創建流,它可能非常的接近監視RTP會話。作為一個高級的練習,轉換我們的地三個演示程序來使用SessionManager,然后監聽流出的RTP流已經哪些客戶端在收聽。· 使用JMF的多點傳送:我們的廣播演示應用程序說明了如何傳送一個網絡的媒體到另外一個網絡的一或多臺機器上去。它也可能使用JMF中的多點傳輸協議來提供給更復雜,多用戶的網絡。JMF用戶指南提供了一個使用JMF的多播協議的更深入的探討。更進一步追蹤本主題查看23頁資源。· 傳輸視頻: 我們的最后一個演示應用程序著眼于如何傳輸一個MP3音頻文件,但是JMF也能夠通過網絡傳遞視頻。關注API文檔中的Format和ContentDescriptor類獲得如何使用的更好的方法。· 導入/導出RTP媒體流: JMF同樣允許將RTP流保存為文件以便將來使用。舉一個實例,一個遠程電信會議可以保存下來以后再看。由于流已經保存再RTP格式中,已經不需要再次轉換,這樣可導致傳輸程序的性能改進。通過一個文件而不是URL來設置DataSink對象中輸入/輸出MediaLocator。你會再JMF用戶指南中發現更深層次的主題探討。資源JMF· 下載mediaplayer.jar,本指南中使用的完整的例源代碼。· JMF主頁 (http://www.javasoft.com/jmf)是最好的探討JMF更多信息的資源。· 你可以找到JMF說明書(http://java.sun.com/products/java-media/jmf/2.1.1/specdownload.html),再Java開發者聯盟上包括API文檔和JMF用戶指南。你必須有權使用所有的這些資源,如果你想做任何更深入的JMF編程的話。· 官方的JMF支持文件格式 頁面(http://java.sun.com/products/java-media/jmf/2.1.1/formats.html) 列出了所有可為JMF辨識并播放的文件格式。此文件格式頁面也包括了學習更多關于捕獲設備和RTP格式的參考。· MPEG-4 Video for JMF (http://www.alphaworks.ibm.com/tech/mpeg-4), 來自IBMalphaWorks, 是一個JMF的視頻編解碼器。RTP· IETF RTP RFC (http://www.ietf.org/rfc/rfc1889.txt) 非常詳細的描述了RTP協議。· 查看 JMF API Guide(http://java.sun.com/products/java-media/jmf/2.1.1/specdownload.html) ,有許多有關于RTP協議和描述以及它是如何在JMF上應用的。· 哥倫比亞大學有一個比較有用的RTP FAQ(http://www.cs.columbia.edu/~hgs/rtp/faq.html).Java技術· Java 2 Platform, Standard Edition (http://java.sun.com/j2se/) 可從sun公司獲得。· sun的指南關于JFC/Swing (http://java.sun.com/docs/books/tutorial/uiswing/index.html)和 AWT (http://java.sun.com/docs/books/tutorial/information/download.html#OLDui) 是非常好的能學習到很多關于Java程序語言中GUI編程的好地方。· 另外一個sun指南學習network programming 基礎(http://java.sun.com/docs/books/tutorial/networking/index.html)。多點傳輸協議· Explicit Multicast (XCAST)(http://oss.software.ibm.com/developerworks/opensource/xcast/) 是IP多點傳輸的一種形式,為非常多的多點傳輸組設計提供可升級的支持,這些組有些少量的參與者代表。XCAST 代碼得到了IBM Common Public License的認可。· Todd Montgomery 的 MTP page (http://www.nard.net/~tmont/rm-links.html),在這里你能找到一個廣泛的涉及到多點傳輸協議的列表。附加資源· 你可以在developerWorks Java technology zone (http://www-106.ibm.com/developerworks/java/)中找到許多的關于Java各方面的內容。· 查看 developerWorks tutorials page(http://www-105.ibm.com/developerworks/education.nsf/dw/java-onlinecourse-bytitle?OpenDocument&Count=for a complete listing of free tutorials. Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd Java媒體架構基礎developerWorks出版,你主要資源的來源ibm.com/developerWorks作者:Eric Olson;pawenwen版權聲明:可以任意轉載,轉載時請務必以超鏈接形式標明文章原始出處和作者信息?
標簽:
Java
相關文章:
排行榜