Захват видео и воспроизведение звука

Приложение может записывать видео или аудио, воспроизводимое другим приложением. Такие приложения должны корректно обрабатывать токен MediaProjection . На этой странице объясняется, как это сделать. Здесь также показано, как администратор устройства может отключить запись снимков экрана, а также как аудиоприложение может запретить другим приложениям записывать воспроизводимый им контент.

Как работать с токеном MediaProjection

API MediaProjection позволяет приложениям получать токен MediaProjection , который предоставляет им однократный доступ к захвату содержимого экрана или звука. ОС Android запрашивает у пользователя разрешение, прежде чем предоставить токен приложению.

Операционная система отображает активные токены MediaProjection в интерфейсе быстрых настроек и позволяет пользователям в любой момент отозвать доступ к токену. При этом виртуальные дисплеи или аудиопотоки, связанные с сеансом, перестают получать медиапотоки. Ваше приложение должно отреагировать соответствующим образом, иначе оно продолжит записывать тишину или черный видеопоток.

Чтобы обработать потерю токена, зарегистрируйте обратный вызов на экземпляре MediaProjection с помощью метода registerCallback и остановите запись при вызове метода onStop .

Более подробную информацию можно найти в разделе Медиапроекция .

Снять видео

Ознакомьтесь с примером приложения ScreenCapture , чтобы узнать, как использовать API Media Projection для захвата экрана устройства в реальном времени и отображения его на SurfaceView.

Вы можете использовать DevicePolicyManager для запрета записи экрана. Для корпоративных учётных записей (Android for Work) администратор может отключить сбор данных помощника для рабочего профиля с помощью метода setScreenCaptureDisabled .

В практической работе «Управление устройствами Android без приложения» показано, как запретить создание снимков экрана.

Захват воспроизведения звука

API AudioPlaybackCapture был представлен в Android 10. Этот API позволяет приложениям копировать звук, воспроизводимый другими приложениями. Эта функция является аналогом захвата экрана, но для аудио. Основной вариант использования — приложения для потоковой передачи, которым требуется записывать звук, воспроизводимый в играх.

Обратите внимание, что API AudioPlaybackCapture не влияет на задержку приложения, звук которого захватывается.

Создание приложения для захвата

В целях безопасности и конфиденциальности запись воспроизведения накладывает некоторые ограничения. Для записи звука приложение должно соответствовать следующим требованиям:

  • Приложение должно иметь разрешение RECORD_AUDIO .
  • Приложение должно вывести запрос, отображаемый MediaProjectionManager.createScreenCaptureIntent() , и пользователь должен его одобрить.
  • Приложения для захвата и воспроизведения должны находиться в одном профиле пользователя.

Чтобы захватить аудио из другого приложения, ваше приложение должно создать объект AudioRecord и добавить к нему AudioPlaybackCaptureConfiguration . Выполните следующие действия:

  1. Вызовите AudioPlaybackCaptureConfiguration.Builder.build() для создания AudioPlaybackCaptureConfiguration .
  2. Передайте конфигурацию в AudioRecord , вызвав setAudioPlaybackCaptureConfig .

Управление захватом звука

Ваше приложение может контролировать, какие типы контента оно может записывать, и какие другие типы приложений могут записывать свое собственное воспроизведение.

Ограничение захвата по аудиоконтенту

Приложение может ограничить объем записываемого звука, используя следующие методы:

  • Передайте AUDIO_USAGE в метод AudioPlaybackCaptureConfiguration.addMatchingUsage() , чтобы разрешить захват конкретного использования. Вызовите метод несколько раз, чтобы указать более одного использования.
  • Передайте AUDIO_USAGE в метод AudioPlaybackCaptureConfiguration.excludeUsage() , чтобы запретить захват этого использования. Вызовите метод несколько раз, чтобы указать более одного использования.
  • Передайте UID в метод AudioPlaybackCaptureConfiguration.addMatchingUid() , чтобы захватывать только приложения с определённым UID. Вызовите метод несколько раз, чтобы указать несколько UID.
  • Передайте UID в метод AudioPlaybackCaptureConfiguration.excludeUid() , чтобы запретить захват этого UID. Вызовите метод несколько раз, чтобы указать несколько UID.

Обратите внимание, что методы addMatchingUsage() и excludeUsage() нельзя использовать одновременно. Необходимо выбрать один из них. Аналогично, addMatchingUid() и excludeUid() нельзя использовать одновременно.

Ограничение захвата другими приложениями

Вы можете настроить приложение так, чтобы другие приложения не могли записывать его звук. Звук, исходящий из приложения, может быть записан только в том случае, если приложение соответствует следующим требованиям:

Использование

Проигрыватель, воспроизводящий звук, должен установить для своего использования значение USAGE_MEDIA , USAGE_GAME или USAGE_UNKNOWN .

Политика захвата

Политика захвата проигрывателя должна быть AudioAttributes.ALLOW_CAPTURE_BY_ALL , что позволяет другим приложениям захватывать воспроизведение. Это можно сделать несколькими способами:

Если эти условия соблюдены, любой звук, воспроизводимый проигрывателем, может быть захвачен.

Отключение захвата системы

Описанные выше средства защиты, разрешающие захват, применяются только к приложениям. Компоненты системы Android по умолчанию могут захватывать воспроизведение. Многие из этих компонентов настраиваются производителями Android и поддерживают такие функции, как специальные возможности и субтитры. По этой причине рекомендуется, чтобы приложения разрешали системе захватывать воспроизведение. В редких случаях, когда вы не хотите, чтобы система захватывала воспроизведение вашего приложения, установите политику захвата на ALLOW_CAPTURE_BY_NONE .

Настройка политики во время выполнения

Вы можете вызвать AudioManager.setAllowedCapturePolicy() , чтобы изменить политику захвата во время работы приложения. Если во время вызова метода воспроизводится MediaPlayer или AudioTrack, звук не изменяется. Чтобы изменение политики вступило в силу, необходимо закрыть и снова открыть проигрыватель или дорожку.

Политика = манифест + AudioManager + AudioAttributes

Поскольку политика захвата может быть задана в нескольких местах, важно понимать, как определяется эффективная политика. Всегда применяется самая строгая политика захвата. Например, приложение, манифест которого включает setAllowedCapturePolicy="false" никогда не разрешит несистемным приложениям захватывать свой аудиопоток, даже если AudioManager#setAllowedCapturePolicy имеет значение ALLOW_CAPTURE_BY_ALL . Аналогично, если AudioManager#setAllowedCapturePolicy имеет значение ALLOW_CAPTURE_BY_ALL и в манифесте установлено setAllowedCapturePolicy="true" , но AudioAttributes медиаплеера были созданы с помощью AudioAttributes.Builder#setAllowedCapturePolicy(ALLOW_CAPTURE_BY_SYSTEM) , то этот медиаплеер не будет доступен для захвата несистемными приложениями.

В таблице ниже обобщен эффект атрибута manifest и действующей политики:

разрешитьAudioPlaybackCapture ALLOW_CAPTURE_BY_ALL ALLOW_CAPTURE_BY_SYSTEM ALLOW_CAPTURE_BY_NONE
истинный любое приложение только система нет захвата
ЛОЖЬ только система только система нет захвата