Chuyển mã tệp đa phương tiện tương thích

Trên Android 12 (API cấp 31) trở lên, hệ thống có thể tự động chuyển đổi video được quay ở định dạng như HEVC (H.265) sang AVC (H.264) khi video được mở bằng một ứng dụng không hỗ trợ HEVC. Tính năng này cho phép các ứng dụng quay video sử dụng phương thức mã hoá hiện đại hơn, tiết kiệm bộ nhớ hơn cho những video được quay trên thiết bị mà vẫn tương thích với các ứng dụng khác.

Các định dạng sau có thể được tự động chuyển mã cho nội dung được tạo trên thiết bị:

Định dạng nội dung nghe nhìn Thuộc tính XML Loại MIME MediaFormat
HEVC (H.265) HEVC (lượt chuyển đổi từ lượt xem được thực hiện) MediaFormat.MIMETYPE_VIDEO_HEVC
HDR10HDR10 MediaFeature.HdrType.HDR10
HDR10+ HDR10Plus MediaFeature.HdrType.HDR10_PLUS

Android giả định rằng các ứng dụng có thể hỗ trợ phát mọi định dạng nội dung nghe nhìn, vì vậy, chế độ chuyển mã nội dung nghe nhìn tương thích sẽ tắt theo mặc định.

Trường hợp sử dụng phương thức chuyển mã

Chuyển mã là một thao tác tiêu tốn tài nguyên tính toán và làm tăng độ trễ đáng kể khi mở tệp video. Ví dụ: một tệp video HEVC dài 1 phút sẽ mất khoảng 20 giây để chuyển mã thành tệp AVC trên điện thoại Pixel 3. Vì lý do này, bạn chỉ nên chuyển mã tệp video khi gửi tệp ra khỏi thiết bị. Ví dụ: khi chia sẻ tệp video với người dùng khác sử dụng cùng một ứng dụng hoặc máy chủ đám mây không hỗ trợ các định dạng video hiện đại.

Đừng chuyển mã khi mở tệp video để phát trên thiết bị hoặc để tạo hình thu nhỏ.

Định cấu hình chuyển mã

Các ứng dụng có thể kiểm soát hành vi chuyển mã bằng cách khai báo tính năng đa phương tiện. Có 2 cách để khai báo các khả năng này: trong mã hoặc trong tài nguyên.

Khai báo chức năng trong mã

Bạn có thể khai báo tính năng đa phương tiện trong mã bằng cách tạo một thực thể của đối tượng ApplicationMediaCapabilities thông qua trình tạo:

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();

Hãy dùng đối tượng này khi truy cập vào nội dung nghe nhìn thông qua các phương thức như 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.
}

Phương thức này cho phép kiểm soát chi tiết các đường dẫn mã cụ thể, chẳng hạn như chỉ gọi chuyển mã khi chuyển một tệp video ra ngoài thiết bị. Phương thức này được ưu tiên hơn phương thức được mô tả dưới đây.

Khai báo chức năng trong tài nguyên

Việc khai báo các chức năng trong tài nguyên cho phép kiểm soát tổng thể đối với quá trình chuyển mã. Bạn chỉ nên sử dụng phương pháp này trong các trường hợp rất cụ thể. Ví dụ: nếu ứng dụng của bạn chỉ nhận tệp video từ các ứng dụng khác (thay vì mở trực tiếp) và tải tệp lên một máy chủ không hỗ trợ bộ mã hoá và giải mã video hiện đại (xem trường hợp ví dụ 1 bên dưới).

Việc sử dụng phương pháp này khi không thực sự cần thiết có thể gọi ra quá trình chuyển mã trong các trường hợp không mong muốn, chẳng hạn như khi thu nhỏ video, dẫn đến trải nghiệm người dùng kém.

Để sử dụng phương thức này, hãy tạo tệp tài nguyên 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>

Trong ví dụ này, video HDR được ghi trên thiết bị sẽ được chuyển mã liền mạch thành video AVC SDR (dải động chuẩn), trong khi video HEVC thì không.

Sử dụng thẻ property trong thẻ application để thêm nội dung tham chiếu đến tệp chức năng đa phương tiện. Thêm các thuộc tính này vào tệp AndroidManifest.xml:

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

Sử dụng tính năng đa phương tiện của một ứng dụng khác để mở tệp video

Nếu ứng dụng của bạn chia sẻ tệp video với một ứng dụng khác, thì tệp video có thể cần phải được chuyển mã trước khi ứng dụng nhận có thể mở tệp đó.

Bạn có thể xử lý trường hợp này bằng cách mở tệp video bằng openTypedAssetFileDescriptor rồi chỉ định UID của ứng dụng nhận. Bạn có thể lấy UID này bằng Binder.getCallingUid. Sau đó, nền tảng sẽ sử dụng tính năng nội dung đa phương tiện của ứng dụng nhận để xác định xem tệp video có được chuyển mã hay không.

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.
}

Tình huống ví dụ

Các biểu đồ sau đây minh hoạ hai trường hợp sử dụng phổ biến. Trong cả hai trường hợp, video gốc được lưu trữ ở định dạng HEVC và ứng dụng chia sẻ video không hỗ trợ HEVC.

Ví dụ 1. Quá trình chuyển mã do ứng dụng quay video khởi tạo. Ví dụ 1 Ứng dụng chia sẻ video khai báo rằng ứng dụng không hỗ trợ HEVC trong tệp tài nguyên về các chức năng đa phương tiện. Sau đó, ứng dụng quay video sẽ yêu cầu video từ ứng dụng quay video. Ứng dụng quay video sẽ xử lý yêu cầu và mở tệp bằng openTypedAssetFileDescriptor, chỉ định UID của ứng dụng chia sẻ. Thao tác này sẽ bắt đầu quá trình chuyển mã. Khi nhận được video đã chuyển mã, video sẽ được cung cấp cho ứng dụng chia sẻ rồi tải video lên máy chủ trên đám mây.

Ví dụ 2. Quá trình chuyển mã được khởi tạo bằng ứng dụng chia sẻ video. Ví dụ 2 Ứng dụng quay video chia sẻ video với ứng dụng chia sẻ video bằng URI MediaStore. Ứng dụng chia sẻ video mở tệp video bằng openTypedAssetFileDescriptor, trong đó chỉ định rằng ứng dụng không hỗ trợ HEVC trong các tính năng đa phương tiện. Việc này sẽ bắt đầu quá trình chuyển mã và sau khi hoàn tất, tệp sẽ được tải lên một máy chủ trên đám mây.

Định dạng không được khai báo

Tính năng chuyển mã nội dung đa phương tiện tương thích được bật cho mọi định dạng được khai báo là không được hỗ trợ và bị tắt đối với mọi định dạng được khai báo. Đối với các định dạng khác không được khai báo, nền tảng sẽ quyết định việc chuyển mã hay không. Trong Android 12, tính năng chuyển mã sẽ bị tắt đối với tất cả các định dạng không được khai báo. Hành vi này có thể thay đổi đối với các định dạng mới trong tương lai.

Tuỳ chọn cho nhà phát triển

Bạn có thể sử dụng các tuỳ chọn sau đây cho nhà phát triển để ghi đè hành vi chuyển mã mặc định của Android:

  • Ghi đè các giá trị mặc định của quá trình chuyển mã Chế độ cài đặt này xác định liệu nền tảng có kiểm soát quá trình chuyển mã tự động hay không. Khi bạn bật chế độ ghi đè, các giá trị mặc định của nền tảng sẽ bị bỏ qua và chế độ cài đặt bật tính năng chuyển mã sẽ kiểm soát việc chuyển mã tự động. Tuỳ chọn này bị tắt theo mặc định.

  • Bật chuyển mã Tùy chọn cài đặt này chỉ định xem các định dạng chưa khai báo có được tự động chuyển mã hay không. Tính năng này được bật theo mặc định, nhưng chỉ có hiệu lực nếu bạn cũng bật chế độ ghi đè mặc định chuyển mã.

  • Giả sử các ứng dụng hỗ trợ các định dạng hiện đại Chế độ cài đặt này kiểm soát điều gì sẽ xảy ra khi ứng dụng cố gắng phát một định dạng chưa được khai báo. Điều này xảy ra khi tệp kê khai không khai báo liệu ứng dụng có hỗ trợ một định dạng cụ thể hay không, hoặc Google chưa thêm ứng dụng vào danh sách chuyển mã buộc phía máy chủ. Khi bạn bật chế độ cài đặt này, ứng dụng sẽ không chuyển mã và khi bạn tắt, ứng dụng sẽ chuyển mã. Tuỳ chọn này được bật theo mặc định.

  • Hiện thông báo chuyển mã Khi được bật, ứng dụng sẽ cho thấy thông báo về tiến trình chuyển mã khi quá trình chuyển mã được kích hoạt bằng cách đọc một tệp nội dung nghe nhìn không được hỗ trợ. Tuỳ chọn này được bật theo mặc định.

  • Tắt bộ nhớ đệm chuyển mã Nếu được bật, các ứng dụng yêu cầu chuyển mã sẽ không sử dụng bộ nhớ đệm chuyển mã. Điều này có thể hữu ích trong quá trình phát triển để dễ dàng kích hoạt quá trình chuyển mã trên một tệp nội dung nghe nhìn không được hỗ trợ, nhưng có thể làm giảm hiệu suất của thiết bị. Tuỳ chọn này bị tắt theo mặc định.