Tworzenie niestandardowego odbiornika internetowego

1. Przegląd

Logo Google Cast

Dzięki nim dowiesz się, jak stworzyć niestandardową aplikację internetową, która odtwarza treści na urządzeniach obsługujących Cast.

Co to jest Google Cast?

Google Cast pozwala użytkownikom przesyłać treści z urządzeń mobilnych na telewizor. Następnie użytkownicy mogą używać swoich urządzeń mobilnych lub przeglądarki Chrome na komputerze jako pilota do odtwarzania multimediów na telewizorze.

Pakiet SDK Google Cast umożliwia aplikacji sterowanie urządzeniami obsługującymi Google Cast (na przykład telewizorem czy systemem audio). Pakiet SDK Cast zawiera niezbędne komponenty interfejsu użytkownika oparte na liście kontrolnej projektowania Google Cast.

Lista kontrolna projektu Google Cast ułatwia obsługę Cast na wszystkich obsługiwanych platformach. Więcej informacji

Co zamierzamy utworzyć?

Po ukończeniu ćwiczeń będziesz mieć aplikację HTML5, która działa jako Twój własny odbiornik z funkcją wyświetlania treści wideo na urządzeniach obsługujących Cast.

Czego się nauczysz

  • Jak skonfigurować odbiornik.
  • Podstawy odbiornika obsługującego Cast na podstawie platformy aplikacji Cast.
  • Jak otrzymać film z obsługą.
  • Integracja z rejestratorem danych debugowania.
  • Optymalizacja odbiornika pod kątem inteligentnych ekranów

Czego potrzebujesz

Funkcja

  • Musisz mieć doświadczenie w tworzeniu stron internetowych.
  • Potrzebna będzie również wiedza na temat oglądania telewizji :)

Jak będziesz korzystać z tego samouczka?

Przeczytaj tylko Przeczytaj i wykonaj ćwiczenia.

Jak oceniasz tworzenie aplikacji internetowych?

Początkujący Poziom średnio zaawansowany Poziom umiejętności

Jak oceniasz oglądanie telewizji?

Początkujący Poziom średnio zaawansowany Prosty znajomość

2. Pobieranie przykładowego kodu

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

i rozpakuj pobrany plik ZIP.

3. Wdrażanie odbiornika lokalnie

Aby używać odbiornika internetowego z urządzeniem przesyłającym, musi być ono hostowane w miejscu, w którym może ono być dostępne. Jeśli masz już dostępny serwer obsługujący https, pomiń poniższe instrukcje i zanotuj adres URL. Będzie on potrzebny w następnej sekcji.

Jeśli nie masz serwera, którego możesz użyć, możesz użyć Hostingu Firebase lub ngrok.

Uruchom serwer

Po skonfigurowaniu wybranej usługi otwórz app-start i uruchom serwer.

Zanotuj adres URL hostowanego odbiornika. Użyjesz ich w następnej sekcji.

4. Rejestrowanie aplikacji w Konsoli programisty Cast

Musisz zarejestrować swoją aplikację, aby móc używać niestandardowego odbiornika (umieszczonego w tym module) na urządzeniach Chromecast. Po zarejestrowaniu aplikacji otrzymasz identyfikator, którego aplikacja nadawcy musi używać do wykonywania wywołań interfejsu API – na przykład do uruchamiania aplikacji odbiornika.

Obraz konsoli programisty Google Cast SDK z wyróżnionym przyciskiem „Dodaj nową aplikację”

Kliknij „Dodaj nową aplikację”.

Obraz ekranu „Nowa aplikacja odbiornika” z zaznaczoną opcją „Niestandardowy odbiornik”

Wybierz „Niestandardowy odbiornik”, nad którym właśnie pracujemy.

Obraz ekranu „Nowy niestandardowy odbiornik” przedstawiający adres URL wpisany w polu „Adres URL aplikacji odbiornika”

Wpisz szczegóły nowego odbiorcy. Pamiętaj, by użyć adresu URL z końca adresu.

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

Musisz też zarejestrować urządzenie Google Cast, aby mieć dostęp do aplikacji odbiornika przed jego opublikowaniem. Udostępniona aplikacja odbiornika będzie dostępna na wszystkich urządzeniach Google Cast. Na potrzeby tego ćwiczenia zalecamy korzystanie z nieopublikowanej aplikacji odbiornika.

Obraz konsoli programisty Google Cast SDK z zaznaczonym przyciskiem „Dodaj nowe urządzenie”

Kliknij „Dodaj nowe urządzenie”.

Obraz okna „Dodaj odbiornik Cast”

Wpisz numer seryjny na odwrocie urządzenia przesyłającego i nadaj mu opisową nazwę. Możesz też go znaleźć, przesyłając ekran z Chrome w konsoli 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 ponownie uruchomić urządzenie przesyłające.

5. Uruchamianie przykładowej aplikacji

Logo Google Chrome

Czekamy, aż nowa aplikacja odbiorniku będzie gotowa do testów, i zobaczmy, jak wygląda przykładowa aplikacja. Odbiornik, który stworzymy, będzie mógł odtwarzać multimedia za pomocą strumieniowego przesyłania danych z adaptacyjną szybkością transmisji bitów (z przykładowego materiału zakodowanego na potrzeby dynamicznego przesyłania adaptacyjnego przez HTTP (DASH).

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

Obraz karty „Sterowanie łączeniem i rejestrowaniem” w narzędziu Command and Control (CaC)

  1. Zobaczysz nasze narzędzie CAC.
  2. Użyj domyślnego przykładowego identyfikatora „CC1AD845” i kliknij przycisk „Ustaw identyfikator aplikacji”.
  3. Kliknij przycisk Cast w lewym górnym rogu i wybierz swoje urządzenie Google Cast.

Obraz karty „Cast Connect & Logger Controls” w narzędziu Command and Control (CaC) wskazującym, że jest ona połączona z aplikacją odbiornika

  1. Otwórz kartę „Wczytaj multimedia” u góry.

Obraz karty „Load Media” narzędzia 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, który pokaże, jak wygląda podstawowa funkcja odbiornika przy użyciu domyślnego odbiornika.

6. Przygotowywanie projektu startowego

Musimy dodać obsługę Google Cast do pobranej aplikacji. Oto terminologia Google Cast, którą będziemy wykorzystywać podczas ćwiczeń z programowania:

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

Teraz możesz kontynuować pracę nad projektem dla początkujących, korzystając z ulubionego edytora tekstu:

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

Ćwiczenia z programowania powinny być dostosowane do zmian wprowadzanych przez użytkownika http-server. Jeśli się nie rozpocznie, spróbuj go zamknąć i ponownie uruchomić http-server.

Projektowanie aplikacji

Aplikacja odbiornika inicjuje sesję przesyłania i przełącza w tryb gotowości do momentu, gdy pojawi się żądanie LOAD (czyli polecenia odtworzenia multimediów).

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

index.html

Ten plik HTML będzie zawierać interfejs naszej aplikacji odbiornika. Na razie jest pusty i dodamy do niego w całym laboratorium kodu.

odbiornik.js

Ten skrypt będzie zarządzał wszystkimi funkcjami odbiornika naszej aplikacji odbiornika. Obecnie jest to po prostu pusty plik, ale w następnej sekcji zmienimy go w pełni działający odbiornik w kilku wierszach kodu.

7. Podstawowy odbiornik Cast

Podstawowy odbiornik rozpocznie inicjowanie sesji przesyłania przy uruchamianiu. Jest to konieczne, aby poinformować wszystkich połączonych aplikacji nadawcy, które odesłały odbiornik. Nowy pakiet SDK jest wstępnie skonfigurowany do obsługi multimediów ze strumieniową transmisją danych z adaptacyjną szybkością transmisji bitów (w przypadku DASH, HLS i Płynnego przesyłania strumieniowego) i plików MP4. Spróbujmy.

Inicjacja

Dodaj do nagłówka ten kod (index.html):

<head>
  ...

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

Dodaj następujący kod do index.html <body> przed wczytaniem footer> receiver.js,, aby zapewnić odbiorcy pakiet SDK z miejscem na wyświetlenie domyślnego interfejsu odbiornika, który jest dodawany do dodanego skryptu.

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

Teraz musimy zainicjować pakiet SDK w aplikacji js/receiver.js. Składa się on z tych elementów:

  • uzyskiwanie odniesienia do CastReceiverContext, Twojego głównego punktu wejścia do całego pakietu SDK odbiornika
  • przechowując odwołanie do PlayerManager, obiekt obsługujący odtwarzanie, dostarczając wszystkie haczyki, które należy podłączyć we własnej logice
  • inicjowanie pakietu SDK przez wywołanie start() na CastReceiverContext

Dodaj do js/receiver.js.

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

context.start();

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

Na potrzeby tego ćwiczenia użyj narzędzia CaC, aby wypróbować nowy odbiornik.

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

Obraz karty „Sterowanie łączeniem i rejestrowaniem” w narzędziu Command and Control (CaC)

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

Przesyłanie multimediów

Aby umożliwić odtwarzanie multimediów na urządzeniu Cast, musisz wykonać te czynności:

  1. Nadawca tworzy obiekt MediaInfo JSON z pakietu SDK Cast, 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 odtwarzać treści.
  4. Odbiorca monitoruje i monitoruje stan multimediów.
  5. Nadawca wysyła polecenia odtwarzania do odbiorcy, aby kontrolować odtwarzanie na podstawie interakcji użytkownika z aplikacją nadawcy.

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

Prawdziwy nadawca używa w MediaInfo.contentId identyfikatora multimediów właściwego dla aplikacji. Odbiorca używa contentId jako identyfikatora do wykonywania odpowiednich wywołań backendu interfejsu API, aby rozpoznać faktyczny URL zasobu i ustawić jego wartość na MediaInfo.contentUrl.. Może też zarządzać takimi zadaniami jak pozyskiwanie licencji DRM czy wstawianie informacji o przerwach na reklamę.

W następnej sekcji poszerzymy odbiornik o funkcję podobną do tej. Kliknij ikonę przesyłania i wybierz urządzenie, aby otworzyć odbiornik.

Obraz karty „Cast Connect & Logger Controls” w narzędziu Command and Control (CaC) wskazującym, że jest ona połączona z aplikacją odbiornika

Otwórz kartę „Wczytaj multimedia” i kliknij przycisk „Wczytaj według treści”. Odbiorca powinien zacząć odtwarzać przykładowe treści.

Obraz karty „Load Media” narzędzia Command and Control (CaC)

Gotowe do użycia funkcje pakietu SDK odbiornika:

  • Inicjowanie sesji przesyłania
  • Obsługa przychodzących LOAD żądań od nadawców zawierających zasoby możliwe do odtworzenia
  • Udostępnij podstawowy interfejs odtwarzacza gotowy do wyświetlenia na dużym ekranie.

Zapoznaj się z narzędziem CaC Tool i jego kodem, zanim przejdziesz do następnej sekcji. Będziemy w niej rozszerzać możliwości odbiornika o prosty przykładowy interfejs API, aby realizować przychodzące żądania LOAD od nadawców.

9. Integracja z zewnętrznym interfejsem API

Aby zadbać o to, aby większość deweloperów wchodziła w interakcje z odbiornikami w prawdziwych aplikacjach, modyfikujemy nasz 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ć URL zasobów reklamowych.

Aplikacje zwykle to robią, ponieważ:

  • Nadawca może nie znać adresu URL treści.
  • Aplikacja Cast obsługuje uwierzytelnianie, inne logiki biznesowe i wywołania interfejsu API bezpośrednio na odbiorniku.

Ta funkcja jest głównie implementowana 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 SDK. W tej sekcji zajmujemy się żądaniami LOAD, w przypadku których:

  • Przeczytaj przychodzące żądanie LOAD i jego niestandardowy contentId.
  • Wywołaj GET do naszego interfejsu API, aby wyszukać zasób strumieniowy za pomocą jego contentId.
  • Zmień żądanie LOAD przy użyciu adresu URL strumienia.
  • Zmodyfikuj obiekt MediaInformation, aby ustawić parametry typu strumienia.
  • Przekaż żądanie do pakietu SDK do odtworzenia lub odrzuć to polecenie, jeśli nie możemy znaleźć żądanych multimediów.

Udostępniamy przykładowy interfejs API, który pokazuje, jak za pomocą chwytliwych funkcji nawiązać połączenie z najczęściej używanymi zadaniami przy użyciu odbiornika.

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 wideo. Uwzględnia ona adresy URL obrazów plakatu w formacie PNG oraz strumieni DASH i HLS. Strumienie DASH i HLS wskazują zdemuksowane źródła wideo i dźwięku 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 (na przykład bbb, fbb_ad) na adres URL strumienia po wywołaniu odbiornika przy użyciu żądania LOAD.

Przechwytywanie żądania LOAD

W tym kroku utworzymy narzędzie do śledzenia obciążenia z funkcją wysyłającą żądanie XHR do hostowanego pliku JSON. Po otrzymaniu pliku JSON przeanalizujemy jego treść i ustawimy metadane. W kolejnych sekcjach dostosujemy parametry MediaInformation, aby określić typ treści.

Dodaj ten kod do pliku js/receiver.js, tuż 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 dowiesz się, jak skonfigurować właściwość media żądania wczytywania treści DASH.

Korzystanie z przykładowej zawartości DASH API

Po przygotowaniu modułu równoważenia obciążenia możemy określić typ treści na odbiorniku. Te informacje przekażą odbiornikowi adres URL playlisty reklamy nadrzędnej i typ MIME strumienia. Dodaj ten kod do pliku js/pickupr.js w tagu Promise() LOAD przechwytującego:

...
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 testowania tej funkcji, by spróbować załadować treści DASH. Jeśli zamiast tego chcesz przetestować wczytywanie treści HLS, przejdź do następnego kroku.

Korzystanie z przykładowych treści HLS

Przykładowy interfejs API zawiera treści HLS i DASH. Oprócz ustawienia contentType jak w poprzednim kroku, żądanie obciążenia będzie wymagało dodatkowych właściwości, aby można było używać przykładowych adresów URL HLS. Gdy odbiornik jest skonfigurowany do odtwarzania strumieni HLS, domyślnym typem kontenera jest strumień transportu (TS). Jeśli odbiorca zmieni tylko właściwość contentUrl, odbiorca spróbuje otworzyć przykładowe strumienie MP4 w formacie TS. W żądaniu wczytania obiekt MediaInformation należy zmodyfikować, dodając dodatkowe właściwości, aby odbiorca wiedział, że treści są w formacie MP4, a nie TS. Aby zmodyfikować właściwości contentUrl i contentType, do pliku js/odbiornika. 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

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

Otwórz kartę „Wczytaj multimedia”. Tym razem usuń tekst w polu „URL zawartości” obok przycisku „Wczytaj według treści”, co zmusi nas do wysłania żądania LOAD zawierającego tylko odwołanie do contentId do naszych multimediów.

Obraz karty „Load Media” narzędzia Command and Control (CaC)

Zakładając, że wszystko się zgadzało z modyfikacjami odbiornika, narzędzie do przechwytywania powinno przekształcać obiekt MediaInfo w coś, co pakiet SDK może odtwarzać na ekranie.

Kliknij przycisk „Załaduj według treści”, aby sprawdzić, czy multimedia są prawidłowo odtwarzane. W pliku content.json możesz zmienić identyfikator treści na inny.

10. Optymalizacja pod kątem inteligentnych ekranów

Inteligentne ekrany to urządzenia z funkcją dotykową, która umożliwia aplikacjom odbiornika obsługę sterowania dotykowego.

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

Dostęp do elementów sterujących interfejsu

Obiekt elementów sterujących interfejsu inteligentnych ekranów można uzyskać za pomocą 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 elementu <cast-media-player>, musisz ustawić touchScreenOptimizedApp w CastReceiverOptions. W tym ćwiczeniu z programowania używamy elementu <cast-media-player>.

context.start({ touchScreenOptimizedApp: true });

Do każdego boksu są przypisywane domyślne przyciski sterujące (MetadataType i MediaStatus.supportedMediaCommands).

Elementy sterujące filmem

W przypadku systemów MetadataType.MOVIE, MetadataType.TV_SHOW i MetadataType.GENERIC obiekt interfejsu UI dotyczący inteligentnych ekranów będzie wyświetlany w poniższym przykładzie.

Obraz przedstawiający odtwarzanie filmu z nałożonymi elementami 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

Elementy sterujące dźwiękiem

W przypadku MetadataType.MUSIC_TRACK obiekt elementów interfejsu interfejsu inteligentnych ekranów będzie wyświetlany poniżej:

Obraz przedstawiający odtwarzanie muzyki z elementami sterującymi nałożonymi na film

  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

Aktualizowanie obsługiwanych poleceń multimedialnych

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

Jeśli wartość supportedMediaCommands jest równa ALL_BASIC_MEDIA, domyślny układ sterujący jest wyświetlany poniżej:

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

Jeśli wartość supportedMediaCommands jest równa ALL_BASIC_MEDIA | QUEUE_PREV | QUEUE_NEXT, domyślny układ sterujący jest wyświetlany poniżej:

Obraz elementów sterujących odtwarzaczem: przycisk postępu, przycisk „Odtwórz”, „Przeskocz do przodu” i „Pomiń do tyłu” oraz przyciski „Poprzednia” i „Kolejka” są włączone

Gdy wartości obsługiwanych multimediówMediaCommand jest równa PAUSE | QUEUE_PREV | QUEUE_NEXT, domyślny układ sterujący wygląda tak:

Obraz elementów sterujących odtwarzaczem: pasek postępu, przycisk „Odtwórz” oraz przyciski „Kolejka” i „Kolejka”

Gdy ścieżki tekstowe są dostępne, przycisk napisów zawsze będzie widoczny na stronie SLOT_1.

Obraz elementów sterujących odtwarzaczem: pasek postępu, przyciski „Odtwórz”, „Przeskocz do przodu” i „Pomiń do tyłu”, „Kolejka” i „Kolejka” oraz włączone „Napisy”

Aby dynamicznie zmienić wartość supportedMediaCommands po uruchomieniu kontekstu odbiornika, możesz wywołać PlayerManager.setSupportedMediaCommands, aby zastąpić tę wartość. Możesz też dodać nowe polecenie za pomocą polecenia addSupportedMediaCommands lub usunąć istniejące polecenie za pomocą removeSupportedMediaCommands.

Dostosowywanie przycisków sterujących

Możesz dostosować elementy sterujące za pomocą polecenia PlayerDataBinder. Dodaj ten kod do pliku js/receiver.js poniżej elementów dotykowych, aby ustawić pierwszy boks 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. Przeglądanie przeglądania multimediów na inteligentnych ekranach

Przeglądanie multimediów to funkcja odbiornika CAF, która umożliwia użytkownikom poznawanie dodatkowych treści na urządzeniach dotykowych. Aby to zrobić, użyj PlayerDataBinder do ustawienia interfejsu użytkownika BrowseContent. Możesz następnie uzupełnić go polem BrowseItems na podstawie treści, którą chcesz wyświetlać.

Przeglądaj zawartość

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

Obraz interfejsu Przeglądaj treści przedstawiający 2 miniatury filmów i 1/3 ich zawartości

  1. BrowseContent.title
  2. BrowseContent.items

Format obrazu

Użyj targetAspectRatio property, aby wybrać najlepszy współczynnik proporcji dla zasobów graficznych. Pakiet SDK odbiornika CAF obsługuje 3 współczynniki proporcji: SQUARE_1_TO_1, PORTRAIT_2_TO_3, LANDSCAPE_16_TO_9.

PrzeglądajElement

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

Obraz interfejsu Przeglądaj treści przedstawiający 2 miniatury filmów i 1/3 ich zawartości

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

Ustawianie danych przeglądania multimediów

Aby udostępnić listę multimediów do przeglądania, zadzwoń pod numer setBrowseContent. Dodaj ten kod do pliku js/receiver.js pod plikiem playerDataBinder i w odbiorniku MEDIA_CHANGED, aby ustawić elementy przeglądania na potrzeby tytułu „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 LOAD, aby zmapować request.media.contentId na request.media.entity z elementu przeglądania multimediów:

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ć obiekt BrowseContent na null, aby usunąć interfejs przeglądania internetu.

12. Debugowanie aplikacji odbiornika

Pakiet SDK odbiornika umożliwia deweloperom łatwe debugowanie aplikacji odbiornika przy użyciu interfejsu CastDebugLogger API oraz towarzyszącego narzędzia Command and Control (CaC) do przechwytywania dzienników.

Zdarzenie inicjujące

Aby włączyć ten interfejs API, dodaj do pliku index.html skrypt źródłowy CastDebugLogger. Źródło należy zadeklarować w tagu <head> po deklaracji pakietu SDK odbiornika.

<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 sekcji js/receiver.js u góry pliku oraz poniżej 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 pojawia się nakładka DEBUG MODE.

Obraz filmu odtwarzanego z komunikatem „TRYB DEBUGOWANIA” na czerwonym tle w lewym górnym rogu ramki

Rejestrowanie zdarzeń odtwarzacza

CastDebugLogger pozwala łatwo rejestrować zdarzenia odtwarzacza, które są uruchamiane przez pakiet SDK odbiornika CAF, oraz używać różnych poziomów rejestrowania w celu rejestrowania danych zdarzenia. Konfiguracja loggerLevelByEvents za pomocą cast.framework.events.EventType i cast.framework.events.category określa, które zdarzenia mają być rejestrowane.

Dodaj ten kod pod deklaracją castDebugLogger, aby zarejestrować, gdy następuje uruchomienie zdarzenia CORE odtwarzacza lub gdy wysyłana jest zmiana 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 dziennika i tagi niestandardowe

Interfejs CastDebugLogger API pozwala tworzyć komunikaty logu, które pojawiają się w nakładce debugowania odbiornika w różnych kolorach. Dostępne są te metody logów uporządkowane 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 logowania pierwszym parametrem jest tag niestandardowy. Może to być dowolny ciąg identyfikujący Ciebie. CastDebugLogger do filtrowania logów używa tagów. Sposób używania tagów został szczegółowo wyjaśniony poniżej. Drugi parametr to komunikat logu.

Aby pokazać, jak działają logi, dodaj logi do przechwytywania 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 wiadomości mają być wyświetlane w nakładce debugowania, ustaw poziom rejestrowania w loggerLevelByTags tagu niestandardowym. Na przykład włączenie tagu niestandardowego na poziomie logu cast.framework.LoggerLevel.DEBUG spowoduje wyświetlenie wszystkich wiadomości dodanych z komunikatami o błędach, ostrzeżeniami, informacjami i debugowaniem. Włączenie tagu niestandardowego na poziomie WARNING spowoduje wyświetlanie tylko komunikatów o błędach i ostrzeżeń.

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

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

Dziennik debugowania Cast zapewnia nakładkę debugowania na odbiorniku, aby wyświetlać na urządzeniu przesyłającym niestandardowe komunikaty logu. Użyj przycisku showDebugLogs, aby przełączyć nakładkę debugowania, i clearDebugLogs, aby wyczyścić komunikaty logu w nakładce.

Dodaj 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, listę komunikatów logu debugowania na przezroczystym tle nad ramką wideo

13. Gratulacje

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

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