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

Приложение может записывать видео или аудио, воспроизводимое другим приложением. Такие приложения должны правильно обрабатывать токен 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 и действующей политики:

разрешитьАудиоВоспроизведениеЗахват ALLOW_CAPTURE_BY_ALL РАЗРЕШИТЬ_ЗАХВАТ_ПО_СИСТЕМЕ ALLOW_CAPTURE_BY_NONE
истинный любое приложение только система нет захвата
ЛОЖЬ только система только система нет захвата
,

Приложение может записывать видео или аудио, воспроизводимое другим приложением. Такие приложения должны правильно обрабатывать токен 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 и действующей политики:

разрешитьАудиоВоспроизведениеЗахват ALLOW_CAPTURE_BY_ALL РАЗРЕШИТЬ_ЗАХВАТ_ПО_СИСТЕМЕ ALLOW_CAPTURE_BY_NONE
истинный любое приложение только система нет захвата
ЛОЖЬ только система только система нет захвата