在 Android 12 (API 級別 31) 以上版本中,如果影片是由不支援 HEVC 的應用程式開啟,系統會自動將以 HEVC (H.265) 等格式錄製的影片轉換為 AVC (H.264)。這項功能可讓錄影應用程式使用更先進的儲存空間最佳化編碼,為裝置上錄製的影片編碼,且不會影響與其他應用程式的相容性。
下列格式可針對裝置上建立的內容自動轉碼:
媒體格式 | XML 屬性 | 媒體格式 MIME 類型 |
---|---|---|
HEVC (H.265) | HEVC | MediaFormat.MIMETYPE_VIDEO_HEVC |
HDR10 | HDR10 | MediaFeature.HdrType.HDR10 |
HDR10+ | HDR10+ | MediaFeature.HdrType.HDR10_PLUS |
Android 會假設應用程式可支援所有媒體格式的播放,因此預設會關閉相容的媒體轉碼功能。
使用轉碼功能的時機
轉碼作業的運算成本高昂,會大幅延遲開啟影片檔案的時間。舉例來說,在 Pixel 3 手機上,一分鐘的 HEVC 影片檔案大約需要 20 秒才能轉碼成 AVC。因此,您應該只在傳送影片檔案時才轉碼。舉例來說,如果您要與使用相同應用程式的其他使用者共用影片檔案,或是與不支援新式影片格式的雲端伺服器共用影片檔案,就會發生這種情況。
開啟影片檔案進行裝置端播放或建立縮圖時,請勿進行轉碼。
設定轉碼
應用程式可以透過宣告媒體功能,控制轉碼行為。宣告這些功能的方式有兩種:在程式碼或資源中。
在程式碼中宣告功能
您可以使用建構工具,建構 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 未將應用程式新增至伺服器端強制轉碼清單。啟用設定後,應用程式不會轉碼;停用設定後,應用程式會轉碼。這個選項預設為啟用。
顯示轉碼通知 啟用此選項後,當應用程式讀取不支援的媒體檔案而觸發轉碼作業時,系統會顯示轉碼進度通知。這個選項預設為啟用。
停用轉碼快取 如果啟用這項設定,需要轉碼的應用程式就不會使用轉碼快取。這在開發期間可能很有幫助,可輕鬆在未支援的媒體檔案上觸發轉碼,但可能會導致裝置效能不佳。這個選項預設為停用。