java音頻播放(轉)


轉自:http://www.codefans.net/articles/1750.shtml

 

Java寫一個視頻播放器,在“Java通過java.applet.AudioClip接口播放簡短的音頻片斷”演示了如何用Java API 來播放音頻剪輯片斷,讀者會發現,如果使用上例中的程序來播放較大的聲音文件( 當然格式必須支持的),程序不會響應, 根本不能得到聲音。這是由於java.applet.AudioClip 對象不能容納大量的音頻數據。為了解決這個問題,本例將演示如何得到一個真正意義上的媒體播放器,效果如圖2-2 所示。它既可以播放音頻也可以播放視頻(當然格式必須是支持的),這個JAVA視頻播放器將用到sun 開發的一個附加API 包——JMF API 包,即Java MediaFramework API。它不是J2SE SDK 中的標准包,因此必須另外到Sun 公司下載 。作者用的是JMF2.1.1 跨平台版本,當然也可以使用Windows 版本或Solaris 版本的。

首先介紹一下JMF API 包的下載和安裝及在JBuilder 中的集成。作者使用的是跨平台的2.1.1zip包版本,可以在如下地址下載:http://java.sun.com/products/java-media/jmf/2.1.1/download.html

另外,還可以在http://java.sun.com/products/java-media/jmf/2.1.1/documentation.html上下載JMF API 的相關文檔和幫助。將下載下來的JMF2.1.1.zip 包解壓到c 盤根目錄下(當然可以是其他位置),然后設置環境變量,在Windows 系統中如下:

set JMFHOME=c:\JMF2.1.1
set CLASSPATH=%JMFHOME%\lib\jmf.jar;.;%CLASSPATH%

如果讀者使用IDE 開發java 程序,也可以很容易地將JMF API 包集成到開發工具上。以BorlandJBuilder 為例,單擊Tools 菜單下的Configure Libraries 項,在彈出的對話框中,單擊New 按鈕,在新的彈出框中設置Name:JMF,Location:User Home, 並根據解壓的JMF 包的位置, 如c:\JMF2.1.1,添加API;然后打開Project 菜單下的Default Project Properties 項,在彈出框的Paths面板中選擇Required Libraries 面板項添加API ,如User Home 下的JMF。本例中,為了播放媒體,相應的需要一個媒體播放器Player 對象,可以通過調用Manager 的createPlayer()方法得到,因為此方法是靜態方法,所以不需要創建Manager 的實例,代碼如下:

player = Manager.createPlayer(new MediaLocator(mediaURL));//根據聲音文件的路徑實例化一個Player 對象

播放器完成從數據源接收數據,申請播放資源,並以精確的時間順序根據每一道(Track)的數據格式分別提交到各自的資源目標,如揚聲器、顯示器。另外,javax.media.Player 接口實現了Controller 接口,因而提供了方法java.awt.ComponentgetControlPanelComponent()來得到播放控制組件、java.awt.Component getVisualComponent()
來得到可視化的畫面組件。一個播放器具有6 種狀態,分別是Unrealized、Realizing、Realized、Prefetching、Prefetched和Started。當一個播放器創建時,處於UnRealized 狀態,此時它對要播放的媒體一無所知。各個狀態之間的轉換,體現了媒體播放的全過程。

當播放器調用realize()方法后,播放器由Unrealized 狀態進入Realizing 狀態,此時播放器可以判定資源的請求,同時查詢它的所有非獨占資源(獨占資源是指,每次只能提供給一個播放器的資源,如特定的硬件資源等),如果需要還可以從網上下載相關的資源。Realizing 是一個時間密集的任務,若成功完成,則播放器進入Realized 狀態。進入Realized 之后,播放器已經得知它需要哪些資源及相關的媒體類型信息,並可以提交數據,獲得可視化組件和控制組件,但此時播放器仍然不擁有任何資源,其他播放器也可以啟動。

當播放器調用prefetch()方法后,隨即進入Prefetching 狀態。此時,播放器已經裝載了媒體數據,獲得了播放資源,正准備播放它的媒體數據。當播放器的媒體被重新定位或播放率的改變,會導致播放器重新進入Prefetching 狀態。成功完成Prefetching 后,播放器進入Prefetched 狀態,可以播放媒體。調用start()方法后播放器進入最終的Started 狀態,播放器將播放器的時基時間和媒體時間映射成它正在運行的時鍾時間,媒體開始播放。另外,本例使用ControllerListener 接口來監聽Player 對象的各個狀態之間轉變時的事件,並完成相應的處理。程序代碼如下:
1. 新建一個Project,取名為JVideoDemo1。
2. 新建一個Application,取名為JVideoDemo1;主窗體取名為MainFrame,標題為JVideoDemo1。
3. 利用wizards|implement interface 使MainFrame 類實現ControllerListener,並添加新的屬性,代碼如下:

public class MainFrame extends JFrame implements           ControllerListener{
2    private JPanel contentPane;
3    private BorderLayout borderLayout1 = new BorderLayout();
4    Component vc = null; //視頻播放組件
5    Component cc = null; //視頻播放控制組件
6    Player player = null; //播放器對象
7    ……
8    }

4. 編寫一個新的MainFrame 類的構造方法,參數是一個String 對象,並在此方法中實例化一個Player 對象。

01    public MainFrame(String mediaURL){
02    this(); //調用默認的構造方法,以便執行jbInit()方法中的初始化工作。
03    //實例化一個Player 對象player
04    try{
05    Manager.setHint(Manager.LIGHTWEIGHT_RENDERER, new Boolean(true));//很重要的一行,可以解決Swing 組
06    //件和awt 組件混用可能帶來的麻煩
07    player = Manager.createPlayer(new MediaLocator(mediaURL));//根據聲音文件的路徑實例化一個Player 對象
08    }catch(IOException err){
09    exitProc ("Could not find the player"); //顯示消息並退出程序
10    }catch(NoPlayerException err){
11    exitProc ("Could not create the player"); //顯示消息並退出程序
12    }
13    if(player==null){
14    exitProc("Could not create the player"); //顯示消息並退出程序
15    }
16    player.addControllerListener(this); //play 對象添加ControllerListener
17    player.prefetch(); //獲取媒體數據
18    }}

5. 實現ControllerListener 接口中的方法controllerUpdate(),用於處理ControllerEvent 事件:

01    public void controllerUpdate(ControllerEvent e){
02    //如果控制事件是關閉,則程序退出
03    if (e instanceof ControllerClosedEvent){
04    System.exit(0);
05    }
06    //如果控制事件是媒體數據播放完畢,則player 設置新的媒體時間,重新開始播放
07    if (e instanceof EndOfMediaEvent){
08    player.setMediaTime(new Time(0));
09    player.start();
10    return;
11    }
12    //如果控制事件是獲得媒體數據完成,則開始播放
13    if (e instanceof PrefetchCompleteEvent){
14    player.start();
15    return;
16    }
17    //如果控制事件是Realize 完成,則播放器player 獲得播放畫面的組件,用於媒體可視化播放,並將組件加到
18    //MainFrame 窗口中;同時獲得播放控制組件,也添加到MainFrame 窗口上,用於控制媒體的播放
19    if (e instanceof RealizeCompleteEvent){
20    vc = player.getVisualComponent();
21    if (vc!=null)
22    this.getContentPane().add(vc,BorderLayout.CENTER);
23    cc = player.getControlPanelComponent();
24    if (cc!=null)
25    this.getContentPane().add(cc,BorderLayout.SOUTH);
26    this.pack();
27    this.setResizable(false);//窗口大小適合媒體畫面,並不可改變。
28    this.setVisible(true);
29    }
30    }}
 

6. 編寫終止方法exitProc (),該方法接收Stirng 對象為參數,並顯示此String 對象,然后程序退出。

1    private void exitProc (String str){
2    System.out.println(str);
3    System.exit(-1);
4    }

 

7. 在JVideoDemo1 類中,修改實例化MainFrame 對象所用的構造方法,傳入媒體文件的地址,演示播放該媒體文件。具體如下:

    MainFrame frame = new MainFrame(ClassLoader.getSystemResource("media/sport.mov").toString());


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM