На устройствах с Android 12 (уровень API 31) и более поздними версиями ОС система может автоматически преобразовывать видео, записанные в таких форматах, как HEVC (H.265), в AVC (H.264), если эти видео открываются в приложении, которое не поддерживает HEVC. Эта функция позволяет приложениям для видеозаписи использовать более современное и эффективное кодирование для видео, записанных на устройстве, без ущерба для совместимости с другими приложениями.
Для контента, созданного на устройстве, автоматически перекодируются следующие форматы:
| Формат медиафайла | Атрибут XML | MIME-тип MediaFormat |
|---|---|---|
| HEVC (H.265) | HEVC | MediaFormat.MIMETYPE_VIDEO_HEVC |
| HDR10 | HDR10 | MediaFeature.HdrType.HDR10 |
| HDR10+ | HDR10Plus | MediaFeature.HdrType.HDR10_PLUS |
По умолчанию перекодирование медиафайлов в совместимый формат отключено, поскольку предполагается, что приложения поддерживают воспроизведение всех форматов.
Когда использовать перекодирование
Перекодирование – это ресурсоемкая операция, которая значительно увеличивает время открытия видеофайла. Например, перекодирование одноминутного видео HEVC в AVC на телефоне Pixel 3 занимает около 20 секунд. Поэтому перекодировать видеофайл следует только при его отправке с устройства. Например, при отправке видеофайла другим пользователям того же приложения или на облачный сервер, который не поддерживает современные форматы видео.
Не перекодируйте видеофайлы, когда открываете их для воспроизведения на устройстве или создания значков.
Настройка перекодирования
Приложения могут управлять перекодированием, объявляя свои возможности работы с медиаконтентом. Объявить эти возможности можно двумя способами: в коде или в ресурсе.
Объявление возможностей в коде
Вы можете объявить возможности мультимедиа в коде, создав экземпляр объекта ApplicationMediaCapabilities с помощью конструктора:
Kotlin
val mediaCapabilities = ApplicationMediaCapabilities.Builder() .addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC) .addUnsupportedHdrType(MediaFeature.HdrType.HDR10) .addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS) .build()
Java
ApplicationMediaCapabilities mediaCapabilities = new ApplicationMediaCapabilities.Builder() .addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC) .addUnsupportedHdrType(MediaFeature.HdrType.HDR10) .addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS) .build();
Используйте этот объект при доступе к медиаконтенту с помощью таких методов, как ContentResolver#openTypedAssetFileDescriptor():
Kotlin
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. }
Java
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.
Затем платформа использует мультимедийные возможности приложения-получателя, чтобы определить, нужно ли перекодировать видеофайл.
Kotlin
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. }
Java
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, который не поддерживается приложением для обмена видео.
Пример 1. Перекодирование инициируется приложением для записи видео.
Приложение для обмена видео заявляет, что не поддерживает HEVC в своем файле ресурсов медиавозможностей. Затем оно запрашивает видео у приложения для записи видео. Приложение для записи видео обрабатывает запрос и открывает файл с помощью
openTypedAssetFileDescriptor, указывая UID приложения для обмена. Начнется процесс перекодирования.
После этого видео передается в приложение для обмена файлами, которое загружает его на облачный сервер.
Пример 2. Перекодирование запускается приложением для обмена видео.
Приложение для записи видео передает видео в приложение для обмена видео с помощью URI
MediaStore. Приложение для предоставления доступа к видео открывает видеофайл с помощью openTypedAssetFileDescriptor, указывая, что оно не поддерживает HEVC в своих медиавозможностях. После этого начнется перекодирование, а затем файл будет загружен на облачный сервер.
Необъявленные форматы
Перекодирование медиафайлов в совместимый формат включено для всех форматов, которые объявлены неподдерживаемыми, и отключено для всех форматов, которые объявлены поддерживаемыми. Для других форматов, которые не объявлены, платформа решает, выполнять ли перекодирование. В Android 12 перекодирование отключено для всех незадекларированных форматов. В будущем это может измениться.
Для разработчиков
Чтобы переопределить стандартное поведение Android при перекодировании, можно использовать следующие параметры для разработчиков:
Переопределить настройки перекодирования по умолчанию. Этот параметр определяет, будет ли платформа управлять автоматическим перекодированием. Если переопределение включено, настройки платформы по умолчанию игнорируются, а автоматическим перекодированием управляет параметр Включить перекодирование. Этот параметр по умолчанию отключен.
Включить перекодирование. Этот параметр определяет, будут ли автоматически перекодироваться необъявленные форматы. Она включена по умолчанию, но действует, только если также включена функция Переопределить настройки перекодирования по умолчанию.
Предполагать, что приложения поддерживают современные форматы. Этот параметр определяет, что происходит, когда приложение пытается воспроизвести недекларированный формат. Это происходит, когда в манифесте не указано, поддерживает ли приложение определенный формат, или Google не добавила приложение в список принудительного перекодирования на стороне сервера. Если параметр включен, приложение не выполняет перекодирование, а если отключен – выполняет. Этот параметр включен по умолчанию.
Показывать уведомления о перекодировании. Если этот параметр включен, приложение показывает уведомление о ходе перекодирования, когда оно запускается при чтении неподдерживаемого медиафайла. Этот параметр включен по умолчанию.
Отключить кеш перекодирования. Если этот параметр включен, приложения, которым требуется перекодирование, не используют кеш перекодирования. Это может быть полезно во время разработки, чтобы легко запускать перекодирование неподдерживаемого медиафайла, но может привести к снижению производительности устройства. Этот параметр по умолчанию отключен.