Bật tính năng truyền cho ứng dụng web

1. Tổng quan

Biểu trưng Google Cast

Lớp học lập trình này sẽ hướng dẫn bạn cách chỉnh sửa một ứng dụng video web hiện có để truyền nội dung trên một thiết bị hỗ trợ Google Cast.

Google Cast là gì?

Google Cast cho phép người dùng truyền nội dung từ thiết bị di động sang TV. Sau đó, người dùng có thể sử dụng thiết bị di động làm điều khiển từ xa để phát nội dung đa phương tiện trên TV.

Google Cast SDK cho phép bạn mở rộng ứng dụng của mình để điều khiển TV hoặc hệ thống âm thanh. Cast SDK cho phép bạn thêm các thành phần giao diện người dùng cần thiết dựa trên Danh sách kiểm tra thiết kế Google Cast.

Danh sách kiểm tra thiết kế Google Cast được cung cấp để giúp trải nghiệm người dùng Cast đơn giản và có thể dự đoán được trên tất cả các nền tảng được hỗ trợ.

Chúng tôi sẽ xây dựng những gì?

Khi đã hoàn tất lớp học lập trình này, bạn sẽ có một ứng dụng video trên web của Chrome có thể truyền video tới thiết bị Google Cast.

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

  • Cách thêm Google Cast SDK vào ứng dụng video mẫu.
  • Cách thêm nút Truyền để chọn thiết bị Google Cast.
  • Cách kết nối với thiết bị truyền và khởi chạy thiết bị nhận nội dung nghe nhìn.
  • Cách truyền video.
  • Cách tích hợp Cast Connect

Bạn cần có

  • Trình duyệt Google Chrome mới nhất.
  • Dịch vụ lưu trữ HTTPS như Lưu trữ Firebase hoặc ngrok.
  • Thiết bị Google Cast như Chromecast hoặc Android TV được định cấu hình có quyền truy cập Internet.
  • TV hoặc màn hình có đầu vào HDMI.
  • Bạn cần phải có Chromecast có Google TV để kiểm thử việc tích hợp Cast Connect nhưng không bắt buộc phải cung cấp cho phần còn lại của Lớp học lập trình. Nếu bạn chưa có tài khoản này, hãy bỏ qua bước Thêm tính năng hỗ trợ Cast Connect ở cuối hướng dẫn này.

Trải nghiệm

  • Bạn cần có kiến thức về phát triển web trước đó.
  • Bạn cũng cần có kiến thức trước về cách xem TV :)

Bạn sẽ sử dụng hướng dẫn này như thế nào?

Chỉ đọc qua Đọc và hoàn thành các bài tập

Bạn đánh giá thế nào về trải nghiệm của mình trong quá trình tạo ứng dụng web?

Người mới bắt đầu Trung cấp Thành thạo

Bạn đánh giá thế nào về trải nghiệm của mình khi xem TV?

Người mới bắt đầu Trung cấp Thành thạo

2. Nhận mã mẫu

Bạn có thể tải tất cả mã mẫu xuống máy tính của mình...

rồi giải nén tệp zip đã tải xuống.

3. Chạy ứng dụng mẫu

Biểu trưng Google Chrome

Trước tiên, hãy xem ứng dụng mẫu hoàn chỉnh trông như thế nào. Ứng dụng này là một trình phát video cơ bản. Người dùng có thể chọn một video trong danh sách rồi phát video đó trên thiết bị hoặc Truyền video đó tới thiết bị Google Cast.

Để có thể sử dụng phiên bản đã hoàn tất, bạn cần lưu trữ phiên bản đó.

Nếu không có máy chủ để sử dụng, bạn có thể sử dụng Lưu trữ Firebase hoặc ngrok.

Chạy máy chủ

Sau khi thiết lập xong dịch vụ mà bạn chọn, hãy chuyển đến app-done và khởi động máy chủ.

Trong trình duyệt, hãy truy cập URL https để xem mẫu bạn đã lưu trữ.

  1. Bạn sẽ thấy ứng dụng video xuất hiện.
  2. Nhấp vào nút Truyền và chọn thiết bị Google Cast của bạn.
  3. Chọn một video, nhấp vào nút phát.
  4. Video sẽ bắt đầu phát trên thiết bị Google Cast của bạn.

Hình ảnh video đang phát trên Thiết bị truyền

Nhấp vào nút tạm dừng trong thành phần video để tạm dừng video trên bộ thu. Nhấp vào nút phát trong phần tử video để tiếp tục phát lại video.

Nhấp vào nút Truyền để dừng truyền tới thiết bị Google Cast.

Trước khi chúng ta tiếp tục, hãy dừng máy chủ.

4. Chuẩn bị dự án khởi động

Hình ảnh video đang phát trên Thiết bị truyền

Chúng tôi cần thêm tính năng hỗ trợ cho Google Cast vào ứng dụng ban đầu mà bạn tải xuống. Dưới đây là một số thuật ngữ của Google Cast mà chúng tôi sẽ sử dụng trong lớp học lập trình này:

  • một ứng dụng của người gửi chạy trên thiết bị di động hoặc máy tính xách tay,
  • một ứng dụng broadcast receiver chạy trên thiết bị Google Cast.

Giờ đây, bạn đã sẵn sàng để xây dựng dựa trên dự án khởi đầu bằng cách sử dụng trình chỉnh sửa văn bản yêu thích của mình:

  1. Chọn thư mục biểu tượng thư mụcapp-start trong tệp tải mã mẫu xuống.
  2. Chạy ứng dụng bằng máy chủ và khám phá giao diện người dùng.

Lưu ý: Khi tìm hiểu lớp học lập trình này, tuỳ thuộc vào dịch vụ mà bạn sẽ cần lưu trữ lại mẫu trên máy chủ của mình.

Thiết kế ứng dụng

Ứng dụng này tìm nạp danh sách video qua một máy chủ web từ xa và cung cấp một danh sách để người dùng duyệt xem. Người dùng có thể chọn một video để xem chi tiết hoặc phát video trên thiết bị di động.

Ứng dụng này bao gồm một khung hiển thị chính, được xác định trong index.html và bộ điều khiển chính là CastVideos.js.

index.html

Tệp html này khai báo gần như toàn bộ giao diện người dùng cho ứng dụng web.

Có một số phần của khung hiển thị, chúng ta có div#main_video chứa phần tử video. Liên quan đến div video, chúng ta có div#media_control, xác định tất cả các chế độ điều khiển cho phần tử video. Bên dưới mục đó là media_info, cho thấy thông tin chi tiết về video đang được xem. Cuối cùng, div carousel hiển thị một danh sách các video trong một div.

Tệp index.html cũng khởi động SDK Truyền và yêu cầu hàm CastVideos tải.

Hầu hết nội dung sẽ điền các phần tử này đều được xác định, chèn và kiểm soát trong CastVideos.js. Hãy cùng xem xét mục tiêu đó.

CastVideos.js

Tập lệnh này quản lý tất cả logic cho ứng dụng web Truyền video. Danh sách video và siêu dữ liệu liên quan được xác định trong CastVideos.js có trong một đối tượng có tên là mediaJSON.

Có một số phần chính chịu trách nhiệm quản lý và phát video cả trên máy tính và từ xa. Nhìn chung, đây là một ứng dụng web khá đơn giản.

CastPlayer là lớp chính quản lý toàn bộ ứng dụng, thiết lập trình phát, chọn nội dung đa phương tiện và liên kết các sự kiện với PlayerHandler để phát nội dung đa phương tiện. CastPlayer.prototype.initializeCastPlayer là phương thức thiết lập tất cả chức năng Truyền. CastPlayer.prototype.switchPlayer chuyển đổi trạng thái giữa trình phát cục bộ và trình phát từ xa. CastPlayer.prototype.setupLocalPlayerCastPlayer.prototype.setupRemotePlayer khởi chạy trình phát cục bộ và trình phát từ xa.

PlayerHandler là lớp chịu trách nhiệm quản lý việc phát nội dung đa phương tiện. Một số phương thức khác sẽ chịu trách nhiệm về chi tiết cho việc quản lý nội dung đa phương tiện và quá trình phát.

Câu hỏi thường gặp

5. Thêm nút Truyền

Hình ảnh của một ứng dụng hỗ trợ Cast

Ứng dụng hỗ trợ Cast hiển thị nút Truyền trong phần tử video. Khi nhấp vào nút Truyền, bạn sẽ thấy danh sách các Thiết bị truyền mà người dùng có thể chọn. Nếu người dùng đang phát nội dung trên thiết bị gửi, thì thao tác chọn một Thiết bị truyền sẽ bắt đầu hoặc tiếp tục phát trên Thiết bị truyền đó. Bất cứ lúc nào trong phiên Truyền, người dùng có thể nhấp vào nút Truyền và dừng truyền ứng dụng của bạn tới Thiết bị truyền. Người dùng phải có khả năng kết nối hoặc ngắt kết nối khỏi Thiết bị truyền khi đang ở bất kỳ màn hình nào của ứng dụng, như mô tả trong Danh sách kiểm tra thiết kế của Google Cast.

Cấu hình

Dự án khởi động yêu cầu các phần phụ thuộc và quy trình thiết lập giống như bạn đã làm đối với ứng dụng mẫu hoàn chỉnh, nhưng lần này lưu trữ nội dung của app-start.

Trong trình duyệt, hãy truy cập URL https để xem mẫu mà bạn đã lưu trữ.

Hãy nhớ rằng khi thực hiện thay đổi, bạn sẽ cần phải lưu trữ lại mẫu trên máy chủ của mình tuỳ thuộc vào dịch vụ.

Khởi chạy

Khung Truyền có một đối tượng singleton toàn cầu là CastContext, đối tượng này sẽ điều phối tất cả hoạt động của khung. Đối tượng này phải được khởi tạo sớm trong vòng đời của ứng dụng, thường được gọi từ lệnh gọi lại được chỉ định cho window['__onGCastApiAvailable']. Lệnh gọi lại này được gọi sau khi SDK truyền được tải và có sẵn để sử dụng. Trong trường hợp này, CastContext được gọi trong CastPlayer.prototype.initializeCastPlayer, được gọi từ lệnh gọi lại nêu trên.

Bạn phải cung cấp đối tượng JSON options khi khởi tạo CastContext. Lớp này chứa các tuỳ chọn ảnh hưởng đến hành vi của khung. Điều quan trọng nhất trong số này là mã ứng dụng của thiết bị nhận. Mã này được dùng để lọc danh sách các Thiết bị truyền hiện có nhằm chỉ hiển thị những thiết bị có khả năng chạy ứng dụng được chỉ định và để chạy ứng dụng nhận khi phiên Truyền bắt đầu.

Khi phát triển ứng dụng có hỗ trợ Cast, bạn phải đăng ký làm nhà phát triển Cast, sau đó lấy mã ứng dụng cho ứng dụng của mình. Đối với lớp học lập trình này, chúng ta sẽ sử dụng một mã ứng dụng mẫu.

Thêm mã sau vào index.html ở cuối phần body:

<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>

Thêm mã sau vào index.html để khởi chạy ứng dụng CastVideos, cũng như để khởi chạy CastContext:

<script src="CastVideos.js"></script>
<script type="text/javascript">
var castPlayer = new CastPlayer();
window['__onGCastApiAvailable'] = function(isAvailable) {
  if (isAvailable) {
    castPlayer.initializeCastPlayer();
  }
};
</script>

Bây giờ, chúng ta cần thêm một phương thức mới trong CastVideos.js, tương ứng với phương thức mà chúng ta vừa gọi trong index.html. Hãy thêm một phương thức mới tên là initializeCastPlayer. Phương thức này sẽ đặt các tuỳ chọn trên CastContext và khởi chạy RemotePlayerRemotePlayerControllers mới:

/**
 * This method sets up the CastContext, and a few other members
 * that are necessary to play and control videos on a Cast
 * device.
 */
CastPlayer.prototype.initializeCastPlayer = function() {

    var options = {};

    // Set the receiver application ID to your own (created in
    // the Google Cast Developer Console), or optionally
    // use the chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID
    options.receiverApplicationId = 'C0868879';

    // Auto join policy can be one of the following three:
    // ORIGIN_SCOPED - Auto connect from same appId and page origin
    // TAB_AND_ORIGIN_SCOPED - Auto connect from same appId, page origin, and tab
    // PAGE_SCOPED - No auto connect
    options.autoJoinPolicy = chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED;

    cast.framework.CastContext.getInstance().setOptions(options);

    this.remotePlayer = new cast.framework.RemotePlayer();
    this.remotePlayerController = new cast.framework.RemotePlayerController(this.remotePlayer);
    this.remotePlayerController.addEventListener(
        cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED,
        this.switchPlayer.bind(this)
    );
};

Cuối cùng, chúng ta cần tạo các biến cho RemotePlayerRemotePlayerController:

var CastPlayer = function() {
  //...
  /* Cast player variables */
  /** @type {cast.framework.RemotePlayer} */
  this.remotePlayer = null;
  /** @type {cast.framework.RemotePlayerController} */
  this.remotePlayerController = null;
  //...
};

Nút truyền

Giờ đây, CastContext đã được khởi chạy, chúng ta cần thêm nút Truyền để cho phép người dùng chọn Thiết bị truyền. SDK Truyền cung cấp thành phần nút Truyền có tên google-cast-launcher với mã nhận dạng là "castbutton". Bạn chỉ cần thêm thành phần này vào phần tử video của ứng dụng bằng cách thêm button vào phần media_control.

Thành phần của nút sẽ có dạng như sau:

<google-cast-launcher id="castbutton"></google-cast-launcher>

Thêm mã sau vào index.html trong phần media_control:

<div id="media_control">
  <div id="play"></div>
  <div id="pause"></div>
  <div id="progress_bg"></div>
  <div id="progress"></div>
  <div id="progress_indicator"></div>
  <div id="fullscreen_expand"></div>
  <div id="fullscreen_collapse"></div>
  <google-cast-launcher id="castbutton"></google-cast-launcher>
  <div id="audio_bg"></div>
  <div id="audio_bg_track"></div>
  <div id="audio_indicator"></div>
  <div id="audio_bg_level"></div>
  <div id="audio_on"></div>
  <div id="audio_off"></div>
  <div id="duration">00:00:00</div>
</div>

Bây giờ, hãy làm mới trang trong trình duyệt Chrome. Bạn sẽ thấy nút Truyền trong thành phần video. Khi bạn nhấp vào nút đó, nút này sẽ liệt kê các Thiết bị truyền trên mạng cục bộ của bạn. Tính năng khám phá thiết bị được trình duyệt Chrome quản lý tự động. Chọn Thiết bị truyền của bạn và ứng dụng nhận mẫu sẽ tải trên Thiết bị truyền.

Chúng tôi chưa kết nối tính năng hỗ trợ phát nội dung nghe nhìn, vì vậy, bạn chưa thể phát video trên thiết bị truyền. Nhấp vào nút Truyền để dừng truyền.

6. Truyền nội dung video

Hình ảnh ứng dụng hỗ trợ Cast với trình đơn chọn thiết bị Truyền

Chúng tôi sẽ mở rộng ứng dụng mẫu để phát video từ xa trên Thiết bị truyền. Để làm được việc đó, chúng ta cần theo dõi các sự kiện do Khung Truyền tạo ra.

Truyền nội dung đa phương tiện

Nhìn chung, nếu bạn muốn phát nội dung nghe nhìn trên Thiết bị truyền, thì những việc sau đây cần xảy ra:

  1. Tạo đối tượng MediaInfo JSON từ Cast SDK để tạo mô hình cho một mục nội dung nghe nhìn.
  2. Người dùng kết nối với Thiết bị truyền để chạy ứng dụng nhận.
  3. Tải đối tượng MediaInfo vào receiver (trình thu nhận) rồi phát nội dung đó.
  4. Theo dõi trạng thái nội dung nghe nhìn.
  5. Gửi lệnh phát đến thiết bị nhận dựa trên tương tác của người dùng.

Bước 1 giống như việc ánh xạ một đối tượng sang một đối tượng khác; MediaInfo là điều mà SDK truyền hiểu được và mediaJSON là gói đóng gói của ứng dụng cho một mục nội dung đa phương tiện; chúng ta có thể dễ dàng liên kết mediaJSON với MediaInfo. Chúng ta đã thực hiện Bước 2 trong phần trước. Bước 3 rất dễ thực hiện bằng Cast SDK.

Ứng dụng mẫu CastPlayer đã phân biệt giữa chế độ phát cục bộ với chế độ phát từ xa trong phương thức switchPlayer:

if (cast && cast.framework) {
  if (this.remotePlayer.isConnected) {
    //...

Trong lớp học lập trình này, điều quan trọng là bạn phải hiểu chính xác cách thức hoạt động của tất cả logic của trình phát mẫu. Tuy nhiên, điều quan trọng cần hiểu là trình phát nội dung đa phương tiện của ứng dụng sẽ phải được sửa đổi để nhận biết được cả việc phát cục bộ và phát từ xa.

Hiện tại, trình phát cục bộ luôn ở trạng thái phát cục bộ vì chưa biết gì về trạng thái Truyền. Chúng ta cần cập nhật giao diện người dùng dựa trên quá trình chuyển đổi trạng thái diễn ra trong khung Truyền. Ví dụ: Nếu bắt đầu truyền, chúng ta cần dừng việc phát trên thiết bị và tắt một số chế độ điều khiển. Tương tự, nếu dừng truyền khi đang sử dụng trình điều khiển khung hiển thị này, chúng ta cần chuyển sang chế độ phát cục bộ. Để xử lý việc đó, chúng ta cần theo dõi các sự kiện do khung Truyền tạo ra.

Quản lý phiên truyền

Đối với khung Truyền, phiên Truyền sẽ kết hợp các bước kết nối với thiết bị, khởi chạy (hoặc tham gia một phiên hiện có), kết nối với ứng dụng bộ thu và khởi động kênh điều khiển nội dung nghe nhìn nếu thích hợp. Kênh điều khiển nội dung nghe nhìn là cách Khung truyền gửi và nhận thông báo liên quan đến việc phát nội dung nghe nhìn từ thiết bị nhận.

Phiên Truyền sẽ tự động bắt đầu khi người dùng chọn một thiết bị từ nút Truyền và sẽ tự động dừng khi người dùng ngắt kết nối. Việc kết nối lại với phiên bộ thu do các sự cố kết nối mạng cũng được Khung truyền tự động xử lý.

Các phiên truyền do CastSession quản lý và có thể truy cập qua cast.framework.CastContext.getInstance().getCurrentSession(). Bạn có thể dùng các lệnh gọi lại EventListener để theo dõi các sự kiện của phiên, chẳng hạn như tạo, tạm ngưng, tiếp tục và chấm dứt.

Trong ứng dụng hiện tại, mọi hoạt động quản lý phiên và trạng thái đều được xử lý cho chúng ta trong phương thức setupRemotePlayer. Hãy bắt đầu định cấu hình trong ứng dụng bằng cách thêm mã sau vào CastVideos.js:

/**
 * Set the PlayerHandler target to use the remote player
 */
CastPlayer.prototype.setupRemotePlayer = function () {
    var castSession = cast.framework.CastContext.getInstance().getCurrentSession();

    this.playerHandler.setTarget(playerTarget);

    // Setup remote player volume right on setup
    // The remote player may have had a volume set from previous playback
    if (this.remotePlayer.isMuted) {
        this.playerHandler.mute();
    }
    var currentVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
    var p = document.getElementById('audio_bg_level');
    p.style.height = currentVolume + 'px';
    p.style.marginTop = -currentVolume + 'px';

    this.hideFullscreenButton();

    this.playerHandler.play();
};

Chúng ta vẫn cần liên kết tất cả sự kiện từ các lệnh gọi lại và xử lý mọi sự kiện xảy ra. Đây là một việc khá đơn giản cần làm, vì vậy hãy quan tâm đến vấn đề đó ngay bây giờ:

/**
 * Set the PlayerHandler target to use the remote player
 */
CastPlayer.prototype.setupRemotePlayer = function () {
    var castSession = cast.framework.CastContext.getInstance().getCurrentSession();

    // Add event listeners for player changes which may occur outside sender app
    this.remotePlayerController.addEventListener(
        cast.framework.RemotePlayerEventType.IS_PAUSED_CHANGED,
        function() {
            if (this.remotePlayer.isPaused) {
                this.playerHandler.pause();
            } else {
                this.playerHandler.play();
            }
        }.bind(this)
    );

    this.remotePlayerController.addEventListener(
        cast.framework.RemotePlayerEventType.IS_MUTED_CHANGED,
        function() {
            if (this.remotePlayer.isMuted) {
                this.playerHandler.mute();
            } else {
                this.playerHandler.unMute();
            }
        }.bind(this)
    );

    this.remotePlayerController.addEventListener(
        cast.framework.RemotePlayerEventType.VOLUME_LEVEL_CHANGED,
        function() {
            var newVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
            var p = document.getElementById('audio_bg_level');
            p.style.height = newVolume + 'px';
            p.style.marginTop = -newVolume + 'px';
        }.bind(this)
    );

    // This object will implement PlayerHandler callbacks with
    // remotePlayerController, and makes necessary UI updates specific
    // to remote playback
    var playerTarget = {};

    playerTarget.play = function () {
        if (this.remotePlayer.isPaused) {
            this.remotePlayerController.playOrPause();
        }

        var vi = document.getElementById('video_image');
        vi.style.display = 'block';
        var localPlayer = document.getElementById('video_element');
        localPlayer.style.display = 'none';
    }.bind(this);

    playerTarget.pause = function () {
        if (!this.remotePlayer.isPaused) {
            this.remotePlayerController.playOrPause();
        }
    }.bind(this);

    playerTarget.stop = function () {
         this.remotePlayerController.stop();
    }.bind(this);

    playerTarget.getCurrentMediaTime = function() {
        return this.remotePlayer.currentTime;
    }.bind(this);

    playerTarget.getMediaDuration = function() {
        return this.remotePlayer.duration;
    }.bind(this);

    playerTarget.updateDisplayMessage = function () {
        document.getElementById('playerstate').style.display = 'block';
        document.getElementById('playerstatebg').style.display = 'block';
        document.getElementById('video_image_overlay').style.display = 'block';
        document.getElementById('playerstate').innerHTML =
            this.mediaContents[ this.currentMediaIndex]['title'] + ' ' +
            this.playerState + ' on ' + castSession.getCastDevice().friendlyName;
    }.bind(this);

    playerTarget.setVolume = function (volumeSliderPosition) {
        // Add resistance to avoid loud volume
        var currentVolume = this.remotePlayer.volumeLevel;
        var p = document.getElementById('audio_bg_level');
        if (volumeSliderPosition < FULL_VOLUME_HEIGHT) {
            var vScale =  this.currentVolume * FULL_VOLUME_HEIGHT;
            if (volumeSliderPosition > vScale) {
                volumeSliderPosition = vScale + (pos - vScale) / 2;
            }
            p.style.height = volumeSliderPosition + 'px';
            p.style.marginTop = -volumeSliderPosition + 'px';
            currentVolume = volumeSliderPosition / FULL_VOLUME_HEIGHT;
        } else {
            currentVolume = 1;
        }
        this.remotePlayer.volumeLevel = currentVolume;
        this.remotePlayerController.setVolumeLevel();
    }.bind(this);

    playerTarget.mute = function () {
        if (!this.remotePlayer.isMuted) {
            this.remotePlayerController.muteOrUnmute();
        }
    }.bind(this);

    playerTarget.unMute = function () {
        if (this.remotePlayer.isMuted) {
            this.remotePlayerController.muteOrUnmute();
        }
    }.bind(this);

    playerTarget.isMuted = function() {
        return this.remotePlayer.isMuted;
    }.bind(this);

    playerTarget.seekTo = function (time) {
        this.remotePlayer.currentTime = time;
        this.remotePlayerController.seek();
    }.bind(this);

    this.playerHandler.setTarget(playerTarget);

    // Setup remote player volume right on setup
    // The remote player may have had a volume set from previous playback
    if (this.remotePlayer.isMuted) {
        this.playerHandler.mute();
    }
    var currentVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
    var p = document.getElementById('audio_bg_level');
    p.style.height = currentVolume + 'px';
    p.style.marginTop = -currentVolume + 'px';

    this.hideFullscreenButton();

    this.playerHandler.play();
};

Đang tải nội dung nghe nhìn

Trong Cast SDK, RemotePlayerRemotePlayerController cung cấp một bộ API thuận tiện để quản lý việc phát nội dung đa phương tiện từ xa trên bộ thu. Đối với CastSession có hỗ trợ tính năng phát nội dung đa phương tiện, các thực thể của RemotePlayerRemotePlayerController sẽ được SDK tự động tạo. Bạn có thể truy cập các lớp này bằng cách tạo các phiên bản của cast.framework.RemotePlayercast.framework.RemotePlayerController tương ứng, như trình bày ở phần trước trong lớp học lập trình.

Tiếp theo, chúng ta cần tải video hiện được chọn trên receiver (trình thu nhận) bằng cách tạo đối tượng MediaInfo để SDK xử lý và truyền yêu cầu. Để thực hiện việc này, hãy thêm mã sau vào setupRemotePlayer:

/**
 * Set the PlayerHandler target to use the remote player
 */
CastPlayer.prototype.setupRemotePlayer = function () {
    //...

    playerTarget.load = function (mediaIndex) {
        console.log('Loading...' + this.mediaContents[mediaIndex]['title']);
        var mediaInfo = new chrome.cast.media.MediaInfo(
            this.mediaContents[mediaIndex]['sources'][0], 'video/mp4');

        mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
        mediaInfo.metadata.metadataType = chrome.cast.media.MetadataType.GENERIC;
        mediaInfo.metadata.title = this.mediaContents[mediaIndex]['title'];
        mediaInfo.metadata.images = [
            {'url': MEDIA_SOURCE_ROOT + this.mediaContents[mediaIndex]['thumb']}];

        var request = new chrome.cast.media.LoadRequest(mediaInfo);
        castSession.loadMedia(request).then(
            this.playerHandler.loaded.bind(this.playerHandler),
            function (errorCode) {
                this.playerState = PLAYER_STATE.ERROR;
                console.log('Remote media load error: ' +
                    CastPlayer.getErrorMessage(errorCode));
            }.bind(this));
    }.bind(this);

    //...
};

Bây giờ, hãy thêm một phương thức để chuyển đổi giữa phát cục bộ và phát từ xa:

/**
 * This is a method for switching between the local and remote
 * players. If the local player is selected, setupLocalPlayer()
 * is run. If there is a cast device connected we run
 * setupRemotePlayer().
 */
CastPlayer.prototype.switchPlayer = function() {
    this.stopProgressTimer();
    this.resetVolumeSlider();
    this.playerHandler.stop();
    this.playerState = PLAYER_STATE.IDLE;
    if (cast && cast.framework) {
        if (this.remotePlayer.isConnected) {
            this.setupRemotePlayer();
            return;
        }
    }
    this.setupLocalPlayer();
};

Cuối cùng, hãy thêm một phương thức để xử lý mọi thông báo lỗi Truyền:

/**
 * Makes human-readable message from chrome.cast.Error
 * @param {chrome.cast.Error} error
 * @return {string} error message
 */
CastPlayer.getErrorMessage = function(error) {
  switch (error.code) {
    case chrome.cast.ErrorCode.API_NOT_INITIALIZED:
      return 'The API is not initialized.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.CANCEL:
      return 'The operation was canceled by the user' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.CHANNEL_ERROR:
      return 'A channel to the receiver is not available.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.EXTENSION_MISSING:
      return 'The Cast extension is not available.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.INVALID_PARAMETER:
      return 'The parameters to the operation were not valid.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.RECEIVER_UNAVAILABLE:
      return 'No receiver was compatible with the session request.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.SESSION_ERROR:
      return 'A session could not be created, or a session was invalid.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.TIMEOUT:
      return 'The operation timed out.' +
        (error.description ? ' :' + error.description : '');
  }
};

Bây giờ, hãy chạy ứng dụng. Kết nối với Thiết bị truyền và bắt đầu phát video. Bạn sẽ thấy video đang phát trên bộ thu.

7. Thêm tính năng hỗ trợ Cast Connect

Thư viện Cast Connect cho phép các ứng dụng hiện có của người gửi giao tiếp với các ứng dụng Android TV thông qua giao thức Cast. Cast Connect được xây dựng dựa trên cơ sở hạ tầng Cast, trong đó ứng dụng Android TV hoạt động như một bộ thu.

Phần phụ thuộc

  • Trình duyệt Chrome phiên bản M87 trở lên

Tương thích với bộ thu tín hiệu Android

Để chạy ứng dụng Android TV, còn được gọi là Bộ thu Android, chúng ta cần đặt cờ androidReceiverCompatible thành true trong đối tượng CastOptions.

Thêm mã sau vào CastVideos.js trong hàm initializeCastPlayer:

var options = {};
...
options.androidReceiverCompatible = true;

cast.framework.CastContext.getInstance().setOptions(options);

Đặt thông tin xác thực khi chạy

Ở phía người gửi, bạn có thể chỉ định CredentialsData để cho biết ai sẽ tham gia phiên này. credentials là một chuỗi có thể do người dùng xác định, miễn là ứng dụng ATV của bạn có thể hiểu được chuỗi đó. CredentialsData chỉ được truyền đến ứng dụng Android TV trong thời gian khởi chạy hoặc tham gia. Nếu bạn thiết lập lại khi đang kết nối thì mã đó sẽ không được chuyển tới ứng dụng Android TV.

Để thiết lập Thông tin đăng nhập khi chạy, bạn cần phải xác định CredentialsData bất cứ lúc nào sau khi đặt các lựa chọn khởi chạy.

Thêm mã sau vào lớp CastVideos.js trong hàm initializeCastPlayer:

cast.framework.CastContext.getInstance().setOptions(options);
...
let credentialsData = new chrome.cast.CredentialsData("{\"userId\": \"abc\"}");
cast.framework.CastContext.getInstance().setLaunchCredentialsData(credentialsData);
...

Đặt thông tin xác thực khi yêu cầu tải

Trong trường hợp ứng dụng Web receiver và ứng dụng Android TV xử lý credentials theo cách khác nhau, bạn có thể cần xác định thông tin xác thực riêng cho từng ứng dụng. Để xử lý vấn đề đó, hãy thêm mã sau vào CastVideos.js bên dưới playerTarget.load trong hàm setupRemotePlayer:

...
var request = new chrome.cast.media.LoadRequest(mediaInfo);
request.credentials = 'user-credentials';
request.atvCredentials = 'atv-user-credentials';
...

Tuỳ thuộc vào ứng dụng nhận mà người gửi đang truyền nội dung đến, SDK giờ đây sẽ tự động xử lý thông tin xác thực nào cần sử dụng cho phiên hiện tại.

Kiểm thử Cast Connect

Các bước cài đặt APK Android TV trên Chromecast có Google TV:

  1. Tìm địa chỉ IP của thiết bị Android TV. Thông thường, bạn có thể tìm thấy thông tin này trong phần Cài đặt > Mạng và Internet > (Tên mạng mà thiết bị của bạn đang kết nối). Ở bên phải, màn hình sẽ hiển thị thông tin chi tiết và IP của thiết bị trên mạng.
  2. Sử dụng địa chỉ IP để thiết bị của bạn kết nối với thiết bị đó qua ADB bằng thiết bị đầu cuối:
$ adb connect <device_ip_address>:5555
  1. Trong cửa sổ dòng lệnh, hãy chuyển đến thư mục cấp cao nhất cho các mẫu lớp học lập trình mà bạn đã tải xuống khi bắt đầu lớp học lập trình này. Ví dụ:
$ cd Desktop/chrome_codelab_src
  1. Cài đặt tệp .apk trong thư mục này vào Android TV bằng cách chạy:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. Giờ đây, bạn có thể thấy một ứng dụng theo tên là Truyền video trong trình đơn Ứng dụng của bạn trên thiết bị Android TV.
  2. Chạy mã của người gửi web đã cập nhật và thiết lập phiên truyền với thiết bị Android TV bằng cách sử dụng biểu tượng truyền hoặc chọn Cast.. trong trình đơn thả xuống trong trình duyệt Chrome. Thao tác này sẽ khởi chạy ứng dụng Android TV trên Bộ thu Android của bạn và cho phép bạn điều khiển quá trình phát bằng điều khiển từ xa cho Android TV.

8. Xin chúc mừng

Giờ đây, bạn đã biết cách Bật tính năng Truyền ứng dụng video bằng tiện ích SDK Truyền trên ứng dụng web Chrome.

Để biết thêm thông tin chi tiết, hãy xem hướng dẫn cho nhà phát triển về Web Sender.