Làm việc với MediaPlayer và công nghệ Quản lý quyền kỹ thuật số (DRM)

Kể từ Android 8.0 (API cấp 26), MediaPlayer bao gồm các API hỗ trợ phát nội dung được bảo vệ bằng DRM. Các API DRM MediaPlayer tương tự như API cấp thấp do MediaDrm cung cấp, nhưng hoạt động ở cấp cao hơn và không hiển thị trình trích xuất, DRM và các đối tượng mã hoá cơ bản.

Mặc dù MediaPlayer DRM API không cung cấp đầy đủ chức năng của MediaDrm, nhưng API này hỗ trợ các trường hợp sử dụng phổ biến nhất. Cách triển khai hiện tại có thể xử lý các loại nội dung sau:

  • Tệp nội dung nghe nhìn cục bộ được bảo vệ bằng Widevine
  • Tệp nội dung nghe nhìn truyền trực tuyến hoặc từ xa được bảo vệ bằng Widevine

Đoạn mã sau đây minh hoạ cách sử dụng các phương thức MediaPlayer DRM mới trong quá trình triển khai đồng bộ.

Để quản lý nội dung nghe nhìn do DRM kiểm soát, bạn cần thêm các phương thức mới cùng với luồng gọi MediaPlayer thông thường, như trong ví dụ sau:

Kotlin

mediaPlayer?.apply {
    setDataSource()
    setOnDrmConfigHelper() // optional, for custom configuration
    prepare()
    drmInfo?.also {
        prepareDrm()
        getKeyRequest()
        provideKeyResponse()
    }

    // MediaPlayer is now ready to use
    start()
    // ...play/pause/resume...
    stop()
    releaseDrm()
}

Java

setDataSource();
setOnDrmConfigHelper(); // optional, for custom configuration
prepare();
if (getDrmInfo() != null) {
  prepareDrm();
  getKeyRequest();
  provideKeyResponse();
}

// MediaPlayer is now ready to use
start();
// ...play/pause/resume...
stop();
releaseDrm();

Bắt đầu bằng cách khởi động đối tượng MediaPlayer và đặt nguồn của đối tượng đó bằng setDataSource() như bình thường. Sau đó, để sử dụng DRM, hãy thực hiện các bước sau:

  1. Nếu bạn muốn ứng dụng của mình thực hiện cấu hình tuỳ chỉnh, hãy xác định giao diện OnDrmConfigHelper và đính kèm giao diện đó vào trình phát bằng setOnDrmConfigHelper().
  2. Gọi prepare().
  3. Gọi getDrmInfo(). Nếu nguồn có nội dung DRM, phương thức này sẽ trả về giá trị MediaPlayer.DrmInfo không rỗng.

Nếu MediaPlayer.DrmInfo tồn tại:

  1. Kiểm tra bản đồ các UUID có sẵn rồi chọn một UUID.
  2. Chuẩn bị cấu hình DRM cho nguồn hiện tại bằng cách gọi prepareDrm().
    • Nếu bạn đã tạo và đăng ký lệnh gọi lại OnDrmConfigHelper, thì lệnh gọi lại đó sẽ được gọi trong khi prepareDrm() đang thực thi. Điều này cho phép bạn thực hiện cấu hình tuỳ chỉnh của các thuộc tính DRM trước khi mở phiên DRM. Lệnh gọi lại được gọi đồng bộ trong luồng đã gọi prepareDrm(). Để truy cập vào các thuộc tính DRM, hãy gọi getDrmPropertyString()setDrmPropertyString(). Tránh thực hiện các thao tác dài.
    • Nếu thiết bị chưa được cấp phép, prepareDrm() cũng truy cập vào máy chủ cấp phép để cấp phép cho thiết bị. Quá trình này có thể mất một khoảng thời gian tuỳ theo khả năng kết nối mạng.
  3. Để nhận một mảng byte yêu cầu khoá mờ gửi đến máy chủ cấp phép, hãy gọi getKeyRequest().
  4. Để thông báo cho công cụ DRM về phản hồi khoá nhận được từ máy chủ cấp phép, hãy gọi provideKeyResponse(). Kết quả phụ thuộc vào loại yêu cầu khoá:
    • Nếu phản hồi là cho một yêu cầu khoá ngoại tuyến, thì kết quả sẽ là giá trị nhận dạng tập hợp khoá. Bạn có thể sử dụng giá trị nhận dạng tập hợp khoá này với restoreKeys() để khôi phục khoá cho một phiên mới.
    • Nếu phản hồi là cho yêu cầu phát trực tuyến hoặc phát hành, kết quả sẽ là rỗng.

Chuẩn bị DRM không đồng bộ

Theo mặc định, prepareDrm() chạy đồng bộ, chặn cho đến khi quá trình chuẩn bị hoàn tất. Tuy nhiên, quá trình chuẩn bị DRM đầu tiên trên thiết bị mới cũng có thể yêu cầu cấp phép mà prepareDrm() xử lý nội bộ và có thể mất một chút thời gian để hoàn tất do liên quan đến hoạt động mạng. Bạn có thể tránh chặn trên prepareDrm() bằng cách xác định và đặt MediaPlayer.OnDrmPreparedListener.

Đặt OnDrmPreparedListener. prepareDrm() thực hiện việc cấp phép (nếu cần) và chuẩn bị ở chế độ nền. Khi quá trình cấp phép và chuẩn bị hoàn tất, hệ thống sẽ gọi trình nghe. Đừng đưa ra bất kỳ giả định nào về trình tự gọi hoặc luồng mà trình nghe chạy (trừ khi bạn đăng ký trình nghe với luồng trình xử lý). Hệ thống có thể gọi trình nghe trước hoặc sau khi prepareDrm() trả về.

Thiết lập DRM không đồng bộ

Bạn có thể khởi chạy DRM không đồng bộ bằng cách tạo và đăng ký MediaPlayer.OnDrmInfoListener để chuẩn bị DRM và MediaPlayer.OnDrmPreparedListener để khởi động trình phát. Các lớp này hoạt động cùng với prepareAsync(), như trong ví dụ sau:

Kotlin

setOnPreparedListener()
setOnDrmInfoListener()
setDataSource()
prepareAsync()
// ...

// If the data source content is protected you receive a call to the onDrmInfo() callback.
override fun onDrmInfo(mediaPlayer: MediaPlayer, drmInfo: MediaPlayer.DrmInfo) {
    mediaPlayer.apply {
        prepareDrm()
        getKeyRequest()
        provideKeyResponse()
    }
}

// When prepareAsync() finishes, you receive a call to the onPrepared() callback.
// If there is a DRM, onDrmInfo() sets it up before executing this callback,
// so you can start the player.
override fun onPrepared(mediaPlayer: MediaPlayer) {
    mediaPlayer.start()
}

Java

setOnPreparedListener();
setOnDrmInfoListener();
setDataSource();
prepareAsync();
// ...

// If the data source content is protected you receive a call to the onDrmInfo() callback.
onDrmInfo() {
  prepareDrm();
  getKeyRequest();
  provideKeyResponse();
}

// When prepareAsync() finishes, you receive a call to the onPrepared() callback.
// If there is a DRM, onDrmInfo() sets it up before executing this callback,
// so you can start the player.
onPrepared() {

start();
}

Xử lý nội dung nghe nhìn đã mã hoá

Kể từ Android 8.0 (API cấp 26), MediaPlayer cũng có thể giải mã Giao thức mã hoá phổ biến (CENC) và nội dung nghe nhìn được mã hoá ở cấp mẫu HLS (METHOD=SAMPLE-AES) cho các loại luồng cơ bản H.264 và AAC. Trước đây, chúng tôi hỗ trợ nội dung nghe nhìn được mã hoá toàn bộ phân khúc (METHOD=AES-128).

Tìm hiểu thêm

Jetpack Media3 là giải pháp được đề xuất để phát nội dung đa phương tiện trong ứng dụng của bạn. Hãy đọc thêm về giải pháp này.

Các trang này đề cập đến các chủ đề liên quan đến việc ghi âm, lưu trữ và phát âm thanh và video: