Điều khiển đa phương tiện thông qua MediaSession

1. Giới thiệu

Lần cập nhật gần đây nhất: ngày 9 tháng 09 năm 2020

Lợi ích của việc thêm MediaSession phát lại video là gì?

Phiên phát nội dung đa phương tiện là một mối liên kết không thể thiếu giữa nền tảng Android và các ứng dụng đa phương tiện. Tính năng này không chỉ thông báo cho Android rằng nội dung nghe nhìn đang phát để có thể chuyển tiếp các hành động đối với nội dung đa phương tiện vào đúng phiên, mà còn thông báo cho nền tảng nội dung đang phát và cách điều khiển nội dung đó.

Việc hiện một MediaSession thông qua ứng dụng của bạn sẽ mang lại nhiều lợi ích mà người dùng sẽ thích. Sau đây là một vài ví dụ hay.

Trợ lý Google

Người dùng có thể dễ dàng tương tác với nội dung nghe nhìn trong ứng dụng thông qua các lệnh thoại như "Tạm dừng" "Resume" (Tiếp tục) và "Tiếp theo". Siêu dữ liệu từ nội dung nghe nhìn của bạn cũng có thể dùng để tìm câu trả lời về nội dung đang phát.

Android TV

Trên trải nghiệm màn hình lớn, ứng dụng Android TV của bạn có thể sử dụng các điều khiển từ xa thông thường cho những người dùng có TV hỗ trợ HDMI-CEC. Các lệnh bằng các nút phát/tạm dừng, dừng, tiếp theo và trước đó sẽ được chuyển tiếp đến ứng dụng của bạn.

Các nút điều khiển nội dung nghe nhìn trên màn hình

Kể từ Android 4.0 (API cấp 14), hệ thống có thể truy cập vào trạng thái phát và siêu dữ liệu của một phiên phát nội dung đa phương tiện. Chức năng này cho phép màn hình khoá hiển thị các nút điều khiển nội dung nghe nhìn và hình minh hoạ. Hành vi này thay đổi tuỳ thuộc vào phiên bản Android.

Nội dung nghe nhìn trong nền

Bạn có thể điều khiển nội dung nghe nhìn trong bất kỳ trường hợp nào kể cả khi ứng dụng phát nội dung nghe nhìn đang chạy ở chế độ nền.

Tính toán môi trường xung quanh

Việc hiện nội dung nghe nhìn của bạn bằng dữ liệu về nội dung đang phát và cách điều khiển nội dung đó có thể kết nối giữa các thiết bị để người dùng có thể tương tác với nội dung đó theo nhiều cách mà họ thích.

Sản phẩm bạn sẽ tạo ra

Trong lớp học lập trình này, bạn sẽ mở rộng mẫu Exoplayer hiện có để thêm tính năng hỗ trợ phiên phát nội dung đa phương tiện. Ứng dụng này sẽ:

  • Phản ánh chính xác trạng thái hoạt động của phiên phát nội dung đa phương tiện
  • Chuyển tiếp các nút điều khiển nội dung nghe nhìn sang ExoPlayer
  • Truyền siêu dữ liệu của các mục trong hàng đợi vào phiên phát nội dung đa phương tiện

Kiến thức bạn sẽ học được

  • Tại sao phiên phát nội dung đa phương tiện lại mang đến cho người dùng trải nghiệm phong phú hơn
  • Cách tạo một phiên phát nội dung đa phương tiện và quản lý trạng thái của phiên đó
  • Cách kết nối một phiên phát nội dung đa phương tiện với ExoPlayer
  • Cách đưa siêu dữ liệu của các mục vào hàng đợi phát trong phiên phát nội dung đa phương tiện
  • Cách thêm các thao tác (tuỳ chỉnh) khác

Lớp học lập trình này sẽ tập trung vào SDK MediaSession. Các khái niệm và khối mã không liên quan, bao gồm cả thông tin chi tiết về việc triển khai ExoPlayer, sẽ không được thảo luận mà chỉ được cung cấp cho bạn để sao chép và dán.

Bạn cần có

  • Phiên bản Android Studio gần đây (3.5 trở lên)
  • Kiến thức cơ bản về cách phát triển ứng dụng Android

2. Thiết lập

Điểm xuất phát của chúng ta là gì?

Chúng tôi bắt đầu với bản minh hoạ chính của ExoPlayer. Bản minh hoạ này chứa video có bộ điều khiển chế độ phát trên màn hình nhưng không sử dụng các phiên phát nội dung nghe nhìn có sẵn. Đó là một nơi tuyệt vời để chúng tôi tìm hiểu và thêm các đóng góp của bạn!

Lấy mẫu ExoPlayer

Để bắt đầu chạy, hãy bắt đầu với mẫu ExoPlayer. Sao chép kho lưu trữ GitHub bằng cách chạy mã dưới đây.

git clone https://github.com/google/ExoPlayer.git

Mở bản minh hoạ

Trong Android Studio, hãy mở dự án minh hoạ chính nằm trong demos/main.

Android Studio sẽ nhắc bạn đặt đường dẫn SDK. Bạn nên làm theo đề xuất về việc cập nhật các công cụ IDE và SDK nếu gặp phải vấn đề nào đó.

10e3b5c652186d57.pngS

Nếu bạn được yêu cầu phải sử dụng phiên bản Gradle mới nhất, hãy tiếp tục và cập nhật phiên bản đó.

Hãy dành chút thời gian để nắm được kiến thức cơ bản về cách ứng dụng được thiết kế. Lưu ý rằng có hai hoạt động: SampleChooserActivity và PlayerActivity. Chúng ta sẽ dành phần còn lại của lớp học lập trình này trong PlayerActivity, nơi nội dung đa phương tiện thực sự phát. Vì vậy, hãy mở lớp này và chuyển sang phần tiếp theo.

3. Tạo một phiên phát nội dung nghe nhìn và quản lý trạng thái của phiên đó

Tạo phiên phát nội dung nghe nhìn

Mở PlayerActivity.java. Lớp này tạo ExoPlayer và quản lý các chức năng của ExoPlayer, chẳng hạn như kết xuất video lên màn hình. Trong hoạt động này, chúng ta sẽ kết nối ExoPlayer với một phiên đa phương tiện.

Khai báo 2 trường sau ở đầu lớp. Chúng tôi sẽ sử dụng các trường này trong phần này.

private MediaSessionCompat mediaSession;
private MediaSessionConnector mediaSessionConnector;

Bạn cần thêm "extension-mediasession" phần phụ thuộc dự án vào build.gradle cấp mô-đun cho "Module: demo":

implementation project(path: ':extension-mediasession')

Lưu ý rằng Android Studio có thể giúp bạn tự động thêm phần phụ thuộc này nếu bạn di chuột qua lỗi khi giải quyết MediaSessionRenderer:

60055e4ad54fbb97.pngS

Cuối cùng, hãy giải quyết các lệnh nhập lớp bằng cách thêm đoạn mã sau:

import android.support.v4.media.session.MediaSessionCompat;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;

Khi hoạt động được tạo, chúng ta sẽ tạo một phiên phát nội dung đa phương tiện và một trình kết nối phiên phát nội dung đa phương tiện đóng vai trò là bên trung gian giữa phiên phát nội dung đa phương tiện và ExoPlayer.

Địa điểm lý tưởng để chèn đoạn mã này cũng là nơi ExoPlayer được tạo. Trong ứng dụng minh hoạ, chúng ta có thể thêm đoạn mã vào cuối initializePlayer(). Hãy nhớ thêm logic này sau khi tạo thực thể cho trình phát!

private void initializePlayer() {
  if (player == null) {
    ...
    player = ...
    ...
    mediaSession = new MediaSessionCompat(this, "sample");
    mediaSessionConnector = new MediaSessionConnector(mediaSession);
    mediaSessionConnector.setPlayer(player);
  }
  ...
}

Phát hành phiên phát nội dung đa phương tiện

Huỷ bỏ phiên phát nội dung nghe nhìn khi không cần thiết nữa. Khi phát hành ExoPlayer trong releasePlayer(), chúng ta cũng có thể thêm mã sau để thực hiện việc này:

private void releasePlayer() {
  if (mediaSession != null) {
    mediaSession.release();
  }
  ...
}

Quản lý trạng thái phiên phát nội dung nghe nhìn

Bây giờ, chúng ta đã tạo thực thể cho phiên phát nội dung đa phương tiện, đảm bảo trạng thái của phiên phát nội dung đa phương tiện được phản ánh chính xác khi người dùng tương tác với hoạt động.

Khi người dùng bắt đầu hoạt động, phiên phát nội dung đa phương tiện sẽ hoạt động:

@Override
public void onStart() {
  ...
  if (mediaSession != null) {
    mediaSession.setActive(true);
  }
}

Vì ứng dụng của chúng ta không phát nội dung nghe nhìn ở chế độ nền nên cần đảm bảo rằng phiên phát nội dung đa phương tiện sẽ chuyển sang trạng thái không hoạt động khi người dùng rời khỏi hoạt động:

@Override
public void onStop() {
  super.onStop();
  if (mediaSession != null) {
    mediaSession.setActive(false);
  }
  ...
}

Hãy chạy bản minh hoạ

  1. Đính kèm thiết bị Android hoặc khởi động trình mô phỏng.
  2. Đảm bảo rằng "bản minh hoạ" được chọn để chạy trên thanh công cụ Android Studio. cb1ec4e50886874f.png
  3. Nhấp vào 9d8fb3a9ddf12827.pngS trên thanh công cụ Android Studio.
  4. Sau khi ứng dụng khởi chạy trên thiết bị của bạn, hãy chọn một luồng video để phát.
  5. Sau khi bắt đầu phát, hãy khám phá bằng các lệnh adb sau đây để điều khiển phiên phát nội dung đa phương tiện:
adb shell media dispatch pause
adb shell media dispatch play
adb shell media dispatch play-pause
adb shell media dispatch fast-forward
adb shell media dispatch rewind
  1. Ngoài ra, hãy khám phá cách Android xem phiên phát nội dung đa phương tiện của bạn. Cụ thể, bạn có thể kiểm tra xem những hành động nào được hỗ trợ bằng cách xem trường hành động đó. Số bạn thấy ở đây là sự kết hợp của các mã thao tác, như được khai báo trong đối tượng PlaybackState. Cách xem phiên phát nội dung nghe nhìn chạy: adb shell dumpsys media_session
  2. Nếu bạn đang sử dụng một thiết bị thực có micrô, hãy thử gọi Trợ lý Google và thực hiện các lệnh thoại, chẳng hạn như: "Tạm dừng". "Tiếp tục." "Tua đi 1 phút."

b8dda02a6fb0f6a4.pngMẫu ExoPlayer chạy trên Android TV.

4. Thêm siêu dữ liệu của các mục vào hàng đợi phát

Giờ đây, chúng ta có thể mở rộng các tính năng được hỗ trợ của phiên đa phương tiện mà trước đây chúng ta đã tạo MediaSessionRenderer trong initializePlayer().

Thêm EventQueueNavigator

ExoPlayer mô tả cấu trúc của nội dung đa phương tiện ở dạng dòng thời gian. Để biết thông tin chi tiết về cách hoạt động của tính năng này, hãy dành thời gian đọc về đối tượng Dòng thời gian của ExoPlayer. Khi bạn khai thác cấu trúc này, chúng tôi có thể nhận được thông báo khi nội dung thay đổi và cung cấp siêu dữ liệu về nội dung đang phát khi được yêu cầu.

Để thực hiện việc này, chúng ta sẽ xác định TimelineQueueNavigator. Xác định vị trí tạo bản sao của MediaSessionRenderer trong initializePlayer() và thêm phương thức triển khai EventQueueNavigator sau khi mediaSession được khởi chạy.

mediaSessionConnector.setQueueNavigator(new TimelineQueueNavigator(mediaSession) {
  @Override
  public MediaDescriptionCompat getMediaDescription(Player player, int windowIndex) {
    return new MediaDescriptionCompat.Builder()
            .setTitle(player.getCurrentMediaItem().mediaMetadata.title)
            .setDescription("MediaDescription description for " + windowIndex)
            .setSubtitle("MediaDescription subtitle")
            .build();
  }
});

Giải quyết việc nhập lớp bằng cách thêm:

import android.support.v4.media.MediaDescriptionCompat;
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator;

Lưu ý rằng tham số windowIndex tương ứng với mục của chỉ mục đó trong hàng đợi phát.

Bây giờ khi đã thêm một số siêu dữ liệu, bạn có thể kiểm tra để đảm bảo Trợ lý hiểu được nội dung đang phát. Trong khi phát một video trên Android TV, hãy gọi Trợ lý và hỏi "Nội dung nào đang phát?"

6c7fc0cb853cbc38.pngS

5. Tuỳ chỉnh thao tác

Có thể trình phát của bạn không hỗ trợ một số thao tác hoặc bạn muốn hỗ trợ thêm các thao tác khác? Bây giờ, hãy tìm hiểu sâu hơn một chút về phiên đa phương tiện mà chúng ta đã tạo trước đây MediaSessionRenderer trong initializePlayer().

Khai báo các thao tác được hỗ trợ

Hãy thử dùng mediaSessionConnector.setEnabledPlaybackActions() để tuỳ chỉnh những thao tác mà bạn muốn phiên phát nội dung đa phương tiện hỗ trợ.

Xin lưu ý rằng tập hợp đầy đủ là:

mediaSessionConnector.setEnabledPlaybackActions(
        PlaybackStateCompat.ACTION_PLAY_PAUSE
                | PlaybackStateCompat.ACTION_PLAY
                | PlaybackStateCompat.ACTION_PAUSE
                | PlaybackStateCompat.ACTION_SEEK_TO
                | PlaybackStateCompat.ACTION_FAST_FORWARD
                | PlaybackStateCompat.ACTION_REWIND
                | PlaybackStateCompat.ACTION_STOP
                | PlaybackStateCompat.ACTION_SET_REPEAT_MODE
                | PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE
);

Hãy xem lại cách dữ liệu này hiển thị với nền tảng:

  1. Như trước đây, hãy bắt đầu phát một video.
  2. Khám phá cách Android xem siêu dữ liệu trong phiên phát nội dung đa phương tiện của bạn bằng cách thực thi: adb shell dumpsys media_session
  3. Tìm dòng chứa siêu dữ liệu và quan sát xem tiêu đề và nội dung mô tả có được đưa vào cũng như liên kết với com.google.android.exoplayer2.demo/sample hay không.

Thêm các hành động khác

Chúng ta có thể mở rộng phiên phát nội dung đa phương tiện bằng một số thao tác bổ sung. Trong phần này, chúng tôi sẽ chỉ hỗ trợ phụ đề.

Phụ đề hỗ trợ

Khi thêm tính năng hỗ trợ phụ đề cho các phiên phát nội dung nghe nhìn, người dùng có thể chuyển đổi bằng giọng nói. Tại nơi bạn đã khởi chạy trình kết nối phiên đa phương tiện, hãy thêm đoạn mã sau:

mediaSessionConnector.setCaptionCallback(new MediaSessionConnector.CaptionCallback() {
      @Override
      public void onSetCaptioningEnabled(Player player, boolean enabled) {
        Log.d("MediaSession", "onSetCaptioningEnabled: enabled=" + enabled);
      }

      @Override
      public boolean hasCaptions(Player player) {
        return true;
      }

      @Override
      public boolean onCommand(Player player, ControlDispatcher controlDispatcher, String command, Bundle extras, ResultReceiver cb) {
        return false;
      }
    }
);

Cuối cùng, hãy giải quyết mọi lệnh nhập bị thiếu.

Bạn có thể kiểm tra việc này bằng cách gọi Trợ lý Google trên Android TV rồi nói "Bật phụ đề". Kiểm tra Logcat cho các thông báo để xem cách mã này gọi vào mã của bạn.

6. Xin chúc mừng

Xin chúc mừng, bạn đã thêm thành công các phiên phát nội dung nghe nhìn vào mẫu!

Bạn đã có được rất nhiều chức năng nhờ:

  • thêm một phiên nội dung nghe nhìn,
  • kết nối các phiên phát nội dung đa phương tiện với một thực thể của ExoPlayer,
  • thêm siêu dữ liệu và các thao tác khác.

Giờ đây, bạn đã biết các bước quan trọng cần thiết để làm phong phú ứng dụng đa phương tiện và mang đến cho người dùng trải nghiệm linh hoạt hơn!

Nhận xét cuối cùng

Lớp học lập trình này được xây dựng dựa trên một mẫu từ mã nguồn ExoPlayer. Không cần phải sử dụng ExoPlayer từ nguồn và thay vào đó, bạn nên kéo các phần phụ thuộc cho ExoPlayer và MediaSessionRenderer để dễ dàng cập nhật bản phát hành mới nhất hơn.

Để thực hiện việc này, bạn chỉ cần thay thế các phần phụ thuộc của dự án, chẳng hạn như:

implementation project(modulePrefix + 'library-core')
implementation project(path: ':extension-mediasession')

để lấy từ các kho lưu trữ Maven, chẳng hạn như:

implementation 'com.google.android.exoplayer:exoplayer-core:2.+'
implementation 'com.google.android.exoplayer:extension-mediasession:2.+'

Tài liệu tham khảo