首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

J2ME MMAPI 聲音播放實戰:從 JAR 資源流式加載 WAV 到 Player 生命周期控制

     編輯:Java 程式設計入門

前言:聲音是遊戲靈魂,MMAPI 是標準接口

Mobile Media API (MMAPI, JSR-135) 是 MIDP 1.0 可選包、MIDP 2.0 必選包。主流手機支持 WAV、MIDI、MP3 (部分)。本文演示最常見場景:**從 JAR 內部資源流式加載 WAV 文件並播放**,含完整異常處理與生命周期控制。

一、核心類與流程

二、標準播放流程 (三步走)

1. 獲取資源流

// WAV 文件位於 JAR 根目錄 /res/raw/autorun.wav
InputStream is = this.getClass().getResourceAsStream("/res/raw/autorun.wav");
// 注意:以 '/' 開頭表示從 classpath 根路徑 (JAR 根) 查找

2. 創建 Player

// MIME 類型:audio/x-wav (WAV)、audio/midi (MIDI)、audio/mpeg (MP3)
Player player = Manager.createPlayer(is, "audio/x-wav");

3. 實現 PlayerListener 異步處理 (生產級必備)

player.addPlayerListener(new PlayerListener() {
    public void playerUpdate(Player player, String event, Object eventData) {
        if (PlayerListener.END_OF_MEDIA.equals(event)) {
            System.out.println("播放自然結束");
            // 可在此觸發下一首、循環邏輯、釋放資源
        } else if (PlayerListener.ERROR.equals(event)) {
            System.err.println("播放錯誤: " + eventData);
        } else if (PlayerListener.DEVICE_UNAVAILABLE.equals(event)) {
            System.err.println("音頻設備被搶佔 (來電/錄音)");
        }
    }
});

4. 啟動播放

player.start(); // 異步非阻塞

// 設置循環次數 (0=無限循環, 1=播放一次, n=播放 n 次)
player.setLoopCount(3);

5. 生命周期管理 (MIDlet 整合)

public class SoundMIDlet extends MIDlet {
    private Player player = null;

    public SoundMIDlet() {
        try {
            InputStream is = getClass().getResourceAsStream("/Autorun.wav");
            player = Manager.createPlayer(is, "audio/x-wav");
            player.addPlayerListener(new PlayerListener() { /* 見上 */ });
        } catch (IOException | MediaException e) {
            System.err.println("Player 初始化失敗: " + e);
        }
    }

    public void startApp() {
        if (player != null) {
            try { player.start(); } 
            catch (MediaException e) { System.err.println("Start 失敗: " + e); }
        }
    }

    public void pauseApp() {
        if (player != null) {
            try { player.stop(); } catch (MediaException e) { /* ignore */ }
        }
    }

    public void destroyApp(boolean unconditional) {
        if (player != null) {
            try { player.close(); } catch (MediaException e) { /* ignore */ }
            player = null;
        }
    }
}

三、進階控制技巧

1. 精確定位與片段播放

// 獲取媒體總時長 (毫秒)
long duration = player.getDuration(); // TIME_UNKNOWN 表示不可知 (如流媒體)

// 設置播放位置
player.setMediaTime(5000); // 跳轉到 5 秒處

// 獲取當前播放位置
long current = player.getMediaTime();

2. 音量控制

VolumeControl vc = (VolumeControl) player.getControl("VolumeControl");
if (vc != null) {
    vc.setLevel(50); // 0-100
    vc.setMute(false);
}

3. 預取與緩衝 (減少首次啟動延遲)

player.prefetch(); // 預載媒體數據到緩衝區,阻塞直到 READY 狀態
// 隨後 start() 近乎瞬間啟動
// 適用於遊戲關鍵音效 (射擊、爆炸) 必須零延遲響應

四、格式兼容性與測試矩陣

類/接口包職責
Managerjavax.microedition.media創建 Player、播放簡單音調、獲取支持格式列表
Playerjavax.microedition.media媒體播放控制器 (start/stop/close, setLoopCount, setMediaTime)
PlayerListenerjavax.microedition.media異步事件回調 (END_OF_MEDIA, ERROR, DEVICE_UNAVAILABLE)
VolumeControljavax.microedition.media.control音量調節 (0-100)、靜音

建議:遊戲音效統一用 **WAV (8kHz/16bit/單聲道)**,背景音樂用 **MIDI** 或 **AMR**,兼顧體積與兼容性。

五、常見坑點避坑指南

格式MIME 類型典型支持設備備註
WAV (PCM)audio/x-wav幾乎所有 MIDP 2.0 手機無壓縮、體積大、兼容性最好
MIDI (SP-MIDI)audio/midi絕大多數功能機/早期智能機合成音樂、體積極小、音色依賴設備
AMR-NBaudio/amr諾基亞 S40/S60、索愛語音編碼、通話錄音常用
MP3audio/mpeg高端智能機 (MIDP 2.0+ 專有擴展)授權費用高、解碼 CPU 佔用大
現象原因解決
createPlayer 拋 MediaException格式不支持 / 數據損壞 / MIME 錯誤Manager.getSupportedContentTypes(null) 檢查支持列表;確認 MIME 大小寫
start() 靜默失敗、無聲音設備被佔用 / 音量為 0 / 流未預取prefetch() + VolumeControl 檢查;捕獲 MediaException
播放中來電導致聲音中斷DEVICE_UNAVAILABLE 事件PlayerListener 中處理:pauseApp stop(), 通話結束 re-prefetch+start
JAR 體積過大導致安裝失敗WAV 文件過多/過大降低採樣率 (8kHz)、單聲道、外部下載、動態生成音調 (Manager.playTone)
模擬器正常、真機無聲真機不支持該格式/採樣率真機測試矩陣覆蓋主流機型;提供降級格式

六、結語

MMAPI 以 **Manager → Player → Control/Listener** 清晰分層,提供了功能完整的移動媒體播放能力。掌握 **資源流獲取、MIME 類型匹配、PlayerListener 異步處理、prefetch 零延遲啟動、生命周期綁定 MIDlet** 五大核心技能,即可在 J2ME 遊戲/應用中實現專業級音頻體驗。記住:**真機測試是唯一標準**,模擬器無法完全模擬硬件解碼器行為。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved