Cómo capturar la reproducción de audio y video

Una app puede grabar el video o el audio que se reproduce desde otra app. Esas apps deben controlar el token MediaProjection de forma correcta. En esta página, se explica cómo hacerlo. También se muestra cómo un administrador de dispositivos puede inhabilitar la capacidad de grabar cualquier instantánea de la pantalla y cómo una app de audio puede evitar que otras apps graben el contenido que reproduce.

Cómo controlar un token MediaProjection

La API de MediaProjection permite que las apps adquieran un token de MediaProjection que les da acceso por única vez para capturar audio o contenido de la pantalla. El SO Android le solicita al usuario el permiso antes de otorgar el token a tu app.

El SO muestra los tokens activos de MediaProjection en la IU de Configuración rápida y permite a los usuarios retirar el acceso a un token en cualquier momento. Cuando esto sucede, las pantallas virtuales o las transmisiones de audio asociadas con la sesión dejan de recibir transmisiones de contenido multimedia. Tu app debe responder como corresponde. De lo contrario, continuará grabando silencio de audio o una transmisión de video por Internet en negro.

Para controlar la pérdida de un token, registra una devolución de llamada en la instancia MediaProjection con el método registerCallback y detén el registro cuando se llame al método onStop.

Capturar video

Consulta la app de ejemplo ScreenCapture para aprender a usar la API de Media Projection para capturar la pantalla de un dispositivo en tiempo real y mostrarla en una SurfaceView.

Puedes usar DevicePolicyManager para evitar la grabación de pantalla. En las cuentas empresariales (Android for Work), el administrador puede inhabilitar la recopilación de datos del Asistente para el perfil de trabajo mediante el método setScreenCaptureDisabled.

En el codelab Cómo administrar dispositivos Android sin una app, se muestra cómo prohibir las capturas de pantalla.

Cómo capturar la reproducción de audio

La API de AudioPlaybackCapture se introdujo en Android 10. Esta API brinda a las apps la capacidad de copiar el audio que reproducen otras apps. Esta función es análoga a la captura de pantalla, pero para audio. El caso de uso principal es para apps de transmisión que desean capturar el audio que reproducen los juegos.

Ten en cuenta que la API de AudioPlaybackCapture no afecta la latencia de la app cuyo audio se está capturando.

Cómo compilar una app de captura

Por cuestiones de seguridad y privacidad, la captura de reproducción impone algunas limitaciones. Para poder capturar audio, una app debe cumplir con estos requisitos:

Para capturar audio de otra app, tu app debe compilar un objeto AudioRecord y agregarle un AudioPlaybackCaptureConfiguration. Sigue estos pasos:

  1. Llama a AudioPlaybackCaptureConfiguration.Builder.build() para compilar un AudioPlaybackCaptureConfiguration.
  2. Pasa la configuración a AudioRecord llamando a setAudioPlaybackCaptureConfig.

Cómo controlar la captura de audio

Tu app puede controlar qué tipos de contenido puede grabar y qué otros tipos de apps pueden grabar su propia reproducción.

Cómo restringir la captura por contenido de audio

Una app puede limitar el audio que puede capturar con estos métodos:

Ten en cuenta que no puedes usar los métodos addMatchingUsage() y excludeUsage() juntos. Debes elegir uno u otro. Del mismo modo, no puedes usar addMatchingUid() y excludeUid() al mismo tiempo.

Cómo restringir la captura por parte de otras apps

Puedes configurar una app para evitar que otras apps capturen su audio. El audio proveniente de una app solo puede capturarse si la app cumple con los siguientes requisitos:

Uso

El reproductor que produce el audio debe configurar su uso en USAGE_MEDIA, USAGE_GAME o USAGE_UNKNOWN.

Política de captura

La política de captura del reproductor debe ser AudioAttributes.ALLOW_CAPTURE_BY_ALL, lo que permite que otras apps capturen la reproducción. Esto se puede realizar de diversas maneras:

Si se cumplen estos requisitos previos, es posible capturar todo el audio que produce el reproductor.

Cómo inhabilitar la captura del sistema

Las protecciones descritas anteriormente que permiten la captura solo se aplican a apps. Los componentes del sistema Android pueden capturar la reproducción de forma predeterminada. Muchos de estos componentes están personalizados por proveedores de Android y admiten funciones como la accesibilidad y los subtítulos. Por este motivo, se recomienda que las apps permitan que el sistema capture su reproducción. En el caso poco probable de que no quieras que el sistema capture la reproducción de tu app, establece la política de captura en ALLOW_CAPTURE_BY_NONE.

Cómo configurar la política en el tiempo de ejecución

Puedes llamar a AudioManager.setAllowedCapturePolicy() para cambiar la política de captura mientras se ejecuta una app. Si un objeto MediaPlayer o AudioTrack están en reproducción cuando llamas al método, el audio no se ve afectado. Debes cerrar y volver a abrir el reproductor o la pista para que se aplique el cambio de política.

Política = Manifiesto + AudioManager + AudioAttributes

Como la política de captura se puede especificar en varios lugares, es importante comprender cómo se determina la política vigente. Siempre se aplica la política de captura más restrictiva. Por ejemplo, una app cuyo manifiesto incluya setAllowedCapturePolicy="false" nunca permitirá que las apps que no sean del sistema capturen su audio, incluso si AudioManager#setAllowedCapturePolicy se establece en ALLOW_CAPTURE_BY_ALL. Del mismo modo, si AudioManager#setAllowedCapturePolicy se establece en ALLOW_CAPTURE_BY_ALL y el manifiesto establece setAllowedCapturePolicy="true", pero el AudioAttributes del reproductor multimedia se compiló con AudioAttributes.Builder#setAllowedCapturePolicy(ALLOW_CAPTURE_BY_SYSTEM), las apps ajenas al sistema no podrán capturar este reproductor multimedia.

En la siguiente tabla, se resume el efecto del atributo del manifiesto y la política vigente:

allowAudioPlaybackCapture ALLOW_CAPTURE_BY_ALL ALLOW_CAPTURE_BY_SYSTEM ALLOW_CAPTURE_BY_NONE
true cualquier app apps del sistema únicamente ninguna captura
false apps del sistema únicamente apps del sistema únicamente no capture