Mobile Media API 提供統一的 Manager.createPlayer() 工廠方法,支援音頻/視頻播放、錄製、MIDI 控制、音調合成、多媒體同步等豐富功能。核心介面:Player、PlayerListener、各類 Control (VolumeControl, VideoControl, TempoControl, RecordControl...)。
try {
Manager.playTone(ToneControl.C4, 5000, 100); // 頻率、持續時間(ms)、音量(0-100)
} catch (MediaException e) { /* 處理 */ }
try {
Player p = Manager.createPlayer("https://server/music.mp3");
p.setLoopCount(5); // 循環 5 次
p.start();
} catch (IOException | MediaException e) { /* 處理 */ }
static final long SECS_TO_MICROS = 1000000L;
Player p; VolumeControl vc;
try {
p = Manager.createPlayer("https://server/music.mp3");
p.realize(); // 獲取資源,準備 Control
p.addPlayerListener(new PlayerListener() {
public void playerUpdate(Player player, String event, Object data) {
if (PlayerListener.END_OF_MEDIA.equals(event) ||
PlayerListener.STOP_AT_TIME.equals(event)) {
try {
p.setMediaTime(5 * SECS_TO_MICROS); // 從 5 秒重播
p.start();
} catch (MediaException ignored) {}
}
}
});
vc = (VolumeControl) p.getControl("VolumeControl");
if (vc != null) vc.setLevel(100); // 最大音量
p.setMediaTime(5 * SECS_TO_MICROS); // 起始位置
p.prefetch(); // 預載數據,降低啟動延遲
p.start();
} catch (IOException | MediaException e) { /* 處理 */ }
try {
Player p = Manager.createPlayer("https://server/tune.mid");
p.realize();
TempoControl tc = (TempoControl) p.getControl("TempoControl");
if (tc != null) tc.setTempo(120000); // 120 BPM (微分音/分鐘)
p.start();
} catch (IOException | MediaException e) { /* 處理 */ }
try {
Player p = Manager.createPlayer("https://server/movie.mpg");
p.realize();
VideoControl vc = (VideoControl) p.getControl("VideoControl");
if (vc != null) {
Form form = new Form("Video");
form.append((Item) vc.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE, null));
Display.getDisplay(midlet).setCurrent(form);
}
p.start();
} catch (IOException | MediaException e) { /* 處理 */ }
try {
byte[] record = recordStore.getRecord(recordId);
InputStream is = new ByteArrayInputStream(record);
Player p = Manager.createPlayer(is, "audio/X-wav"); // 需指定 MIME
p.start();
} catch (IOException | MediaException | RecordStoreException e) { /* 處理 */ }
try {
InputStream is = getClass().getResourceAsStream("/audio.wav");
Player p = Manager.createPlayer(is, "audio/X-wav");
p.start();
} catch (IOException | MediaException e) { /* 處理 */ }
try {
Player p1 = Manager.createPlayer("https://server/tune.mid");
Player p2 = Manager.createPlayer("https://server/movie.mpg");
p1.realize(); p2.realize();
p2.setTimeBase(p1.getTimeBase()); // p2 追隨 p1 時間基準
p1.prefetch(); p2.prefetch();
p1.start(); p2.start(); // 同步啟動
} catch (IOException | MediaException e) { /* 處理 */ }
byte[] sequence = {
ToneControl.VERSION, 1,
ToneControl.TEMPO, 30, // 120 BPM
ToneControl.BLOCK_START, 0, // 定義區塊 A
ToneControl.C4 + 4, 8, // E4 八分音符
ToneControl.C4 + 2, 8, // D4
ToneControl.C4, 8, // C4
ToneControl.C4 + 4, 8, // E4
ToneControl.BLOCK_END, 0,
ToneControl.PLAY_BLOCK, 0, // 播放區塊 A
ToneControl.C4 + 2, 8, ToneControl.C4 + 2, 8, ToneControl.C4 + 2, 8, ToneControl.SILENCE, 8, // B 區
ToneControl.C4 + 4, 8, ToneControl.C4 + 7, 8, ToneControl.C4 + 7, 8, ToneControl.SILENCE, 8,
ToneControl.PLAY_BLOCK, 0, // 重複 A
ToneControl.C4 + 2, 8, ToneControl.C4 + 2, 8, ToneControl.C4 + 4, 8, ToneControl.C4 + 2, 8, ToneControl.C4, 8 // C 區
};
try {
Player p = Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR);
p.realize();
ToneControl tc = (ToneControl) p.getControl("ToneControl");
tc.setSequence(sequence);
p.start();
} catch (IOException | MediaException e) { /* 處理 */ }
// 語音錄製 (AMR/WAV)
try {
Player p = Manager.createPlayer("capture://audio");
p.realize();
RecordControl rc = (RecordControl) p.getControl("RecordControl");
rc.setRecordLocation("file:///tmp/audio.wav");
rc.startRecord();
p.start();
Thread.sleep(5000); // 錄製 5 秒
p.stop(); rc.stopRecord(); rc.commit();
} catch (Exception e) { /* 處理 */ }
// 攝影預覽與拍照
try {
Player p = Manager.createPlayer("capture://video");
p.realize();
VideoControl vc = (VideoControl) p.getControl("VideoControl");
if (vc != null) {
Form form = new Form("Camera");
form.append((Item) vc.initDisplayMode(VideoControl.USE_GUI_PRIMITIVE, null));
Display.getDisplay(midlet).setCurrent(form);
}
p.start();
// 拍照瞬間
byte[] png = vc.getSnapshot(null); // null 使用預設 PNG
Image img = Image.createImage(png, 0, png.length);
} catch (IOException | MediaException e) { /* 處理 */ }
realize() → prefetch() → start() 三階段獲取資源,stop() → deallocate() → close() 釋放getControl() 返回非 null 才轉型CONNECTION_ERROR、BUFFERING_STARTED/STOPPED 事件MMAPI 的靈活性在於統一抽象了多種媒體型別,掌握上述模式即可應對絕大多數 Java ME 多媒體開發需求。