相容媒體轉碼
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
在 Android 12 (API 級別 31) 以上版本中,如果應用程式不支援 HEVC,系統會在開啟以 HEVC (H.265) 等格式錄製的影片時,自動將影片轉換為 AVC (H.264)。這項功能可讓影片擷取應用程式使用更先進、節省儲存空間的影片編碼,在裝置上錄製影片,同時確保與其他應用程式的相容性。
如果內容是在裝置上建立,系統可以自動轉碼為下列格式:
媒體格式 |
XML 屬性 |
MediaFormat MIME 類型 |
HEVC (H.265) |
HEVC |
MediaFormat.MIMETYPE_VIDEO_HEVC |
HDR10 | HDR10 |
MediaFeature.HdrType.HDR10 |
HDR10+ |
HDR10Plus |
MediaFeature.HdrType.HDR10_PLUS |
Android 會假設應用程式可以支援所有媒體格式的播放,因此相容媒體轉碼功能預設為關閉。
使用轉碼的時機
轉碼是需要大量運算資源的作業,開啟影片檔案時會大幅延遲。舉例來說,在 Pixel 3 手機上,將 1 分鐘的 HEVC 影片檔案轉碼為 AVC 大約需要 20 秒。因此,只有在將影片檔案傳送至裝置外時,才需要轉碼。舉例來說,與相同應用程式的其他使用者共用影片檔案,或是與不支援新式影片格式的雲端伺服器共用。
開啟影片檔案以在裝置上播放,或建立縮圖時,請勿轉碼。
設定轉碼
應用程式可以宣告媒體功能,藉此控制轉碼行為。宣告這些功能的方式有兩種:在程式碼中或在資源中。
在程式碼中宣告功能
您可以使用建構工具,建構 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.
}
這個方法可精細控管特定程式碼路徑,例如僅在將影片檔案移出裝置時叫用轉碼。優先順序高於下述方法。
在資源中宣告功能
在資源中宣告功能,即可全面控管轉碼作業。
這個方法只適用於非常特殊的情況。舉例來說,如果您的應用程式只會接收其他應用程式的影片檔案 (而非直接開啟),並將這些檔案上傳至不支援新式影片轉碼器的伺服器 (請參閱下方的範例情境 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 影片則不會。
在 application
標記中使用 property
標記,加入媒體功能檔案的參照。將這些屬性新增至 AndroidManifest.xml
檔案:
<property
android:name="android.media.PROPERTY_MEDIA_CAPABILITIES"
android:resource="@xml/media_capabilities" />
如果應用程式與其他應用程式共用影片檔案,接收端應用程式可能需要先轉碼影片檔案,才能開啟。
如要處理這種情況,請使用 openTypedAssetFileDescriptor
開啟影片檔案,並指定接收端應用程式的 UID (可使用 Binder.getCallingUid
取得)。平台接著會使用接收端應用程式的媒體功能,判斷是否應轉碼影片檔案。
Kotlin
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:轉碼是由影片分享應用程式啟動。
影片擷取應用程式會使用 MediaStore
URI 與影片分享應用程式共用影片。影片分享應用程式會使用 openTypedAssetFileDescriptor
開啟影片檔案,並在媒體功能中指定不支援 HEVC。這會啟動轉碼程序,完成後檔案會上傳至雲端伺服器。
系統會為所有聲明為不支援的格式啟用相容媒體轉碼,並為所有聲明為支援的格式停用相容媒體轉碼。對於未宣告的其他格式,平台會決定是否要轉碼。在 Android 12 中,系統會針對所有未宣告的格式停用轉碼功能。日後新格式的這項行為可能會有所變更。
開發人員選項
您可以使用下列開發人員選項,覆寫 Android 的預設轉碼行為:
覆寫轉碼預設設定:這項設定會決定平台是否控管自動轉碼。啟用覆寫功能後,系統會忽略平台預設值,並由「啟用轉碼」設定控管自動轉碼。這個選項預設為停用。
啟用轉碼:這項設定用於指定是否自動轉碼未宣告的格式。這項設定預設為啟用,但只有在同時啟用「覆寫轉碼預設值」時才會生效。
假設應用程式支援新格式:這項設定可控制應用程式嘗試播放未宣告格式時的行為。如果資訊清單未聲明應用程式是否支援特定格式,或 Google 尚未將應用程式加入伺服器端強制轉碼清單,就會發生這種情況。啟用這項設定後,應用程式不會轉碼;停用後,應用程式會轉碼。這個選項預設為啟用。
顯示轉碼通知:啟用後,應用程式會在讀取不支援的媒體檔案時觸發轉碼,並顯示轉碼進度通知。這個選項預設為啟用。
停用轉碼快取:啟用後,需要轉碼的應用程式不會使用轉碼快取。這項功能在開發期間很有幫助,可輕鬆觸發不支援的媒體檔案轉碼,但可能會導致裝置效能不佳。這個選項預設為停用。
這個頁面中的內容和程式碼範例均受《內容授權》中的授權所規範。Java 與 OpenJDK 是 Oracle 和/或其關係企業的商標或註冊商標。
上次更新時間:2025-08-27 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-08-27 (世界標準時間)。"],[],[],null,["On Android 12 (API level 31) and higher, the system can automatically convert\nvideos recorded in formats such as HEVC (H.265) to AVC (H.264) when the videos\nare opened by an app that does not support HEVC. This feature allows video\ncapture apps to utilize more modern, storage-efficient encoding for videos\nrecorded on the device without sacrificing compatibility with other apps.\n\nThe following formats can be automatically transcoded for content that's\ncreated on-device:\n\n| Media format | XML Attribute | MediaFormat mime type |\n|--------------|---------------|---------------------------------|\n| HEVC (H.265) | HEVC | MediaFormat.MIMETYPE_VIDEO_HEVC |\n| HDR10 | HDR10 | MediaFeature.HdrType.HDR10 |\n| HDR10+ | HDR10Plus | MediaFeature.HdrType.HDR10_PLUS |\n\nAndroid assumes that apps can support playback of all media formats, so\ncompatible media transcoding is off by default.\n\nWhen to use transcoding\n\nTranscoding is a computationally expensive operation and adds a significant\ndelay when opening a video file. For example, a one minute HEVC video file takes\nroughly 20 seconds to transcode into AVC on a Pixel 3 phone. For this reason,\nyou should transcode a video file only when you are sending it off the\ndevice. For example, when sharing a video file with other users of the same\napp, or a cloud server which does not support modern video\nformats.\n\nDo not transcode when opening video files for on-device playback or for creating thumbnail images.\n\nConfiguring transcoding\n\nApps can control their transcoding behavior by declaring their media\ncapabilities. There are two ways to declare these capabilities: in code,\nor in a resource.\n\nDeclare capabilities in code\n\nYou can declare media capabilities in code by constructing an instance of an\n`ApplicationMediaCapabilities` object using a builder: \n\nKotlin \n\n```kotlin\nval mediaCapabilities = ApplicationMediaCapabilities.Builder()\n .addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC)\n .addUnsupportedHdrType(MediaFeature.HdrType.HDR10)\n .addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS)\n .build()\n```\n\nJava \n\n```java\nApplicationMediaCapabilities mediaCapabilities = new ApplicationMediaCapabilities.Builder()\n .addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC)\n .addUnsupportedHdrType(MediaFeature.HdrType.HDR10)\n .addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS)\n .build();\n```\n\nUse this object when accessing media content via methods such as\n`ContentResolver#openTypedAssetFileDescriptor()`: \n\nKotlin \n\n```kotlin\nval providerOptions = Bundle().apply {\n putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES, mediaCapabilities)\n}\ncontentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)\n .use { fileDescriptor -\u003e\n // Content will be transcoded based on values defined in the\n // ApplicationMediaCapabilities provided.\n }\n```\n\nJava \n\n```java\nBundle providerOptions = new Bundle();\nproviderOptions.putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES, mediaCapabilities);\ntry (AssetFileDescriptor fileDescriptor = contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)) {\n // Content will be transcoded based on values defined in the\n // ApplicationMediaCapabilities provided.\n}\n```\n\nThis method allows granular control for particular code paths, such\nas invoking transcoding only when transferring a video file off-device. It takes precedence over the method described below.\n\nDeclare capabilities in a resource\n\nDeclaring capabilities in a resource allows blanket control over transcoding.\nThis method should only be used in very specific cases. For example, if your app\nonly receives video files from other apps (rather than opening them directly)\nand uploads them to a server which does not support modern video codecs (see\nexample scenario 1 below).\n\nUsing this method when not absolutely necessary might invoke transcoding in unintended scenarios, such as when thumbnailing videos, resulting in a degraded user experience.\n\nTo use this method, create a `media_capabilities.xml` resource file: \n\n \u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n \u003cmedia-capabilities xmlns:android=\"http://schemas.android.com/apk/res/android\"\u003e\n \u003cformat android:name=\"HEVC\" supported=\"true\"/\u003e\n \u003cformat android:name=\"HDR10\" supported=\"false\"/\u003e\n \u003cformat android:name=\"HDR10Plus\" supported=\"false\"/\u003e\n \u003c/media-capabilities\u003e\n\nIn this example, HDR videos recorded on the device are seamlessly transcoded to\nAVC SDR (standard dynamic range) video, while HEVC videos are not.\n\nUse a `property` tag within the `application` tag to add a reference to the media\ncapabilities file. Add these properties to your `AndroidManifest.xml` file: \n\n \u003cproperty\n android:name=\"android.media.PROPERTY_MEDIA_CAPABILITIES\"\n android:resource=\"@xml/media_capabilities\" /\u003e\n\nUsing another app's media capabilities to open a video file\n\nIf your app shares a video file with another app, the video file might need to\nbe transcoded before the receiving app can open it.\n\nYou can handle this case by opening a video file using [`openTypedAssetFileDescriptor`](https://developer.android.com/reference/android/content/ContentResolver#openTypedAssetFileDescriptor(android.net.Uri,%20java.lang.String,%20android.os.Bundle))\nand specifying the UID of the receiving app, which can be obtained using [`Binder.getCallingUid`](https://developer.android.com/reference/android/os/Binder#getCallingUid()).\nThe platform then uses the receiving app's media capabilities to determine\nwhether the video file should be transcoded. \n\nKotlin \n\n```kotlin\nval providerOptions = Bundle().apply {\n putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES_UID, Binder.getCallingUid())\n}\ncontentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)\n .use { fileDescriptor -\u003e\n // Content will be transcoded based on the media capabilities of the\n // calling app.\n }\n```\n\nJava \n\n```java\nBundle providerOptions = new Bundle();\nproviderOptions.putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES_UID, Binder.getCallingUid());\ntry (AssetFileDescriptor fileDescriptor = contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)) {\n // Content will be transcoded based on the media capabilities of the\n // calling app.\n}\n```\n\nExample scenarios\n\nThe following diagrams demonstrate the two common use cases. In both cases the original video is stored in HEVC format and the video sharing app does not\nsupport HEVC.\n\n**Example 1.** Transcoding is initiated by video capture app.\n\nThe video sharing app declares that it does not support HEVC in its media\ncapabilities resource file. It then requests a video from the video capture app. The video capture\napp handles the request and opens the file using [`openTypedAssetFileDescriptor`](https://developer.android.com/reference/android/content/ContentResolver#openTypedAssetFileDescriptor(android.net.Uri,%20java.lang.String,%20android.os.Bundle)), specifying the sharing app's UID. This initiates the transcoding process.\nWhen the transcoded video is received it is supplied to the sharing app, which uploads it to a server in the cloud.\n\n**Example 2.** Transcoding is initiated by video sharing app.\n\nThe video capture app shares a video with the video sharing app using a\n`MediaStore` URI. The video sharing app opens the video file using [`openTypedAssetFileDescriptor`](https://developer.android.com/reference/android/content/ContentResolver#openTypedAssetFileDescriptor(android.net.Uri,%20java.lang.String,%20android.os.Bundle)), specifying that it does not support HEVC in its media capabilities. This\ninitiates the transcoding process, and once complete, the file is uploaded to\na server in the cloud.\n\nUndeclared formats\n\nCompatible media transcoding is enabled for all formats that are declared\nunsupported, and is disabled for all formats that are declared supported. For\nother formats that are not declared, the platform decides whether to transcode\nor not. In Android 12 transcoding is disabled\nfor all undeclared formats. This behavior might change for new formats in the\nfuture.\n\nDeveloper options\n\nYou can use the following developer options to override Android's default\ntranscoding behavior:\n\n- **Override transcoding defaults** This setting determines whether or not\n the platform controls automatic transcoding. When override\n is enabled, the platform defaults are ignored and the **enable\n transcoding** setting controls automatic transcoding. This option is disabled by\n default.\n\n- **Enable transcoding** This setting specifies whether or not undeclared\n formats are automatically transcoded. It is enabled by default, but it only\n has an effect if **override transcoding defaults** is also enabled.\n\n- **Assume apps support modern formats** This setting controls what happens when\n the app tries to play an undeclared format. This happens when the manifest does\n not declare whether or not the app supports a particular format, or Google\n hasn't added the app to the server-side force-transcode list. When the setting\n is enabled, the app does not transcode, when it's disabled, the app does\n transcode. This option is enabled by default.\n\n- **Show transcoding notifications** When enabled, the app displays a\n transcoding progress notification when transcoding is triggered by reading an\n unsupported media file. This option is enabled by default.\n\n- **Disable transcoding cache** If enabled, apps that require transcoding do not\n use the transcoding cache. This can be helpful during development to easily\n trigger transcoding on an unsupported media file, but can cause poor device\n performance. This option is disabled by default."]]