標籤:android blog http java 使用 檔案
Android的MediaPlayer包含了Audio和video的播放功能,在Android的介面上,Music和Video兩個應用程式都是調用MediaPlayer實現的。MediaPlayer在底層是基於OpenCore(PacketVideo)的庫實現的,為了構建一個MediaPlayer程式,上層還包含了進程間通訊等內容,這種進程間通訊的基礎是Android基本庫中的Binder機制。但是該類只能對完整的音頻檔案進行操作,而不能直接對純PCM音頻資料操作。假如我們通過解碼得到PCM資料來源,又當如何將它們播放?沒錯,就是用AudioTrack這個類(MediaPlayer內部也是調用該類進行真正的播放音頻流操作)下面這個DEMO示範了如何使用AudioTrack不囉嗦,先以下這個類對AudioTrack做了簡單封裝:
public class MyAudioTrack { int mFrequency; // 採樣率 int mChannel; // 聲道 int mSampBit; // 採樣精度 AudioTrack mAudioTrack; public MyAudioTrack(int frequency, int channel, int sampbit){ mFrequency = frequency; mChannel = channel; mSampBit = sampbit; } public void init(){ if (mAudioTrack != null){ release(); }// 獲得構建對象的最小緩衝區大小 int minBufSize = AudioTrack.getMinBufferSize(mFrequency, mChannel, mSampBit); // STREAM_ALARM:警告聲// STREAM_MUSCI:音樂聲,例如music等// STREAM_RING:鈴聲// STREAM_SYSTEM:系統聲音// STREAM_VOCIE_CALL:電話聲音 mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, mFrequency, mChannel, mSampBit, minBufSize, AudioTrack.MODE_STREAM);// AudioTrack中有MODE_STATIC和MODE_STREAM兩種分類。// STREAM的意思是由使用者在應用程式通過write方式把資料一次一次得寫到audiotrack中。// 這個和我們在socket中發送資料一樣,應用程式層從某個地方擷取資料,例如通過編解碼得到PCM資料,然後write到audiotrack。// 這種方式的壞處就是總是在JAVA層和Native層互動,效率損失較大。// 而STATIC的意思是一開始建立的時候,就把音頻資料放到一個固定的buffer,然後直接傳給audiotrack,// 後續就不用一次次得write了。AudioTrack會自己播放這個buffer中的資料。// 這種方法對於鈴聲等記憶體佔用較小,延時要求較高的聲音來說很適用。 mAudioTrack.play(); }public void release(){ if (mAudioTrack != null){ mAudioTrack.stop(); mAudioTrack.release(); } } public void playAudioTrack(byte []data, int offset, int length){ if (data == null || data.length == 0){ return ; } try { mAudioTrack.write(data, offset, length); } catch (Exception e) { // TODO: handle exception Log.i("MyAudioTrack", "catch exception..."); } } public int getPrimePlaySize(){ int minBufSize = AudioTrack.getMinBufferSize(mFrequency, mChannel, mSampBit); return minBufSize * 2; }}
mAudioTrack.write(data, offset, length);該函數正是將資料寫入硬體播放的關鍵!