相容媒體轉碼

在 Android 12 (API 級別 31) 以上版本中,如果影片是由不支援 HEVC 的應用程式開啟,系統會自動將以 HEVC (H.265) 等格式錄製的影片轉換為 AVC (H.264)。這項功能 擷取應用程式,使用更現代化且節省儲存空間的影片編碼方式 未犧牲與其他應用程式的相容性

下列格式可針對裝置上建立的內容自動轉碼:

媒體格式 XML 屬性 MediaFormat MIME 類型
HEVC (H.265) HEVC MediaFormat.MIMETYPE_VIDEO_HEVC
HDR10HDR10 MediaFeature.HdrType.HDR10
HDR10+ HDR10+ MediaFeature.HdrType.HDR10_PLUS

Android 會假設應用程式可支援所有媒體格式的播放,因此相容的媒體轉碼功能預設為關閉。

使用轉碼的時機

轉碼作業的運算成本高昂,會大幅延遲開啟影片檔案的時間。舉例來說,在 Pixel 3 手機上,一分鐘的 HEVC 影片檔案大約需要 20 秒才能轉碼成 AVC。因此,您應該只在傳送影片檔案時才轉碼。舉例來說,如果您要與使用相同應用程式的其他使用者共用影片檔案,或是與不支援新式影片格式的雲端伺服器共用影片檔案,就會發生這種情況。

開啟影片檔案進行裝置端播放或建立縮圖時,請勿轉碼。

正在設定轉碼

應用程式可以透過宣告媒體來控制轉碼行為 即便沒有技術背景,也能因這些工具的功能而受益宣告這些功能的方式有兩種:在程式碼中、 或是在資源中

在程式碼中宣告功能

您可以在程式碼中建構媒體功能的執行個體,方法是建立 ApplicationMediaCapabilities 物件使用建構工具:

KotlinJava
val mediaCapabilities = ApplicationMediaCapabilities.Builder()
    .addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC)
    .addUnsupportedHdrType(MediaFeature.HdrType.HDR10)
    .addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS)
    .build()
ApplicationMediaCapabilities mediaCapabilities = new ApplicationMediaCapabilities.Builder()
        .addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC)
        .addUnsupportedHdrType(MediaFeature.HdrType.HDR10)
        .addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS)
        .build();

如要透過下列方法存取媒體內容,請使用這個物件: ContentResolver#openTypedAssetFileDescriptor():

KotlinJava
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.
    }
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 取得),藉此處理這種情況。接著,平台會使用接收端應用程式的媒體功能來判斷 影片檔案是否應轉碼。

KotlinJava
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.
    }
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.轉碼作業由影片擷取應用程式啟動。 示例 1 影片分享應用程式在其媒體功能資源檔案中宣告不支援 HEVC。接著要求影片擷取應用程式播放影片。影片擷取畫面 應用程式會處理要求,並使用 openTypedAssetFileDescriptor 指定分享應用程式的 UID 來開啟檔案。這會啟動轉碼程序。收到轉碼後的影片後,系統會將影片提供給分享應用程式,再由應用程式將影片上傳至雲端伺服器。

範例 2:轉碼作業由影片分享應用程式啟動。 示例 2 影片擷取應用程式會使用 MediaStore URI 與影片分享應用程式分享影片。影片分享應用程式使用 openTypedAssetFileDescriptor 開啟影片檔案,指定其媒體功能不支援 HEVC。這會啟動轉碼程序,完成後,檔案就會上傳至雲端伺服器。

未宣告的格式

所有宣告的格式皆已啟用相容媒體轉碼功能 ,系統會為所有宣告支援的格式停用此功能。對於未宣告的其他格式,平台會決定是否要轉碼。在 Android 12 中,轉碼功能已停用 適用於所有未宣告的格式這項行為日後可能會針對新格式有所變更。

開發人員選項

您可以使用下列開發人員選項覆寫 Android 的預設值 轉碼行為:

  • 覆寫轉碼預設值:這項設定會決定平台是否控管自動轉碼作業。啟用覆寫功能後,系統會忽略平台預設設定,並以「啟用轉碼」設定控管自動轉碼作業。這個選項 預設值。

  • 啟用轉碼功能:這項設定可指定是否未宣告 就會自動轉碼預設為啟用,但只有在同時啟用「覆寫轉碼預設值」時才會生效。

  • 假設應用程式支援新格式:這項設定可控管 應用程式會嘗試播放未宣告的格式。如果資訊清單 未宣告應用程式是否支援特定格式,或 尚未將應用程式加入伺服器端的強制轉碼清單。啟用設定時,應用程式不會轉碼;停用設定時,應用程式會轉碼。這個選項預設為啟用。

  • 顯示轉碼通知 啟用此選項後,當應用程式讀取不支援的媒體檔案而觸發轉碼作業時,系統會顯示轉碼進度通知。這個選項預設為啟用。

  • 停用轉碼快取:如果啟用,需要轉碼的應用程式就不會執行。 使用轉碼快取這在開發期間可用於輕鬆觸發對不支援的媒體檔案進行轉碼,但可能會導致裝置效能不佳。這個選項預設為停用。