Cómo compartir entradas de audio

La entrada de audio suele provenir del micrófono integrado, un micrófono externo de audio conectada al dispositivo. La entrada de audio también puede provenir una conversación telefónica.

A veces, es posible que dos o más apps quieran "capturar" la misma entrada de audio. Incluso para diferentes tareas. Por ejemplo, algunas aplicaciones que reciben audio pueden estar "grabando", como una simple grabadora de voz, mientras que otras podrían estar "escuchando", como el Asistente de Google o un servicio de accesibilidad que responder a comandos por voz.

En cualquier caso, esas apps quieren recibir entradas de audio. En esta página, usamos el término "captura" sin importar si una app está grabando o escuchando.

Si dos o más apps desean capturar audio al mismo tiempo, puede haber un problema. y entregar la señal de audio de la misma fuente a todos. En esta página, se describen cómo el sistema Android comparte la entrada de audio entre varias apps que capturan audio.

Comportamiento anterior a Android 10

En versiones anteriores a Android 10, solo una app a la vez podía capturar la transmisión de audio de entrada tiempo. Si una app ya estaba grabando o escuchando audio, podría crear un objeto AudioRecord, pero se mostrará un error cuando llames AudioRecord.startRecording() y la grabación no comenzaba.

Una excepción a esta regla fue cuando una app con privilegios (como Asistente de Google o una accesibilidad) tenía el permiso android.permission.CAPTURE_AUDIO_HOTWORD y usaste una fuente de audio de tipo HOTWORD En ese caso, otra app podía empezar a grabar. Cuando eso pasó, finalizaba la app con privilegios y la nueva app capturó la entrada.

Se agregó un cambio más en Android 9: solo las apps que se ejecutan en primer plano (o un servicio en primer plano) podrían capturar la entrada de audio. Cuando una app sin un servicio en primer plano o componente de IU en primer plano comenzaron a capturarse, la app siguió corriendo, pero recibía silencio, aun si era la única app que captaba de audio en ese momento.

Comportamiento de Android 10

El comportamiento anterior a Android 10 era "por orden de llegada". Una vez que una aplicación comienza a capturar audio, ninguna otra aplicación puede acceder al hasta que se detenga la app que está capturando audio.

Android 10 impone un esquema de prioridad que puede cambiar la transmisión de audio de entrada entre las apps mientras se ejecutan. En la mayoría de los casos, si una nueva app adquiere la entrada de audio la app que estaba capturando anteriormente continúa ejecutándose, pero recibe silencio. En algunos en estos casos, el sistema puede seguir entregando audio a ambas apps. Las diversas de uso compartido se explican a continuación.

Este esquema es similar a la forma en que el foco de audio controla varias apps por el uso de la salida de audio. Sin embargo, el foco de audio es administrado por las solicitudes programáticas para obtener y liberar el enfoque, mientras que el cambio de entrada esquema descrito aquí se basa en una política de priorización que se aplica automáticamente cada vez que una nueva app comienza a capturar audio.

Para la captura de audio, Android distingue dos tipos de apps:

  • “Común” y las apps instaladas por el usuario.
  • “Con privilegios” apps vienen preinstaladas en el dispositivo. Entre estas, se incluyen el Asistente de Google y todos los servicios de accesibilidad.

Además, una app se trata de manera diferente si utiliza un parámetro "sensible a la privacidad" fuente de audio: CAMCORDER o VOICE_COMMUNICATION.

Las reglas de priorización para usar y compartir la entrada de audio son las siguientes:

  • Las apps privilegiadas tienen mayor prioridad que las comunes.
  • Las apps que tienen IU visibles en primer plano tienen mayor prioridad que las que están en segundo plano.
  • Las apps que capturan audio de una fuente sensible a la privacidad tienen mayor prioridad que las que no lo hacen.
  • Dos apps comunes no pueden capturar audio al mismo tiempo.
  • En algunas situaciones, una app privilegiada puede compartir la entrada de audio con otra app.
  • Si dos apps en segundo plano de la misma prioridad están capturando audio, la última que se inició tiene mayor prioridad.

Situaciones de uso compartido

Cuando dos apps intentan capturar audio, ambos pueden recibir la señal de entrada, o uno de ellos puede recibir silencio.

Hay cuatro situaciones principales:

  • Asistente y app común
  • Servicio de accesibilidad y app común
  • Dos apps comunes
  • Llamada de voz y app común

Asistente y app común

El Asistente es una app privilegiada porque está preinstalada y contiene las rol RoleManager.ROLE_ASSISTANT. Se trata de forma similar a cualquier otra app preinstalada con esta función.

Android comparte el audio de entrada según estas reglas:

  • El Asistente puede recibir audio (independientemente de si está en primer o segundo plano) a menos que otra app que use una fuente de audio sensible a la privacidad ya esté capturando contenido.

  • La app recibe audio, a menos que Asistente tenga una IU visible componente en la parte superior de la pantalla.

Ten en cuenta que ambas apps reciben audio solo cuando Asistente está en segundo plano. y la otra no realiza capturas de una fuente de audio sensible a la privacidad.

Servicio de accesibilidad y app común

Un objeto AccessibilityService requiere una declaración estricta.

Android comparte el audio de entrada según estas reglas:

  • Si la IU del servicio está en la parte superior, tanto el servicio como la app reciben entrada de audio. Este comportamiento ofrece funciones como controlar una llamada de voz o un video capturar con comandos por voz.

  • Si el servicio no está en la parte superior, este caso se trata como el de dos apps comunes, que se explica a continuación.

Dos apps comunes

Cuando dos apps capturan contenido simultáneamente, solo una recibe audio, y la otra recibe silencio.

Android comparte el audio de entrada según estas reglas:

  • Si ninguna app es sensible a la privacidad, la app con una IU en la parte superior recibe audio. Si ninguna tiene una IU, la que haya iniciado la captura más reciente recibirá audio.
  • Si una de las apps es sensible a la privacidad, recibe audio y las otra app obtiene silencio incluso si tiene una IU en la parte superior o comienza a capturar más recientemente.
  • Si ambas apps son sensibles a la privacidad, la app que empezó a captar recibe audio recientemente y al otro recibe silencio.

Llamada de voz y app común

Una llamada de voz está activa si el modo de audio devuelto AudioManager.getMode() es MODE_IN_CALL o MODE_IN_COMMUNICATION

Android comparte el audio de entrada según estas reglas:

Comportamiento de Android 11

Android 11 (nivel de API 30) observa el esquema de prioridad de Android 10. descrita anteriormente. También proporciona métodos nuevos en AudioRecord, MediaRecorder y AAudioStream, que habilitan o inhabilitan la captura de audio de forma simultánea sin importar el caso de uso seleccionado.

Los nuevos métodos son los siguientes:

Cuando setPrivacySensitive() es true, el caso de uso de la captura es privado y hasta un Asistente con privilegios no puede capturar simultáneamente. Este parámetro de configuración anula comportamiento predeterminado que depende de la fuente de audio. Por ejemplo: VOICE_COMMUNICATION es privado de forma predeterminada, pero UNPROCESSED no lo es.

Cambios de configuración

Cuando varias apps capturan audio simultáneamente, solo se permite una o dos apps “activo” (recibiendo audio) los demás están silenciados (recibiendo silencio). Cuando las apps activas cambian, el framework de audio puede reconfigurar las rutas de audio según estas reglas:

  • El dispositivo de entrada de audio para cada app activa puede cambiar (por ejemplo, de el micrófono integrado en los auriculares Bluetooth conectados).
  • El preprocesamiento asociado a la app activa de mayor prioridad está habilitado. Todo se ignora otro procesamiento previo.

Como una app activa puede silenciarse cuando se activa una app con mayor prioridad, puedes registrar un AudioManager.AudioRecordingCallback en el AudioRecord o MediaRecorder el objeto de escucha para recibir una notificación cuando cambia la configuración. Los posibles cambios podrían ser los siguientes:

  • Se silenció o dejó de silenciar la captura.
  • Cambió el dispositivo.
  • Cambió el preprocesamiento.
  • Cambiaron las propiedades de transmisión (tasa de muestreo, máscara de canal y formato de muestreo).

Debes llamar AudioRecord.registerAudioRecordingCallback() antes de iniciar la captura. La devolución de llamada se ejecuta solo cuando la app está recibiendo audio y se produce un cambio.

El método onRecordingConfigChanged() devuelve un objeto AudioRecordingConfiguration que contiene el estado de captura de audio actual. Usa los siguientes métodos para conocer el cambio:

isClientSilenced()
El resultado es verdadero si el audio que se muestra al cliente está en silencio debido a la política de captura.
getAudioDevice()
Devuelve el dispositivo de audio activo.
getEffects()
Muestra el efecto de procesamiento previo activo. Ten en cuenta que el efecto activo podría no ser el mismo que los que muestra getClientEffects() si el cliente no es la app activa con la prioridad más alta.
getFormat()
Muestra las propiedades de transmisión. Ten en cuenta que los datos de audio reales que recibe el cliente siempre respetan el formato requerido que muestra getClientFormat(). El framework realiza automáticamente el remuestreo, el canal y la conversión de formato necesarios, desde el formato que se usa en la interfaz de hardware hasta el que especifica el cliente.
AudioRecord.getActiveRecordingConfiguration().
Muestra la configuración de registro activa.

Puedes llamar para obtener una vista general de todas las grabaciones activas en el dispositivo AudioManager.getActiveRecordingConfigurations()