在本節中,我們將進行創建一個簡單的音頻播放器的第一個練習。本例將介紹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 classSimpleAudioPlayer {
private Player audioPlayer = null;
術語Player聽起來由點熟悉,因爲它是建立在我們公用的音頻或者視頻播放器的基礎上的。事實上,這個接口的例子就像是當作它們的真實的副本。Players揭示了一個實體上的媒體播放器(如立體音箱系統或者VCR)涉及到功能上的方法。例如,一個JMF媒體播放器可以開始和結束一個媒體流。在本節種,我們將使用Player的開始和結束功能。
在一個文件上創建一個Player
使用JMF獲得一個特定媒體文件的Player實例非常簡單。Manager類在JMF中如同一個工廠製作許多的特殊接口類型,包括Player接口。因此,Manager類的責任就是創建Player實例,如下例:
publicSimpleAudioPlayer(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 = newFile(args[0]);
SimpleAudioPlayer player = new SimpleAudioPlayer(audioFile);
在播放音頻文件之前的唯一的一些事情就是調用已經創建的音頻player的方法play(),如下所示:
player.play();
要停止和清除掉音頻player,在main()方法中也應該有如下調用:
player.stop();
編譯和運行SimpleAudioPlayer
通過在命令提示行輸入javac SimpleAudioPlayer.java來編譯例程序。所創建的文件SimpleAudioPlayer.class在當前工作目錄中。
然後在命令提示行中鍵入如下命令來運行例程序:
java SimpleAudioPlayeraudioFile
將audioFile替換成你本地機器上的音頻文件。所有的相對文件名都試相對於當前的工作目錄。你會看到一些當前正在播放文件的標誌信息。要終止播放,按下回車鍵。
如果編譯失敗,確認JMF的jar文件已經正確的包含在CLASSPATH環境變量中。
我測試的完整源碼
import javax.media.*;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.MalformedURLException;
public class SimpleAudioPlayer {
private Player audioPlayer = null;
public SimpleAudioPlayer(URL url)
throwsIOException,NoPlayerException,CannotRealizeException {
audioPlayer = Manager.createRealizedPlayer(url);
}
public SimpleAudioPlayer(File file)
throwsIOException,NoPlayerException,CannotRealizeException {
this(file.toURL());
}
public void play() {
audioPlayer.start();
}
public void stop() {
audioPlayer.stop();
audioPlayer.close();
}
public static void main(String[] s){
try{
File audioFile = new File("1.mp3");
SimpleAudioPlayer player = newSimpleAudioPlayer(audioFile);
player.play();
Thread.sleep(10000);//延時10s
player.stop();
System.exit(0);
}
catch (Exception e){
e.printStackTrace();
System.exit(0);
}
}
}