

# SDK de transmisión de IVS: modos de audio móvil \| Transmisión en tiempo real
<a name="broadcast-mobile-audio-modes"></a>

La calidad del audio es una parte importante de la experiencia multimedia de cualquier equipo real, y no existe una configuración de audio única que funcione mejor para todos los casos de uso. Para garantizar que sus usuarios disfruten de la mejor experiencia al escuchar una transmisión en tiempo real de IVS, nuestros SDK para dispositivos móviles ofrecen varias configuraciones de audio predefinidas, así como personalizaciones más potentes, según sea necesario.

## Introducción
<a name="broadcast-mobile-audio-modes-introduction"></a>

Los SDK de transmisión móvil de IVS ofrecen una clase `StageAudioManager`. Esta clase está diseñada para ser el único punto de contacto para controlar los modos de audio subyacentes en ambas plataformas. En Android, esto controla el [AudioManager](https://developer.android.com/reference/android/media/AudioManager), incluidos el modo de audio, la fuente de audio, el tipo de contenido, el uso y los dispositivos de comunicación. En iOS, controla la aplicación [AVAudioSession](https://developer.apple.com/documentation/avfaudio/avaudiosession), así como si [VoiceProcessing](https://developer.apple.com/documentation/avfaudio/avaudioionode/3152101-voiceprocessingenabled?language=objc) está habilitado.

**Importante**: no interactúe con `AVAudioSession` ni `AudioManager` directamente mientras el SDK de transmisión en tiempo real de IVS esté activo. Si lo hace, podría perderse el audio o grabarse o reproducirse en el dispositivo incorrecto.

Antes de crear el primer objeto `DeviceDiscovery` o `Stage`, debe estar configurada la clase `StageAudioManager`.

------
#### [ Android (Kotlin) ]

```
StageAudioManager.getInstance(context).setPreset(StageAudioManager.UseCasePreset.VIDEO_CHAT) // The default value

val deviceDiscovery = DeviceDiscovery(context)
val stage = Stage(context, token, this)

// Other Stage implementation code
```

------
#### [ iOS (Swift) ]

```
IVSStageAudioManager.sharedInstance().setPreset(.videoChat) // The default value

let deviceDiscovery = IVSDeviceDiscovery()
let stage = try? IVSStage(token: token, strategy: self)

// Other Stage implementation code
```

------

Si no hay nada establecido en `StageAudioManager` antes de la inicialización de una instancia `DeviceDiscovery` o `Stage`, el ajuste preestablecido `VideoChat` se aplica automáticamente.

## Ajustes preestablecidos de casos de uso de audio
<a name="broadcast-mobile-audio-modes-presets"></a>

El SDK de transmisión en tiempo real proporciona tres ajustes preestablecidos, cada uno adaptado a los casos de uso más comunes, tal y como se describe a continuación. Para cada ajuste preestablecido, cubrimos cinco categorías clave que diferencian los ajustes preestablecidos entre sí.

La categoría **Control de volumen** hace referencia al tipo de volumen (volumen de contenido multimedia o volumen de llamadas) que se utiliza o se cambia mediante los controles de volumen físicos del dispositivo. Tenga en cuenta que esto afecta al volumen al cambiar de modo de audio. Por ejemplo, supongamos que el volumen del dispositivo está ajustado al valor máximo mientras se utiliza el ajuste preestablecido de chat de video. Al cambiar al ajuste preestablecido Suscripción única, el nivel de volumen es diferente al del sistema operativo, lo que podría provocar un cambio de volumen significativo en el dispositivo.

### Chat de vídeo
<a name="audio-modes-presets-video-chat"></a>

Este es el ajuste preestablecido predeterminado, diseñado para cuando el dispositivo local va a mantener una conversación en tiempo real con otros participantes.

**Problema conocido en iOS**: al usar este ajuste preestablecido y no conectar un micrófono, el audio se reproduce a través del auricular en lugar del altavoz del dispositivo. Use este ajuste preestablecido solo en combinación con un micrófono.


| Categoría | Android | iOS | 
| --- | --- | --- | 
| Cancelación de eco | Habilitado | Habilitado | 
| Supresión de ruido | Habilitado | Habilitado | 
| Control de volumen | Volumen de llamadas | Volumen de llamadas | 
| Selección de micrófono | Limitado según el sistema operativo. Es posible que los micrófonos USB no estén disponibles. | Limitado según el sistema operativo. Es posible que los micrófonos USB y Bluetooth no estén disponibles.<br />Deberían funcionar los auriculares Bluetooth que admiten tanto la entrada como la salida al mismo tiempo; por ejemplo, los AirPods. | 
| Salida de audio | Cualquier dispositivo de salida debería funcionar. | Limitado según el sistema operativo. Es posible que los auriculares con cable no estén disponibles. | 
| Calidad de audio | Media/baja. Sonará como una llamada telefónica, no como una reproducción multimedia. | Media/baja. Sonará como una llamada telefónica, no como una reproducción multimedia. | 

### Suscripción única
<a name="audio-modes-presets-subscribe-only"></a>

Este ajuste preestablecido está diseñado para suscribir a otros participantes de la publicación, pero no para publicar usted mismo. Se centra en la calidad del audio y es compatible con todos los dispositivos de salida disponibles.


| Categoría | Android | iOS | 
| --- | --- | --- | 
| Cancelación de eco | Deshabilitad | Deshabilitado | 
| Supresión de ruido | Deshabilitad | Deshabilitado | 
| Control de volumen | Volumen multimedia | Volumen multimedia | 
| Selección de micrófono | N/A, este ajuste preestablecido no está diseñado para su publicación. | N/A, este ajuste preestablecido no está diseñado para su publicación. | 
| Salida de audio | Cualquier dispositivo de salida debería funcionar. | Cualquier dispositivo de salida debería funcionar. | 
| Calidad de audio | Alta. Cualquier tipo multimedia debería mostrarse con claridad, incluida la música. | Alta. Cualquier tipo multimedia debería mostrarse con claridad, incluida la música. | 

### Studio
<a name="audio-modes-presets-studio"></a>

Este ajuste preestablecido está diseñado para una suscripción de alta calidad y, al mismo tiempo, permite publicar. Requiere el hardware de grabación y reproducción para poder cancelar el eco. Un caso de uso en este caso sería usar un micrófono USB y unos auriculares con cable. El SDK mantendrá la más alta calidad de audio y, al mismo tiempo, se basará en la separación física de esos dispositivos para evitar que produzcan eco.


| Categoría | Android | iOS | 
| --- | --- | --- | 
| Cancelación de eco | Deshabilitad | Deshabilitado | 
| Supresión de ruido | Deshabilitad | Deshabilitado | 
| Control de volumen | Volumen multimedia en la mayoría de los casos. Volumen de llamadas cuando hay un micrófono Bluetooth conectado.  | Volumen multimedia | 
| Selección de micrófono | Cualquier micrófono debería funcionar. | Cualquier micrófono debería funcionar. | 
| Salida de audio | Cualquier dispositivo de salida debería funcionar. | Cualquier dispositivo de salida debería funcionar. | 
| Calidad de audio | Alta. Ambos lados deberían poder enviar música y escucharla con claridad en el otro lado.<br />Cuando se conecta un auricular Bluetooth, la calidad del audio disminuirá debido a que el modo Bluetooth SCO está activado. | Alta. Ambos lados deberían poder enviar música y escucharla con claridad en el otro lado.<br />Cuando se conecta un auricular Bluetooth, la calidad del audio puede disminuir debido a la activación del modo Bluetooth SCO, en función del auricular.  | 

## Casos de uso avanzados
<a name="broadcast-mobile-audio-modes-advanced-use-cases"></a>

Más allá de los ajustes preestablecidos, los SDK de transmisión en tiempo real de iOS y Android permiten configurar los modos de audio de la plataforma subyacente:
+ En Android, configure [AudioSource](https://developer.android.com/reference/android/media/MediaRecorder.AudioSource), [Usage](https://developer.android.com/reference/android/media/AudioAttributes#USAGE_ALARM) y [ContentType](https://developer.android.com/reference/android/media/AudioAttributes#CONTENT_TYPE_MOVIE).
+ En iOS, use [AVAudioSession.Category](https://developer.apple.com/documentation/avfaudio/avaudiosession/category), [AVAudioSession.CategoryOptions](https://developer.apple.com/documentation/avfaudio/avaudiosession/categoryoptions), [AVAudioSession.Mode](https://developer.apple.com/documentation/avfaudio/avaudiosession/mode) y la posibilidad de activar o no el [procesamiento de voz](https://developer.apple.com/documentation/avfaudio/avaudioionode/3152101-voiceprocessingenabled?language=objc) durante la publicación.

Nota: Al utilizar estos métodos del SDK de audio, es posible configurar incorrectamente la sesión de audio subyacente. Por ejemplo, si se utiliza la opción `.allowBluetooth` en iOS en combinación con la categoría `.playback`, se crea una configuración de audio no válida y el SDK no puede grabar ni reproducir audio. Estos métodos están diseñados para usarse solo cuando una aplicación tiene requisitos específicos de sesión de audio que se han validado.

------
#### [ Android (Kotlin) ]

```
// This would act similar to the Subscribe Only preset, but it uses a different ContentType.
StageAudioManager.getInstance(context)
    .setConfiguration(StageAudioManager.Source.GENERIC,
                      StageAudioManager.ContentType.MOVIE,
                      StageAudioManager.Usage.MEDIA);

val stage = Stage(context, token, this)

// Other Stage implementation code
```

------
#### [ iOS (Swift) ]

```
// This would act similar to the Subscribe Only preset, but it uses a different mode and options.
IVSStageAudioManager.sharedInstance()
    .setCategory(.playback,
                 options: [.duckOthers, .mixWithOthers],
                 mode: .default)

let stage = try? IVSStage(token: token, strategy: self)

// Other Stage implementation code
```

------

### Cancelación de eco de iOS
<a name="advanced-use-cases-ios_echo_cancellation"></a>

La cancelación de eco de iOS también se puede controlar de forma independiente a través de `IVSStageAudioManager` y mediante el método `echoCancellationEnabled`. Este método controla si el [procesamiento de voz](https://developer.apple.com/documentation/avfaudio/avaudioionode/3152101-voiceprocessingenabled?language=objc) está habilitado en los nodos de entrada y salida de la propiedad subyacente `AVAudioEngine` utilizada por el SDK. Es importante comprender el efecto de cambiar esta propiedad de forma manual:
+ La propiedad `AVAudioEngine` solo se respeta si el micrófono del SDK está activo; esto es necesario debido al requisito de iOS de que el procesamiento de voz esté habilitado simultáneamente en los nodos de entrada y salida. Normalmente, esto se hace con el micrófono devuelto por `IVSDeviceDiscovery` para crear un objeto `IVSLocalStageStream` y publicarlo. Como alternativa, el micrófono se puede habilitar, sin que se utilice para publicar, mediante la asociación de un objeto `IVSAudioDeviceStatsCallback` al propio micrófono. Este enfoque alternativo resulta útil si se necesita cancelar el eco al utilizar un micrófono basado en un origen de audio personalizado en lugar del micrófono del SDK del IVS.
+ Para habilitar la propiedad `AVAudioEngine`, se requiere el modo `.videoChat` o `.voiceChat`. Al solicitar otro modo, la estructura de audio subyacente de iOS se opone al SDK, lo que provoca la pérdida de audio.
+ Al habilitar `AVAudioEngine`, la opción `.allowBluetooth ` se habilita automáticamente.

Los comportamientos pueden variar según el dispositivo y la versión de iOS.

### Orígenes de audio personalizados para iOS
<a name="advanced-use-cases-ios_custom_audio_sources"></a>

Los orígenes de audio personalizados se pueden usar con el SDK mediante `IVSDeviceDiscovery.createAudioSource`. Al conectarse a una fase, el SDK de retransmisión en tiempo real de IVS sigue administrando una instancia de `AVAudioEngine` interna para la reproducción de audio, aunque no se utilice el micrófono del SDK. Como resultado, los valores proporcionados a `IVSStageAudioManager` deben ser compatibles con el audio que proporciona el origen de audio personalizado.

Si el origen de audio personalizado que se utiliza para publicar graba desde el micrófono pero lo administra la aplicación host, el SDK de cancelación de eco anterior no funcionará a menos que el micrófono administrado por el SDK esté activado. Para evitar ese requisito, consulte [Cancelación de eco de iOS](#advanced-use-cases-ios_echo_cancellation).

### Publicación con Bluetooth en Android
<a name="advanced-use-cases-bluetooth-android"></a>

El SDK vuelve automáticamente al `VIDEO_CHAT` preestablecido en Android cuando se cumplen las siguientes condiciones:
+ La configuración asignada no usa el valor de uso `VOICE_COMMUNICATION`.
+ Hay un micrófono Bluetooth conectado al dispositivo.
+ El participante local está publicando en un escenario.

Esta es una limitación del sistema operativo Android en lo que respecta al uso de auriculares Bluetooth para grabar audio.

## Integración con otros servicios de SDK
<a name="broadcast-mobile-audio-modes-integrating-other-sdks"></a>

Como tanto iOS como Android admiten solo un modo de audio activo por aplicación, es habitual que surjan conflictos si la aplicación utiliza varios SDK que requieren el control del modo de audio. Cuando se encuentre con estos conflictos, puede probar algunas estrategias de resolución habituales, que se explican a continuación.

### Coincidencia de los valores del modo de audio
<a name="integrating-other-sdks-match-values"></a>

Con las opciones de configuración de audio avanzadas del SDK de IVS o las funciones de otro SDK, haga que los dos SDK se alineen con los valores subyacentes.

### Ágora
<a name="integrating-other-sdks-agora"></a>

#### iOS
<a name="integrating-other-sdks-agora-ios"></a>

En iOS, decirle al SDK de Agora que mantenga la `AVAudioSession` activa evitará que se desactive mientras el SDK de transmisión en tiempo real de IVS lo esté utilizando.

```
myRtcEngine.SetParameters("{\"che.audio.keep.audiosession\":true}");
```

#### Android
<a name="integrating-other-sdks-agora-android"></a>

Evita llamar `setEnableSpeakerphone` en `RtcEngine`, y llame a `enableLocalAudio(false)` mientras publica con el SDK de transmisión en tiempo real de IVS. Puede volver a llamar a `enableLocalAudio(true)` cuando el SDK de IVS no esté publicándose.