Xây dựng trình thu nhận web tuỳ chỉnh

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 tạo ứng dụng Trình thu phát web tuỳ chỉnh để phát nội dung trên các thiết bị có hỗ trợ tính năng Truyền.

Google Cast là gì?

Google Cast cho phép người dùng truyền nội dung từ thiết bị di động tới TV. Sau đó, người dùng có thể sử dụng thiết bị di động hoặc Trình duyệt Chrome trên máy tính làm điều khiển từ xa để phát nội dung nghe nhìn trên TV.

SDK Google Cast cho phép ứng dụng của bạn điều khiển các thiết bị hỗ trợ Google Cast (ví dụ: TV hoặc hệ thống âm thanh). SDK Cast cung cấp cho bạn 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 để mang lại trải nghiệm đơn giản và dễ dự đoán cho người dùng Cast trên tất cả các nền tảng được hỗ trợ. Xem thêm ở đây.

Chúng ta sẽ xây dựng gì?

Khi hoàn thành lớp học lập trình này, bạn sẽ có một ứng dụng HTML5 đóng vai trò là bộ thu tuỳ chỉnh của riêng mình, có thể hiển thị nội dung video trên các thiết bị hỗ trợ tính năng Truyền.

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

  • Cách thiết lập để phát triển bộ thu.
  • Kiến thức cơ bản về bộ thu hỗ trợ tính năng Truyền dựa trên Khung ứng dụng truyền.
  • Cách nhận video được truyền.
  • Cách tích hợp Trình ghi nhật ký gỡ lỗi.
  • Cách tối ưu hoá trình thu nhận cho màn hình thông minh.

Bạn cần có

  • Trình duyệt Google Chrome mới nhất.
  • Dịch vụ lưu trữ HTTPS, chẳng hạn như Lưu trữ Firebase hoặc ngrok.
  • Một thiết bị Google Cast như Chromecast hoặc Android TV được định cấu hình có kết nối Internet.
  • TV hoặc màn hình có đầu vào HDMI.

Trải nghiệm

  • Bạn cần có kiến thức phát triển web trước đó.
  • Bạn cũng cần có kiến thức trước đây về việc 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 bài tập

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

Tân binh Trung cấp Thành thạo

Bạn đánh giá trải nghiệm của bạn khi xem TV ở mức nào?

Tân binh 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...

và giải nén tệp zip đã tải xuống.

3. Triển khai trình nhận cục bộ

Để có thể sử dụng trình thu phát web với thiết bị Cast, bạn cần lưu trữ trình thu phát web ở nơi thiết bị Cast có thể truy cập. Nếu bạn đã có một máy chủ hỗ trợ https, hãy bỏ qua hướng dẫn sau và ghi lại URL vì bạn sẽ cần URL đó trong phần tiếp theo.

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

Chạy máy chủ

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

Ghi lại URL của dịch vụ nhận được lưu trữ. Bạn sẽ sử dụng lớp này trong phần tiếp theo.

4. Đăng ký ứng dụng trong Cast Developer Console

Bạn phải đăng ký ứng dụng của mình để có thể chạy trình thu tuỳ chỉnh (như được tích hợp trong lớp học lập trình này) trên các thiết bị Chromecast. Sau khi đăng ký ứng dụng, bạn sẽ nhận được một mã ứng dụng mà ứng dụng gửi phải sử dụng để thực hiện các lệnh gọi API, chẳng hạn như để khởi chạy ứng dụng nhận.

Hình ảnh Bảng điều khiển dành cho nhà phát triển SDK của Google Cast, trong đó nút "Thêm ứng dụng mới" được làm nổi bật

Nhấp vào "Thêm ứng dụng mới"

Hình ảnh màn hình "New Receiver Application" (Ứng dụng bộ thu mới) với tuỳ chọn "Custom Receiver" (Bộ thu tuỳ chỉnh) được làm nổi bật

Chọn "Custom Receiver" (Trình thu nhận tuỳ chỉnh). Đây là ứng dụng mà chúng ta đang xây dựng.

Hình ảnh màn hình "Trình nhận tuỳ chỉnh mới" hiển thị một URL mà người dùng đang nhập vào trường "URL ứng dụng của trình nhận"

Nhập thông tin chi tiết về người nhận mới, nhớ sử dụng URL mà bạn đã kết thúc

trong phần cuối. Ghi lại Mã ứng dụng được chỉ định cho bộ thu hoàn toàn mới.

Bạn cũng phải đăng ký thiết bị Google Cast để thiết bị này có thể truy cập vào ứng dụng receiver trước khi bạn phát hành ứng dụng. Sau khi bạn phát hành ứng dụng tiếp nhận, ứng dụng đó sẽ có sẵn cho tất cả thiết bị Google Cast. Để phục vụ cho mục đích của lớp học lập trình này, bạn nên làm việc với một ứng dụng receiver chưa xuất bản.

Hình ảnh Bảng điều khiển dành cho nhà phát triển SDK của Google Cast, trong đó nút "Thêm thiết bị mới" được làm nổi bật

Nhấp vào "Thêm thiết bị mới"

Hình ảnh hộp thoại "Thêm thiết bị nhận nội dung truyền"

Nhập số sê-ri được in ở mặt sau của thiết bị Cast rồi đặt tên mô tả cho thiết bị đó. Bạn cũng có thể tìm thấy số sê-ri bằng cách truyền màn hình trong Chrome khi truy cập vào Bảng điều khiển dành cho nhà phát triển SDK của Google Cast

Bạn sẽ phải chờ 5 đến 15 phút để bộ thu và thiết bị của bạn sẵn sàng kiểm thử. Sau khi đợi 5 đến 15 phút, bạn phải khởi động lại thiết bị Truyền.

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

Biểu trưng Google Chrome

Trong khi chờ ứng dụng receiver mới của chúng ta sẵn sàng để kiểm thử, hãy xem ứng dụng receiver hoàn chỉnh mẫu trông như thế nào. Trình thu nhận mà chúng ta sắp tạo sẽ có khả năng phát nội dung đa phương tiện bằng cách truyền trực tuyến tốc độ bit thích ứng (chúng ta sẽ sử dụng nội dung mẫu được mã hoá cho tính năng Truyền phát thích ứng động qua HTTP (DASH)).

Trong trình duyệt, hãy mở Công cụ Command và Control (CaC).

Hình ảnh thẻ "Cast Connect & Logger Controls" (Kết nối truyền và điều khiển trình ghi nhật ký) của Công cụ điều khiển và ra lệnh (CaC)

  1. Bạn sẽ thấy Công cụ CaC của chúng tôi.
  2. Sử dụng mã nhận dạng mẫu mặc định "CC1AD845" và nhấp vào nút "Đặt mã ứng dụng".
  3. Nhấp vào nút Truyền ở trên cùng bên trái và chọn thiết bị Google Cast của bạn.

Hình ảnh thẻ "Cast Connect & Logger Controls" (Điều khiển kết nối truyền và điều khiển trình ghi nhật ký) trong Công cụ Command and Control (CaC) cho biết công cụ này được kết nối với Ứng dụng bộ thu

  1. Chuyển đến thẻ "Tải nội dung nghe nhìn" ở trên cùng.

Hình ảnh thẻ "Load Media" (Tải nội dung nghe nhìn) của Công cụ điều khiển và ra lệnh (CaC)

  1. Nhấp vào nút "Tải theo nội dung" để phát một video mẫu.
  2. Video sẽ bắt đầu phát trên thiết bị Google Cast để cho thấy chức năng cơ bản của bộ thu khi sử dụng Bộ thu mặc định.

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

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

  • ứng dụng sender chạy trên thiết bị di động hoặc máy tính xách tay,
  • ứng dụng receiver (trình nhận) chạy trên thiết bị Google Cast.

Bây giờ, bạn đã sẵn sàng xây dựng dựa trên dự án khởi động bằng trình soạn thảo văn bản yêu thích:

  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. Mở js/receiver.jsindex.html

Xin lưu ý rằng khi bạn thực hiện lớp học lập trình này, http-server sẽ chọn những thay đổi bạn thực hiện. Nếu bạn nhận thấy không có, hãy thử tắt và khởi động lại http-server.

Thiết kế ứng dụng

Ứng dụng nhận sẽ khởi chạy phiên Truyền và sẽ ở chế độ chờ cho đến khi nhận được yêu cầu LOAD (tức là lệnh phát lại nội dung nghe nhìn) từ ứng dụng gửi.

Ứng dụng này bao gồm một thành phần hiển thị chính, được xác định trong index.html và một tệp JavaScript có tên là js/receiver.js chứa tất cả logic để làm cho trình thu nhận của chúng ta hoạt động.

index.html

Tệp html này sẽ chứa giao diện người dùng cho ứng dụng nhận. Hiện tại, tệp này đang trống và chúng ta sẽ thêm vào trong toàn bộ lớp học lập trình.

receiver.js

Tập lệnh này sẽ quản lý tất cả logic cho ứng dụng nhận. Hiện tại, đây chỉ là một tệp trống, nhưng chúng ta sẽ biến nó thành một bộ thu Cast hoạt động đầy đủ chỉ bằng một vài dòng mã trong phần tiếp theo.

7. Thiết bị nhận nội dung truyền cơ bản

Một trình nhận Cast cơ bản sẽ khởi chạy phiên Cast khi khởi động. Điều này là cần thiết để thông báo cho tất cả ứng dụng người gửi đã kết nối rằng đã khởi chạy thành công trình nhận. Ngoài ra, SDK mới này còn được định cấu hình sẵn để xử lý nội dung nghe nhìn truyền trực tuyến với tốc độ bit thích ứng (sử dụng DASH, HLS và moot Streaming) và các tệp MP4 đơn giản ngay từ đầu. Hãy thử tính năng này.

Khởi chạy

Thêm mã sau vào index.html trong tiêu đề:

<head>
  ...

  <script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
</head>

Thêm mã sau vào index.html <body> trước khi <footer> tải receiver.js, để cung cấp cho SDK trình nhận không gian hiển thị giao diện người dùng trình nhận mặc định đi kèm với tập lệnh bạn vừa thêm.

<cast-media-player></cast-media-player>

Bây giờ, chúng ta cần khởi chạy SDK trong js/receiver.js, bao gồm:

  • lấy thông tin tham chiếu đến CastReceiverContext, điểm truy cập chính của bạn đến toàn bộ SDK Bộ thu
  • lưu trữ tham chiếu đến PlayerManager, đối tượng xử lý phát và cung cấp cho bạn tất cả các trình bổ trợ bạn cần để cắm logic tuỳ chỉnh của riêng mình
  • khởi chạy SDK bằng cách gọi start() trên CastReceiverContext

Thêm nội dung sau vào js/receiver.js.

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();

context.start();

8. Truyền nội dung video "cơ bản"

Trong lớp học lập trình này, hãy sử dụng Công cụ CaC để thử nghiệm bộ thu hoàn toàn mới của bạn.

Chuyển trình duyệt web của bạn đến Công cụ điều khiển và kiểm soát (CaC).

Hình ảnh thẻ &quot;Cast Connect & Logger Controls&quot; (Kết nối truyền và điều khiển trình ghi nhật ký) của Công cụ điều khiển và ra lệnh (CaC)

Hãy nhớ thay thế Mã ứng dụng của riêng bạn như đã đăng ký trước đó trong trường này rồi nhấp vào "Đặt mã ứng dụng". Thao tác này sẽ hướng dẫn công cụ sử dụng bộ thu của bạn khi bắt đầu phiên Truyền.

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

Nhìn chung, để phát nội dung nghe nhìn trên thiết bị Cast, bạn cần thực hiện những bước sau:

  1. Trình gửi tạo một đối tượng JSON MediaInfo từ SDK truyền để mô hình hoá một mục nội dung nghe nhìn.
  2. Phương thức gửi kết nối với thiết bị Cast để chạy ứng dụng nhận.
  3. Trình nhận tải đối tượng MediaInfo thông qua yêu cầu LOAD để phát nội dung.
  4. Trình thu phát theo dõi và theo dõi trạng thái nội dung nghe nhìn.
  5. Người gửi gửi lệnh phát đến người nhận để điều khiển chế độ phát dựa trên hoạt động tương tác của người dùng với ứng dụng của người gửi.

Trong lần thử cơ bản đầu tiên này, chúng ta sẽ điền vào MediaInfo một URL thành phần có thể phát (được lưu trữ trong MediaInfo.contentUrl).

Người gửi trong thực tế sử dụng giá trị nhận dạng nội dung đa phương tiện dành riêng cho ứng dụng trong MediaInfo.contentId. Trình nhận sử dụng contentId làm giá trị nhận dạng để thực hiện các lệnh gọi API phụ trợ thích hợp nhằm phân giải URL tài sản thực tế và đặt URL đó thành MediaInfo.contentUrl.. Trình nhận cũng sẽ xử lý các tác vụ như thu nạp giấy phép DRM hoặc chèn thông tin về điểm chèn quảng cáo.

Chúng tôi sẽ mở rộng tính năng nhận tín hiệu để làm điều tương tự như vậy trong phần tiếp theo. Bây giờ, hãy nhấp vào biểu tượng Truyền và chọn thiết bị của bạn để mở bộ thu.

Hình ảnh thẻ &quot;Cast Connect & Logger Controls&quot; (Điều khiển Cast Connect và Logger) của Công cụ điều khiển và ra lệnh (CaC) cho biết công cụ này đã kết nối với một Ứng dụng Receiver

Chuyển đến thẻ "Tải nội dung nghe nhìn" rồi nhấp vào nút "Tải theo nội dung". Trình thu của bạn sẽ bắt đầu phát nội dung mẫu.

Hình ảnh thẻ &quot;Tải nội dung nghe nhìn&quot; của Công cụ Command và Control (CaC)

Vì vậy, ngay từ đầu, SDK Trình nhận sẽ xử lý:

  • Khởi chạy phiên Truyền
  • Xử lý các yêu cầu LOAD được gửi đến từ người gửi có chứa tài sản có thể phát
  • Cung cấp giao diện người dùng trình phát cơ bản sẵn sàng hiển thị trên màn hình lớn.

Bạn có thể khám phá Công cụ CaC và mã của công cụ này trước khi chuyển sang phần tiếp theo. Chúng ta sẽ mở rộng receiver để trò chuyện với một API mẫu đơn giản nhằm thực hiện các yêu cầu LOAD đến từ người gửi.

9. Tích hợp với API bên ngoài

Để phù hợp với cách hầu hết các nhà phát triển tương tác với Trình nhận truyền trong các ứng dụng thực tế, chúng ta sẽ sửa đổi trình nhận để xử lý các yêu cầu LOAD tham chiếu đến nội dung đa phương tiện dự định bằng khoá API thay vì gửi qua URL thành phần có thể phát.

Các ứng dụng thường làm việc này vì:

  • Người gửi có thể không biết URL nội dung.
  • Ứng dụng Cast được thiết kế để xử lý việc xác thực, logic nghiệp vụ khác hoặc lệnh gọi API trực tiếp trên thiết bị nhận.

Chức năng này chủ yếu được triển khai trong phương thức PlayerManager setMessageInterceptor(). Điều này cho phép bạn chặn các thông báo đến theo loại và sửa đổi các thông báo đó trước khi chúng đến trình xử lý thông báo nội bộ của SDK. Trong phần này, chúng ta sẽ xử lý các yêu cầu LOAD, trong đó chúng ta sẽ làm như sau:

  • Đọc yêu cầu LOAD sắp tới và contentId tuỳ chỉnh của yêu cầu đó.
  • Gọi GET đến API của chúng tôi để tra cứu thành phần có thể truyền trực tuyến theo contentId của thành phần đó.
  • Sửa đổi yêu cầu LOAD bằng URL của luồng.
  • Sửa đổi đối tượng MediaInformation để đặt các tham số loại luồng.
  • Truyền yêu cầu đến SDK để phát hoặc từ chối lệnh nếu chúng tôi không thể tra cứu nội dung nghe nhìn được yêu cầu.

API mẫu được cung cấp cho thấy các trình nối của SDK để tuỳ chỉnh các tác vụ phổ biến của trình nhận, đồng thời vẫn dựa vào trải nghiệm hầu hết là sẵn có.

API mẫu

Hướng trình duyệt của bạn đến https://storage.googleapis.com/cpe-sample-media/content.json và xem danh mục video mẫu của chúng tôi. Nội dung này bao gồm URL của hình ảnh áp phích ở định dạng png cũng như cả luồng DASH và HLS. Các luồng DASH và HLS trỏ đến các nguồn video và âm thanh đã tách biệt, được lưu trữ trong các vùng chứa mp4 phân đoạn.

{
  "bbb": {
    "author": "The Blender Project",
    "description": "Grumpy Bunny is grumpy",
    "poster": "https://[...]/[...]/BigBuckBunny/images/screenshot1.png",
    "stream": {
      "dash": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.mpd",
      "hls": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.m3u8",
    "title": "Big Buck Bunny"
  },
  "fbb_ad": {
    "author": "Google Inc.",
    "description": "Introducing Chromecast. The easiest way to enjoy [...]",
    "poster": "https://[...]/[...]/ForBiggerBlazes/images/screenshot8.png",
    "stream": {
      "dash": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.mpd",
      "hls": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.m3u8",
    "title": "For Bigger Blazes"
  },

  [...]

}

Ở bước tiếp theo, chúng ta sẽ liên kết khoá của từng mục nhập (ví dụ: bbb, fbb_ad ) với URL của luồng sau khi trình thu được gọi bằng một yêu cầu LOAD.

Chặn yêu cầu LOAD

Ở bước này, chúng ta sẽ tạo một trình chặn tải bằng một hàm tạo yêu cầu XHR đến tệp JSON được lưu trữ. Sau khi nhận được tệp JSON, chúng tôi sẽ phân tích cú pháp nội dung và đặt siêu dữ liệu. Trong các phần sau, chúng ta sẽ tuỳ chỉnh các thông số MediaInformation để chỉ định loại nội dung.

Thêm mã sau vào tệp js/receiver.js, ngay trước lệnh gọi đến context.start().

function makeRequest (method, url) {
  return new Promise(function (resolve, reject) {
    let xhr = new XMLHttpRequest();
    xhr.open(method, url);
    xhr.onload = function () {
      if (this.status >= 200 && this.status < 300) {
        resolve(JSON.parse(xhr.response));
      } else {
        reject({
          status: this.status,
          statusText: xhr.statusText
        });
      }
    };
    xhr.onerror = function () {
      reject({
        status: this.status,
        statusText: xhr.statusText
      });
    };
    xhr.send();
  });
}

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      return new Promise((resolve, reject) => {
        // Fetch content repository by requested contentId
        makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json').then(function (data) {
          let item = data[request.media.contentId];
          if(!item) {
            // Content could not be found in repository
            reject();
          } else {
            // Add metadata
            let metadata = new
               cast.framework.messages.GenericMediaMetadata();
            metadata.title = item.title;
            metadata.subtitle = item.author;

            request.media.metadata = metadata;

            // Resolve request
            resolve(request);
          }
        });
      });
    });

Phần tiếp theo sẽ trình bày cách định cấu hình thuộc tính media của yêu cầu tải cho nội dung DASH.

Sử dụng nội dung DASH API mẫu

Giờ đây, khi đã chuẩn bị trình chặn tải, chúng ta sẽ chỉ định loại nội dung cho trình nhận. Thông tin này sẽ cung cấp cho người nhận URL danh sách phát chính và loại MIME của luồng. Thêm mã sau vào tệp js/receiver.js trong Promise() của trình chặn LOAD:

...
playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      return new Promise((resolve, reject) => {
          ...
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.dash;
            request.media.contentType = 'application/dash+xml';
            ...
          }
        });
      });
    });

Sau khi hoàn tất bước này, bạn có thể chuyển sang bước Kiểm thử để thử tải nội dung DASH. Nếu bạn muốn thử nghiệm tải bằng nội dung HLS, hãy xem bước tiếp theo.

Sử dụng nội dung HLS của API mẫu

API mẫu bao gồm nội dung HLS cũng như DASH. Ngoài việc thiết lập contentType như chúng ta đã làm trong bước trước, yêu cầu tải sẽ cần thêm một số thuộc tính để sử dụng URL HLS của API mẫu. Khi bộ thu được định cấu hình để phát luồng HLS, loại vùng chứa mặc định dự kiến là luồng truyền tải (TS). Do đó, trình nhận sẽ cố gắng mở các luồng MP4 mẫu ở định dạng TS nếu chỉ sửa đổi thuộc tính contentUrl. Trong yêu cầu tải, đối tượng MediaInformation phải được sửa đổi bằng các thuộc tính bổ sung để trình nhận biết được nội dung thuộc loại MP4 chứ không phải TS. Thêm mã sau vào tệp js/receiver.js trong trình chặn tải để sửa đổi các thuộc tính contentUrlcontentType. Ngoài ra, hãy thêm các thuộc tính HlsSegmentFormatHlsVideoSegmentFormat.

...
playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      return new Promise((resolve, reject) => {
          ...
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.hls;
            request.media.contentType = 'application/x-mpegurl';
            request.media.hlsSegmentFormat = cast.framework.messages.HlsSegmentFormat.FMP4;
            request.media.hlsVideoSegmentFormat = cast.framework.messages.HlsVideoSegmentFormat.FMP4;
            ...
          }
        });
      });
    });

Thử nghiệm

Một lần nữa, hãy mở Công cụ điều khiển và kiểm soát (CaC) rồi đặt mã nhận dạng ứng dụng thành mã nhận dạng ứng dụng của thiết bị nhận. Chọn thiết bị của bạn bằng nút Truyền.

Chuyển đến thẻ "Tải nội dung nghe nhìn". Lần này, hãy xoá văn bản trong trường "URL nội dung" bên cạnh nút "Tải theo nội dung". Thao tác này sẽ buộc ứng dụng của chúng ta gửi một yêu cầu LOAD chỉ chứa tham chiếu contentId đến nội dung nghe nhìn của chúng ta.

Hình ảnh thẻ &quot;Load Media&quot; (Tải nội dung nghe nhìn) của Công cụ điều khiển và ra lệnh (CaC)

Giả sử mọi thứ hoạt động tốt với các sửa đổi của bạn đối với trình thu, trình chặn sẽ xử lý việc định hình đối tượng MediaInfo thành nội dung mà SDK có thể phát trên màn hình.

Nhấp vào nút "Tải theo nội dung" để xem nội dung nghe nhìn của bạn có phát đúng cách không. Bạn có thể thay đổi mã Content ID thành một mã khác trong tệp content.json.

10. Tối ưu hoá cho màn hình thông minh

Màn hình thông minh là những thiết bị có chức năng cảm ứng, cho phép các ứng dụng tiếp nhận hỗ trợ các chế độ điều khiển có hỗ trợ cảm ứng.

Phần này giải thích cách tối ưu hoá ứng dụng receiver khi chạy trên màn hình thông minh và cách tuỳ chỉnh các nút điều khiển của trình phát.

Truy cập vào các thành phần điều khiển trên giao diện người dùng

Bạn có thể truy cập vào đối tượng Điều khiển giao diện người dùng cho Màn hình thông minh bằng cast.framework.ui.Controls.GetInstance(). Thêm mã sau vào tệp js/receiver.js phía trên context.start():

...

// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();

context.start();

Nếu không sử dụng phần tử <cast-media-player>, bạn cần đặt touchScreenOptimizedApp trong CastReceiverOptions. Trong lớp học lập trình này, chúng ta sẽ sử dụng phần tử <cast-media-player>.

context.start({ touchScreenOptimizedApp: true });

Các nút điều khiển mặc định được gán cho từng vị trí dựa trên MetadataTypeMediaStatus.supportedMediaCommands.

Các nút điều khiển video

Đối với MetadataType.MOVIE, MetadataType.TV_SHOWMetadataType.GENERIC, đối tượng Điều khiển giao diện người dùng cho Màn hình thông minh sẽ xuất hiện như trong ví dụ dưới đây.

Hình ảnh video đang phát với các nút điều khiển giao diện người dùng phủ lên trên

  1. --playback-logo-image
  2. MediaMetadata.subtitle
  3. MediaMetadata.title
  4. MediaStatus.currentTime
  5. MediaInformation.duration
  6. ControlsSlot.SLOT_SECONDARY_1: ControlsButton.QUEUE_PREV
  7. ControlsSlot.SLOT_PRIMARY_1: ControlsButton.SEEK_BACKWARD_30
  8. PLAY/PAUSE
  9. ControlsSlot.SLOT_PRIMARY_2: ControlsButton.SEEK_FORWARD_30
  10. ControlsSlot.SLOT_SECONDARY_2: ControlsButton.QUEUE_NEXT

Điều khiển âm thanh

Đối với MetadataType.MUSIC_TRACK, đối tượng Điều khiển giao diện người dùng cho Màn hình thông minh sẽ hiển thị như sau:

Hình ảnh nhạc đang phát với các chế độ điều khiển giao diện người dùng phủ lên trên

  1. --playback-logo-image
  2. MusicTrackMediaMetadata.albumName
  3. MusicTrackMediaMetadata.title
  4. MusicTrackMediaMetadata.albumArtist
  5. MusicTrackMediaMetadata.images[0]
  6. MediaStatus.currentTime
  7. MediaInformation.duration
  8. ControlsSlot.SLOT_SECONDARY_1: ControlsButton.NO_BUTTON
  9. ControlsSlot.SLOT_PRIMARY_1: ControlsButton.QUEUE_PREV
  10. PLAY/PAUSE
  11. ControlsSlot.SLOT_PRIMARY_2: ControlsButton.QUEUE_NEXT
  12. ControlsSlot.SLOT_SECONDARY_2: ControlsButton.NO_BUTTON

Cập nhật các lệnh nội dung nghe nhìn được hỗ trợ

Đối tượng Điều khiển giao diện người dùng cũng xác định liệu ControlsButton có xuất hiện hay không dựa trên MediaStatus.supportedMediaCommands.

Khi giá trị của supportedMediaCommands bằng ALL_BASIC_MEDIA, bố cục điều khiển mặc định sẽ hiển thị như bên dưới:

Hình ảnh các nút điều khiển trình phát nội dung đa phương tiện: thanh tiến trình, nút &quot;Phát&quot;, nút &quot;Bỏ qua trước&quot; và nút &quot;Bỏ qua sau&quot; đang bật

Khi giá trị của supportedMediaCommands bằng ALL_BASIC_MEDIA | QUEUE_PREV | QUEUE_NEXT, bố cục điều khiển mặc định sẽ hiển thị như bên dưới:

Hình ảnh các nút điều khiển trình phát nội dung đa phương tiện: thanh tiến trình, nút &quot;Phát&quot;, nút &quot;Tiến&quot; và &quot;Lùi&quot;, đồng thời nút &quot;Thêm vào danh sách phát trước&quot; và &quot;Thêm vào danh sách phát tiếp theo&quot; đang bật

Khi giá trị của supportedMediaCommands bằng PAUSE | QUEUE_PREV | QUEUE_NEXT, bố cục điều khiển mặc định sẽ hiển thị như bên dưới:

Hình ảnh các nút điều khiển trình phát nội dung nghe nhìn: thanh tiến trình, nút &quot;Phát&quot; và nút &quot;Thêm vào danh sách phát trước&quot; và &quot;Thêm vào danh sách phát tiếp theo&quot; đang bật

Khi có bản lồng tiếng, nút phụ đề sẽ luôn xuất hiện tại SLOT_1.

Hình ảnh các nút điều khiển trình phát nội dung nghe nhìn: thanh tiến trình, nút &quot;Phát&quot;, nút &quot;Tua đi&quot; và &quot;Tua lại&quot;, nút &quot;Thêm vào danh sách phát trước&quot; và &quot;Thêm vào danh sách phát tiếp theo&quot;, nút &quot;Bản lồng tiếng&quot; đang bật

Để thay đổi linh động giá trị của supportedMediaCommands sau khi bắt đầu ngữ cảnh của receiver, bạn có thể gọi PlayerManager.setSupportedMediaCommands để ghi đè giá trị này. Ngoài ra, bạn có thể thêm lệnh mới bằng cách sử dụng addSupportedMediaCommands hoặc xoá lệnh hiện có bằng cách sử dụng removeSupportedMediaCommands.

Tuỳ chỉnh các nút điều khiển

Bạn có thể tuỳ chỉnh các chế độ điều khiển bằng cách sử dụng PlayerDataBinder. Thêm mã sau vào tệp js/receiver.js của bạn bên dưới TouchControls để đặt vị trí đầu tiên của các nút điều khiển:

...

// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);

playerDataBinder.addEventListener(
  cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
  (e) => {
    if (!e.value) return;

    // Clear default buttons and re-assign
    touchControls.clearDefaultSlotAssignments();
    touchControls.assignButton(
      cast.framework.ui.ControlsSlot.SLOT_PRIMARY_1,
      cast.framework.ui.ControlsButton.SEEK_BACKWARD_30
    );
  });

context.start();

11. Triển khai tính năng duyệt qua nội dung nghe nhìn trên màn hình thông minh

Media Browse là một tính năng của Trình thu CAF cho phép người dùng khám phá nội dung bổ sung trên thiết bị cảm ứng. Để triển khai việc này, bạn sẽ sử dụng PlayerDataBinder để thiết lập giao diện người dùng BrowseContent. Sau đó, bạn có thể điền BrowseItems vào trường này dựa trên nội dung bạn muốn hiển thị.

BrowseContent

Dưới đây là ví dụ về giao diện người dùng BrowseContent và các thuộc tính tương ứng:

Hình ảnh giao diện người dùng BrowseContent hiển thị hai hình thu nhỏ video và một phần của hình thu nhỏ thứ ba

  1. BrowseContent.title
  2. BrowseContent.items

Tỷ lệ khung hình

Sử dụng targetAspectRatio property để chọn tỷ lệ khung hình phù hợp nhất cho thành phần hình ảnh. SDK Receiver CAF hỗ trợ 3 tỷ lệ khung hình: SQUARE_1_TO_1, PORTRAIT_2_TO_3, LANDSCAPE_16_TO_9.

BrowseItem

Sử dụng BrowseItem để hiển thị tiêu đề, phụ đề, thời lượng và hình ảnh cho từng mục:

Hình ảnh giao diện người dùng BrowseContent hiển thị hai hình thu nhỏ video và một phần của video thứ ba

  1. BrowseItem.image
  2. BrowseItem.duration
  3. BrowseItem.title
  4. BrowseItem.subtitle

Thiết lập dữ liệu duyệt qua nội dung nghe nhìn

Bạn có thể cung cấp danh sách nội dung đa phương tiện để duyệt xem bằng cách gọi setBrowseContent. Thêm mã sau vào tệp js/receiver.js bên dưới playerDataBinder và trong trình nghe sự kiện MEDIA_CHANGED để thiết lập tiêu đề "Tiếp theo" cho các mục duyệt qua.

// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);

...

let browseItems = getBrowseItems();

function getBrowseItems() {
  let browseItems = [];
  makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
  .then(function (data) {
    for (let key in data) {
      let item = new cast.framework.ui.BrowseItem();
      item.entity = key;
      item.title = data[key].title;
      item.subtitle = data[key].description;
      item.image = new cast.framework.messages.Image(data[key].poster);
      item.imageType = cast.framework.ui.BrowseImageType.MOVIE;
      browseItems.push(item);
    }
  });
  return browseItems;
}

let browseContent = new cast.framework.ui.BrowseContent();
browseContent.title = 'Up Next';
browseContent.items = browseItems;
browseContent.targetAspectRatio = cast.framework.ui.BrowseImageAspectRatio.LANDSCAPE_16_TO_9;

playerDataBinder.addEventListener(
  cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
  (e) => {
    if (!e.value) return;

    ....

    // Media browse
    touchControls.setBrowseContent(browseContent);
  });

Thao tác nhấp vào một mục duyệt qua nội dung nghe nhìn sẽ kích hoạt trình chặn LOAD. Thêm mã sau vào trình chặn LOAD để ánh xạ request.media.contentId với request.media.entity từ mục duyệt qua nội dung nghe nhìn:

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      ...

      // Map contentId to entity
      if (request.media && request.media.entity) {
        request.media.contentId = request.media.entity;
      }

      return new Promise((resolve, reject) => {
            ...
        });
    });

Bạn cũng có thể đặt đối tượng BrowseContent thành null để xoá giao diện người dùng Duyệt qua nội dung nghe nhìn.

12. Gỡ lỗi ứng dụng Receiver

SDK Cast Receiver cung cấp một lựa chọn khác để nhà phát triển dễ dàng gỡ lỗi ứng dụng receiver bằng cách sử dụng API CastDebugLoggerCông cụ điều khiển và kiểm soát (CaC) đồng hành để ghi nhật ký.

Khởi chạy

Để kết hợp API, hãy thêm tập lệnh nguồn CastDebugLogger vào tệp index.html. Nguồn phải được khai báo trong thẻ <head> sau khi khai báo SDK của Bộ thu truyền.

<head>
  ...
  <script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
  <!-- Cast Debug Logger -->
  <script src="//www.gstatic.com/cast/sdk/libs/devtools/debug_layer/caf_receiver_logger.js"></script>
</head>

Trong js/receiver.js ở đầu tệp và bên dưới playerManager, hãy thêm mã sau để truy xuất phiên bản CastDebugLogger và bật trình ghi nhật ký:

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();

// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
const LOG_TAG = 'MyAPP.LOG';

// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
  if (!castDebugLogger.debugOverlayElement_) {
      castDebugLogger.setEnabled(true);
  }
});

Khi trình ghi gỡ lỗi được bật, một lớp phủ hiển thị DEBUG MODE sẽ xuất hiện trên trình nhận.

Hình ảnh video đang phát với thông báo &quot;DEBUG MODE&quot; xuất hiện trên nền đỏ ở góc trên bên trái của khung hình

Ghi nhật ký sự kiện của người chơi

Khi sử dụng CastDebugLogger, bạn có thể dễ dàng ghi nhật ký các sự kiện của người chơi được kích hoạt bởi SDK Bộ thu CAF và sử dụng nhiều cấp độ trình ghi nhật ký để ghi nhật ký dữ liệu sự kiện. Cấu hình loggerLevelByEvents sử dụng cast.framework.events.EventTypecast.framework.events.category để chỉ định những sự kiện sẽ được ghi lại.

Thêm mã sau vào bên dưới phần khai báo castDebugLogger để ghi lại khi sự kiện CORE của người chơi được kích hoạt hoặc thay đổi về mediaStatus được phát sóng:

// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();

// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
  if (!castDebugLogger.debugOverlayElement_) {
      castDebugLogger.setEnabled(true);
  }
});

// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
  'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
  'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}

Thông điệp nhật ký và thẻ tuỳ chỉnh

API CastDebugLogger cho phép bạn tạo thông điệp nhật ký xuất hiện trên lớp phủ gỡ lỗi của trình nhận bằng nhiều màu. Có các phương thức ghi nhật ký sau đây, được liệt kê theo thứ tự ưu tiên từ cao nhất đến thấp nhất:

  • castDebugLogger.error(custom_tag, message);
  • castDebugLogger.warn(custom_tag, message);
  • castDebugLogger.info(custom_tag, message);
  • castDebugLogger.debug(custom_tag, message);

Đối với mỗi phương thức ghi nhật ký, tham số đầu tiên là một thẻ tuỳ chỉnh. Đây có thể là chuỗi ký tự nhận dạng bất kỳ mà bạn thấy có ý nghĩa. CastDebugLogger sử dụng các thẻ để lọc nhật ký. Cách sử dụng thẻ được giải thích chi tiết hơn ở phần dưới đây. Tham số thứ hai là thông báo nhật ký.

Để hiển thị nhật ký trong thực tế, hãy thêm nhật ký vào trình chặn LOAD.

playerManager.setMessageInterceptor(
  cast.framework.messages.MessageType.LOAD,
  request => {
    castDebugLogger.info(LOG_TAG, 'Intercepting LOAD request');

    // Map contentId to entity
    if (request.media && request.media.entity) {
      request.media.contentId = request.media.entity;
    }

    return new Promise((resolve, reject) => {
      // Fetch content repository by requested contentId
      makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
        .then(function (data) {
          let item = data[request.media.contentId];
          if(!item) {
            // Content could not be found in repository
            castDebugLogger.error(LOG_TAG, 'Content not found');
            reject();
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.dash;
            request.media.contentType = 'application/dash+xml';
            castDebugLogger.warn(LOG_TAG, 'Playable URL:', request.media.contentUrl);

            // Add metadata
            let metadata = new cast.framework.messages.MovieMediaMetadata();
            metadata.metadataType = cast.framework.messages.MetadataType.MOVIE;
            metadata.title = item.title;
            metadata.subtitle = item.author;

            request.media.metadata = metadata;

            // Resolve request
            resolve(request);
          }
      });
    });
  });

Bạn có thể kiểm soát thông điệp nào xuất hiện trên lớp phủ gỡ lỗi bằng cách đặt cấp độ nhật ký trong loggerLevelByTags cho từng thẻ tuỳ chỉnh. Ví dụ: việc bật một thẻ tuỳ chỉnh có cấp độ nhật ký cast.framework.LoggerLevel.DEBUG sẽ hiển thị tất cả thông điệp được thêm cùng với thông điệp nhật ký lỗi, cảnh báo, thông tin và thông điệp gỡ lỗi. Việc bật một thẻ tuỳ chỉnh có cấp WARNING sẽ chỉ hiển thị lỗi và cảnh báo thông điệp nhật ký.

Cấu hình loggerLevelByTags là không bắt buộc. Nếu bạn không định cấu hình thẻ tuỳ chỉnh cho cấp độ trình ghi nhật ký, thì tất cả thông điệp nhật ký sẽ hiển thị trên lớp phủ gỡ lỗi.

Thêm mã sau vào bên dưới trình ghi sự kiện CORE:

// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
  'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
  'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}

// Set verbosity level for custom tags.
castDebugLogger.loggerLevelByTags = {
    [LOG_TAG]: cast.framework.LoggerLevel.DEBUG,
};

Lớp phủ gỡ lỗi

Trình ghi nhật ký gỡ lỗi truyền cung cấp một lớp phủ gỡ lỗi trên trình nhận để hiển thị thông điệp nhật ký tuỳ chỉnh của bạn trên thiết bị truyền. Sử dụng showDebugLogs để bật/tắt lớp phủ gỡ lỗi và clearDebugLogs để xoá thông báo nhật ký trên lớp phủ.

Thêm mã sau để xem trước lớp phủ gỡ lỗi trên trình thu của bạn.

context.addEventListener(cast.framework.system.EventType.READY, () => {
  if (!castDebugLogger.debugOverlayElement_) {
      // Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
      castDebugLogger.setEnabled(true);

      // Show debug overlay
      castDebugLogger.showDebugLogs(true);

      // Clear log messages on debug overlay
      castDebugLogger.clearDebugLogs();
  }
});

Hình ảnh hiển thị lớp phủ gỡ lỗi, danh sách thông điệp nhật ký gỡ lỗi trên nền mờ ở đầu khung video

13. Xin chúc mừng

Giờ đây, bạn đã biết cách tạo ứng dụng trình thu phát web tuỳ chỉnh bằng cách sử dụng SDK Trình thu phát web của tính năng Truyền.

Để biết thêm thông tin, hãy xem hướng dẫn dành cho nhà phát triển về Trình thu phát trên web.