Tworzenie niestandardowego odbiornika internetowego

1. Omówienie

Logo Google Cast

W ramach tego ćwiczenia w Codelabs dowiesz się, jak stworzyć niestandardową aplikację odbiornika internetowego do odtwarzania treści na urządzeniach obsługujących Cast.

Co to jest Google Cast?

Google Cast umożliwia użytkownikom przesyłanie treści z urządzenia mobilnego na telewizor. Dzięki temu użytkownicy mogą używać przeglądarki Chrome na swoich urządzeniach mobilnych lub komputerach jako pilota do odtwarzania multimediów na telewizorze.

Pakiet Google Cast SDK umożliwia aplikacji sterowanie urządzeniami obsługującymi Google Cast (np. telewizorem lub systemem audio). Pakiet Cast SDK zapewnia niezbędne komponenty interfejsu zgodnie z listą kontrolną projektu Google Cast.

Znajdziesz tam listę kontrolną projektowania Google Cast, która ułatwia i przewidywalność korzystania z Google Cast na wszystkich obsługiwanych platformach. Więcej informacji

Co utworzymy?

Po ukończeniu tego ćwiczenia w Codelabs otrzymasz aplikację HTML5, która będzie działać jak własny niestandardowy odbiornik do wyświetlania treści wideo na urządzeniach obsługujących Cast.

Czego się nauczysz

  • Jak skonfigurować tworzenie odbiorników.
  • Podstawowe informacje o odbiorniku obsługującym Cast bazującym na platformie Cast Application Framework.
  • Jak odebrać przesłany film.
  • Jak zintegrować rejestrator debugowania
  • Jak zoptymalizować odbiornik na potrzeby inteligentnych ekranów

Czego potrzebujesz

Doświadczenie

  • Niezbędna jest do tego wiedza o programowaniu stron internetowych.
  • Wymagamy też wcześniejszej wiedzy na temat oglądania telewizji. :)

Jak wykorzystasz ten samouczek?

Tylko do przeczytania Przeczytaj go i wykonaj ćwiczenia

Jak oceniasz swoje doświadczenia z tworzeniem aplikacji internetowych?

Początkujący Poziom średnio zaawansowany Biegły

Jak oceniasz swoje wrażenia z oglądania telewizji?

Początkujący Poziom średnio zaawansowany Biegły

2. Pobieranie przykładowego kodu

Możesz pobrać cały przykładowy kod na swój komputer...

i rozpakuj pobrany plik ZIP.

3. Lokalne wdrażanie odbiornika

Aby można było korzystać z odbiornika internetowego z urządzeniem przesyłającym, musi on być hostowany w miejscu, w którym urządzenie przesyłające ma do niego dostęp. Jeśli masz już dostępny serwer obsługujący protokół https, pomiń poniższe instrukcje i zanotuj adres URL, ponieważ będzie on potrzebny w następnej sekcji.

Jeśli nie masz serwera do użycia, możesz skorzystać z Hostingu Firebase lub ngrok.

Uruchamianie serwera

Po skonfigurowaniu wybranej usługi przejdź do app-start i uruchom serwer.

Zanotuj adres URL hostowanego odbiornika. Wykorzystasz go w następnej sekcji.

4. Rejestrowanie aplikacji w konsoli programisty Cast

Aby na urządzeniach Chromecast uruchamiać niestandardowy odbiornik (zgodnie z instrukcjami w tym ćwiczeniu w Codelabs), musisz zarejestrować swoją aplikację. Po zarejestrowaniu aplikacji otrzymasz identyfikator, którego aplikacja nadawcy musi używać do wykonywania wywołań interfejsu API, np. uruchamiania aplikacji odbierającej.

Obraz konsoli programisty Google Cast SDK z opcją „Add New Application” (Dodaj nową aplikację) zaznaczony przycisk

Kliknij „Dodaj nową aplikację”

Obraz „New Receiver Application” (Nowa aplikacja odbiornika) z niestandardowym odbiornikiem. wyróżniona opcja

Wybierz „Odbiornik niestandardowy”, nad tym właśnie pracujemy.

Obraz „Nowy niestandardowy odbiornik” ekran z adresem URL wpisywanym przez użytkownika w polu „Adres URL aplikacji odbiornika” pole

Wpisz dane nowego odbiornika, pamiętaj, aby użyć adresu URL

w ostatniej sekcji. Zanotuj identyfikator aplikacji przypisany do nowego odbiornika.

Musisz też zarejestrować urządzenie Google Cast, by mogło ono uzyskiwać dostęp do aplikacji odbiornika przed jej opublikowaniem. Po opublikowaniu aplikacja odbiornika będzie dostępna dla wszystkich urządzeń Google Cast. Na potrzeby tego ćwiczenia z programowania zaleca się korzystanie z nieopublikowanej aplikacji odbierającej.

Obraz konsoli programisty Google Cast SDK z opcją „Dodaj nowe urządzenie” zaznaczony przycisk

Kliknij „Dodaj nowe urządzenie”.

Obraz „Dodaj odbiornik Cast” okno

Wpisz numer seryjny wydrukowany z tyłu urządzenia przesyłającego i nadaj mu opisową nazwę. Numer seryjny możesz też znaleźć, przesyłając ekran w Chrome po otwarciu konsoli programisty Google Cast SDK.

Zanim odbiornik i urządzenie będą gotowe do testowania, może minąć 5–15 minut. Po odczekaniu 5–15 minut musisz zrestartować urządzenie przesyłające.

5. Uruchamianie przykładowej aplikacji

Logo Google Chrome

Czekając, aż nowa aplikacja odbiornika będzie gotowa do testowania, zobaczmy, jak wygląda przykładowa, wypełniona aplikacja odbiornika. Odbiornik, który stworzysz, będzie mógł odtwarzać multimedia za pomocą strumieniowego przesyłania danych z adaptacyjną szybkością transmisji bitów (użyj przykładowej treści zakodowanej na potrzeby dynamicznego adaptacyjnego strumieniowego przesyłania przez HTTP (DASH)).

W przeglądarce otwórz narzędzie Command i Control (CaC).

Obraz „Cast Connect &” Opcje Rejestratora karta w narzędziu Command and Control (CaC)

  1. Powinno się wyświetlić narzędzie CaC.
  2. Użyj domyślnej wartości „CC1AD845” przykładowy identyfikator odbiorcy i kliknij „Ustaw identyfikator aplikacji”. Przycisk
  3. Kliknij przycisk Cast w lewym górnym rogu i wybierz urządzenie Google Cast.

Obraz „Cast Connect &” Opcje Rejestratora w narzędziu Command and Control (CaC) wskazującą, że jest ono połączone z aplikacją Receiver (Odbiornik).

  1. Przejdź do okna „Load Media” (Wczytaj multimedia). u góry.

Obraz przycisku „Load Media” (Wczytaj multimedia) karta w narzędziu Command and Control (CaC)

  1. Kliknij przycisk „Wczytaj według treści”, , aby odtworzyć przykładowy film.
  2. Rozpocznie się odtwarzanie filmu na urządzeniu Google Cast, co pozwoli pokazać podstawowe funkcje odbiornika w przypadku domyślnego odbiornika.

6. Przygotowywanie projektu początkowego

Musisz dodać obsługę Google Cast do pobranej przez Ciebie aplikacji startowej. Oto terminologia dotycząca Google Cast, której będziemy używać w tym ćwiczeniu z programowania:

  • aplikacja nadawca działa na urządzeniu mobilnym lub laptopie,
  • aplikacja odbiornika na urządzeniu Google Cast).

Teraz możesz zacząć tworzyć projekt początkowy za pomocą ulubionego edytora tekstu:

  1. Wybierz katalog ikona folderuapp-start z pobranego przykładowego kodu.
  2. Otwórz js/receiver.js i index.html

Uwaga: w trakcie ćwiczeń z programowania http-server powinien wykrywać wprowadzane przez Ciebie zmiany. Jeśli nie, spróbuj wyłączyć i uruchomić ponownie http-server.

Projektowanie aplikacji

Aplikacja odbiornika inicjuje sesję przesyłania i będzie w trybie gotowości, dopóki nie nadejdzie żądanie LOAD (czyli polecenie odtworzenia pliku multimedialnego).

Aplikacja składa się z 1 widoku głównego zdefiniowanego w index.html i 1 pliku JavaScript o nazwie js/receiver.js, który zawiera wszystkie funkcje logiczne umożliwiające odbiornik.

index.html

Ten plik HTML będzie zawierać interfejs użytkownika naszej aplikacji odbiornika. Na razie jest ona pusta, ale będziemy ją uzupełniać w trakcie całego laboratorium dotyczącego kodu.

receiver.js

Ten skrypt będzie zarządzać całą logiką naszej aplikacji odbiornika. Na razie jest to tylko pusty plik, ale w następnej sekcji zmienimy go w w pełni działający odbiornik Cast.

7. Podstawowy odbiornik Cast

Podstawowy odbiornik Cast zainicjuje sesję przesyłania podczas uruchamiania. Jest to konieczne, aby można było poinformować wszystkie połączone aplikacje nadawcy, że udało się skomunikować się z odbiorcą. Poza tym nowy pakiet SDK jest od razu skonfigurowany do obsługi strumieniowych transmisji multimedialnych (za pomocą DASH, HLS i Smooth Streaming) oraz zwykłych plików MP4. Wypróbujmy to.

Inicjalizacja

Dodaj w nagłówku w polu index.html ten kod:

<head>
  ...

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

Dodaj ten kod do index.html <body> przed <footer> ładowanie receiver.js,, aby dać pakietowi SDK odbiorcy miejsce na wyświetlenie domyślnego interfejsu odbiornika, który jest dostarczany przez dodany przed chwilą skrypt.

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

Teraz musimy zainicjować w interfejsie js/receiver.js pakiet SDK. Będzie się on składać z:

  • uzyskiwanie odniesienia do CastReceiverContext, czyli głównego punktu wejścia do całego pakietu SDK odbiornika
  • zapisując odniesienie do obiektu PlayerManager, czyli obiektu, który obsługuje odtwarzanie i udostępnia wszystkie elementy potrzebne do zainstalowania własnych algorytmów.
  • inicjuję pakiet SDK, wywołując interfejs start() CastReceiverContext

Dodaj do js/receiver.js te elementy.

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

context.start();

8. Przesyłanie „podstawowe” treści wideo

Na potrzeby tego ćwiczenia z programowania użyj narzędzia CaC do wypróbowania nowego odbiornika.

Wskaż w przeglądarce narzędzie Command i Control (CaC).

Obraz „Cast Connect &” Opcje Rejestratora karta w narzędziu Command and Control (CaC)

Zastąp swój identyfikator aplikacji zarejestrowanym wcześniej w polu i kliknij „Ustaw identyfikator aplikacji”. Dzięki temu narzędzie do uruchamiania sesji przesyłania użyje odbiornika.

Przesyłanie multimediów

Ogólnie rzecz biorąc, aby odtwarzać multimedia na urządzeniu przesyłającym, musisz spełnić te warunki:

  1. Nadawca tworzy z pakietu SDK Cast obiekt MediaInfo JSON, który modeluje element multimedialny.
  2. Nadawca łączy się z urządzeniem przesyłającym, aby uruchomić aplikację odbiornika.
  3. Odbiorca wczytuje obiekt MediaInfo za pomocą żądania LOAD, aby odtworzyć treść.
  4. Odbiornik monitoruje i śledzi stan multimediów.
  5. Nadawca wysyła polecenia odtwarzania do odbiorcy, aby sterować odtwarzaniem na podstawie interakcji użytkownika z aplikacją nadawcy.

W pierwszej podstawowej próbie uzupełnimy pole MediaInfo adresem URL zasobu z możliwością odtworzenia (zapisanego w systemie MediaInfo.contentUrl).

Prawdziwy nadawca używa identyfikatora mediów specyficznego dla aplikacji w MediaInfo.contentId. Odbiorca używa contentId jako identyfikatora do wykonywania odpowiednich wywołań interfejsu API backendu, aby rozpoznać rzeczywisty URL zasobu i ustawiać go na MediaInfo.contentUrl.. Odbiorca będzie też obsługiwać zadania takie jak pozyskiwanie licencji DRM lub wstrzykiwanie informacji o przerwach na reklamy.

W następnej sekcji udostępnimy odbiornikowi takie same możliwości. Na razie kliknij ikonę Cast i wybierz urządzenie, żeby otworzyć odbiornik.

Obraz „Cast Connect &” Opcje Rejestratora w narzędziu Command and Control (CaC) wskazującą, że jest ono połączone z aplikacją Receiver (Odbiornik).

Przejdź do okna „Load Media” (Wczytaj multimedia). i kliknij przycisk „Wczytaj według treści”, Przycisk Odbiornik powinien zacząć odtwarzać próbkę.

Obraz przycisku „Load Media” (Wczytaj multimedia) karta w narzędziu Command and Control (CaC)

Tak więc pakiet SDK odbierający od razu obsługuje te funkcje:

  • Inicjuję sesję przesyłania
  • Obsługuj przychodzące żądania LOAD od nadawców zawierających zasoby do odtwarzania
  • Udostępnij podstawowy interfejs odtwarzacza do wyświetlenia na dużym ekranie.

Zapoznaj się z narzędziem CaC i jego kodem, zanim przejdziesz do następnej sekcji, w której nasz odbiorca będzie mógł porozmawiać o prostym, przykładowym interfejsie API, który obsługuje przychodzące żądania LOAD od nadawców.

9. Integracja z zewnętrznym interfejsem API

Zgodnie z tym, jak większość deweloperów używa odbiorników Cast w rzeczywistych aplikacjach, zmienimy odbiornik tak, aby obsługiwał żądania LOAD, które odwołują się do odpowiednich treści multimedialnych za pomocą klucza interfejsu API, zamiast wysyłać adres URL zasobu przeznaczonego do odtworzenia.

Zwykle dzieje się tak, ponieważ:

  • Nadawca może nie znać adresu URL treści.
  • Aplikacja Cast jest przeznaczona do obsługi uwierzytelniania i innych wywołań logiki biznesowej oraz wywołań interfejsu API bezpośrednio w odbiorniku.

Ta funkcja jest wdrażana głównie w metodzie PlayerManager setMessageInterceptor(). Dzięki temu możesz przechwytywać wiadomości przychodzące według typu i modyfikować je, zanim dotrą do wewnętrznego modułu obsługi wiadomości pakietu SDK. W tej sekcji zajmujemy się prośbami (LOAD), w których:

  • Odczytaj przychodzące żądanie LOAD i jego niestandardowe żądanie contentId.
  • Wywołaj nasz interfejs API za pomocą funkcji GET, aby wyszukać zasób z możliwością strumieniowania według jego contentId.
  • Zmodyfikuj żądanie LOAD, podając adres URL strumienia.
  • Zmodyfikuj obiekt MediaInformation, aby ustawić parametry typu strumienia.
  • Przekaż żądanie do pakietu SDK w celu odtworzenia lub odrzuć polecenie, jeśli nie uda nam się wyszukać żądanych multimediów.

Podany przykładowy interfejs API prezentuje hooki pakietu SDK do dostosowywania typowych zadań odbiornika, wciąż korzystając z bardziej gotowych rozwiązań.

Przykładowy interfejs API

Otwórz w przeglądarce stronę https://storage.googleapis.com/cpe-sample-media/content.json i zapoznaj się z naszym przykładowym katalogiem filmów. Treści obejmują adresy URL obrazów plakatów w formacie PNG, a także strumienie DASH i HLS. Strumienie DASH i HLS wskazują źródła zdemultipleksowane źródła wideo i audio przechowywane w pofragmentowanych kontenerach mp4.

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

  [...]

}

W następnym kroku zmapujemy klucz każdego wpisu (np. bbb, fbb_ad) na adres URL strumienia po wywołaniu go przez odbiorcę za pomocą żądania LOAD.

Przechwyć żądanie LOAD

W tym kroku utworzymy element przechwytujący obciążenie z funkcją, która wysyła żądanie XHR do hostowanego pliku JSON. Po uzyskaniu pliku JSON przeanalizujemy jego treść i ustawimy metadane. W kolejnych sekcjach dostosujemy parametry MediaInformation, aby określić typ treści.

Dodaj poniższy kod do pliku js/receiver.js bezpośrednio przed wywołaniem 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);
          }
        });
      });
    });

W następnej sekcji opisujemy, jak skonfigurować właściwość media żądania wczytania na potrzeby treści DASH.

Korzystanie z przykładowej treści DASH w interfejsie API

Przygotujemy już element przechwytujący obciążenie, więc określimy typ treści odbiornika. Odbiorca otrzyma adres URL playlisty reklamy nadrzędnej oraz typ MIME strumienia. Dodaj ten kod do pliku js/receiver.js w elemencie Promise() elementu przechwytującego 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';
            ...
          }
        });
      });
    });

Po wykonaniu tego kroku możesz przejść do sekcji Testowanie, aby spróbować wczytać stronę z treściami DASH. Jeśli chcesz zamiast tego przetestować wczytywanie z użyciem treści HLS, przejdź do następnego kroku.

Korzystanie z przykładowej treści HLS interfejsu API

Przykładowy interfejs API obejmuje zarówno treści HLS, jak i DASH. Oprócz skonfigurowania contentType tak jak w poprzednim kroku, żądanie wczytywania będzie wymagało pewnych dodatkowych właściwości, aby można było używać adresów URL HLS z przykładowego interfejsu API. Gdy odbiornik jest skonfigurowany do odtwarzania strumieni HLS, domyślnym typem kontenera jest strumień transportu (TS). W rezultacie odbiornik będzie próbował otworzyć przykładowe strumienie MP4 w formacie TS, jeśli tylko zostanie zmodyfikowana właściwość contentUrl. W żądaniu wczytywania obiekt MediaInformation powinien zostać zmodyfikowany za pomocą dodatkowych właściwości, tak aby odbiorca wiedział, że treść jest typu MP4, a nie TS. Dodaj poniższy kod do pliku js/receiver.js w elemencie przechwytującym obciążenie, aby zmodyfikować właściwości contentUrl i contentType. Dodaj też właściwości HlsSegmentFormat i HlsVideoSegmentFormat.

...
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;
            ...
          }
        });
      });
    });

Testowanie

Ponownie otwórz narzędzie Command and Control (CaC) i jako identyfikator aplikacji ustaw identyfikator aplikacji odbiorcy. Wybierz urządzenie, klikając przycisk Cast.

Przejdź do okna „Load Media” (Wczytaj multimedia). . Tym razem usuń tekst z pola „Adres URL treści”. obok pola „Load by Content” (Wczytaj według treści). , co zmusi naszą aplikację do wysłania żądania LOAD zawierającego tylko odwołanie do contentId do naszych multimediów.

Obraz przycisku „Load Media” (Wczytaj multimedia) karta w narzędziu Command and Control (CaC)

Zakładając, że wszystko działa dobrze z modyfikacjami odbiornika, element przechwytujący powinien kształtować obiekt MediaInfo w coś, co pakiet SDK może odtworzyć na ekranie.

Kliknij przycisk „Wczytaj według treści”, , by sprawdzić, czy multimedia prawidłowo się odtwarzają. Możesz zmienić Content ID na inny w pliku content.json.

10. Optymalizuję pod kątem inteligentnych ekranów

Inteligentne ekrany to urządzenia z obsługą dotykową, które umożliwiają aplikacjom odbiornika obsługę dotykową.

Z tej sekcji dowiesz się, jak zoptymalizować aplikację odbiornika po uruchomieniu jej na inteligentnych ekranach oraz jak dostosować elementy sterujące odtwarzaczem.

Dostęp do elementów sterujących interfejsu

Do obiektu elementów sterujących interfejsu dla inteligentnych ekranów można uzyskać dostęp za pomocą usługi cast.framework.ui.Controls.GetInstance(). Dodaj ten kod do pliku js/receiver.js powyżej context.start():

...

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

context.start();

Jeśli nie używasz <cast-media-player> musisz ustawić touchScreenOptimizedApp w CastReceiverOptions. W tym ćwiczeniu w Codelabs korzystamy z odtwarzacza <cast-media-player> .

context.start({ touchScreenOptimizedApp: true });

Domyślne przyciski sterujące są przypisane do każdego gniazda na podstawie zasad MetadataType i MediaStatus.supportedMediaCommands.

Sterowanie odtwarzaniem

W MetadataType.MOVIE, MetadataType.TV_SHOW i MetadataType.GENERIC obiekt elementów sterujących interfejsu dla inteligentnych ekranów będzie wyświetlany jak w przykładzie poniżej.

Obraz przedstawiający odtwarzanie filmu z nałożonymi na siebie elementami sterującymi interfejsu

  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

Sterowanie dźwiękiem

W przypadku MetadataType.MUSIC_TRACK obiekt elementów sterujących interfejsu dla inteligentnych ekranów będzie wyświetlany w ten sposób:

Obraz przedstawiający muzykę z nałożonymi na siebie elementami sterującymi interfejsu

  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

Aktualizuję obsługiwane polecenia multimedialne

Obiekt elementów sterujących interfejsu określa też, czy obiekt ControlsButton jest wyświetlany na podstawie MediaStatus.supportedMediaCommands.

Gdy wartość parametru supportedMediaCommands jest równa ALL_BASIC_MEDIA, domyślny układ elementu sterującego będzie wyglądać tak:

Obraz elementów sterujących odtwarzaczem: pasek postępu, „Odtwórz” przycisk „Przeskocz do przodu” i „Przeskocz do tyłu” Włączone przyciski

Gdy wartość parametru supportedMediaCommands jest równa ALL_BASIC_MEDIA | QUEUE_PREV | QUEUE_NEXT, domyślny układ elementu sterującego będzie wyglądać tak:

Obraz elementów sterujących odtwarzaczem: pasek postępu, „Odtwórz” przycisk „Przeskocz do przodu” i „Przeskocz do tyłu” i „Kolejka do poprzedniej” i „Kolejka dalej” Włączone przyciski

Gdy wartość SupportMediaCommands jest równa PAUSE | QUEUE_PREV | QUEUE_NEXT, domyślny układ elementów sterujących jest wyświetlany w ten sposób:

Obraz elementów sterujących odtwarzaczem: pasek postępu, „Odtwórz” i „Kolejka poprzednia”. i „Kolejka dalej” Włączone przyciski

Jeśli ścieżki tekstowe są dostępne, przycisk napisów będzie zawsze pokazywany w miejscu SLOT_1.

Obraz elementów sterujących odtwarzaczem: pasek postępu, „Odtwórz” przycisk „Przeskocz do przodu” i „Przeskocz do tyłu” Przyciski, Kolejka do poprzedniej i „Kolejka dalej” i opcję Napisy Włączone przyciski

Aby dynamicznie zmieniać wartość supportedMediaCommands po uruchomieniu kontekstu odbiorcy, możesz wywołać PlayerManager.setSupportedMediaCommands w celu zastąpienia wartości. Możesz też dodać nowe polecenie (addSupportedMediaCommands) lub usunąć obecne polecenie (removeSupportedMediaCommands).

Dostosowywanie przycisków sterujących

Elementy sterujące możesz dostosować za pomocą PlayerDataBinder. Dodaj ten kod do pliku js/receiver.js pod elementami sterującymi dotykowymi, aby ustawić pierwsze gniazdo elementów sterujących:

...

// 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. Wdrażanie przeglądania multimediów na inteligentnych ekranach

Przeglądanie multimediów to funkcja odbiornika CAF, która umożliwia użytkownikom przeglądanie dodatkowych treści na urządzeniach dotykowych. Aby to zrobić, użyj kodu PlayerDataBinder do skonfigurowania interfejsu użytkownika BrowseContent. Następnie możesz wypełnić to pole BrowseItems na podstawie treści, które chcesz wyświetlać.

BrowseContent

Poniżej znajdziesz przykład interfejsu użytkownika BrowseContent i jego właściwości:

Obraz przedstawiający interfejs dla przeglądania z 2 miniaturami filmów i częścią trzecią

  1. BrowseContent.title
  2. BrowseContent.items

Współczynnik proporcji

Użyj narzędzia targetAspectRatio property, aby wybrać najlepszy format dla komponentów z obrazem. Pakiet SDK odbiornika CAF obsługuje 3 formaty obrazu: SQUARE_1_TO_1, PORTRAIT_2_TO_3 i LANDSCAPE_16_TO_9.

BrowseItem

Użyj pola BrowseItem, aby wyświetlić tytuł, podtytuł, czas trwania i obraz dla każdego produktu:

Obraz przedstawiający interfejs dla przeglądania z 2 miniaturami filmów i częścią trzecią

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

Ustawianie danych przeglądania multimediów

Możesz udostępnić listę treści multimedialnych do przeglądania, dzwoniąc pod numer setBrowseContent. Dodaj ten kod do pliku js/receiver.js pod tagiem playerDataBinder i w detektorze zdarzeń MEDIA_CHANGED, aby elementy przeglądania miały tytuł „Następny”.

// 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);
  });

Kliknięcie elementu przeglądania multimediów aktywuje przechwytywanie LOAD. Dodaj ten kod do elementu przechwytującego LOAD, aby zmapować request.media.contentId z elementu przeglądania multimediów na request.media.entity:

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) => {
            ...
        });
    });

Możesz też ustawić wartość null dla obiektu BrowseContent, aby usunąć interfejs przeglądania multimediów.

12. Debugowanie aplikacji odbiorników

Pakiet Cast Receiver SDK to inna opcja dla programistów, która pozwala łatwo debugować aplikacje odbiorników. Służy do tego interfejs CastDebugLogger API i narzędzie Command and Control (CaC) do przechwytywania dzienników.

Zdarzenie inicjujące

Aby włączyć ten interfejs API, dodaj skrypt źródłowy CastDebugLogger do pliku index.html. Źródło powinno być zadeklarowane w elemencie <head> po deklaracji 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>

W pliku js/receiver.js na górze pliku i pod sekcją playerManager dodaj ten kod, aby pobrać instancję CastDebugLogger i włączyć rejestrator:

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);
  }
});

Gdy rejestrator debugowania jest włączony, na odbiorniku wyświetla się nakładka z komunikatem DEBUG MODE.

Grafika filmu odtwarzanego w „trybie DEBUGOWANIA” komunikat wyświetlany na czerwonym tle w lewym górnym rogu ramki

Zdarzenia odtwarzacza logów

Korzystając z CastDebugLogger, możesz łatwo rejestrować zdarzenia odtwarzacza wywoływane przez pakiet SDK CAF Receiver SDK i rejestrować dane zdarzeń na różnych poziomach rejestrowania. Konfiguracja loggerLevelByEvents wykorzystuje parametry cast.framework.events.EventType i cast.framework.events.category, aby określić, które zdarzenia będą rejestrowane.

Pod deklaracją castDebugLogger dodaj ten kod, aby rejestrować wywołanie zdarzenia CORE odtwarzacza lub rozgłaszanie zmiany mediaStatus:

// 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
}

Komunikaty logu i tagi niestandardowe

Interfejs CastDebugLogger API umożliwia tworzenie komunikatów dziennika w różnych kolorach wyświetlanych na nakładce debugowania odbiornika. Dostępne są te metody logowania, które są wymienione w kolejności od najwyższego do najniższego priorytetu:

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

W przypadku każdej metody logu pierwszym parametrem jest tag niestandardowy. Może to być dowolny ciąg znaków, który Twoim zdaniem ma znaczenie. CastDebugLogger używa tagów do filtrowania logów. Zastosowanie tagów zostało szczegółowo wyjaśnione poniżej. Drugim parametrem jest komunikat logu.

Aby wyświetlić logi w działaniu, dodaj logi do elementu przechwytującego 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);
          }
      });
    });
  });

Aby określić, które komunikaty mają się wyświetlać w nakładce debugowania, ustaw poziom rejestrowania każdego tagu niestandardowego w loggerLevelByTags. Na przykład włączenie niestandardowego tagu o poziomie logowania cast.framework.LoggerLevel.DEBUG spowoduje wyświetlanie wszystkich dodanych komunikatów z błędami, ostrzeżeniami, informacjami i komunikatami z dziennika debugowania. Włączenie tagu niestandardowego na poziomie WARNING będzie powodować wyświetlanie tylko komunikatów o błędach i ostrzeżeń w logu.

Konfiguracja loggerLevelByTags jest opcjonalna. Jeśli tag niestandardowy nie jest skonfigurowany na poziomie rejestratora, na nakładce debugowania będą wyświetlane wszystkie komunikaty dziennika.

Dodaj ten kod pod rejestratorem zdarzeń 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,
};

Nakładka debugowania

Rejestrator Cast Debugger udostępnia nakładkę debugowania na odbiorniku, aby wyświetlać niestandardowe komunikaty dziennika na urządzeniu przesyłającym. Użyj klawisza showDebugLogs, aby przełączyć nakładkę debugowania, a przycisku clearDebugLogs, aby wyczyścić komunikaty logu w nakładce.

Dodaj poniższy kod, aby wyświetlić podgląd nakładki debugowania na odbiorniku.

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();
  }
});

Obraz przedstawiający nakładkę debugowania z listą komunikatów dziennika debugowania na półprzezroczystym tle na ramce wideo

13. Gratulacje

Wiesz już, jak utworzyć niestandardową aplikację odbiornika internetowego, używając pakietu SDK Cast Web Receiver.

Więcej informacji znajdziesz w przewodniku dla programistów dotyczącym odbiornika internetowego.