介紹
幾乎是MIDP(Mobile Information Device Profile)1.0一出來的時候,基於它的一個簡單的視頻播放器(第三方廠商開發)就同時發布了。這個播放器只支持MPEG格式,而且也並不復雜,但它展示了觀看和使用媒體(本例是視頻)的能力,這一點大大激發了程序員們的興趣。不過這個早期的視頻播放器並不是為程序員設計,所以要想在軟件中使用播放視頻的功能,必須要麼拷貝所有代碼(這樣做可能有道德上的存疑)要麼自己寫所有的相關代碼。由此看出對播放各類媒體的API的需求顯然是存在的,但僅僅為播放視頻開發API並不能實現開發API的所有用途。於是當移動媒體API(MMAPI)專家委員會開始致力於明確移動媒體概念的時候,他們首先需要為各種移動設備,范圍從簡單的蜂窩電話到PDA以及平板式電腦,提供可供參考的媒體種類。最終他們完成了兩類不同的API設置:
• 移動媒體API(MMAPI),為擁有高級聲音和多媒體性能的移動設備設計。
• 媒體API(MIDP2.0),適用於有限的移動設備(僅僅提供音頻)。
經過以上的發展歷程,令人感到奇怪的是API的第一個版本似乎並不支持視頻,不過為此有個很好的解釋:一些MIDP設備的內存和處理器性能太有限。事實上對MIDP2.0媒體API的需求很容易勾勒,它必須提供對以下功能的支持:
• 音階的產生
• “開始播放”、“停止”、“暫停”之類基礎的控制
• 媒體特效控制,比如音量
• 內容數量查詢
MIDP2.0媒體API賦予你創建、播放簡單旋律(只有音節)和音頻的功能。提到聲音首先進入我們腦海的手機鈴聲,但其實API和MIDP涉及的全部相關概念有相同的限制條件:它只能在Java的環境下使用,所以你不能為你的手機創作新的鈴聲。但是除此以外對於其他需要比鈴聲更復雜聲音的游戲或者應用,API就提供了巨大的好處。
通用架構
API由三個部分:Manager,Player和Control,和兩個包:javax.microedition.media,Javax.microedition.media.control構成。Media包中包含Manager和可能用到的Players,control包中包含了所有的Controls。
API中最重要的類是Manager。Manager的用處包括,創建各種不同類型的Players(用於播放音頻,視頻等等),獲得各種支持協議和內容格式,播放簡單的曲調。Player類用來播放各類格式的多媒體內容。Control是一個用來控制Players的接口,Control控制諸如音量、音色、音調之類的東西。
圖1 Manager, Player, Control東西類間調用關系說明
創建一個播放器與創建一個網絡連接類似,根據不同情況,需要調用Manager中的一或兩個方法完成。
以下代碼根據Internet上的音頻文件創建了一個Player,然後播放該音頻:
try {
Player audioPlayer = Manager.createPlayer("http://www.nullplace.com/music.wav");
audioPlayer.start();
} catch (IOException ioe) {
} catch (MediaException me) { }
第二個例子是從應用的.jar文件中的音頻文件創建一個Player,然後播放音頻:
try {
InputStream is = getClass().getResourceAsStream("music.wav");
Player audioPlayer = Manager.createPlayer(is, "audio/X-wav");
audioPlayer.start();
} catch (IOException ioe) {
} catch (MediaException me) { }
發出一個簡單音調
發出一個簡單音調是一個簡單的過程,用Manager類中一個隨手可得的方法就能輕易實現。注意下面的MIDlet有兩個簡單動作:一個是退出應用,另一個是發出簡單聲調。發出聲調由simpleTone()方法實現,而它實際上是調用Manager類的playTone(int note, int duration, int volume)方法實現。
import Javax.microedition.midlet.*;
import Javax.microedition.lcdui.*;
import Javax.microedition.media.*;
import Javax.microedition.media.control.*;public class MediaMIDlet extends MIDlet implements CommandListener{
private Player mp;
private Display display;
private List list;
private Command exitCommand = new Command("Exit", Command.EXIT, 2);
private Command playCommand = new Command("Play", Command.ITEM, 1);public MediaMIDlet() {
display = Display.getDisplay(this);
list = new List("Demo", List.IMPLICIT);
}public void startApp() {
list.addCommand(exitCommand);
list.addCommand(playCommand);
list.setCommandListener(this);display.setCurrent(list);
}public void destroyApp(boolean unconditional) {}
public void pauseApp() {}
public void commandAction(Command c, Displayable s) {
if (c == exitCommand) {
destroyApp(false);
notifyDestroyed();
}
if (c == playCommand) {
simpleTone();
}
}private void simpleTone() {
try {
Manager.playTone(ToneControl.C4, 100, 80);
} catch (Exception ex){}
}
}
如果音符不是中音C,設定聲音中的音調需要些技巧。如上所示,事實上ToneControl類中的常量屬性來表示中音C:ToneControl.C4。還有一個特殊的常量表示不發聲:ToneControl.SILENCE。下一節介紹如何利用這些現成的代碼構架來創作一段曲調。
播放曲調
下列代碼介紹了不同音符的變量(bytes)表達,其中最有趣的是創建數組mySequence:
1. 數組元素是整型變量,成對的常量值或者音符長度。
2. version和tempo被設置,接著是blocks 0和1(A部和B部)。
3. 播放部分。
曲調准備好後,其余的代碼展示了如何創建一個ToneControl類和如何用它播放曲調。
private void toneSequence() {
byte tempo = 30;
byte d = 8;byte C4 = ToneControl.C4;;
byte D4 = (byte)(C4 + 2);
byte E4 = (byte)(C4 + 4);
byte F4 = (byte)(C4 + 5);
byte G4 = (byte)(C4 + 7);
byte rest = ToneControl.SILENCE;byte[] mySequence = {
ToneControl.VERSION, 1,
ToneControl.TEMPO, tempo,
ToneControl.BLOCK_START, 0, // starting A part
C4,d, F4,d, F4,d, C4,d, F4,d, F4,d, C4,d, F4,d,
ToneControl.BLOCK_END, 0, // ending A part
ToneControl.BLOCK_START, 1, // starting B part
C4,d, E4,d, E4,d, C4,d, E4,d, E4,d, C4,d, E4,d,
ToneControl.BLOCK_END, 1, // ending B part
ToneControl.PLAY_BLOCK, 0, // playing A part
ToneControl.PLAY_BLOCK, 1, // playing A part
ToneControl.PLAY_BLOCK, 0, // playing A part
};try{
Player p = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);
p.realize();
ToneControl c = (ToneControl)p.getControl("ToneControl");
c.setSequence(mySequence);
p.start();
} catch (IOException ioe) {
} catch (MediaException me) {}
}
總結
MIDP2.0 Media API使在MIDP設備中發聲,演奏曲調,和播放不同的音頻的工作成為可能。未來(依靠一些手機的具體實現功能,如Nokia的用戶攝象接口),API還將實現播放和記錄視頻的功能。至少目前,API為程序員給他們的游戲和應用加入音頻效果提供了很好的解決方法。