45 lines
2.1 KiB
Markdown
45 lines
2.1 KiB
Markdown
AudioTrack 和 MediaPlayer 都可以播放聲音,主要差別是 AudioTrack 沒有 decode 的能力,只能播放 PCM。
|
||
|
||
## 底層原理
|
||
每一個 audio stream 對應著一個 AudioTrack 類的一個實例,每個 AudioTrack 會在建立時會註冊到 AudioFlinger 中,由 AudioFlinger 把所有的 AudioTrack 進行混合(Mixer),然後輸送到 AudioHardware中 進行播放,目前 Android 同時最多可以創建32個音頻流,也就是說,Mixer 最多會同時處理32個 AudioTrack 的資料。
|
||
|
||
## 建立 AudioTrack 物件
|
||
```kotlin
|
||
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_STREAM 與 AudioTrack.MODE_STATIC。
|
||
|
||
## AudioTrack.MODE_STREAM
|
||
這個模式會邊讀邊播,必須不停的使用 `AudioTrack.write()` 來將資料寫入,若是來不及寫入會造成斷音,可以先呼叫 AudioTrack.play(),然後開始填資料。
|
||
|
||
## AudioTrack.MODE_STATIC
|
||
這個模式中,audioBufferSize 就是你要播放的聲音長度,一樣要透過 `AudioTrack.write()` 來寫入資料,寫完之後呼叫 AudioTrack.play() 開始播放。
|
||
|
||
## 狀態判斷
|
||
### `getState()`
|
||
用 `getState()` 來取得目前的狀態。
|
||
- STATE_INITIALIZED 表示AudioTrack 已經是可以使用了。
|
||
- STATE_UNINITIALIZED 表示AudioTrack 創建時沒有成功地初始化。
|
||
- STATE_NO_STATIC_DATA 表示當前是使用MODE_STATIC ,但是還沒往緩衝區中寫入數據。當接收數據之後會變為STATE_INITIALIZED 狀態。
|
||
|
||
### `getPlayState()`
|
||
用 `getPlayState()` 來取得目前的播放狀態。
|
||
- PLAYSTATE_STOPPED 停止
|
||
- PLAYSTATE_PAUSED 暫停
|
||
- PLAYSTATE_PLAYING 正在播放
|
||
|
||
## 暫停
|
||
`pause()` 可以暫停播放,但是暫存區不會被清空 |