На устройствах 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 |
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 по умолчанию можно использовать следующие параметры разработчика:
Переопределить настройки перекодировки по умолчанию. Этот параметр определяет, управляет ли платформа автоматическим перекодированием. Если переопределение включено, настройки платформы по умолчанию игнорируются, а настройка «Включить перекодировку» управляет автоматическим перекодированием. По умолчанию этот параметр отключен.
Включить перекодирование. Этот параметр определяет, будет ли автоматически перекодироваться необъявленный формат. Он включен по умолчанию, но действует только в том случае, если также включен параметр «Переопределить значения по умолчанию для перекодирования» .
Предполагать, что приложения поддерживают современные форматы. Этот параметр управляет действиями, которые выполняются при попытке приложения воспроизвести необъявленный формат. Это происходит, когда в манифесте не указано, поддерживает ли приложение определённый формат, или Google не добавил приложение в список принудительного перекодирования на стороне сервера. Если параметр включён, приложение не перекодирует, если отключён, приложение перекодирует. Этот параметр включён по умолчанию.
Показывать уведомления о перекодировании. Если эта опция включена, приложение отображает уведомление о ходе перекодирования, когда перекодирование инициируется чтением неподдерживаемого медиафайла. Эта опция включена по умолчанию.
Отключить кэш перекодировки. Если этот параметр включен, приложения, требующие перекодировки, не используют кэш перекодировки. Это может быть полезно при разработке для быстрого запуска перекодировки неподдерживаемых медиафайлов, но может привести к снижению производительности устройства. По умолчанию эта опция отключена.