<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    KevinGong

      BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
      15 Posts :: 1 Stories :: 9 Comments :: 0 Trackbacks

    最近一個(gè)項(xiàng)目要用到JMF,所以搜集了點(diǎn)資料,以供自己學(xué)習(xí)!
    內(nèi)容表格
    1. 關(guān)于此指南
    2. 一個(gè)簡(jiǎn)單的音頻播放器
    3. JMF用戶(hù)接口組件
    4. JMF概念
    5. 傳播和接收媒體
    6. 總結(jié)以及資源



    第一節(jié). 關(guān)于此指南

    此指南包含的內(nèi)容?

    Java媒體架構(gòu)(JMF)是一個(gè)令人激動(dòng)的通用的API,它允許Java開(kāi)發(fā)者用許多不同的方法處理媒體。本指南主要通過(guò)使用工作的例子提供一個(gè)JMF的一些主要的特征的概述。閱讀完本指南后,你將會(huì)明白JMF體系結(jié)構(gòu)中的主要播放功能。你同樣能正確的使用JMF,使用現(xiàn)存的例子和可為更多特殊功能擴(kuò)展的源代碼。

    本指南包含著以下主題:
    · 下載和安裝JMF
    · 主要的JMF類(lèi)以及它們?cè)贘MF體系結(jié)構(gòu)中的應(yīng)用
    · 播放本地的媒體文件
    · 為媒體的存取和操作制作以和圖形用戶(hù)界面(GUI)
    · 通過(guò)網(wǎng)絡(luò)傳播媒體
    · 通過(guò)網(wǎng)絡(luò)接收媒體

    幾乎所有的媒體類(lèi)型的操作和處理都可以通過(guò)JMF來(lái)實(shí)現(xiàn)。全面的討論JMF所提供的所有特征已經(jīng)超過(guò)了本指南的范圍,我們將使用三個(gè)簡(jiǎn)單的媒體應(yīng)用程序來(lái)學(xué)習(xí)此框架的構(gòu)建模塊。通過(guò)這個(gè)方法,本指南將為你未來(lái)學(xué)習(xí)和實(shí)施更多特殊的應(yīng)用提供準(zhǔn)備。
    我應(yīng)該使用此指南嗎?

    本指南會(huì)帶你學(xué)習(xí)使用JMF工作的基礎(chǔ)。為完成這些,我們會(huì)創(chuàng)建三個(gè)的獨(dú)立工作的例程序。每個(gè)例子都會(huì)建立前一個(gè)例子的基礎(chǔ)上,顯示JMF功能性的不同方面。
    在本指南中的例子假定你曾經(jīng)使用過(guò)并且已經(jīng)熟悉了Java程序語(yǔ)言。除了Java核心和JMF的類(lèi)之外,我們會(huì)使用一些Java AWT和Swing類(lèi)(用于創(chuàng)建GUI),也會(huì)有一些Java網(wǎng)絡(luò)類(lèi)(用于在網(wǎng)絡(luò)中傳輸媒體)。對(duì)GUI和網(wǎng)絡(luò)類(lèi)一些熟悉有助于你更快的明白觀點(diǎn)和這里的例子,但并非是閱讀本指南必須的。

    我們將學(xué)習(xí)的例程序如下
    · 一個(gè)簡(jiǎn)單的音頻播放器(JMF的HelloWorld應(yīng)用):這個(gè)字符界面的播放器通過(guò)在命令行中簡(jiǎn)單的輸入媒體文件的名字就可以播放大多數(shù)的音頻類(lèi)型。此音頻播放器的演示大體上顯示了JMF的特有的類(lèi)。
    · 一個(gè)圖形界面的媒體播放器:我們將使用JMF內(nèi)置的接口組件來(lái)建立圖形界面,所以在此練習(xí)中必須有一些圖形界面的編程經(jīng)驗(yàn)。這個(gè)媒體閱覽器演示使用了一些Java AWT和Swing類(lèi)來(lái)為用戶(hù)顯示圖形組件。
    · 一個(gè)媒體廣播應(yīng)用:此應(yīng)用程序允許一個(gè)本地媒體文件通過(guò)網(wǎng)絡(luò)傳播。此程序能靈活的使媒體只傳輸?shù)街付ǖ木W(wǎng)絡(luò)節(jié)點(diǎn),或者傳輸?shù)揭粋€(gè)子網(wǎng)絡(luò)中的所有節(jié)點(diǎn)。此演示使用了一些Java的網(wǎng)絡(luò)APIs來(lái)在網(wǎng)絡(luò)中傳輸媒體。
    作為第三個(gè)練習(xí)的一部分,我們將修改圖形界面的播放器,讓其能接收并且播放媒體。
    跳至23頁(yè)觀看Resources,文章,指南,和其他參考書(shū)目的列表,這會(huì)幫助你學(xué)習(xí)到更到關(guān)于此指南包括的主題。

    安裝需求
    要運(yùn)行此指南中的例程序,你需要如下的工具和組件:
    ·??Java 2 平臺(tái),標(biāo)準(zhǔn)版,編譯和運(yùn)行演示程序
    ·??Java媒體框架,版本2.1.1a或者更高
    · 一塊已經(jīng)安裝并且配置號(hào)的適當(dāng)?shù)穆暱?br />· 一臺(tái)或者多臺(tái)測(cè)試機(jī)器
    · 演示的源代碼文件在mediaplayer.jar中
    最后的一個(gè)演示應(yīng)用顯示了JMF在網(wǎng)絡(luò)中的應(yīng)用。如果需要,此演示能運(yùn)行在一個(gè)獨(dú)立的機(jī)器上,使用此機(jī)器即是傳輸方也是接收方。可是要觀察到在網(wǎng)絡(luò)中使用JMF的所有功能,你仍然需要至少兩臺(tái)聯(lián)網(wǎng)的機(jī)器。
    在23頁(yè)中的Resources可下載Java 2平臺(tái),完整的源代碼文件,以及其他一些完成本指南所需要的工具。

    下載安裝文件
    將JMF安裝到你的計(jì)算機(jī)中的第一步是在JMF的主頁(yè)中下載安裝文件,它同樣包括了JMF源代碼和API文檔的鏈接。23頁(yè)的Resources中有下載JMF的鏈接。
    目前,JMF有Windows, Solaris, Linux等版本,以及可運(yùn)行在任何裝有虛擬機(jī)的計(jì)算機(jī)上一個(gè)純Java版本。為了增加性能,你需要下載一個(gè)與你操作系統(tǒng)所適應(yīng)的版本。任何在一個(gè)操作系統(tǒng)JMF版本下書(shū)寫(xiě)和編譯的代碼都可以方便的移植到另外的操作系統(tǒng)上。例如,如果你下載了一個(gè)Solaris版本的JMF并且編譯了一個(gè)類(lèi),這些類(lèi)就可以在Linux上使用,不會(huì)有任何問(wèn)題。
    作為選擇,你可以選擇下載純Java版本,或者跨平臺(tái)版本的JMF。這些版本沒(méi)有使用操作系統(tǒng)特有的庫(kù)文件。如果沒(méi)有合適的JMF版本適合的操作系統(tǒng),那么跨平臺(tái)版本就是一個(gè)不錯(cuò)的選擇。

    安裝JMF
    下載完JMF安裝程序后,雙擊安裝程序的圖標(biāo)。
    大部分安裝程序都會(huì)有個(gè)選項(xiàng),安裝本地庫(kù)到系統(tǒng)目錄中;例如,Windows版本安裝程序會(huì)有一個(gè)選項(xiàng)“Move DLLs to Windows/System directory.”。最好將此選項(xiàng)選中,因?yàn)樗艽_保這些操作系統(tǒng)的庫(kù)文件能正確的安裝
    在安裝的過(guò)程中,你還需要選擇項(xiàng)目來(lái)更新系統(tǒng)的CLASSPATH和PATH變量。如果這些選項(xiàng)被關(guān)閉,那么在你編譯和運(yùn)行本指南的例程序的時(shí)候就需要在classpath中引入JMF的jar文件。

    關(guān)于作者
    Eric Olson在Retek Inc工作的軟件工程師。它在Java平臺(tái)上有四年的工作經(jīng)驗(yàn),并且在不同的基于Java的技術(shù)上富有經(jīng)驗(yàn),包括JMF, Jini, Jiro, JSP, servlets, and EJBs。Eric畢業(yè)于St. Paul, MN的St. Thomas大學(xué),獲得計(jì)算機(jī)科學(xué)的學(xué)位。他在IBM的SanFrancisco項(xiàng)目組工作,負(fù)責(zé)WebSphere商業(yè)組件。他同時(shí)再為Imation Corp.工作,負(fù)責(zé)存儲(chǔ)應(yīng)用。現(xiàn)在,他正在開(kāi)發(fā)零售行業(yè)的基于web的軟件解決方案。再業(yè)余的時(shí)間,Eric和Paul
    Monday在Stereo Beacon上合作—一個(gè)分布式的點(diǎn)對(duì)點(diǎn)的基于JMF的媒體播放器。聯(lián)系
    Eric zpalffy@yahoo.com.

    第二節(jié). 一個(gè)簡(jiǎn)單的音頻播放器
    瀏覽
    在本節(jié)中,我們將進(jìn)行創(chuàng)建一個(gè)簡(jiǎn)單的音頻播放器的第一個(gè)練習(xí)。本例將介紹Manager類(lèi)和Player接口,中兩個(gè)都是建立大多數(shù)基于JMF應(yīng)用的重要部分。
    本例的功能目標(biāo)是在字符界面下播放本地的音頻文件。我們將學(xué)習(xí)此源代碼,并了解每一行所做的任務(wù)。完成本節(jié)后,你將會(huì)有一個(gè)基于JMF的可播放包括MP3, WAV, AU等多種音頻文件的演示程序。
    在本練習(xí)后的源代碼分類(lèi)種可查詢(xún)文件SimpleAudioPlayer.java。

    引入必要的類(lèi)
    SimpleAudioPlayer類(lèi)中包括了一些調(diào)用,在其前幾行中需要引入所有必要的類(lèi):
    import javax.media.*;
    import java.io.File;
    import java.io.IOException;
    import java.net.URL;
    import java.net.MalformedURLException;

    The javax.media包是由JMF定義的多個(gè)包之一。javax.media是一個(gè)核心包,包括了定義Manager類(lèi)和Player接口等。本節(jié)中,我們主要學(xué)習(xí)Manager類(lèi)和Player接口,其余的javax.media類(lèi)放在后面的章節(jié)中。
    除了引入javax.media聲明外,以上的代碼片斷引入了一些創(chuàng)建媒體播放器的輸入的聲明。

    Player接口
    在下面的代碼片斷中,創(chuàng)建一個(gè)公共類(lèi)SimpleAudioPlayer并舉例定義一個(gè)Player變量:

    public class SimpleAudioPlayer {
    private Player audioPlayer = null;


    術(shù)語(yǔ)Player聽(tīng)起來(lái)由點(diǎn)熟悉,因?yàn)樗墙⒃谖覀児玫囊纛l或者視頻播放器的基礎(chǔ)上的。事實(shí)上,這個(gè)接口的例子就像是當(dāng)作它們的真實(shí)的副本。Players揭示了一個(gè)實(shí)體上的媒體播放器(如立體音箱系統(tǒng)或者VCR)涉及到功能上的方法。例如,一個(gè)JMF媒體播放器可以開(kāi)始和結(jié)束一個(gè)媒體流。在本節(jié)種,我們將使用Player的開(kāi)始和結(jié)束功能。

    在一個(gè)文件上創(chuàng)建一個(gè)Player
    使用JMF獲得一個(gè)特定媒體文件的Player實(shí)例非常簡(jiǎn)單。Manager類(lèi)在JMF中如同一個(gè)工廠制作許多的特殊接口類(lèi)型,包括Player接口。因此,Manager類(lèi)的責(zé)任就是創(chuàng)建Player實(shí)例,如下例:

    public SimpleAudioPlayer(URL url) throws IOException,
    NoPlayerException,
    CannotRealizeException {
    audioPlayer = Manager.createRealizedPlayer(url);
    }
    public SimpleAudioPlayer(File file) throws IOException,
    NoPlayerException,
    CannotRealizeException {
    this(file.toURL());
    }



    如果你看完本節(jié)的代碼,你可以注意到Manager類(lèi)包含了創(chuàng)建一個(gè)Player實(shí)例的其他方法。我們會(huì)研究其中的一些,如在后面的章節(jié)中的DataSource或者M(jìn)ediaLocator的實(shí)例化。

    Player的狀態(tài)
    JMF定義了大量的一個(gè)Player實(shí)例可能存在的不同狀態(tài)。如下:
    · Prefetched
    · Prefetching
    · Realized
    · Realizing
    · Started
    · Unrealized

    使用這些狀態(tài)
    因?yàn)槭褂妹襟w常常是資源非常密集的,由JMF對(duì)象揭示的許多方法都是不閉塞的,允許一系列事件監(jiān)聽(tīng)的狀態(tài)改變的異步通知。例如,一個(gè)Player在它可以啟動(dòng)之前,必須經(jīng)過(guò)Prefetched和Realized狀態(tài)。由于這些狀態(tài)的改變都需要一些時(shí)間來(lái)完成,JMF媒體應(yīng)用可以分配一個(gè)線(xiàn)程來(lái)初始化創(chuàng)建Player實(shí)例,然后再繼續(xù)其他的操作。當(dāng)Player準(zhǔn)備就緒的時(shí)候,它會(huì)通知應(yīng)用程序其狀態(tài)已經(jīng)改變。

    在一個(gè)如同我們的這樣簡(jiǎn)單的程序中,多功能性的類(lèi)型并不是很重要。處于這個(gè)原因,Manager類(lèi)也提供了一些創(chuàng)建Realized player的有用方法。調(diào)用一個(gè)createRealizedPlayer()方法來(lái)阻塞調(diào)用線(xiàn)程,直到player達(dá)到Realized狀態(tài)。為了調(diào)用一個(gè)無(wú)阻塞的創(chuàng)建player的方法,我們?cè)贛anager類(lèi)中使用了一個(gè)createPlayer()方法。下面的一行代碼中創(chuàng)建了一個(gè)我們需要在例程序中使用的

    Realized player:
    audioPlayer = Manager.createRealizedPlayer(url);



    啟動(dòng)和停止Player
    設(shè)定一個(gè)Player實(shí)例的啟動(dòng)或是停止就如同調(diào)用Player的一個(gè)簡(jiǎn)單的認(rèn)證方法,如下所示:

    public void play() {
    audioPlayer.start();
    }
    public void stop() {
    audioPlayer.stop();
    audioPlayer.close();
    }


    調(diào)用SimpleAudioPlayer類(lèi)中的play()方法來(lái)實(shí)現(xiàn)調(diào)用Player實(shí)例的start()方法。調(diào)用此方法后,你能聽(tīng)到本地的喇叭的聲音文件。同樣的,stop()方法使player停止并且關(guān)閉掉Player對(duì)象。

    對(duì)于讀取和或者播放本地媒體文件來(lái)說(shuō),關(guān)閉Player實(shí)例釋放所有資源是一個(gè)有用的方法。因?yàn)檫@是一個(gè)簡(jiǎn)單的例子,關(guān)閉Player是終止一個(gè)會(huì)話(huà)可接受的方法。但是在實(shí)際的應(yīng)用中,你需要小心的確認(rèn)在除掉Player之前必須要關(guān)閉掉。一但你已經(jīng)關(guān)閉掉player,在再次播放一個(gè)媒體之前你必須要?jiǎng)?chuàng)建一個(gè)新的Player實(shí)例(等待它的狀態(tài)改變)。

    建立一個(gè)SimpleAudioPlayer

    最后,這個(gè)媒體播放應(yīng)用程序要包含一個(gè)可以從命令提示行中輸入命令而調(diào)用的main()方法。在此main()方法中,我們將調(diào)用創(chuàng)建SimpleAudioPlayer的方法:

    File audioFile = new File(args[0]);
    SimpleAudioPlayer player = new SimpleAudioPlayer(audioFile);



    在播放音頻文件之前的唯一的一些事情就是調(diào)用已經(jīng)創(chuàng)建的音頻player的方法play(),如下所示:

    player.play();



    要停止和清除掉音頻player,在main()方法中也應(yīng)該有如下調(diào)用:

    player.stop();



    編譯和運(yùn)行SimpleAudioPlayer
    通過(guò)在命令提示行輸入javac SimpleAudioPlayer.java來(lái)編譯例程序。所創(chuàng)建的文件SimpleAudioPlayer.class在當(dāng)前工作目錄中。
    然后在命令提示行中鍵入如下命令來(lái)運(yùn)行例程序:

    java SimpleAudioPlayer audioFile


    將audioFile替換成你本地機(jī)器上的音頻文件。所有的相對(duì)文件名都試相對(duì)于當(dāng)前的工作目錄。你會(huì)看到一些當(dāng)前正在播放文件的標(biāo)志信息。要終止播放,按下回車(chē)鍵。
    如果編譯失敗,確認(rèn)JMF的jar文件已經(jīng)正確的包含在CLASSPATH環(huán)境變量中。


    第三節(jié). JMF用戶(hù)界面組件
    播放視頻
    在前一節(jié)中,我們學(xué)習(xí)了建立一個(gè)通過(guò)字符界面播放音頻文件的應(yīng)用程序。JMF中一個(gè)最重要的特點(diǎn)就是你不需要為了配置媒體播放器而去了解媒體文件的格式;一切都內(nèi)置了。舉一個(gè)例子,再我們前面的例子中,需要使用MP3格式的時(shí)候,我們不需要讓?xiě)?yīng)用程序?yàn)橐粋€(gè)MP3文件建立一個(gè)特殊的Player。
    如同你將會(huì)再本節(jié)所見(jiàn)到的,對(duì)于視頻文件的操作同樣有效。JMF有所有媒體文件類(lèi)型接口的詳細(xì)資料。
    處理視頻媒體與音頻最大的不同就是,我們必須建立一個(gè)能播放視頻的顯示屏幕。幸運(yùn)的是,JMF能處理許多的這些資料。如同再上例一樣我們會(huì)建立一個(gè)Player對(duì)象,并且使用很多的可視組件來(lái)直接從JMF對(duì)象中創(chuàng)建我們的可視的媒體瀏覽器。
    本節(jié)中,我們將學(xué)習(xí)兩個(gè)例程序。In this section, we'll walk through the second example application. 請(qǐng)?jiān)俸竺娴木毩?xí)的源代碼分布中查閱MediaPlayerFrame.java。

    關(guān)于例子
    在本節(jié)中,我們將創(chuàng)建一個(gè)能顯示和運(yùn)行本地音頻和視頻媒體的應(yīng)用程序。作為練習(xí)的一部分,我們將研究JMF內(nèi)置的一些GUI組件。熟悉AWT和Swing將有助于你理解本例,但這并不是必須的。除非需要直接涉及到JMF的GUI組件,或者我們是不會(huì)詳細(xì)介紹源代碼的。你可以在源代碼的注釋中找到這里未涉及的詳細(xì)說(shuō)明。
    本例中我們使用的許多概念,類(lèi)和方法都和第一個(gè)例子的類(lèi)似。建立Player的基本操作大都一樣。最大的不同就是我們需要對(duì)Player對(duì)象專(zhuān)研更深一點(diǎn),特別當(dāng)需要從Player獲取媒體信息的時(shí)候。

    如何開(kāi)始
    視頻播放器例子被設(shè)計(jì)得如同音頻播放例子一樣通過(guò)命令行來(lái)運(yùn)行,但是本例需要建立在GUI基礎(chǔ)上。如同在上節(jié)一樣,我們先通過(guò)媒體文件名調(diào)用應(yīng)用。然后,應(yīng)用程序顯示一個(gè)帶有可操作媒體組件的窗體。
    在MediaPlayerFrame開(kāi)始的一行中我們定義了類(lèi)并擴(kuò)展自,javax.swing.Jframe類(lèi)。這就是使媒體播放器如同一個(gè)在桌面上的單獨(dú)窗體的方法。任何客戶(hù)機(jī)程序創(chuàng)建了本媒體播放對(duì)象后都可以通過(guò)調(diào)用Jframe類(lèi)中定義的show()方法來(lái)顯示。
    下面是一個(gè)MediaPlayerFrame正在播放MPEG電影的屏幕截圖:

    獲取GUI組件
    Player界面有一些方法來(lái)獲取已選擇可視組件的涉及。在MediaPlayerFrame中,我們使用如下組件:
    · player.getVisualComponent()是一個(gè)播放所有視頻媒體的可視組件。
    · player.getControlPanelComponent() 是一個(gè)操作時(shí)間軸的可視組件(包括開(kāi)始,停止,回放),也包含了一些媒體流的有用信息。
    · player.getGainControl().getControlComponent() 是操作音量(增加)的可視組件。getGainControl()方法返回一個(gè)GainControl實(shí)例,可用于改變節(jié)目的增加等級(jí)。

    使用可視化組件
    上面的界面方法都返回一個(gè)java.awt.Component類(lèi)的實(shí)例。沒(méi)個(gè)實(shí)例都視可加載到我們窗體上的可視組件。這些組件都與Player有直接的聯(lián)系,所以在這些組件上的所有可視元素的處理都會(huì)產(chǎn)生Player播放媒體后相應(yīng)的變化。
    在我們將這些組件加入到我們的窗體的之前,必須要保證它們不為空。因?yàn)椴⒉皇撬械拿襟w播放器包括每一種可視組件,我們只需添加相關(guān)播放器類(lèi)型的組件。比如,一般來(lái)說(shuō)一個(gè)音頻播放器沒(méi)有可視組件,所以getVisualComponent()就要返回空。你不會(huì)想在音頻播放器窗體上添加可視組件的。

    獲得媒體的特殊控制
    一個(gè)Player實(shí)例也可以通過(guò)getControl()和getControls()方法來(lái)暴露其控制,getControls()返回一個(gè)控制對(duì)象集,而getControl()返回一個(gè)控制。不同的播放器類(lèi)型可選擇為特殊的操作來(lái)暴露控制集去指定的媒體類(lèi)型,或者用于獲取該媒體的傳輸機(jī)制。如果你在寫(xiě)一個(gè)只支持某些媒體類(lèi)型的播放器,你需要依靠某些在Player實(shí)例中可用Control對(duì)象。
    由于我們的播放器是非常抽象的,被設(shè)計(jì)于播放多種不同媒體類(lèi)型,我們簡(jiǎn)單的為用戶(hù)暴露所有的Control對(duì)象。如果找到任何擴(kuò)展的控制集,我們就可使用getControlComponent()方法來(lái)增加相應(yīng)的可視控件到標(biāo)簽面板上。通過(guò)這個(gè)辦法,用戶(hù)就可以觀察播放器上的所有組件。以下代碼片斷將所有的控制對(duì)象暴露給用戶(hù):

    Control[] controls = player.getControls();
    for (int i = 0; i < controls.length; i++) {
    if (controls[i].getControlComponent() != null) {
    tabPane.add(controls[i].getControlComponent());
    }
    }


    為了使一個(gè)真實(shí)的應(yīng)用程序能用Control實(shí)例做一些有用的事(除了能顯示可視組件之外),應(yīng)用程序需要知道該Control的特殊類(lèi)型,并分配它。此后,應(yīng)用程序就可使用這些control來(lái)控制媒體節(jié)目了。例如,如果你知道你經(jīng)常使用的媒體暴露javax.media.control.QualityControl類(lèi)型的Control,你能使用QualityControl界面,之后在QualityControl界面上通過(guò)調(diào)用各種方法來(lái)改變性質(zhì)設(shè)定。

    使用一個(gè)MediaLocator
    在我們新的基于GUI的媒體播放器和我們的第一個(gè)簡(jiǎn)單播放器之間最大的不同就是,我們使用一個(gè)MediaLocator對(duì)象而不是URL來(lái)創(chuàng)建Player實(shí)例,如下所示:

    public void setMediaLocator(MediaLocator locator) throws IOException,
    NoPlayerException, CannotRealizeException {
    setPlayer(Manager.createRealizedPlayer(locator));
    }


    我們將在稍后的章節(jié)中討論這個(gè)變化的原因。目前,在網(wǎng)絡(luò)上資源站點(diǎn)上,關(guān)于MediaLocator對(duì)象和URL的描述被認(rèn)為是非常相似的。事實(shí)上,你可以從一個(gè)URL創(chuàng)建一個(gè)MediaLocator,也可以從MediaLocator獲取到URL。我們的新媒體播放器一個(gè)URL中創(chuàng)建一個(gè)MediaLocator,并使用該MediaLocator通過(guò)文件創(chuàng)建了一個(gè)Player。

    編譯和運(yùn)行MediaPlayerFrame
    通過(guò)在命令提示行輸入javac MediaPlayerFrame.java來(lái)編譯例程序。在工作目錄下將創(chuàng)建一個(gè)名為MediaPlayerFrame.class的文件。
    在命令提示行中鍵入如下來(lái)運(yùn)行例程序:

    java MediaPlayerFrame mediaFile


    你需要用你本機(jī)上的一個(gè)媒體文件來(lái)替換掉mediaFile(音頻或者視頻文件都可以)。所有的相對(duì)文件名都是相對(duì)于當(dāng)前工作目錄。你會(huì)看見(jiàn)一個(gè)顯示控制媒體文件的GUI控制集的窗口。欲了解JMF支持的音頻和視頻文件列表,在23頁(yè)的資源。
    如果初始編譯時(shí)失敗,請(qǐng)確認(rèn)JMF的jar文件已經(jīng)包含在當(dāng)前的CLASSPATH環(huán)境變量中。

    MediaPlayerFrame在行動(dòng)
    在本節(jié)前你看見(jiàn)的一個(gè)視頻播放器正在播放MPEG視頻文件的屏幕截圖。下面的屏幕截圖顯示了一個(gè)音頻播放器正在播放一個(gè)MP3文件:
    要更多的學(xué)習(xí)本練習(xí)中的例子,查看完成的MediaPlayerFrame源代碼。

    第四節(jié). JMF概念
    JMF體系結(jié)構(gòu)
    你曾見(jiàn)過(guò)了使用JMF播放本地媒體文件是多么的容易,現(xiàn)在我們將后退一步,來(lái)看看一幅是如何通過(guò)JMF創(chuàng)建了如此成熟的基于媒體的應(yīng)用程序的大的畫(huà)面,是如何通過(guò)JMF創(chuàng)建了如此成熟的基于媒體的應(yīng)用程序。全面的了解JMF體系結(jié)構(gòu)是沒(méi)有意義的,本節(jié)將給你一個(gè)大體的概念,關(guān)于高級(jí)的JMF組件是如何組合起來(lái)創(chuàng)建想得到的東西。
    JMF的組件結(jié)構(gòu)非常的靈活,它的組件一般可以分成三個(gè)部分:
    · Input描述某種被用于在進(jìn)程休息的時(shí)候作為一個(gè)輸入的媒體。
    · process執(zhí)行某些輸入上的活動(dòng)。一個(gè)過(guò)程有一個(gè)明確的輸入和輸出。大量的過(guò)程可用, 能被用于一個(gè)輸入或者一批輸入。這些過(guò)程能被聯(lián)系起來(lái),一個(gè)過(guò)程的輸出被用于另外一個(gè)過(guò)程的輸入。在這種風(fēng)格中,大量的過(guò)程可能被應(yīng)用于一個(gè)輸入。(這段期間是可選擇的——我們開(kāi)始的兩個(gè)例子沒(méi)有包含真正的數(shù)據(jù)過(guò)程,只有一個(gè)來(lái)自文件的輸入和一個(gè)通過(guò)Player的輸出。)
    · Output 描述了媒體的某些目的地。

    從這些描述中,你可以想象到JMF組件體系結(jié)構(gòu)聽(tīng)起來(lái)就好像在一個(gè)典型的立體聲系統(tǒng)或者VCR之后。很容易設(shè)想到,使用JMF就如同打開(kāi)電視或者在立體聲音箱系統(tǒng)下調(diào)節(jié)聲音的風(fēng)格。例如,錄制喜愛(ài)的電視節(jié)目的簡(jiǎn)單的動(dòng)作能在這些組件的基礎(chǔ)中:
    · Input 是電視廣播流,在同一個(gè)頻道運(yùn)輸音頻和視頻。
    · Process 是一個(gè)記錄設(shè)備(就是,一個(gè)VCR或者許多的數(shù)字設(shè)備)轉(zhuǎn)換模擬或者數(shù)字音頻視頻廣播流成適合復(fù)制到磁帶或其他媒體上的格式。
    · Output 是記錄已格式化軌跡(音頻和視頻)到某些類(lèi)型的媒體上。

    JMF資料處理模式
    以下圖片說(shuō)明了JMF數(shù)據(jù)處理模塊并對(duì)每個(gè)類(lèi)型給出了例子:
    使用此模式,很容易明白我們前面的兩個(gè)例子,從文件中輸入音頻和視頻并輸出到本地計(jì)算機(jī)上。在后面的章節(jié)中,我們也會(huì)談?wù)撘恍┩ㄟ^(guò)傳播和接收音頻媒體的JMF網(wǎng)絡(luò)功能。

    處理模型例子
    將JMF的輸入,處理和輸出模式聯(lián)系起來(lái),我們能開(kāi)始想象許多基于媒體的操作都可能通過(guò)JMF完成。一個(gè)例子,轉(zhuǎn)換一種媒體類(lèi)型為其他類(lèi)型并將其輸出存儲(chǔ)到一個(gè)新的文件。舉一個(gè)例子,我們想要在不損壞原始文件的前提下轉(zhuǎn)化一個(gè)WAV格式的音頻文件為MP3格式。以下的過(guò)程模式插圖,就是我們將開(kāi)始執(zhí)行轉(zhuǎn)換的步驟:
    本例的輸入是一個(gè)WAV文件。它被一個(gè)媒體格式轉(zhuǎn)換工具加工,并輸出到一個(gè)新的文件。現(xiàn)在,讓我們看看JMF API中的這個(gè)模式的每一步。我們使用輸入,處理和輸出模式作為概念上的路標(biāo)。

    JMF輸入
    再JMF中,一般由一個(gè)MediaLocator對(duì)象來(lái)描述一個(gè)輸入。如先前規(guī)定的,
    MediaLocator的外觀和行為都非常象一個(gè)URL,這樣它可以唯一確定網(wǎng)絡(luò)上的一個(gè)資源。事實(shí)上,使用一個(gè)URL來(lái)創(chuàng)建一個(gè)MediaLocator是完全可能的;我們?cè)谇懊娴膬蓚€(gè)例子中就是這樣做的。
    為了我們的媒體轉(zhuǎn)換例子,我們需要建立一個(gè)MediaLocator來(lái)描述最初的WAV文件。如同我們將在后面的章節(jié)中見(jiàn)到的,一個(gè)MediaLocator也可以用于描述一個(gè)跨越網(wǎng)絡(luò)中媒體流。在這個(gè)案例中,MediaLocator會(huì)描述傳播的URL――很像一個(gè)被URL指定的在Web上的資源,用于取代指定一個(gè)本地文件系統(tǒng)的文件來(lái)建立MediaLocator。

    一個(gè)MediaLocator和一個(gè)URL之間的不同
    要成功的建立一個(gè)URL對(duì)象,需要適當(dāng)?shù)膉ava.net.URLStreamHandler安裝于系統(tǒng)中。這個(gè)流處理的用途是能夠處理被URL描述的流類(lèi)型。一個(gè)MediaLocator對(duì)象并沒(méi)有這個(gè)需要。例如,我們的下個(gè)應(yīng)用程序?qū)⑹褂脤?shí)時(shí)傳輸協(xié)議(RTP)在網(wǎng)絡(luò)上傳輸音頻。由于多數(shù)的系統(tǒng)都未為RTP協(xié)議安裝一個(gè)URLStreamHandler,所以創(chuàng)建一個(gè)URL對(duì)象會(huì)失敗。在這個(gè)應(yīng)用中,只有MediaLocator對(duì)象會(huì)成功。
    要理解更多關(guān)于URL對(duì)象以及創(chuàng)建和注冊(cè)一個(gè)URLStreamHandler的信息,查閱JDK幫助文檔(查看23頁(yè)資源)。

    JMF處理機(jī)
    當(dāng)我們使用JMF的時(shí)候,應(yīng)用程序的處理機(jī)組件被Processor接口實(shí)例描述。你需要已有些熟悉Processor,它擴(kuò)展至Player接口。由于Processor繼承直P(pán)layer接口,它同樣也從Player繼承所有可用屬性。另外,Processor增加了兩個(gè)屬性:Configuring和Configured。這些擴(kuò)展的屬性(和與之關(guān)聯(lián)的方法)用于Processor從輸入流收集信息時(shí)的通信。
    在我們的最后的例程序中,我們將建立一個(gè)Processor用于將MP3編碼格式的音頻轉(zhuǎn)換成適合在網(wǎng)絡(luò)上傳播的格式。在稍后的板塊中我們會(huì)討論創(chuàng)建一個(gè)簡(jiǎn)單的Processor的步驟。

    JMF輸出
    有少許的方法用于描述JMF中處理模式的輸出狀態(tài)。最簡(jiǎn)單的(并且我們將在最后一個(gè)例子中使用的)是javax.media.DataSink接口。一個(gè)DataSink讀取媒體內(nèi)容并且將其傳送到一些目的地。本節(jié)中最開(kāi)始的音頻格式轉(zhuǎn)換過(guò)程中,MP3(輸出)文件將被DataSink描述。在我們最后一個(gè)例子中,我們將使用一個(gè)DataSink在實(shí)際上完成網(wǎng)絡(luò)中傳播音頻媒體的工作。一個(gè)DataSink是在Manager類(lèi)中,由指定一個(gè)DataSource(輸入到DataSink)和一個(gè)MediaLocator(輸出到DataSink)完成的。
    一個(gè)DataSource實(shí)例描述可用于Players,Processors和DataSinks的輸入數(shù)據(jù)。一個(gè)處理機(jī)的輸出也被描述成一個(gè)DataSource對(duì)象。
    這就是為什么處理器能彼此聯(lián)系起來(lái),在同一媒體數(shù)據(jù)中完成多種操作。這也是來(lái)自Processor的輸出能作為輸入被Player或者DataSink使用的原因(它可將媒體傳遞到輸出目的地)。
    一個(gè)DataSink的最后目的文件由一個(gè)MediaLocator對(duì)象說(shuō)明。如同前面一樣,MediaLocator描述一個(gè)網(wǎng)絡(luò)資源;這就是媒體流將被傳遞的地方。

    第五節(jié).傳播接收媒體
    JMF和實(shí)時(shí)傳輸協(xié)議(RTP)
    許多的友善網(wǎng)絡(luò)的特征直接建立在JMF中,這些使為客戶(hù)端程序通過(guò)網(wǎng)絡(luò)傳輸和接收媒體非常容易。當(dāng)在一個(gè)網(wǎng)絡(luò)上的一個(gè)用戶(hù)想要接收任何種類(lèi)的媒體流的時(shí)候,它不需要在觀看媒體前等待全部的廣播下載到機(jī)器上;用戶(hù)可以實(shí)時(shí)的觀看廣播。在流媒體中些提出了這個(gè)概念。通過(guò)流媒體,一個(gè)網(wǎng)絡(luò)客戶(hù)端能接收到其他機(jī)器上廣播的音頻,甚至獲取正在發(fā)生的實(shí)況視頻廣播。
    在IETF RFC 1889中定義了實(shí)時(shí)傳輸協(xié)議(RTP)。發(fā)展在快速和可靠的狀態(tài)下通過(guò)網(wǎng)絡(luò)傳輸時(shí)間極其敏感的數(shù)據(jù),RTP在JMF中用于提供給用戶(hù)向其他網(wǎng)絡(luò)節(jié)點(diǎn)中傳輸媒體流的方法。
    在本節(jié)中,我們將學(xué)習(xí)我們的最后一個(gè)例程序。這里,你將學(xué)習(xí)到如何傳輸一個(gè)存儲(chǔ)在一臺(tái)機(jī)器上的MP3文件到另外的在同一個(gè)網(wǎng)絡(luò)的機(jī)器上去。實(shí)際的MP3源文件并不從主計(jì)算機(jī)上移除,它也不使復(fù)制到其他機(jī)器上去;事實(shí)上它將會(huì)轉(zhuǎn)換成能使用RTP傳輸?shù)奈募袷讲⑼ㄟ^(guò)網(wǎng)絡(luò)發(fā)送。一旦被一個(gè)客戶(hù)端接收到,源文件(現(xiàn)在是RTP信息包的形式)可以再次傳輸,這一次是在接收機(jī)器上可播放的一種格式。
    在MediaTransmitter.java文件中源代碼查看學(xué)習(xí)以下練習(xí)。

    設(shè)置處理模式
    我們可以在前面的章節(jié)中定義的處理模式的基礎(chǔ)下來(lái)討論我們的最終的例子。在傳輸機(jī)器上,處理模式看起來(lái)像這樣:
    事實(shí)上,MediaTransmitter對(duì)象源代碼包括了以下三行:

    private MediaLocator mediaLocator = null;
    private DataSink dataSink = null;
    private Processor mediaProcessor = null;



    這三個(gè)實(shí)例變量可以直接映射到前面的處理模式圖表,如下:
    ·??mediaProcessor變量是我們的處理器;它將負(fù)責(zé)轉(zhuǎn)換音頻文件從MP3文件模式到一個(gè)適合通過(guò)RTP協(xié)議傳輸?shù)母袷健?br />·??dataSink變量是我們的輸出塊。
    · 當(dāng)我們建立DataSink時(shí)我們需要指定一個(gè)MediaLocator,它是DataSink的目的文件。

    當(dāng)我們通過(guò)運(yùn)行DataSink我們的處理過(guò)的媒體,它將傳輸?shù)轿覀冊(cè)贛ediaLocator中指定的地點(diǎn)。

    RTP MediaLocator
    在前面的兩個(gè)練習(xí)中,我們通過(guò)從文件中獲得的一個(gè)URL建立了MediaLocator實(shí)例。 在本練習(xí)中,我們必須建立一個(gè)MediaLocator來(lái)描述網(wǎng)絡(luò)上媒體傳播輸出流;換句話(huà)說(shuō),我們必須創(chuàng)建一個(gè)能我們的音頻傳播的目的地的MediaLocator。一個(gè)RTP MediaLocator符合如下規(guī)則,看起來(lái)就像一個(gè)典型的URL:

    rtp://address:port/content-type



    讓我們看看上面URL規(guī)范的每一段:
    · address 是將傳輸?shù)拿襟w的地址。以單播的模式傳輸(一個(gè)專(zhuān)用IP地址),地址將會(huì)是有意接收的機(jī)器的IP地址。以廣播的模式傳播(到子網(wǎng)中的所有機(jī)器),地址將會(huì)是以255作為最后的一塊的子網(wǎng)地址。舉個(gè)例子,如果我再子網(wǎng)中可指定地址為192.168.1和想要傳播到子網(wǎng)中的所有節(jié)點(diǎn),我可以指定192.168.1.255作為地址;這樣允許子網(wǎng)中的每個(gè)節(jié)點(diǎn)監(jiān)聽(tīng)廣播媒體。
    · port 必須是被傳輸者和接收者都允許的一個(gè)端口。
    · content-type 是媒體流類(lèi)型。在我們的案子中,這個(gè)將會(huì)是音頻。
    下面的一個(gè)簡(jiǎn)單的RTP傳播MediaLocator例子會(huì)讓所有在指定網(wǎng)絡(luò)中的機(jī)器接收到媒體流:

    rtp://192.168.1.255:49150/audio



    創(chuàng)建一個(gè)處理機(jī)
    在setDataSource()方法中我們首先要做的就是創(chuàng)建一個(gè)Processor實(shí)例。
    下面的Processor的職責(zé)是轉(zhuǎn)換MP3音頻媒體為一個(gè)RTP來(lái)表示:
    public void setDataSource(DataSource ds) throws IOException,
    NoProcessorException, CannotRealizeException, NoDataSinkException {
    mediaProcessor = Manager.createRealizedProcessor(
    new ProcessorModel(ds, FORMATS, CONTENT_DESCRIPTOR));
    在Manager類(lèi)中,我們能創(chuàng)建一個(gè)Processor對(duì)象,通過(guò)兩種方法中的一種:
    createProcessor()或者createRealizedProcessor()。你很可能會(huì)注意到這兩個(gè)方法樣式的顯示和前面例子中創(chuàng)建一個(gè)Player的方法很相似。在目前的例子中,我們將創(chuàng)建一個(gè)已實(shí)現(xiàn)的Processor。我們這樣做是因?yàn)槲覀兪褂玫膽?yīng)用非常簡(jiǎn)單,在Processo處于Realized狀態(tài)時(shí)我們不需要關(guān)心任何真實(shí)的工作。

    創(chuàng)建一個(gè)ProcessorModel
    創(chuàng)建一個(gè)已實(shí)現(xiàn)的Processor,我們需要?jiǎng)?chuàng)建一個(gè)為Processor描述輸入和輸出媒體類(lèi)型的ProcessorModel實(shí)例。為了創(chuàng)建ProcessorModel,我們需要下面的一些:
    · 一個(gè)DataSource,將被處理的媒體(輸入文件)。
    · 一個(gè)javax.media.Format數(shù)組,描述輸入媒體的格式。
    · 一個(gè)javax.media.protocol.ContentDescriptor實(shí)例,為我們的處理機(jī)描述輸出格式。傳送者的DataSource是通過(guò)一個(gè)參數(shù)傳遞到此方法。

    定義輸入和輸出格式
    因?yàn)槲覀兊腗ediaTransmitter類(lèi)會(huì)被時(shí)常用于將輸入媒體格式(MP3)轉(zhuǎn)換成一種輸出格式(音頻RTP),中學(xué)對(duì)象被定義成靜態(tài)。我們創(chuàng)建一個(gè)新的javax.media.format.AudioFormat實(shí)例用于描述媒體輸入類(lèi)型(在java幫助文檔中查看可用格式)。這就是我們的處理機(jī)可以獲取MP3音頻文件的原因。
    我們也創(chuàng)建一個(gè)javax.media.protocol.ContentDescriptor實(shí)例來(lái)描述想要處理機(jī)輸出的。在我們的案子中,這是一個(gè)RTP媒體流。

    這就是為什么我們的處理機(jī)可以只制造RTP流。
    下面的代碼片斷顯示了我們?nèi)绾卧O(shè)置格式和內(nèi)容描述符變量,用于創(chuàng)建ProcessorModel對(duì)象:

    private static final Format[] FORMATS = new Format[] {
    new AudioFormat(AudioFormat.MPEG_RTP)};
    private static final ContentDescriptor CONTENT_DESCRIPTOR =
    new ContentDescriptor(ContentDescriptor.RAW_RTP);



    連接輸入,處理機(jī)和輸出
    現(xiàn)在我們有一個(gè)處于Realized狀態(tài)的Processor,我們需要設(shè)置DataSink以能實(shí)際上傳播RTP媒體。創(chuàng)建DataSink是簡(jiǎn)單的大概使用另外一個(gè)調(diào)用給Manager對(duì)象,如下所示:

    dataSink = Manager.createDataSink(mediaProcessor.getDataOutput(),
    mediaLocator);



    createDataSink()方法獲取新Processor的輸出(作為一個(gè)DataSource參數(shù))和MediaLocator對(duì)象,我們和MediaTransmitter對(duì)象同時(shí)建立的。通過(guò)這樣,你能開(kāi)始我們的不同的組件是如何在處理模式中聯(lián)系起來(lái)的:我們從一個(gè)Processor中獲取輸出并使用他們作為輸入到其他組件。在這個(gè)特殊的應(yīng)用中,Processor輸出用于傳輸媒體的DataSink的一個(gè)輸入。

    創(chuàng)建一個(gè)DataSource實(shí)例
    在這點(diǎn)上,我們?nèi)慷际亲龊驮O(shè)置我們的媒體播放器的廣播傳輸。
    我們需要?jiǎng)?chuàng)建DataSource對(duì)象,我們用于創(chuàng)建處理機(jī)(就是,在我們的MediaTransmitter中,參數(shù)傳遞到setDataSource()方法)。下面是創(chuàng)建一個(gè)DataSource實(shí)例的代碼:

    File mediaFile = new File(args[1]);
    DataSource source = Manager.createDataSource(new MediaLocator(
    mediaFile.toURL()));



    這段代碼是在MediaTransmitter對(duì)象中的vmain()方法。這里我們通過(guò)從命令行輸入的第二個(gè)參數(shù)創(chuàng)建一個(gè)File對(duì)象。我們通過(guò)文件創(chuàng)建一個(gè)MediaLocator,而后通過(guò)位置創(chuàng)建一個(gè)DataSource。這個(gè)新近創(chuàng)建的DataSource是一個(gè)涉及到傳送者的輸入文件。我們能使用這個(gè)DataSource初始化傳輸者。

    開(kāi)始和停止MediaTransmitter
    我們通過(guò)調(diào)用其中的startTransmitting()方法來(lái)開(kāi)始MediaTransmitter,如下所示:

    public void startTransmitting() throws IOException {
    mediaProcessor.start();
    dataSink.open();
    dataSink.start();
    }



    這個(gè)方法首先開(kāi)啟處理機(jī),然后打開(kāi)并啟動(dòng)DataSink。在這個(gè)調(diào)用后,接收機(jī)器就可在媒體傳送者上監(jiān)聽(tīng)。
    停止傳輸者是非常簡(jiǎn)單的。以下代碼將DataSink和Processor都停止和關(guān)閉掉:

    public void stopTransmitting() throws IOException {
    dataSink.stop();
    dataSink.close();
    mediaProcessor.stop();
    mediaProcessor.close();
    }



    編譯和運(yùn)行MediaTransmitter
    通過(guò)在命令行中輸入javac MediaTransmitter.java來(lái)編譯例程序,可在你的工作目錄中生成一個(gè)同名的.class文件。
    要運(yùn)行例程序,在命令提示行中輸入以下代碼:

    java MediaTransmitter rtpMediaLocator audioFile



    此例將創(chuàng)建一個(gè)myAudio.mp3文件的媒體廣播。不要忘記將rtpMediaLocator替換成一個(gè)媒體傳輸?shù)腞TP URL,如同先前討論的。
    你同樣也需要將audioFile替換成你本機(jī)的音頻文件名。
    所有的相對(duì)文件名都是相對(duì)于當(dāng)前工作目錄的。你會(huì)看見(jiàn)一些信息標(biāo)志正在播放的文件。按下Enter鍵來(lái)停止播放。

    為傳送者的一個(gè)例命令行交互如下:
    java MediaTransmitter rtp://192.168.1.255:49150/audio myAudio.mp3
    如果初始編輯失敗,確定JMF的jar文件包含CLASSPATH環(huán)境變量中。要近一步探索本程序和練習(xí),請(qǐng)查閱MediaTransmitter源代碼。

    接收傳輸?shù)拿襟w
    現(xiàn)在你可能會(huì)問(wèn),“如果沒(méi)有人可以看或者收聽(tīng)的話(huà),這個(gè)傳播媒體有什么好的?”
    幸運(yùn)的是,設(shè)定一個(gè)接收傳播媒體的客戶(hù)端只需要對(duì)我們?cè)诘诙€(gè)例程序的MediaPlayerFrame源代碼做很小的改動(dòng)。
    MediaPlayerFrame類(lèi)需要一個(gè)很小的調(diào)節(jié)來(lái)接收和播放音頻文件。在main()方法中,你需要注釋掉如下的一行:

    mpf.setMediaLocator(new MediaLocator(new File(args[0]).toURL()));


    并且輸入如下的一行:

    mpf.setMediaLocator(new MediaLocator(args[0]));


    這個(gè)簡(jiǎn)單的改動(dòng)允許我們通過(guò)String來(lái)創(chuàng)建一個(gè)MediaLocator對(duì)象,而不是通過(guò)創(chuàng)建一個(gè)File來(lái)創(chuàng)建MediaLocator。
    其他代碼都一樣。

    指定RTP URL
    在12頁(yè)的說(shuō)明編譯和運(yùn)行MediaPlayerFrame介紹了如何編譯和運(yùn)行MediaPlayerFrame例程序。這唯一的不同就是你需要為傳輸者指定RTP URL。為接收者的例命令行交互如下:

    java MediaPlayerFrame rtp://192.168.1.255:49150/audio



    運(yùn)行網(wǎng)絡(luò)媒體傳送者的注意事項(xiàng)
    如果你在網(wǎng)絡(luò)上只有權(quán)使用一臺(tái)機(jī)器,你仍然可以運(yùn)行傳輸程序。當(dāng)你啟動(dòng)傳送程序的時(shí)候,你可以即使用RTP URL傳輸?shù)刂罚部芍付愎ぷ鞯臋C(jī)器的機(jī)器地址。為了能夠調(diào)節(jié)傳輸,在開(kāi)始前接收者必須使用精確的同樣的RTP URL。
    如果你運(yùn)行本例真實(shí)的網(wǎng)絡(luò)版本,每臺(tái)你使用的機(jī)器都需要安裝JMF,不論是傳輸還是接收媒體流。這是必須的,因?yàn)椴徽撌莻魉统绦蜻€是接收程序都大量的使用了JMF的API。
    在任一個(gè)案子中,確認(rèn)在指定的RTP URL中使用了相同的地址和端口;否則媒體傳輸是不會(huì)工作的。

    第六節(jié). 約束和資源
    摘要
    我希望本指南能給你提供如何使用JMF的API的有用的瀏覽。
    我們建立了三個(gè)小的應(yīng)用程序來(lái)播放本地的音頻和視頻,也通過(guò)網(wǎng)絡(luò)傳播和接收媒體。這些應(yīng)用程序的源代碼中包含了很多的javadoc樣式的注釋。這就有助于你理解你剩余的問(wèn)題。
    許多JMF的主題在本指南中并沒(méi)有涉及。實(shí)際上,我們更關(guān)注JMF的基本概念和應(yīng)用;在此基礎(chǔ)上,我們能輕易地?cái)U(kuò)展學(xué)習(xí)的其他范圍。要更深入JMF的應(yīng)用程序,你可能想要學(xué)習(xí)下面的面板中所提到的主題。更近一步的閱讀本指南中的主題,查閱23頁(yè)的資源。

    高級(jí)主題
    大量的值得做的練習(xí)在本指南的范圍之上。在簡(jiǎn)單的說(shuō)明之下自己更進(jìn)一步的學(xué)習(xí),你可以擴(kuò)展我們的應(yīng)用程序代碼,也可以反展你的JMF相關(guān)知識(shí)。使用以下的練習(xí)開(kāi)始:
    · 媒體捕獲:JMF包含了豐富的API來(lái)捕獲媒體數(shù)據(jù)。如果你對(duì)使用JMF捕獲媒體感興趣,你可以使用javax.media.CaptureDeviceManager類(lèi)和javax.media.protocol.CaptureDevice接口的API來(lái)學(xué)習(xí)。對(duì)于一個(gè)高級(jí)的練習(xí),考慮使用CaptureDeviceManager和CaptureDevice接口來(lái)增加媒體捕獲功能到媒體播放應(yīng)用程序的GUI版本上。
    · 會(huì)話(huà)管理:由于本指南是一個(gè)JMF的說(shuō)明,我們使輸出表現(xiàn)非常的簡(jiǎn)單,僅僅實(shí)現(xiàn)了javax.media.DataSink輸出。
    另外的輸出表示是使用javax.media.rtp.SessionManager。這個(gè)管理類(lèi)允許客戶(hù)端創(chuàng)建并監(jiān)視他們的RTP流和連接。通過(guò)SessionManager并隨后創(chuàng)建流,它可能非常的接近監(jiān)視RTP會(huì)話(huà)。作為一個(gè)高級(jí)的練習(xí),轉(zhuǎn)換我們的地三個(gè)演示程序來(lái)使用SessionManager,然后監(jiān)聽(tīng)流出的RTP流已經(jīng)哪些客戶(hù)端在收聽(tīng)。
    · 使用JMF的多點(diǎn)傳送:我們的廣播演示應(yīng)用程序說(shuō)明了如何傳送一個(gè)網(wǎng)絡(luò)的媒體到另外一個(gè)網(wǎng)絡(luò)的一或多臺(tái)機(jī)器上去。它也可能使用JMF中的多點(diǎn)傳輸協(xié)議來(lái)提供給更復(fù)雜,多用戶(hù)的網(wǎng)絡(luò)。
    JMF用戶(hù)指南提供了一個(gè)使用JMF的多播協(xié)議的更深入的探討。更進(jìn)一步追蹤本主題查看23頁(yè)資源。
    · 傳輸視頻: 我們的最后一個(gè)演示應(yīng)用程序著眼于如何傳輸一個(gè)MP3音頻文件,但是JMF也能夠通過(guò)網(wǎng)絡(luò)傳遞視頻。關(guān)注API文檔中的Format和ContentDescriptor類(lèi)獲得如何使用的更好的方法。
    · 導(dǎo)入/導(dǎo)出RTP媒體流: JMF同樣允許將RTP流保存為文件以便將來(lái)使用。舉一個(gè)實(shí)例,一個(gè)遠(yuǎn)程電信會(huì)議可以保存下來(lái)以后再看。
    由于流已經(jīng)保存再RTP格式中,已經(jīng)不需要再次轉(zhuǎn)換,這樣可導(dǎo)致傳輸程序的性能改進(jìn)。通過(guò)一個(gè)文件而不是URL來(lái)設(shè)置DataSink對(duì)象中輸入/輸出MediaLocator。你會(huì)再JMF用戶(hù)指南中發(fā)現(xiàn)更深層次的主題探討。

    資源
    JMF
    · 下載mediaplayer.jar,本指南中使用的完整的例源代碼。
    ·??JMF主頁(yè) (http://www.javasoft.com/jmf)是最好的探討JMF更多信息的資源。
    · 你可以找到JMF說(shuō)明書(shū)(http://java.sun.com/products/java-media/jmf/2.1.1/specdownload.html),再Java開(kāi)發(fā)者聯(lián)盟上包括API文檔和JMF用戶(hù)指南。你必須有權(quán)使用所有的這些資源,如果你想做任何更深入的JMF編程的話(huà)。
    · 官方的JMF支持文件格式 頁(yè)面
    (http://java.sun.com/products/java-media/jmf/2.1.1/formats.html) 列出了所有可為JMF辨識(shí)并播放的文件格式。此文件格式頁(yè)面也包括了學(xué)習(xí)更多關(guān)于捕獲設(shè)備和RTP格式的參考。
    · MPEG-4 Video for JMF (http://www.alphaworks.ibm.com/tech/mpeg-4), 來(lái)自IBM
    alphaWorks, 是一個(gè)JMF的視頻編解碼器。
    RTP
    ·??IETF RTP RFC (http://www.ietf.org/rfc/rfc1889.txt) 非常詳細(xì)的描述了RTP協(xié)議。
    · 查看 JMF API Guide
    (http://java.sun.com/products/java-media/jmf/2.1.1/specdownload.html) ,有許多有關(guān)于RTP協(xié)議和描述以及它是如何在JMF上應(yīng)用的。
    · 哥倫比亞大學(xué)有一個(gè)比較有用的RTP FAQ(http://www.cs.columbia.edu/~hgs/rtp/faq.html).
    Java技術(shù)
    ·??Java 2 Platform, Standard Edition (http://java.sun.com/j2se/) 可從sun公司獲得。
    · sun的指南關(guān)于JFC/Swing (http://java.sun.com/docs/books/tutorial/uiswing/index.html)
    和 AWT (http://java.sun.com/docs/books/tutorial/information/download.html#OLDui) 是非常好的能學(xué)習(xí)到很多關(guān)于Java程序語(yǔ)言中GUI編程的好地方。
    · 另外一個(gè)sun指南學(xué)習(xí)network programming 基礎(chǔ)
    (http://java.sun.com/docs/books/tutorial/networking/index.html)。
    多點(diǎn)傳輸協(xié)議
    · Explicit Multicast (XCAST)
    (http://oss.software.ibm.com/developerworks/opensource/xcast/) 是IP多點(diǎn)傳輸?shù)囊环N形式,為非常多的多點(diǎn)傳輸組設(shè)計(jì)提供可升級(jí)的支持,這些組有些少量的參與者代表。XCAST 代碼得到了IBM Common Public License的認(rèn)可。
    · Todd Montgomery 的 MTP page (http://www.nard.net/~tmont/rm-links.html),
    在這里你能找到一個(gè)廣泛的涉及到多點(diǎn)傳輸協(xié)議的列表。
    附加資源
    · 你可以在
    developerWorks Java technology zone (http://www-106.ibm.com/developerworks/java/)中找到許多的關(guān)于Java各方面的內(nèi)容。
    · 查看 developerWorks tutorials page
    (http://www-105.ibm.com/developerworks/education.nsf/dw/java-onlinecourse-bytitle?OpenDocument&Count=for a complete listing of free tutorials.

    posted on 2006-07-27 20:05 KevinGong 閱讀(567) 評(píng)論(1)  編輯  收藏 所屬分類(lèi): UI設(shè)計(jì)

    Feedback

    # re: Java Media Framework Basics 2006-08-04 11:41 方佳瑋
    謝謝,收藏  回復(fù)  更多評(píng)論
      

    主站蜘蛛池模板: 暖暖免费中文在线日本| 日本一线a视频免费观看| 一区二区三区在线观看免费| 久久久久久国产a免费观看不卡 | 免费一级毛片无毒不卡| 成年人网站免费视频| 成年女人免费v片| 久久亚洲精品专区蓝色区| 亚洲国产综合第一精品小说| 一级毛片aaaaaa免费看| 国产午夜鲁丝片AV无码免费| 亚洲精品无码久久久久A片苍井空| 久久久久国产精品免费免费搜索| 久久久久久A亚洲欧洲AV冫| 一级毛片免费全部播放| 亚洲一区二区三区无码中文字幕| 亚洲人成黄网在线观看| 黄色一级免费网站| 在线免费观看你懂的| 亚洲码一区二区三区| 国产高清免费视频| 亚洲国产精品自在自线观看| 国产成人无码免费视频97| 深夜福利在线视频免费| 久久亚洲国产午夜精品理论片| 日韩电影免费在线观看| 亚洲剧情在线观看| 欧洲美熟女乱又伦免费视频| 青青青视频免费观看| 国产成人亚洲综合无码精品| 0588影视手机免费看片| 亚洲国产a∨无码中文777| 1000部拍拍拍18勿入免费凤凰福利 | 亚洲人成网站看在线播放| 国内外成人免费视频| av片在线观看永久免费| 久久亚洲精品无码AV红樱桃| 成人免费无码大片A毛片抽搐色欲| 色多多A级毛片免费看| 亚洲精品第一国产综合精品| 国产成人在线观看免费网站|