Files
Obsidian-Main/20.1. Android/AudioTrack.md

2.9 KiB
Raw Blame History

AudioTrackMediaPlayer 都可以播放聲音,主要差別是 AudioTrack 沒有 decode 的能力,只能播放 PCM。MediaPlayer 除了可以 demux、decode 以外也可以播放video。

底層原理

每一個 audio stream 對應著一個 AudioTrack 類的一個實例,每個 AudioTrack 會在建立時會註冊到 AudioFlinger 中,由 AudioFlinger 把所有的 AudioTrack 進行混合Mixer然後輸送到 AudioHardware 中 進行播放,目前 Android 同時最多可以創建32個音頻流也就是說Mixer 最多會同時處理32個 AudioTrack 的資料。

建立 AudioTrack 物件

const val SAMPLE_RATE = 44100  
const val CHANNEL_OUT_FORMAT = AudioFormat.CHANNEL_OUT_STEREO  
const val AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT
var audioBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_OUT_FORMAT, AUDIO_FORMAT)

audioTrack = AudioTrack(
    AudioManager.STREAM_MUSIC,
    SAMPLE_RATE,  
    CHANNEL_OUT_FORMAT,  
    AUDIO_FORMAT,  
    audioBufferSize,
    AudioTrack.MODE_STREAM)
audioTrack?.play()

其中需要注意的是最後一個參數,AudioTrack 有兩種模式,分別是 AudioTrack.MODE_STREAMAudioTrack.MODE_STATIC

AudioTrack.MODE_STREAM

這個模式會邊讀邊播,必須不停的使用 AudioTrack.write() 來將資料寫入,若是來不及寫入會造成斷音,先呼叫 AudioTrack.play(),然後開始填資料,透過 AudioTrack.write()

AudioTrack.MODE_STATIC

這個模式中audioBufferSize 就是你要播放的聲音長度,一樣要透過 AudioTrack.write() 來寫入資料,寫完之後呼叫 AudioTrack.play() 開始播放。

狀態判斷

getState()

getState() : Int 來取得目前的狀態。

  • STATE_INITIALIZED 表示 AudioTrack 已經是可以使用了。
  • STATE_UNINITIALIZED 表示 AudioTrack 創建時沒有成功地初始化。
  • STATE_NO_STATIC_DATA 表示當前是使用 MODE_STATIC ,但是還沒往緩衝區中寫入數據。當接收數據之後會變為 STATE_INITIALIZED 狀態。

getPlayState()

getPlayState() : Int 來取得目前的播放狀態。

  • PLAYSTATE_STOPPED 停止
  • PLAYSTATE_PAUSED 暫停
  • PLAYSTATE_PLAYING 正在播放

暫停

pause() 可以暫停播放,但是暫存區不會被清空

停止

如果是 AudioTrack.MODE_STREAM mode需要先呼叫 pause() 再呼叫 flush() 才能馬上停止,否則會等暫存區清空才停止。 AudioTrack.MODE_STATIC mode 直接使用 stop() 即可。

釋放

使用 release() 來結束資源。

參考