На Android 12 (API уровня 31) и выше система может автоматически конвертировать видео, записанные в таких форматах, как HEVC (H.265), в AVC (H.264), когда видео открываются приложением, не поддерживающим HEVC. Эта функция позволяет приложениям для захвата видео использовать более современное, эффективное для хранения кодирование для видео, записанных на устройстве, без ущерба для совместимости с другими приложениями.
Следующие форматы могут быть автоматически перекодированы для контента, созданного на устройстве:
Формат носителя | XML-атрибут | Тип MIME MediaFormat |
---|---|---|
HEVC-кодек (H.265) | HEVC | Формат носителя.MIMETYPE_VIDEO_HEVC |
HDR10 | HDR10 | MediaFeature.HdrType.HDR10 |
HDR10+ | HDR10Plus | MediaFeature.HdrType.HDR10_PLUS |
Android предполагает, что приложения могут поддерживать воспроизведение всех форматов мультимедиа, поэтому совместимое перекодирование мультимедиа по умолчанию отключено.
Когда использовать транскодирование
Транскодирование — это затратная с точки зрения вычислений операция, которая вносит существенную задержку при открытии видеофайла. Например, для транскодирования минутного видеофайла HEVC в AVC на телефоне Pixel 3 требуется около 20 секунд. По этой причине вам следует транскодировать видеофайл только при отправке его с устройства. Например, при совместном использовании видеофайла с другими пользователями того же приложения или облачного сервера, который не поддерживает современные видеоформаты.
Не перекодируйте видеофайлы при открытии для воспроизведения на устройстве или для создания миниатюр.
Настройка транскодирования
Приложения могут контролировать свое поведение транскодирования, объявляя свои медиавозможности. Есть два способа объявить эти возможности: в коде или в ресурсе.
Объявление возможностей в коде
Вы можете объявить возможности мультимедиа в коде, создав экземпляр объекта ApplicationMediaCapabilities
с помощью конструктора:
Котлин
val mediaCapabilities = ApplicationMediaCapabilities.Builder() .addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC) .addUnsupportedHdrType(MediaFeature.HdrType.HDR10) .addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS) .build()
Ява
ApplicationMediaCapabilities mediaCapabilities = new ApplicationMediaCapabilities.Builder() .addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC) .addUnsupportedHdrType(MediaFeature.HdrType.HDR10) .addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS) .build();
Используйте этот объект при доступе к медиа-контенту с помощью таких методов, как ContentResolver#openTypedAssetFileDescriptor()
:
Котлин
val providerOptions = Bundle().apply { putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES, mediaCapabilities) } contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions) .use { fileDescriptor -> // Content will be transcoded based on values defined in the // ApplicationMediaCapabilities provided. }
Ява
Bundle providerOptions = new Bundle(); providerOptions.putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES, mediaCapabilities); try (AssetFileDescriptor fileDescriptor = contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)) { // Content will be transcoded based on values defined in the // ApplicationMediaCapabilities provided. }
Этот метод позволяет осуществлять детальный контроль для определенных путей кода, например, вызывать транскодирование только при передаче видеофайла с устройства. Он имеет приоритет над методом, описанным ниже.
Объявление возможностей в ресурсе
Объявление возможностей в ресурсе позволяет полностью контролировать транскодирование. Этот метод следует использовать только в очень особых случаях. Например, если ваше приложение только получает видеофайлы из других приложений (а не открывает их напрямую) и загружает их на сервер, который не поддерживает современные видеокодеки (см. пример сценария 1 ниже).
Использование этого метода без крайней необходимости может привести к перекодированию в непреднамеренных сценариях, например при создании миниатюр видео, что приведет к ухудшению пользовательского опыта.
Чтобы использовать этот метод, создайте файл ресурсов media_capabilities.xml
:
<?xml version="1.0" encoding="utf-8"?>
<media-capabilities xmlns:android="http://schemas.android.com/apk/res/android">
<format android:name="HEVC" supported="true"/>
<format android:name="HDR10" supported="false"/>
<format android:name="HDR10Plus" supported="false"/>
</media-capabilities>
В этом примере HDR-видео, записанные на устройстве, легко транскодируются в видео AVC SDR (стандартный динамический диапазон), а HEVC-видео — нет.
Используйте тег property
в теге application
, чтобы добавить ссылку на файл возможностей мультимедиа. Добавьте эти свойства в файл AndroidManifest.xml
:
<property
android:name="android.media.PROPERTY_MEDIA_CAPABILITIES"
android:resource="@xml/media_capabilities" />
Использование медиа-возможностей другого приложения для открытия видеофайла
Если ваше приложение предоставляет доступ к видеофайлу другому приложению, возможно, его придется перекодировать, прежде чем принимающее приложение сможет его открыть.
Вы можете справиться с этим случаем, открыв видеофайл с помощью openTypedAssetFileDescriptor
и указав UID принимающего приложения, который можно получить с помощью Binder.getCallingUid
. Затем платформа использует медиавозможности принимающего приложения, чтобы определить, следует ли транскодировать видеофайл.
Котлин
val providerOptions = Bundle().apply { putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES_UID, Binder.getCallingUid()) } contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions) .use { fileDescriptor -> // Content will be transcoded based on the media capabilities of the // calling app. }
Ява
Bundle providerOptions = new Bundle(); providerOptions.putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES_UID, Binder.getCallingUid()); try (AssetFileDescriptor fileDescriptor = contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)) { // Content will be transcoded based on the media capabilities of the // calling app. }
Примеры сценариев
На следующих диаграммах показаны два распространенных варианта использования. В обоих случаях исходное видео хранится в формате HEVC, а приложение для обмена видео не поддерживает HEVC.
Пример 1. Транскодирование инициируется приложением для захвата видео. Приложение для обмена видео заявляет, что не поддерживает HEVC в своем файле ресурсов возможностей мультимедиа. Затем оно запрашивает видео из приложения для захвата видео. Приложение для захвата видео обрабатывает запрос и открывает файл с помощью
openTypedAssetFileDescriptor
, указывая UID приложения для обмена. Это инициирует процесс транскодирования. Когда транскодированное видео получено, оно передается в приложение для обмена, которое загружает его на сервер в облаке.
Пример 2. Транскодирование инициируется приложением для обмена видео. Приложение для захвата видео делится видео с приложением для обмена видео с помощью URI
MediaStore
. Приложение для обмена видео открывает видеофайл с помощью openTypedAssetFileDescriptor
, указывая, что оно не поддерживает HEVC в своих медиавозможностях. Это инициирует процесс перекодирования, и после его завершения файл загружается на сервер в облаке.
Необъявленные форматы
Совместимое перекодирование медиа включено для всех форматов, которые объявлены неподдерживаемыми, и отключено для всех форматов, которые объявлены поддерживаемыми. Для других форматов, которые не объявлены, платформа решает, перекодировать или нет. В Android 12 перекодирование отключено для всех необъявленных форматов. Это поведение может измениться для новых форматов в будущем.
Варианты разработчика
Для переопределения поведения перекодирования Android по умолчанию можно использовать следующие параметры разработчика:
Override transcoding defaults Этот параметр определяет, управляет ли платформа автоматическим транскодированием. Если включено override, значения по умолчанию платформы игнорируются, а параметр enable transcoding управляет автоматическим транскодированием. По умолчанию этот параметр отключен.
Включить транскодирование Этот параметр определяет, будут ли автоматически транскодироваться необъявленные форматы. Он включен по умолчанию, но действует только в том случае, если также включен параметр переопределения значений транскодирования по умолчанию .
Предполагать, что приложения поддерживают современные форматы Этот параметр управляет тем, что происходит, когда приложение пытается воспроизвести необъявленный формат. Это происходит, когда в манифесте не указано, поддерживает ли приложение определенный формат, или Google не добавил приложение в список принудительного перекодирования на стороне сервера. Если параметр включен, приложение не перекодирует, если он отключен, приложение перекодирует. Этот параметр включен по умолчанию.
Показывать уведомления о перекодировании Если эта опция включена, приложение отображает уведомление о ходе перекодирования, когда перекодирование запускается путем чтения неподдерживаемого медиафайла. Эта опция включена по умолчанию.
Отключить кэш транскодирования Если включено, приложения, которым требуется транскодирование, не используют кэш транскодирования. Это может быть полезно во время разработки для легкого запуска транскодирования неподдерживаемого медиафайла, но может привести к снижению производительности устройства. Эта опция отключена по умолчанию.