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 nhận web tuỳ chỉnh để phát nội dung trên các thiết bị hỗ trợ 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 hoặc trình duyệt Chrome dành cho máy tính 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 ứ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). Cast SDK 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 của Google Cast Design.

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ợ. Xem thêm tại đây.

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 HTML5 hoạt động như trình thu nhận tuỳ chỉnh của riêng bạn có khả năng hiển thị nội dung video trên thiết bị hỗ trợ Cast.

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

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

Bạn cần có

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. Triển khai bộ thu cục bộ

Để có thể sử dụng bộ thu web bằng Thiết bị truyền, thiết bị này cần được lưu trữ ở nơi mà Thiết bị truyền của bạn có thể tiếp cận. Nếu bạn đã có một máy chủ hỗ trợ https, hãy bỏ qua các 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 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-start và khởi động máy chủ.

Ghi lại URL của thiết bị nhận được lưu trữ. Bạn sẽ dùng phương phá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 nhận tuỳ chỉnh (như được tạo trong lớp học lập trình này) trên thiết bị Chromecast. Sau khi đăng ký ứng dụng, bạn sẽ nhận được mã ứng dụng mà ứng dụng của người gửi phải sử dụng để thực hiện lệnh gọi API, chẳng hạn như để 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 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 mới nhận), trong đó tuỳ chọn "Custom receiver" (Bộ thu tuỳ chỉnh) được làm nổi bật

Chọn "Custom receiver" (Trình thu tuỳ chỉnh), đây là những gì chúng ta đang xây dựng.

Hình ảnh màn hình "New Custom receiver" (Trình thu tuỳ chỉnh mới) cho thấy một URL mà người nào đó đang nhập vào trường "Receiver Application URL" (URL ứng dụng của người nhận)

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

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

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 của thiết bị thu trước khi bạn xuất bản. Sau khi bạn phát hành ứng dụng nhận, ứng dụng đó sẽ có trên tất cả thiết bị Google Cast. Để phục vụ 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 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 "Add Cast receiver Device" (Thêm thiết bị nhận Cast)

Nhập số sê-ri in ở mặt sau của Thiết bị truyền và đặt tên mang tính mô tả. Bạn cũng có thể tìm thấy số sê-ri của mình bằng cách truyền màn hình trong Chrome khi truy cập Google Cast SDK Developer Console

Sẽ mất từ 5 đến 15 phút trước khi bộ thu và thiết bị của bạn sẵn sàng để thử nghiệm. Sau khi chờ 5-15 phút, bạn phải khởi động lại thiết bị Truyền của mình.

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

Biểu trưng Google Chrome

Trong khi chờ ứng dụng receiver mới sẵn sàng thử nghiệm, hãy cùng xem một mẫu ứng dụng receiver đã hoàn thiện trông như thế nào. Bộ thu mà chúng ta sẽ xây dựng sẽ có khả năng phát lại nội dung nghe nhìn bằng cách sử dụng phương thức 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 Truyền phát thích ứng động qua HTTP (DASH)).

Trong trình duyệt của bạn, hãy mở Command and Control (CaC) Tool (Công cụ Command và Control (CaC)).

Hình ảnh thẻ "Cast Connect & Logger Controls" (Điều khiển trình kết nối và trình ghi nhật ký) của Công cụ Command và Control (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 người nhận mẫu "CC1AD845" mặc định 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 trình kết nối và trình ghi nhật ký) của Công cụ Command và Control (CaC) cho biết công cụ này đã kết nối với ứng dụng receiver

  1. Điều hướng đến thẻ "Tải nội dung nghe nhìn" ở trên cùng.

Hình ảnh thẻ "Tải phương tiện" của công cụ Command and Control (CaC)

  1. Nhấp vào nút "Tải theo nội dung" để phá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 bộ thu cơ bản 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 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. Mở js/receiver.jsindex.html

Lưu ý rằng trong quá trình thực hiện lớp học lập trình này, http-server sẽ xử lý những thay đổi mà bạn thực hiện. Nếu bạn nhận thấy sự thay đổi không mong muốn, hãy thử tắt và khởi động lại http-server.

Thiết kế ứng dụng

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

Ứng dụng này bao gồm một khung 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 để giúp receiver 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 của chúng ta. Hiện tại, tệp này trống và chúng ta sẽ bổ sung tệp vào lớp học lập trình này.

receiver.js

Tập lệnh này sẽ quản lý toàn bộ logic cho ứng dụng receiver (trình thu nhận). Hiện tại, đó chỉ là một tệp trống. Chúng ta sẽ chuyển tập lệnh này thành một bộ thu Cast hoạt động với đầy đủ chức năng chỉ bằng một vài dòng mã trong phần tiếp theo.

7. Một bộ thu Cast cơ bản

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

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 không gian cho SDK trình thu nhận để hiển thị giao diện người dùng của trình thu mặc định đang vận chuyển cùng 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 động 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 đến toàn bộ SDK của người nhận
  • lưu trữ tham chiếu đến PlayerManager, đối tượng xử lý việc phát và cung cấp cho bạn tất cả các hook cần thiết để bổ sung logic tuỳ chỉnh của riêng bạn
  • khởi động SDK bằng cách gọi start() trên CastReceiverContext

Thêm đoạn mã 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"

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

Trỏ trình duyệt web của bạn tới Công cụ Command và Control (CaC).

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

Hãy nhớ thay thế Mã ứng dụng của bạn như đã đăng ký trước đó trong trường này và 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 khi bắt đầu phiên Truyền.

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

Ở cấp độ cao, để phát nội dung nghe nhìn trên Thiết bị truyền, những việc sau cần xảy ra:

  1. Người gửi tạo một đối tượng MediaInfo JSON từ SDK truyền để tạo mô hình cho một mục nội dung nghe nhìn.
  2. Người gửi kết nối với Thiết bị truyền để chạy ứng dụng nhận.
  3. Trình thu nhận sẽ tải đối tượng MediaInfo thông qua một yêu cầu LOAD để phát nội dung.
  4. Bộ thu sẽ giám sát và theo dõi trạng thái của nội dung nghe nhìn.
  5. Người gửi gửi lệnh phát cho thiết bị nhận để điều khiển quá trình 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 cơ bản đầu tiên này, chúng ta sẽ điền sẵn URL tài sản có thể phát vào MediaInfo (được lưu trữ trong MediaInfo.contentUrl).

Người gửi trong thế giới thực 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 thu nhận sử dụng contentId làm giá trị nhận dạng để thực hiện lệnh gọi API phụ trợ thích hợp nhằm phân giải URL của tài sản thực tế rồi đặt URL đó thành MediaInfo.contentUrl.. Trình thu nhận cũng sẽ xử lý các công việc 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 ta sẽ mở rộng bộ nhận của bạn để thực hiện một thao tác 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ở thiết bị nhận.

Hình ảnh thẻ &quot;Cast Connect & Logger Controls&quot; (Điều khiển trình kết nối và trình ghi nhật ký) của Công cụ Command và Control (CaC) cho biết công cụ này đã kết nối với ứng dụng receiver

Điều hướng đến thẻ "Tải phương tiện" và nhấp vào nút "Tải theo nội dung". Bộ thu của bạn sẽ bắt đầu phát nội dung mẫu.

Hình ảnh thẻ &quot;Tải phương tiện&quot; của công cụ Command and Control (CaC)

Ngoài ra, SDK của bộ thu có thể xử lý ngay từ đầu:

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

Vui lòng 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. Tại đây, chúng ta sẽ mở rộng bộ nhận để giao tiếp 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

Tuân theo cách hầu hết các nhà phát triển tương tác với Bộ thu nội dung truyền của họ trong các ứng dụng thực tế, chúng tôi sẽ sửa đổi bộ thu để xử lý các yêu cầu LOAD tham chiếu đến nội dung đa phương tiện dự kiến bằng khoá API thay vì gửi qua URL của tài sản có thể phát.

Các ứng dụng thường làm điều này vì:

  • Người gửi có thể không biết URL nội dung.
  • Ứng dụng Truyền được thiết kế để xử lý việc xác thực, logic nghiệp vụ khác hoặc các lệnh gọi API ngay 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 tin nhắn đến theo loại và sửa đổi chúng trước khi chúng đến trình xử lý tin nhắn 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ững việc sau:

  • Đọc yêu cầu LOAD đến và contentId tuỳ chỉnh của yêu cầu đó.
  • Thực hiện lệnh gọi GET đến API của chúng tôi để tra cứu tài sản có thể phát trực tuyến theo contentId.
  • Sửa đổi yêu cầu LOAD bằng URL của luồng.
  • Sửa đổi đối tượng MediaInformation để đặt tham số cho loại luồng.
  • Chuyển yêu cầu đến SDK để phát lại 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 hook của SDK giúp tuỳ chỉnh các tác vụ phổ biến của trình thu nhận, trong khi vẫn dựa vào trải nghiệm hầu như có sẵn.

API mẫu

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

{
  "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"
  },

  [...]

}

Trong 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 nhận được gọi để yêu cầu LOAD.

Chặn yêu cầu TẢI

Ở bước này, chúng ta sẽ tạo một giao diện chặn tải có hàm thực hiện yêu cầu XHR đến tệp JSON được lưu trữ. Sau khi lấy 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 tham số MediaInformation để chỉ định loại nội dung.

Thêm mã sau vào tệp js/receiver.js, ngay trước khi gọi 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

Bây giờ, khi đã chuẩn bị được trình chặn tải, chúng ta sẽ chỉ định kiểu nội dung cho trình thu nhận. Thông tin này sẽ cung cấp cho trình thu nhận URL của 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ể tiếp tục thử nghiệm để thử tải với nội dung DASH. Nếu bạn muốn thử nghiệm việc tải với nội dung HLS, hãy xem bước tiếp theo.

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

API mẫu bao gồm nội dung HLS cũng như DASH. Ngoài việc đặt contentType như chúng ta đã làm ở 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 trình thu được định cấu hình để phát luồng HLS, loại vùng chứa mặc định cần có là luồng truyền tải (TS). Do đó, trình thu sẽ cố gắng mở các luồng MP4 mẫu ở định dạng TS nếu chỉ có thuộc tính contentUrl được sửa đổi. Trong yêu cầu tải, bạn phải sửa đổi đối tượng MediaInformation bằng các thuộc tính bổ sung để bộ nhận biết rằng 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 của bạn 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, mở Công cụ Command và Control (CaC) rồi đặt Mã ứng dụng của bạn thành Mã ứ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.

Điều hướng đế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 tôi gửi yêu cầu LOAD chỉ chứa thông tin tham chiếu contentId đến nội dung đa phương tiện.

Hình ảnh thẻ &quot;Tải phương tiện&quot; của công cụ Command and Control (CaC)

Giả sử mọi thứ hoạt động tốt với nội dung sửa đổi của bạn đối với receiver, thì trình chặn sẽ đảm nhiệm 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 hay không. Bạn có thể thay đổi Content ID thành một mã nhận dạng 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 ứng dụng nhận hỗ trợ điều khiển bằng cách chạm.

Phần này giải thích cách tối ưu hoá ứng dụng nhận 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 trình phát.

Truy cập vào các chế độ đ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 của bạn ở 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 thiết lập 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 ô dựa trên MetadataTypeMediaStatus.supportedMediaCommands.

Đ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ẽ hiển thị như trong ví dụ bên dưới.

Hình ảnh video đang phát với các nút điều khiển trê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 bản nhạc đang phát với các nút điều khiển trên giao diện người dùng được 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 đa phương tiện được hỗ trợ

Đối tượng Chế độ điều khiển trên giao diện người dùng cũng xác định xem ControlsButton có hiển thị 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ư dưới đây:

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à nút &quot;Bỏ qua&quot; đã 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ư dưới đây:

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;Tua đi&quot; và &quot;Bỏ qua lùi&quot;, cũng như các nút &quot;Hàng đợi trước&quot; và &quot;Hàng đợi tiếp theo&quot;

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 đa phương tiện: thanh tiến trình, nút &quot;Phát&quot;, cũng như các nút &quot;Hàng đợi trước&quot; và &quot;Hàng đợi tiếp theo&quot;

Khi có bản văn bản, nút phụ đề sẽ luôn hiển thị 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;Bỏ qua lùi&quot;, nút &quot;Hàng đợi trước&quot; và &quot;Hàng đợi tiếp theo&quot; và các nút &quot;Phụ đề chi tiết&quot; đang bật

Để linh động thay đổi giá trị của supportedMediaCommands sau khi bắt đầu ngữ cảnh receiver (trình thu nhận), bạn có thể gọi PlayerManager.setSupportedMediaCommands để ghi đè giá trị đó. Ngoài ra, bạn có thể thêm một lệnh mới bằng cách sử dụng addSupportedMediaCommands hoặc xoá một lệnh hiện có bằ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 bên dưới TouchControl để thiết lập ô đầu tiên của các chế độ đ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 xem nội dung nghe nhìn trên màn hình thông minh

Duyệt qua nội dung đa phương tiện là tính năng Bộ thu CAF cho phép người dùng khám phá thêm nội dung trên thiết bị cảm ứng. Để triển khai việc này, bạn 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 mẫu 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 của giao diện đó:

Hình ảnh giao diện người dùng BrowseContent cho thấy hai hình thu nhỏ của video và một phần của phần 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 các 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 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 cho thấy hai hình thu nhỏ của video và một phần của phần 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 nghe nhìn để duyệt qua 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 để đặt 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 nội dung đa phương tiệ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 nội dung đa phương tiệ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. Ứng dụng nhận gỡ lỗi

Cast receiver SDK cung cấp một tuỳ 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 CastDebugLogger APICông cụ lệnh và điều khiển (CaC) đi kèm để ghi lại nhật ký.

Khởi chạy

Để kết hợp API này, hãy thêm tập lệnh nguồn CastDebugLogger vào tệp index.html. Bạn phải khai báo nguồn trong thẻ <head> sau phần khai báo SDK Cast receiver.

<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 thực thể 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 bạn bật trình ghi nhật ký gỡ lỗi, một lớp phủ hiển thị DEBUG MODE sẽ hiển thị trên trình nhận.

Hình ảnh video đang phát với thông báo &#39;CHẾ ĐỘ GỠ LỖI&#39; 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

Bằng cách 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 do SDK receiver CAF kích hoạt và sử dụng các cấp độ trình ghi nhật ký khác nhau để 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 vào nhật ký.

Thêm mã sau vào bên dưới phần khai báo castDebugLogger để ghi nhật ký khi sự kiện CORE của trình phát được kích hoạt hoặc sự thay đổi mediaStatus được phát đi:

// 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 thu nhận bằng nhiều màu. Có các phương thức ghi nhật ký đượ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 nhận dạng bất kỳ mà bạn thấy có ý nghĩa. CastDebugLogger sử dụng thẻ để lọc nhật ký. Cách sử dụng thẻ được giải thích chi tiết hơn ở bên dưới. Tham số thứ hai là thông điệp 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 báo nào sẽ xuất hiện trên lớp phủ gỡ lỗi bằng cách thiết lập cấp độ nhật ký trong loggerLevelByTags cho từng thẻ tuỳ chỉnh. Ví dụ: thao tá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 báo được thêm kèm theo lỗi, cảnh báo, thông tin và thông điệp nhật ký gỡ lỗi. Việc bật thẻ tuỳ chỉnh ở cấp độ WARNING sẽ chỉ cho thấy lỗi và cảnh báo thông điệp nhật ký.

Không bắt buộc phải có cấu hình loggerLevelByTags. Nếu một thẻ tuỳ chỉnh không được định cấu hình ở 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 bên dưới trình ghi nhật ký 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 bộ thu để 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 điệp nhật ký trên lớp phủ này.

Thêm mã sau để xem trước lớp phủ gỡ lỗi trên receiver 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 minh hoạ lớp phủ gỡ lỗi, một danh sách các thông điệp nhật ký gỡ lỗi trên một nền mờ ở phía trên một khung video

13. Xin chúc mừng

Giờ đây, bạn đã biết cách tạo ứng dụng bộ thu web tuỳ chỉnh bằng SDK Cast Web receiver.

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