AOQ Client SDK 支援自訂音頻播放功能,通過音訊框架回調機制將解碼後的 PCM 資料回調給應用程式層,由開發人員自行實現音頻渲染播放。
功能介紹
AOQ Client SDK 內部音頻模組預設會將接收到的遠端音頻資料通過系統擴音器/耳機播放,但在特定情境中,SDK 內部的音頻播放模組可能無法滿足開發需求,需要實現自訂音頻播放功能,例如:
- 需要將接收到的音頻資料輸出到自訂的播放裝置或音頻處理管線。
- 需要對接收到的音頻資料進行二次處理(如 AI 語音辨識、音效處理等)。
- 解決音頻播放裝置被佔用的問題。
AOQ Client SDK 支援靈活的自訂播放功能,通過音訊框架回調機制,將解碼後的 PCM 資料回調給應用程式層,由開發人員自行實現音頻渲染播放。
範例程式碼
暫無
前提條件
- 已建立引擎執行個體(調用
createEngine)。 - 已成功串連伺服器(
onConnectionStatusChange回調狀態為AoqConnectionStatusConnected)。
功能實現
1. 開啟音頻播放(外部模式)
調用 startAudioPlayer 時設定 isExternal=true,關閉 SDK 內部的音頻渲染裝置,由應用程式層自行處理音頻播放。
AoqClientEngine.AoqAudioPlaybackConfig config = new AoqClientEngine.AoqAudioPlaybackConfig();
config.isExternal = true; // 關閉 SDK 內部播放,由應用程式層自行渲染
config.channel = 1; // 聲道數
engine.startAudioPlayer(config);
參數說明:
參數 | 類型 | 預設值 | 說明 |
|---|---|---|---|
isVoipMode | boolean | false | 是否啟用 VoIP 模式(硬體AEC),移動端有效 |
isDefaultSpeaker | boolean | true | 是否預設擴音器,移動端有效 |
isExternal | boolean | false | 是否外部播放模式,true 時 SDK 不開啟播放裝置 |
channel | int | 1 | 聲道數 |
2. 設定音訊框架回調監聽
調用 setAudioFrameObserver 設定音訊框架資料回調監聽器,實現 onPlaybackAudioFrame 回調方法接收播放 PCM 資料。
engine.setAudioFrameObserver(new AoqClientListener.AoqAudioFrameListener() {
@Override
public void onPlaybackAudioFrame(@NonNull AoqClientEngine.AoqAudioFrameData frame) {
// 在此處理接收到的播放音頻資料
// frame.dataPtr: PCM 資料
// frame.numOfSamples: 採樣點數
// frame.numOfChannels: 聲道數
// frame.samplesPerSec: 採樣率
// frame.bytesPerSample: 每採樣點位元組數
playPcmData(frame);
}
});
3. 開啟播放資料回調
調用 enableAudioFrameObserver 開啟播放位置的音訊框架回調,指定資料來源為 AoqAudioSourcePlayback。
AoqClientEngine.AoqAudioObserverConfig observerConfig = new AoqClientEngine.AoqAudioObserverConfig();
observerConfig.sampleRate = 48000; // 回調音頻採樣率
observerConfig.channels = 1; // 回調音頻聲道數
observerConfig.mode = AoqClientEngine.AoqAudioObserverMode.AoqAudioObserverModeReadOnly; // 唯讀模式
engine.enableAudioFrameObserver(
true, // 開啟回調
AoqClientEngine.AoqAudioSource.AoqAudioSourcePlayback, // 播放資料來源
observerConfig
);
參數說明:
參數 | 類型 | 預設值 | 說明 |
|---|---|---|---|
sampleRate | int | 48000 | 回調音頻採樣率(Hz) |
channels | int | 1 | 回調音頻聲道數 |
mode | AoqAudioObserverMode | AoqAudioObserverModeReadOnly | 讀寫入模式 |
4. 實現自訂音頻渲染
在 onPlaybackAudioFrame 回調中接收到 PCM 資料後,由應用程式層自行實現音頻渲染播放。常見的實現方式:
- Android AudioTrack:通過 AudioTrack 將 PCM 資料寫入系統音訊裝置播放。
- AI 語音辨識:將 PCM 資料傳入 ASR 引擎進行語音辨識。
- 音效處理:對 PCM 資料進行音效處理後再播放。
- 檔案儲存體:將接收到的音頻資料儲存到本地檔案。
// 樣本:使用 Android AudioTrack 播放
private AudioTrack mAudioTrack;
private volatile boolean mPlayRunning = false;
private void initAudioTrack(int sampleRate, int channels) {
int channelConfig = (channels == 2)
? AudioFormat.CHANNEL_OUT_STEREO
: AudioFormat.CHANNEL_OUT_MONO;
int bufferSize = AudioTrack.getMinBufferSize(
sampleRate, channelConfig, AudioFormat.ENCODING_PCM_16BIT);
mAudioTrack = new AudioTrack(
AudioManager.STREAM_VOICE_CALL,
sampleRate,
channelConfig,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize,
AudioTrack.MODE_STREAM);
mAudioTrack.play();
mPlayRunning = true;
}
private void playPcmData(AoqClientEngine.AoqAudioFrameData frame) {
if (!mPlayRunning || mAudioTrack == null) {
return;
}
if (frame.dataPtr != null && frame.dataSize > 0) {
mAudioTrack.write(frame.dataPtr, 0, frame.dataSize);
}
}
注意事項:
onPlaybackAudioFrame回調在 SDK 內部線程觸發,回調中的frame.dataPtr僅在回調期間有效,非同步使用需自行拷貝。- AudioTrack.write 是阻塞操作,在回調中直接寫入即可,SDK 內部會按節奏回調。
- 需要維護
mPlayRunning標記,當引擎退出或停止播放時退出處理邏輯。
5. 停止自訂播放
當不再需要自訂播放時,先關閉音訊框架回調,再停止播放裝置,釋放 AudioTrack 資源。
// 1. 關閉播放位置的音訊框架回調
AoqClientEngine.AoqAudioObserverConfig observerConfig = new AoqClientEngine.AoqAudioObserverConfig();
engine.enableAudioFrameObserver(
false, // 關閉回調
AoqClientEngine.AoqAudioSource.AoqAudioSourcePlayback,
observerConfig
);
// 2. 移除音訊框架回調監聽
engine.setAudioFrameObserver(null);
// 3. 停止 SDK 音頻播放
engine.stopAudioPlayer();
// 4. 釋放 AudioTrack 資源
mPlayRunning = false;
if (mAudioTrack != null) {
mAudioTrack.stop();
mAudioTrack.release();
mAudioTrack = null;
}