Skip to main content

Reproducción de audio personalizada

El AOQ Client SDK admite la reproducción de audio personalizada. A través del mecanismo de devolución de llamada de tramas de audio, los datos PCM decodificados se entregan a la capa de aplicación, lo que le permite implementar su propia lógica de renderización de audio.

Visión general

De forma predeterminada, el AOQ Client SDK reproduce los datos de audio remoto recibidos a través del altavoz o auricular del sistema. En algunos escenarios, el módulo de reproducción de audio integrado del SDK puede no satisfacer sus necesidades. La reproducción de audio personalizada es útil cuando necesita:
  • Enviar los datos de audio recibidos a un dispositivo de reproducción personalizado o a una canalización de procesamiento de audio.
  • Posprocesar los datos de audio recibidos, por ejemplo, para reconocimiento de voz por IA o efectos de audio.
  • Solucionar conflictos de dispositivos de reproducción de audio.
El AOQ Client SDK proporciona soporte flexible para reproducción personalizada. A través del mecanismo de devolución de llamada de tramas de audio, los datos PCM decodificados se entregan a la capa de aplicación para que usted los renderice y reproduzca.

Requisitos previos

  • Se ha creado una instancia del motor llamando a createEngine.
  • Se ha establecido una conexión con el servidor (la devolución de llamada onConnectionStatusChange ha reportado AoqConnectionStatusConnected).

Implementación

1. Iniciar la reproducción de audio en modo externo

Al llamar a startAudioPlayer, establezca isExternal=true para desactivar el dispositivo de renderización de audio interno del SDK. La capa de aplicación será entonces responsable de reproducir el audio.
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

Predeterminado

Descripción

isVoipMode

boolean

false

Indica si se debe activar el modo VoIP (AEC por hardware). Válido en dispositivos móviles.

isDefaultSpeaker

boolean

true

Indica si se debe usar el altavoz de forma predeterminada. Válido en dispositivos móviles.

isExternal

boolean

false

Indica si se debe usar el modo de reproducción externa. Cuando es true, el SDK no abre el dispositivo de reproducción.

channel

int

1

Número de canales

2. Configurar el listener de devolución de llamada de tramas de audio

Llame a setAudioFrameObserver para registrar el listener de devolución de llamada de datos de tramas de audio. Implemente el método de devolución de llamada onPlaybackAudioFrame para recibir los datos PCM de reproducción.
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. Habilitar las devoluciones de llamada de datos de reproducción

Llame a enableAudioFrameObserver para habilitar las devoluciones de llamada de tramas de audio en la posición de reproducción. Especifique la fuente de datos 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

Predeterminado

Descripción

sampleRate

int

48000

Tasa de muestreo de audio de la devolución de llamada (Hz)

channels

int

1

Recuento de canales de audio del callback

mode

AoqAudioObserverMode

AoqAudioObserverModeReadOnly

Modo de lectura/escritura

4. Implementar la renderización de audio personalizada

Cuando llegan datos PCM en la devolución de llamada onPlaybackAudioFrame, la capa de aplicación maneja la renderización y la reproducción. Los enfoques comunes incluyen:
  • Android AudioTrack: Escriba los datos PCM en el dispositivo de audio del sistema mediante AudioTrack.
  • Reconocimiento de voz por IA: Pase los datos PCM a un motor ASR para el reconocimiento de voz.
  • Efectos de audio: Aplique efectos de audio a los datos PCM antes de la reproducción.
  • Almacenamiento de archivos: Guarde los datos de audio recibidos en un archivo 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);
    }
}
Notas importantes:
  • La devolución de llamada onPlaybackAudioFrame se ejecuta en un hilo interno del SDK. El frame.dataPtr solo es válido durante la devolución de llamada. Si necesita usar los datos de forma asíncrona, cópielos primero.
  • AudioTrack.write es una operación bloqueante. Escribir directamente dentro de la devolución de llamada es adecuado porque el SDK entrega las devoluciones de llamada a una tasa controlada.
  • Mantenga la bandera mPlayRunning para poder detener el procesamiento cuando el motor finalice o se detenga la reproducción.

5. Detener la reproducción personalizada

Cuando ya no se necesite la reproducción personalizada, desactive primero la devolución de llamada de tramas de audio, luego detenga el dispositivo de reproducción y libere los recursos de 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;
}