1. Przegląd

Z tego ćwiczenia z programowania dowiesz się, jak utworzyć niestandardową aplikację odbiornika internetowego do odtwarzania treści na urządzeniach obsługujących Cast.
Co to jest Google Cast?
Google Cast umożliwia przesyłanie treści z urządzenia mobilnego na telewizor. Użytkownicy mogą wtedy używać urządzenia mobilnego lub przeglądarki Chrome na komputerze 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 dźwiękowym). Pakiet Cast SDK udostępnia niezbędne komponenty interfejsu na podstawie listy kontrolnej projektu Google Cast.
Lista kontrolna projektu Google Cast została opracowana, aby zapewnić prostotę i przewidywalność korzystania z Cast na wszystkich obsługiwanych platformach. Więcej informacji
Co będziemy tworzyć?
Po ukończeniu tego kursu będziesz mieć aplikację HTML5, która będzie działać jako Twój własny odbiornik niestandardowy, który może wyświetlać treści wideo na urządzeniach obsługujących Cast.
Czego się nauczysz
- Jak przygotować się do tworzenia odbiorników.
- Podstawowe informacje o odbiorniku obsługującym Casta, który jest oparty na platformie aplikacji Cast.
- Jak odbierać przesyłany film.
- Jak zintegrować narzędzie Debug Logger.
- Jak zoptymalizować odbiornik pod kątem inteligentnych wyświetlaczy.
Czego potrzebujesz
- Najnowsza wersja przeglądarki Google Chrome.
- usługi hostingowej HTTPS, takiej jak Hosting Firebase lub ngrok;
- Urządzenie przesyłające, np. Chromecast lub Android TV, skonfigurowane z dostępem do internetu.
- telewizor lub monitor z wejściem HDMI,
Doświadczenie
- Musisz mieć wcześniejszą wiedzę na temat tworzenia stron internetowych.
- Musisz też mieć doświadczenie w oglądaniu telewizji.
Jak zamierzasz korzystać z tego samouczka?
Jak oceniasz swoje doświadczenie w tworzeniu aplikacji internetowych?
Jak oceniasz oglądanie telewizji?
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 można było używać odbiornika internetowego z urządzeniem przesyłającym, musi on być hostowany w miejscu, do którego urządzenie przesyłające ma dostęp. Jeśli masz już serwer obsługujący protokół HTTPS, pomiń poniższe instrukcje i zanotuj adres URL, ponieważ będzie Ci potrzebny w następnej sekcji.
Jeśli nie masz serwera, którego możesz użyć, możesz skorzystać z Hostingu Firebase lub ngrok.
Uruchamianie serwera
Po skonfigurowaniu wybranej usługi otwórz app-start i uruchom serwer.
Zanotuj adres URL hostowanego odbiornika. Będzie on potrzebny w następnej sekcji.
4. Rejestrowanie aplikacji w Konsoli programisty Cast
Aby móc uruchamiać na urządzeniach Chromecast niestandardowy odbiornik, taki jak ten utworzony w tym ćwiczeniu, musisz zarejestrować aplikację. Po zarejestrowaniu aplikacji otrzymasz identyfikator aplikacji, którego aplikacja wysyłająca musi używać do wykonywania wywołań interfejsu API, np. do uruchamiania aplikacji odbierającej.

Kliknij „Dodaj nową aplikację”.

Wybierz „Odbiornik niestandardowy” – to właśnie tworzymy.

Wpisz dane nowego odbiorcy, używając adresu URL, który został Ci przypisany.
w ostatniej sekcji. Zanotuj identyfikator aplikacji przypisany do nowego odbiornika.
Musisz też zarejestrować urządzenie przesyłające Google Cast, aby przed opublikowaniem aplikacji odbiornika mogło ono uzyskać do niej dostęp. Po opublikowaniu aplikacji odbiornika będzie ona dostępna na wszystkich urządzeniach Google Cast. Na potrzeby tego modułu zalecamy pracę z nieopublikowaną aplikacją odbiorcy.

Kliknij „Dodaj nowe urządzenie”.

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 podczas korzystania z Konsoli programisty Google Cast SDK.
Zanim odbiornik i urządzenie będą gotowe do testowania, minie 5–15 minut. Po odczekaniu 5–15 minut musisz ponownie uruchomić urządzenie przesyłające.
5. Uruchamianie przykładowej aplikacji

Zanim nasza nowa aplikacja odbiornika będzie gotowa do testowania, zobaczmy, jak wygląda przykładowa ukończona aplikacja odbiornika. Odbiornik, który zamierzamy utworzyć, będzie w stanie odtwarzać multimedia przy użyciu strumieniowego przesyłania danych z adaptacyjną szybkością transmisji bitów (będziemy używać przykładowych treści zakodowanych na potrzeby dynamicznego adaptacyjnego strumieniowego przesyłania danych przez HTTP (DASH)).
W przeglądarce otwórz narzędzie do zarządzania i kontroli.

- Powinno się wyświetlić nasze narzędzie CaC.
- Użyj domyślnego przykładowego identyfikatora odbiornika „CC1AD845” i kliknij przycisk „Set App ID” (Ustaw identyfikator aplikacji).
- W lewym górnym rogu kliknij przycisk Cast i wybierz urządzenie przesyłające Google Cast.

- U góry kliknij kartę „Wczytaj multimedia”.

- Aby odtworzyć przykładowy film, kliknij przycisk „Wczytaj według treści”.
- Film zacznie się odtwarzać na urządzeniu przesyłającym Google Cast, aby pokazać, jak wygląda podstawowa funkcjonalność odbiornika przy użyciu odbiornika domyślnego.
6. Przygotowywanie projektu początkowego
Musimy dodać obsługę Google Cast do pobranej aplikacji startowej. W tym ćwiczeniu będziemy używać tych terminów związanych z Google Cast:
- aplikacja nadawcy jest uruchomiona na urządzeniu mobilnym lub laptopie,
- na urządzeniu przesyłającym działa aplikacja odbiornika;
Teraz możesz rozbudowywać projekt początkowy za pomocą ulubionego edytora tekstu:
- W pobranych przykładowych kodach wybierz katalog

app-start. - Otwórz
js/receiver.jsiindex.html
Pamiętaj, że w trakcie wykonywania tego samouczka http-server powinno wykrywać wprowadzane przez Ciebie zmiany. Jeśli zauważysz, że tak nie jest, zamknij i ponownie uruchom http-server.
Projektowanie aplikacji
Aplikacja odbiorcy inicjuje sesję Cast i pozostaje w trybie gotowości, dopóki nie nadejdzie żądanie LOAD (czyli polecenie odtworzenia multimediów) od nadawcy.
Aplikacja składa się z jednego głównego widoku zdefiniowanego w pliku index.html i jednego pliku JavaScript o nazwie js/receiver.js, który zawiera całą logikę działania odbiornika.
index.html
Ten plik HTML będzie zawierać interfejs aplikacji odbiorcy. Na razie jest pusty, ale będziemy go uzupełniać w trakcie tego modułu.
receiver.js
Ten skrypt będzie zarządzać całą logiką aplikacji odbiorcy. Obecnie jest to tylko pusty plik, ale w następnej sekcji przekształcimy go w w pełni funkcjonalny odbiornik Cast za pomocą zaledwie kilku wierszy kodu.
7. podstawowy odbiornik Cast,
Podstawowy odbiornik Cast zainicjuje sesję Cast podczas uruchamiania. Jest to konieczne, aby poinformować wszystkie połączone aplikacje wysyłające, że uruchomienie odbiornika się powiodło. Dodatkowo nowy pakiet SDK jest wstępnie skonfigurowany do obsługi strumieniowego przesyłania multimediów z adaptacyjną szybkością transmisji bitów (przy użyciu DASH, HLS i Smooth Streaming) oraz zwykłych plików MP4. Spróbujmy.
Inicjowanie
Dodaj do pliku index.html w nagłówku ten kod:
<head>
...
<script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
</head>
Dodaj poniższy kod do index.html <body> przed <footer> loading receiver.js,, aby zapewnić pakietowi SDK odbiornika miejsce na wyświetlenie domyślnego interfejsu odbiornika, który jest dostarczany ze skryptem, który właśnie dodajesz.
<cast-media-player></cast-media-player>
Teraz musimy zainicjować pakiet SDK w js/receiver.js, który składa się z:
- uzyskanie odwołania do
CastReceiverContext, głównego punktu wejścia do całego pakietu SDK odbiornika; - przechowywanie odwołania do obiektu
PlayerManager, który obsługuje odtwarzanie i zapewnia wszystkie niezbędne punkty zaczepienia do włączenia własnej logiki niestandardowej; - inicjowanie pakietu SDK przez wywołanie
start()wCastReceiverContext;
Dodać te boty do pokoju „js/receiver.js”?
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
context.start();
8. Przesyłanie „podstawowych” treści wideo
Na potrzeby tych ćwiczeń z programowania użyj narzędzia CaC, aby wypróbować nowy odbiornik.
W przeglądarce otwórz narzędzie do zarządzania i kontroli.

W polu wpisz swój identyfikator aplikacji zarejestrowany wcześniej i kliknij „Set App ID” (Ustaw identyfikator aplikacji). Ta opcja nakazuje narzędziu używanie odbiornika podczas rozpoczynania sesji przesyłania.
Przesyłanie multimediów
Aby odtworzyć multimedia na urządzeniu przesyłającym, musisz wykonać te czynności:
- Nadawca tworzy obiekt
MediaInfoJSONz pakietu Cast SDK, który modeluje element multimedialny. - Nadawca łączy się z urządzeniem przesyłającym, aby uruchomić aplikację odbiornika.
- Odbiorca wczytuje obiekt
MediaInfoza pomocą żądaniaLOAD, aby odtworzyć treści. - Odbiornik monitoruje i śledzi stan multimediów.
- Nadawca wysyła do odbiornika polecenia odtwarzania, aby sterować odtwarzaniem na podstawie interakcji użytkownika z aplikacją nadawcy.
W pierwszej podstawowej próbie wypełnimy pole MediaInfo adresem URL odtwarzanego zasobu (przechowywanym w MediaInfo.contentUrl).
Prawdziwy nadawca używa w atrybucie MediaInfo.contentId identyfikatora multimediów specyficznego dla aplikacji. Odbiornik używa contentId jako identyfikatora do wykonywania odpowiednich wywołań interfejsu API backendu w celu rozpoznania rzeczywistego adresu URL zasobu i ustawienia go na MediaInfo.contentUrl. Odbiornik będzie też obsługiwać zadania takie jak uzyskiwanie licencji DRM czy wstawianie informacji o przerwach na reklamy.
W następnej sekcji rozszerzymy funkcjonalność odbiornika, aby mógł to robić. Na razie kliknij ikonę przesyłania i wybierz urządzenie, aby otworzyć odbiornik.

Otwórz kartę „Load Media” (Wczytaj multimedia) i kliknij przycisk „Load by Content” (Wczytaj według treści). Odbiornik powinien rozpocząć odtwarzanie przykładowych treści.

Pakiet SDK odbiornika od razu obsługuje:
- Inicjowanie sesji przesyłania
- Obsługuj przychodzące żądania
LOADod nadawców, które zawierają zasoby do odtworzenia. - Zapewnij podstawowy interfejs odtwarzacza gotowy do wyświetlania na dużym ekranie.
Zanim przejdziesz do następnej sekcji, w której rozszerzymy nasz odbiornik, aby komunikował się z prostym przykładowym interfejsem API w celu obsługi przychodzących LOAD żądań od nadawców, możesz zapoznać się z narzędziem CaC i jego kodem.
9. Integracja z zewnętrznym interfejsem API
Podobnie jak w przypadku większości deweloperów, którzy w aplikacjach działających w rzeczywistych warunkach korzystają z odbiorników Cast, zmodyfikujemy nasz odbiornik, aby obsługiwał żądania LOAD, które odwołują się do docelowych treści multimedialnych za pomocą klucza interfejsu API, zamiast wysyłać adres URL odtwarzanego zasobu.
Aplikacje zwykle robią to z tych powodów:
- Nadawca może nie znać adresu URL treści.
- Aplikacja Cast jest przeznaczona do obsługi uwierzytelniania, innej logiki biznesowej lub wywołań interfejsu API bezpośrednio na odbiorniku.
Ta funkcja jest zaimplementowana głównie w metodzie PlayerManager setMessageInterceptor(). Umożliwia to przechwytywanie wiadomości przychodzących według typu i modyfikowanie ich, zanim dotrą do wewnętrznego modułu obsługi wiadomości w pakiecie SDK. W tej sekcji zajmujemy się żądaniami LOAD, w przypadku których wykonamy te czynności:
- Przeczytaj przychodzące
LOADżądanie i jego niestandardowecontentId. - Wywołaj nasz interfejs API, aby wyszukać zasób, który można przesyłać strumieniowo, na podstawie jego
contentId.GET - Zmodyfikuj żądanie
LOAD, dodając adres URL transmisji. - Zmodyfikuj obiekt
MediaInformation, aby ustawić parametry typu strumienia. - Przekaż prośbę do pakietu SDK w celu odtworzenia lub odrzuć polecenie, jeśli nie możemy znaleźć żądanych multimediów.
Przykładowy interfejs API pokazuje punkty zaczepienia pakietu SDK do dostosowywania typowych zadań odbiornika, przy jednoczesnym zachowaniu w większości gotowego środowiska.
Przykładowy interfejs API
Otwórz w przeglądarce adres https://storage.googleapis.com/cpe-sample-media/content.json i zapoznaj się z naszym przykładowym katalogiem filmów. Treści zawierają adresy URL obrazów plakatów w formacie PNG, a także strumienie DASH i HLS. Strumienie DASH i HLS wskazują na zdemuksowane źródła wideo i audio przechowywane w kontenerach z plikami MP4 podzielonymi na fragmenty.
{
"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 odbiorcy za pomocą żądania LOAD.
Przechwyć żądanie LOAD
W tym kroku utworzymy przechwytujący wczytywanie z funkcją, która wysyła żądanie XHR do hostowanego pliku JSON. Po uzyskaniu JSON pliku przeanalizujemy jego zawartość 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 funkcji 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 wczytywania w przypadku treści DASH.
Korzystanie z przykładowych treści DASH API
Po przygotowaniu przechwytującego ładowanie określimy typ treści dla odbiorcy. Te informacje zawierają adres URL playlisty reklamy nadrzędnej i typ MIME strumienia. Dodaj ten kod do pliku js/receiver.js w LOAD interceptorze Promise():
...
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ć 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 API
Przykładowy interfejs API zawiera treści HLS i DASH. Oprócz ustawienia parametru contentType, tak jak w poprzednim kroku, żądanie wczytania będzie wymagać dodatkowych właściwości, aby można było używać adresów URL HLS przykładowego interfejsu API. Gdy odbiornik jest skonfigurowany do odtwarzania strumieni HLS, domyślnym oczekiwanym typem kontenera jest strumień transportowy (TS). W rezultacie odbiorca spróbuje otworzyć przykładowe strumienie MP4 w formacie TS, jeśli zmodyfikowana zostanie tylko właściwość contentUrl. W żądaniu wczytania należy zmodyfikować obiekt MediaInformation, dodając do niego dodatkowe właściwości, aby odbiorca wiedział, że treść jest typu MP4, a nie TS. Dodaj ten kod do pliku js/receiver.js w interceptorze wczytywania, 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 do sterowania i zarządzania (CaC) i ustaw identyfikator aplikacji na identyfikator aplikacji odbiorcy. Wybierz urządzenie za pomocą przycisku Cast.
Otwórz kartę „Wczytaj multimedia”. Tym razem usuń tekst w polu „Adres URL treści” obok przycisku „Wczytaj według treści”, co spowoduje, że nasza aplikacja wyśle żądanie LOAD zawierające tylko odwołanie contentId do naszych multimediów.

Zakładając, że zmiany w odbiorniku zostały wprowadzone prawidłowo, przechwytujący powinien przekształcić obiekt MediaInfo w formę, którą pakiet SDK może odtworzyć na ekranie.
Kliknij przycisk „Load by Content” (Wczytaj według treści), aby sprawdzić, czy multimedia są odtwarzane prawidłowo. Możesz zmienić identyfikator Content ID na inny w pliku content.json.
10. Optymalizacja pod kątem inteligentnych wyświetlaczy
Inteligentne wyświetlacze to urządzenia z funkcją dotykową, które umożliwiają aplikacjom odbiornika obsługę elementów sterujących z funkcją dotykową.
W tej sekcji dowiesz się, jak zoptymalizować aplikację odbiorcy uruchamianą na inteligentnych wyświetlaczach i jak dostosować elementy sterujące odtwarzacza.
Dostęp do elementów sterujących interfejsu
Do obiektu UI Controls na inteligentnych wyświetlaczach można uzyskać dostęp za pomocą funkcji cast.framework.ui.Controls.GetInstance(). Dodaj do pliku js/receiver.js ten kod 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 używamy elementu <cast-media-player>.
context.start({ touchScreenOptimizedApp: true });
Do każdego miejsca docelowego przypisywane są domyślne przyciski sterujące na podstawie MetadataType i MediaStatus.supportedMediaCommands.
Sterowanie odtwarzaniem
W przypadku MetadataType.MOVIE, MetadataType.TV_SHOW i MetadataType.GENERIC obiekt UI Controls dla inteligentnych wyświetlaczy będzie wyświetlany jak w poniższym przykładzie.

--playback-logo-imageMediaMetadata.subtitleMediaMetadata.titleMediaStatus.currentTimeMediaInformation.durationControlsSlot.SLOT_SECONDARY_1:ControlsButton.QUEUE_PREVControlsSlot.SLOT_PRIMARY_1:ControlsButton.SEEK_BACKWARD_30PLAY/PAUSEControlsSlot.SLOT_PRIMARY_2:ControlsButton.SEEK_FORWARD_30ControlsSlot.SLOT_SECONDARY_2:ControlsButton.QUEUE_NEXT
Sterowanie dźwiękiem
W przypadku MetadataType.MUSIC_TRACK obiekt elementów sterujących interfejsu na inteligentnych ekranach będzie wyświetlany w ten sposób:

--playback-logo-imageMusicTrackMediaMetadata.albumNameMusicTrackMediaMetadata.titleMusicTrackMediaMetadata.albumArtistMusicTrackMediaMetadata.images[0]MediaStatus.currentTimeMediaInformation.durationControlsSlot.SLOT_SECONDARY_1:ControlsButton.NO_BUTTONControlsSlot.SLOT_PRIMARY_1:ControlsButton.QUEUE_PREVPLAY/PAUSEControlsSlot.SLOT_PRIMARY_2:ControlsButton.QUEUE_NEXTControlsSlot.SLOT_SECONDARY_2:ControlsButton.NO_BUTTON
Aktualizowanie obsługiwanych poleceń multimedialnych
Obiekt UI Controls określa też, czy ControlsButton jest wyświetlany, na podstawie wartości MediaStatus.supportedMediaCommands.
Gdy wartość supportedMediaCommands jest równa ALL_BASIC_MEDIA, domyślny układ elementów sterujących będzie wyglądać tak:

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

Gdy wartość supportedMediaCommands wynosi PAUSE | QUEUE_PREV | QUEUE_NEXT, domyślny układ sterowania będzie wyglądać tak:

Gdy ścieżki tekstowe są dostępne, przycisk napisów jest zawsze wyświetlany w pozycji SLOT_1.

Aby dynamicznie zmienić wartość supportedMediaCommands po rozpoczęciu kontekstu odbiorcy, możesz wywołać PlayerManager.setSupportedMediaCommands, aby zastąpić wartość. Możesz też dodać nowe polecenie, klikając addSupportedMediaCommands, lub usunąć istniejące polecenie, klikając removeSupportedMediaCommands.
Dostosowywanie przycisków sterujących
Możesz dostosować elementy sterujące za pomocą funkcji PlayerDataBinder. Dodaj ten kod do pliku js/receiver.js poniżej elementu touchControls, aby ustawić pierwszy slot 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 PlayerDataBinder do ustawienia interfejsu BrowseContent. Następnie możesz wypełnić go BrowseItems na podstawie treści, które chcesz wyświetlać.
BrowseContent
Poniżej znajdziesz przykład interfejsu BrowseContent i jego właściwości:

BrowseContent.titleBrowseContent.items
Współczynnik proporcji
Użyj ikony targetAspectRatio property, aby wybrać najlepszy współczynnik proporcji dla komponentów z obrazem. Pakiet CAF Receiver SDK obsługuje 3 formaty obrazu: SQUARE_1_TO_1, PORTRAIT_2_TO_3 i LANDSCAPE_16_TO_9.
BrowseItem
Użyj BrowseItem, aby wyświetlić tytuł, podtytuł, czas trwania i obraz każdego elementu:

BrowseItem.imageBrowseItem.durationBrowseItem.titleBrowseItem.subtitle
Ustawianie danych przeglądania multimediów
Aby udostępnić listę treści multimedialnych do przeglądania, wywołaj funkcję setBrowseContent. Dodaj poniższy kod do pliku js/receiver.js pod tagiem playerDataBinder i w detektorze zdarzeń MEDIA_CHANGED, aby ustawić przeglądanie elementów z tytułem „Następne”.
// 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 spowoduje uruchomienie LOAD interfejsu. Dodaj ten kod do interfejsu 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 multimediów.
12. Debugowanie aplikacji odbiorczych
Pakiet Cast Receiver SDK zapewnia programistom kolejną opcję łatwego debugowania aplikacji odbiornika za pomocą interfejsu CastDebugLogger API i powiązanego narzędzia Command and Control (CaC) do rejestrowania dzienników.
Zdarzenie inicjujące
Aby zintegrować interfejs API, dodaj skrypt źródłowy CastDebugLogger do pliku index.html. Źródło należy zadeklarować w tagu <head> po deklaracji pakietu SDK odbiornika Cast.
<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 u góry i pod 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 rejestrowanie debugowania jest włączone, na odbiorniku wyświetli się nakładka z symbolem DEBUG MODE.

Rejestrowanie zdarzeń odtwarzacza
Za pomocą CastDebugLogger możesz łatwo rejestrować zdarzenia odtwarzacza wywoływane przez pakiet SDK odbiornika CAF i używać różnych poziomów rejestrowania do rejestrowania danych zdarzeń. Konfiguracja loggerLevelByEvents używa pól cast.framework.events.EventType i cast.framework.events.category do określania, które zdarzenia będą rejestrowane.
Aby rejestrować zdarzenie CORE odtwarzacza lub zmianę mediaStatus, dodaj ten kod pod deklaracją castDebugLogger:
// 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 logów i tagi niestandardowe
Interfejs CastDebugLogger API umożliwia tworzenie komunikatów dziennika, które pojawiają się na nakładce debugowania odbiornika w różnych kolorach. Dostępne są te metody rejestrowania, 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 rejestrowania pierwszym parametrem jest tag niestandardowy. Może to być dowolny ciąg znaków, który ma dla Ciebie znaczenie. CastDebugLogger używa tagów do filtrowania dzienników. Sposób używania tagów opisujemy szczegółowo poniżej. Drugi parametr to komunikat logu.
Aby zobaczyć logi w działaniu, dodaj je do LOAD interfejsu przechwytującego.
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);
}
});
});
});
Możesz określić, które wiadomości mają się wyświetlać na nakładce debugowania, ustawiając poziom rejestrowania w parametrze loggerLevelByTags dla każdego tagu niestandardowego. Na przykład włączenie tagu niestandardowego z poziomem logowania cast.framework.LoggerLevel.DEBUG spowoduje wyświetlenie wszystkich wiadomości dodanych z komunikatami o błędach, ostrzeżeniami, informacjami i komunikatami dziennika debugowania. 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 dla poziomu rejestratora, wszystkie komunikaty dziennika będą wyświetlane na 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
Rejestrator debugowania Cast 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łączać nakładkę debugowania, a klawisza clearDebugLogs, aby wyczyścić wiadomości dziennika na nakładce.
Dodaj ten 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();
}
});

13. Gratulacje
Wiesz już, jak utworzyć niestandardową aplikację odbiornika internetowego za pomocą pakietu Cast Web Receiver SDK.
Więcej informacji znajdziesz w przewodniku dla programistów dotyczącym odbiornika internetowego.