Welcome to Android 12 Developer Preview! Please give us feedback early and often, and help us make Android 12 the best release yet!

Compatible media transcoding

Give feedback icon We'd love to hear your feedback regarding compatibile media transcoding. Take a short survey to tell us what you think. In particular, let us know what use cases in your app are affected by this change.

Android 12 introduces a new feature that allows video capture apps to utilize more modern, storage-efficient encoding for videos recorded on the device without sacrificing compatibility with other apps.

Android can automatically convert videos recorded in formats such as HEVC (H.265) to AVC (H.264) when the videos are opened by an app that does not support HEVC.

The following formats can be automatically transcoded for content that's created on-device:

Media format XML Attribute MediaFormat mime type
HEVC (H.265) HEVC MediaFormat.MIMETYPE_VIDEO_HEVC
HDR10HDR10 MediaFeature.HdrType.HDR10
HDR10+ HDR10Plus MediaFeature.HdrType.HDR10_PLUS

Android assumes that apps can support playback of all media formats, so compatible media transcoding is off by default. Apps that would like to request that media be transcoded into a more compatible format should declare their media capabilities. There are two ways to declare these capabilities: in a resource, or inline in code.

Declare capabilities in a resource

First, create a media_capabilities.xml resource file:

<?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>

In this example, HDR videos recorded on the device are seamlessly transcoded to AVC SDR (standard dynamic range) video, while HEVC videos are not.

Use a property tag within the application tag to add a reference to the media capabilities file. Add these properties to your AndroidManifest.xml file:

<property
    android:name="android.media.PROPERTY_MEDIA_CAPABILITIES"
    android:resource="@xml/media_capabilities" />

Declare capabilities in code

You can declare media capabilities in code by constructing an instance of an ApplicationMediaCapabilities object using a builder:

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();

Use this object when accessing media content via methods such as 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.
}

This method takes precedence over the capabilities linked in the app's AndroidManifest.xml, allowing more granular control for particular code paths, such as performing A/B testing.