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.

Undeclared formats

Compatible media transcoding is enabled for all formats that are declared unsupported, and is disabled for all formats that are declared supported. For other formats that are not declared, the platform decides whether to transcode or not. In Android 12 transcoding is disabled for all undeclared formats. This behavior might change for new formats in the future.

You can use the following developer options to override Android's default transcoding behavior:

  • Override transcoding defaults This setting determines whether or not the platform controls automatic transcoding. When override is enabled, the platform defaults are ignored and the enable transcoding setting controls automatic transcoding. This option is disabled by default.

  • Enable transcoding This setting specifies whether or not undeclared formats are automatically transcoded. It is enabled by default, but it only has an effect if override transcoding defaults is also enabled.

  • Assume apps support modern formats This setting controls what happens when the app tries to play an undeclared format. This happens when the manifest does not declare whether or not the app supports a particular format, or Google hasn't added the app to the server-side force-transcode list. When the setting is enabled, the app does not transcode, when it's disabled, the app does transcode. This option is enabled by default.

  • Show transcoding notifications When enabled, the app displays a transcoding progress notification when transcoding is triggered by reading an unsupported media file. This option is enabled by default.

  • Disable transcoding cache If enabled, apps that require transcoding do not use the transcoding cache. This can be helpful during development to easily trigger transcoding on an unsupported media file, but can cause poor device performance. This option is disabled by default.