O AOQ Client SDK oferece suporte à reprodução de áudio personalizada. Por meio do mecanismo de callback de quadros de áudio, os dados PCM decodificados são entregues à camada de aplicação, permitindo a implementação de uma lógica própria de renderização de áudio.
Visão geral
Por padrão, o AOQ Client SDK reproduz os dados de áudio remoto recebidos pelo alto-falante ou auricular do sistema. Em alguns cenários, o módulo de reprodução de áudio integrado do SDK pode não atender às suas necessidades. A reprodução de áudio personalizada é útil quando você precisa:
- Direcionar os dados de áudio recebidos para um dispositivo de reprodução personalizado ou pipeline de processamento de áudio.
- Pós-processar os dados de áudio recebidos, por exemplo, para reconhecimento de fala por IA ou efeitos sonoros.
- Contornar conflitos com dispositivos de reprodução de áudio.
O AOQ Client SDK fornece suporte flexível para reprodução personalizada. Por meio do mecanismo de callback de quadros de áudio, os dados PCM decodificados chegam à camada de aplicação para renderização e reprodução.
Código de exemplo
Em breve.
Pré-requisitos
- Uma instância de engine foi criada pela chamada de
createEngine. - Uma conexão com o servidor foi estabelecida (o callback
onConnectionStatusChangereportouAoqConnectionStatusConnected).
Implementação
1. Inicie a reprodução de áudio no modo externo
Ao chamar startAudioPlayer, defina isExternal=true para desativar o dispositivo interno de renderização de áudio do SDK. Assim, a camada de aplicação assume a responsabilidade pela reprodução do áudio.
AoqClientEngine.AoqAudioPlaybackConfig config = new AoqClientEngine.AoqAudioPlaybackConfig();
config.isExternal = true; // Disable SDK internal playback; application layer renders audio
config.channel = 1; // Number of channels
engine.startAudioPlayer(config);
Parâmetros:
Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
isVoipMode | boolean | false | Indica se o modo VoIP deve ser ativado (AEC via hardware). Válido em dispositivos móveis. |
isDefaultSpeaker | boolean | true | Defina se o alto-falante será usado por padrão. Válido em dispositivos móveis. |
isExternal | boolean | false | Especifica se o modo de reprodução externa será utilizado. Quando verdadeiro, o SDK não abre o dispositivo de reprodução. |
channel | int | 1 | Número de canais |
2. Configure o listener de callback de quadros de áudio
Chame setAudioFrameObserver para registrar o listener de callback de dados de quadros de áudio. Implemente o método de callback onPlaybackAudioFrame para receber os dados PCM de reprodução.
engine.setAudioFrameObserver(new AoqClientListener.AoqAudioFrameListener() {
@Override
public void onPlaybackAudioFrame(@NonNull AoqClientEngine.AoqAudioFrameData frame) {
// Process the received playback audio data here
// frame.dataPtr: PCM data
// frame.numOfSamples: number of samples
// frame.numOfChannels: number of channels
// frame.samplesPerSec: sample rate
// frame.bytesPerSample: bytes per sample
playPcmData(frame);
}
});
3. Ative os callbacks de dados de reprodução
Execute enableAudioFrameObserver para ativar os callbacks de quadros de áudio na posição de reprodução. Especifique a source de dados como AoqAudioSourcePlayback.
AoqClientEngine.AoqAudioObserverConfig observerConfig = new AoqClientEngine.AoqAudioObserverConfig();
observerConfig.sampleRate = 48000; // Callback audio sample rate
observerConfig.channels = 1; // Callback audio channel count
observerConfig.mode = AoqClientEngine.AoqAudioObserverMode.AoqAudioObserverModeReadOnly; // Read-only mode
engine.enableAudioFrameObserver(
true, // Enable callbacks
AoqClientEngine.AoqAudioSource.AoqAudioSourcePlayback, // Playback data source
observerConfig
);
Parâmetros:
Parâmetro | Tipo | Padrão | Descrição |
|---|---|---|---|
sampleRate | int | 48000 | Taxa de amostragem do áudio no callback (Hz) |
channels | int | 1 | Quantidade de canais de áudio no callback |
mode | AoqAudioObserverMode | AoqAudioObserverModeReadOnly | Modo de leitura/escrita |
4. Implemente a renderização de áudio personalizada
Quando os dados PCM chegarem ao callback onPlaybackAudioFrame, a camada de aplicação cuidará da renderização e da reprodução. As abordagens mais comuns incluem:
- Android AudioTrack: Escreva os dados PCM no dispositivo de áudio do sistema usando AudioTrack.
- Reconhecimento de fala por IA: Encaminhe os dados PCM para um motor ASR destinado ao reconhecimento de fala.
- Efeitos de áudio: Aplique efeitos sonoros aos dados PCM antes da reprodução.
- Armazenamento em arquivo: Salve os dados de áudio recebidos em um arquivo local.
// Example: Playback using 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);
}
}
Observações importantes:
- O callback
onPlaybackAudioFrameé executado em uma thread interna do SDK. O ponteiroframe.dataPtrpermanece válido apenas durante a execução do callback. Caso precise usar os dados de forma assíncrona, faça uma cópia deles previamente. - A operação
AudioTrack.writeé bloqueante. Escrever diretamente dentro do callback é aceitável, pois o SDK entrega os callbacks em uma taxa controlada. - Mantenha a flag
mPlayRunningpara interromper o processamento quando a engine for encerrada ou a reprodução parar.
5. Interrompa a reprodução personalizada
Quando a reprodução personalizada não for mais necessária, desative primeiro o callback de quadros de áudio. Em seguida, pare o dispositivo de reprodução e libere os recursos do AudioTrack.
// 1. Disable audio frame callbacks at the playback position
AoqClientEngine.AoqAudioObserverConfig observerConfig = new AoqClientEngine.AoqAudioObserverConfig();
engine.enableAudioFrameObserver(
false, // Disable callbacks
AoqClientEngine.AoqAudioSource.AoqAudioSourcePlayback,
observerConfig
);
// 2. Remove the audio frame callback listener
engine.setAudioFrameObserver(null);
// 3. Stop SDK audio playback
engine.stopAudioPlayer();
// 4. Release AudioTrack resources
mPlayRunning = false;
if (mAudioTrack != null) {
mAudioTrack.stop();
mAudioTrack.release();
mAudioTrack = null;
}