欢迎使用 Android 12 开发者预览版!请尽早并且经常向我们提供反馈,帮助我们将 Android 12 打造为最佳版本!

兼容的媒体转码

“提供反馈”图标我们非常期待收到您对兼容的媒体转码的反馈。 请填写一份简短的调查问卷,告诉我们您的想法。具体而言,请告诉我们您的应用中的哪些用例受到此变更的影响。

Android 12 引入了一项新功能,让视频捕捉应用可以对设备上录制的视频进行更现代、存储效率更高的编码,同时又不影响与其他应用的兼容性。

如果视频被不支持 HEVC 格式的应用打开,Android 会自动将以 HEVC (H.265) 等格式录制的视频转码为 AVC (H.264) 格式。

对于在设备上创建的以下格式的内容,系统可以自动进行转码:

媒体格式 XML 属性 MediaFormat MIME 类型
HEVC (H.265) HEVC MediaFormat.MIMETYPE_VIDEO_HEVC
HDR10HDR10 MediaFeature.HdrType.HDR10
HDR10+ HDR10Plus MediaFeature.HdrType.HDR10_PLUS

Android 假定应用可以支持播放所有媒体格式,因此兼容的媒体转码在默认情况下是关闭的。如果应用请求将媒体转码为更兼容的格式,则应声明其媒体功能。有两种声明这些功能的方法:在资源中声明,或在代码中内嵌声明。

在资源中声明功能

首先,创建 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 视频则无法转码。

application 标记中使用 property 标记来添加对媒体功能文件的引用。将以下属性添加到 AndroidManifest.xml 文件中:

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

在代码中声明功能

您可以使用构建器构造 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.
}

此方法优先于应用的 AndroidManifest.xml 中关联的功能,允许针对特定代码路径进行更精细的控制,例如执行 A/B 测试。