В 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()
Java
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. }
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 . Затем платформа использует возможности работы с медиафайлами принимающего приложения, чтобы определить, следует ли перекодировать видеофайл.
Котлин
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, а приложение для обмена видео не поддерживает HEVC.
Пример 1. Транскодирование инициируется приложением для захвата видео. Приложение для обмена видео заявляет в файле ресурсов медиафайлов, что оно не поддерживает HEVC. Затем оно запрашивает видео у приложения для захвата видео. Приложение для захвата видео обрабатывает запрос и открывает файл с помощью
openTypedAssetFileDescriptor , указывая UID приложения для обмена. Это запускает процесс транскодирования. После получения транскодированного видео оно передается приложению для обмена, которое загружает его на сервер в облаке.
Пример 2. Транскодирование инициируется приложением для обмена видео. Приложение для захвата видео передает видео приложению для обмена видео, используя URI
MediaStore . Приложение для обмена видео открывает видеофайл с помощью openTypedAssetFileDescriptor , указывая, что оно не поддерживает HEVC в своих медиавозможностях. Это запускает процесс транскодирования, и после его завершения файл загружается на сервер в облаке.
Необъявленные форматы
Совместимое транскодирование мультимедиа включено для всех форматов, которые объявлены неподдерживаемыми, и отключено для всех форматов, которые объявлены поддерживаемыми. Для других форматов, которые не объявлены, платформа сама решает, транскодировать их или нет. В Android 12 транскодирование отключено для всех необъявленных форматов. Это поведение может измениться для новых форматов в будущем.
Параметры разработчика
Для изменения стандартного поведения транскодирования в Android можно использовать следующие параметры разработчика:
Переопределение параметров транскодирования по умолчанию. Этот параметр определяет, будет ли платформа контролировать автоматическое транскодирование. Если параметр «Переопределение» включен, параметры платформы по умолчанию игнорируются, и параметр «Включить транскодирование» управляет автоматическим транскодированием. Этот параметр отключен по умолчанию.
Включить транскодирование. Этот параметр определяет, будут ли автоматически транскодироваться неуказанные форматы. Он включен по умолчанию, но эффект проявляется только в том случае, если также включена опция «Переопределить параметры транскодирования по умолчанию» .
Предполагать, что приложения поддерживают современные форматы. Этот параметр определяет, что происходит, когда приложение пытается воспроизвести неуказанный формат. Это происходит, когда в манифесте не указано, поддерживает ли приложение определенный формат, или Google не добавил приложение в список приложений, требующих принудительного перекодирования на стороне сервера. Если параметр включен, приложение не выполняет перекодирование, если выключен — выполняет. Этот параметр включен по умолчанию.
Отображать уведомления о транскодировании. Если эта опция включена, приложение отображает уведомление о ходе транскодирования при запуске транскодирования при чтении неподдерживаемого медиафайла. Эта опция включена по умолчанию.
Отключить кэширование транскодирования. Если эта опция включена, приложения, требующие транскодирования, не будут использовать кэширование транскодирования. Это может быть полезно во время разработки для простого запуска транскодирования неподдерживаемых медиафайлов, но может привести к снижению производительности устройства. Эта опция отключена по умолчанию.