1. Omówienie
Z tego ćwiczenia z programowania dowiesz się, jak utworzyć aplikację Custom Web Receiver, która umożliwia odtwarzanie treści na urządzeniach z wsparciem technologii 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.
Google Cast SDK umożliwia sterowanie aplikacją za pomocą urządzeń obsługujących Google Cast (np. telewizora lub systemu audio). Pakiet Cast SDK zapewnia niezbędne komponenty interfejsu zgodnie z listą kontrolną projektu Google Cast.
Lista kontrolna dotycząca projektowania Google Cast została przygotowana, aby zapewnić użytkownikom prostotę i przewidywalność korzystania z Casta na wszystkich obsługiwanych platformach. Więcej informacji
Co utworzymy?
Po ukończeniu tego ćwiczenia będziesz mieć aplikację HTML5, która będzie działać jako niestandardowy odbiornik i będzie wyświetlać treści wideo na urządzeniach obsługujących Google Cast.
Czego się nauczysz
- Jak przygotować się do tworzenia odbiornika.
- 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
- najnowsza wersja przeglądarki Google Chrome,
- Usługa hostingu HTTPS, np. Hosting Firebase lub ngrok.
- Urządzenie przesyłające Google Cast, takie jak Chromecast lub Android TV, skonfigurowane z dostępem do internetu.
- telewizor lub monitor z wejściem HDMI.
Doświadczenie
- Niezbędna jest do tego wiedza o programowaniu stron internetowych.
- Wymagamy też wcześniejszej wiedzy na temat oglądania telewizji. :)
Jak będziesz korzystać z tego samouczka?
Jak oceniasz swoje doświadczenia z tworzeniem aplikacji internetowych?
Jak oceniasz oglądanie telewizji?
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 używać odbiornika internetowego z urządzeniem Google Cast, musi on być hostowany w miejscu, do którego może dotrzeć urządzenie Google Cast. 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, możesz użyć hostingu Firebase lub ngrok.
Uruchamianie serwera
Po skonfigurowaniu wybranej usługi przejdź do app-start
i uruchom serwer.
Zapisz 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 aplikacji, którego aplikacja nadawcza musi używać do wykonywania wywołań interfejsu API, np. do uruchamiania aplikacji odbiorcy.
Kliknij „Dodaj nową aplikację”.
Wybierz „Odbiornik niestandardowy”, nad tym właśnie pracujemy.
Wpisz dane nowego odbiorcy. Pamiętaj, aby użyć adresu URL, który został utworzony.
w ostatniej sekcji. Zanotuj identyfikator aplikacji przypisany do nowego odbiornika.
Musisz też zarejestrować urządzenie Google Cast, aby mogło uzyskać dostęp do aplikacji odbiorczej przed jej opublikowaniem. Po opublikowaniu aplikacji odbiornika będzie ona dostępna na wszystkich urządzeniach Google Cast. Na potrzeby tego modułu zalecamy korzystanie z nieopublikowanej aplikacji odbiorczej.
Kliknij „Dodaj nowe urządzenie”.
Wpisz numer seryjny wydrukowany z tyłu urządzenia Cast i nadaj mu nazwę. Numer seryjny możesz też znaleźć, przesyłając ekran w Chrome, gdy otwierasz Konsolę programisty Google Cast SDK.
Urządzenie i odbiornik będą gotowe do testowania po 5–15 minutach. Po odczekaniu 5–15 minut musisz zrestartować urządzenie przesyłające.
5. Uruchamianie przykładowej aplikacji
Zanim nowa aplikacja odbiornika będzie gotowa do testowania, zobaczmy, jak wygląda gotowa aplikacja odbiornika. Odbiornik, który zamierzamy zbudować, będzie mógł odtwarzać media przy użyciu strumieniowego przesyłania danych z adaptacyjną szybkością transmisji bitów (użyjemy przykładowych treści zakodowanych w ramach dynamicznego adaptacyjnego strumieniowego przesyłania danych przez HTTP (DASH)).
W przeglądarce otwórz narzędzie Command and Control (CaC).
- Powinno się wyświetlić narzędzie CaC.
- Użyj domyślnej wartości „CC1AD845” przykładowy identyfikator odbiorcy i kliknij „Ustaw identyfikator aplikacji”. Przycisk
- Kliknij przycisk Cast w lewym górnym rogu i wybierz urządzenie Google Cast.
- U góry kliknij kartę „Load Media” (Wczytaj multimedia).
- Aby odtworzyć przykładowy film, kliknij przycisk „Wczytaj według treści”.
- 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
Musimy 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 nadawcy działa na urządzeniu mobilnym lub laptopie,
- na urządzeniu Google Cast działa aplikacja odbiornikowa.
Teraz możesz zacząć tworzyć projekt początkowy za pomocą ulubionego edytora tekstu:
- Wybierz katalog
app-start
z pobranego przykładowego kodu. - Otwórz
js/receiver.js
iindex.html
Podczas pracy z tym laboratorium kodu http-server
powinien rejestrować wprowadzane przez Ciebie zmiany. Jeśli nie, spróbuj zamknąć i ponownie uruchomić 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 pliku index.html
oraz 1 pliku JavaScript o nazwie js/receiver.js
zawierającego całą logikę potrzebną do działania odbiornika.
index.html
Ten plik HTML będzie zawierać interfejs 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ą aplikacji odbiorczej. Obecnie jest to pusty plik, ale w następnej sekcji zamienimy go w pełnofunkcyjny odbiornik Cast za pomocą kilku linii kodu.
7. Podstawowy odbiornik przesyłania treści
Podstawowy odbiornik Cast inicjuje sesję Cast po uruchomieniu. Jest to konieczne, aby można było poinformować wszystkie połączone aplikacje nadawcy, że udało się skomunikować się z odbiorcą. 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 gładkiego przesyłania strumieniowego) oraz prostych 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>
loading receiver.js,
, aby dać pakietowi SDK odbiornika miejsce na wyświetlenie domyślnego interfejsu odbiornika, który jest dostarczany z dopiero co dodanym skryptem.
<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 dodania własnych logiki. - inicjuję pakiet SDK, wywołując interfejs
start()
CastReceiverContext
Dodaj te elementy do js/receiver.js
.
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
context.start();
8. Przesyłanie „podstawowych” treści wideo
W ramach tego ćwiczenia z programowania użyj narzędzia CaC, aby wypróbować nowy odbiornik.
Otwórz w przeglądarce narzędzie do zarządzania.
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żywa odbiornika.
Przesyłanie multimediów
Ogólnie rzecz biorąc, aby odtwarzać multimedia na urządzeniu przesyłającym, musisz spełnić te warunki:
- Nadawca tworzy obiekt
MediaInfo
JSON
z pakietu Cast SDK, który modeluje element multimedialny. - Aby uruchomić aplikację odbiorczą, nadawca łączy się z urządzeniem przesyłającym.
- Odbiorca wczytuje obiekt
MediaInfo
za pomocą żądaniaLOAD
, aby odtworzyć treści. - Odbiornik monitoruje i śledzi stan multimediów.
- Nadawca wysyła do odbiorcy polecenia odtwarzania, aby kontrolować odtwarzanie na podstawie interakcji użytkownika z aplikacją nadawcy.
W tym pierwszym podstawowym podejściu wypełnimy kolumnę MediaInfo
adresem URL odtwarzalnego zasobu (przechowywanego w kolumnie MediaInfo.contentUrl
).
Prawdziwy nadawca używa w polu MediaInfo.contentId
identyfikatora multimediów w ramach aplikacji. Odbiorca używa identyfikatora contentId
do wykonywania odpowiednich wywołań interfejsu API w celu rozwiązywania rzeczywistego adresu URL zasobu i ustawiania go jako MediaInfo.contentUrl.
. Odbiorca będzie też wykonywać takie zadania jak pozyskiwanie licencji DRM czy wstrzykiwanie informacji o przerwach na reklamę.
W następnej sekcji rozszerzymy odbiornik, aby wykonał właśnie taką czynność. Na razie kliknij ikonę Cast i wybierz urządzenie, żeby otworzyć odbiornik.
Otwórz kartę „Wczytaj multimedia” i kliknij przycisk „Wczytaj według treści”. Odbiornik powinien zacząć odtwarzać przykładowe treści.
Pakiet SDK odbiornika obsługuje:
- Inicjuję sesję przesyłania
- obsługiwać przychodzące
LOAD
żądania od nadawców zawierające zasoby do odtworzenia; - Zapewnij podstawowe elementy interfejsu odtwarzacza, które można wyświetlić na dużym ekranie.
Zanim przejdziesz do następnej sekcji, w której rozszerzymy odbiornik, aby komunikował się z interfejsem API prostego przykładu, który będzie obsługiwał przychodzące LOAD
żądania 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.
Aplikacje zwykle robią to, 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:
- Przeczytaj przychodzące żądanie
LOAD
i jego niestandardowe żądaniecontentId
. - Wywołaj nasz interfejs API za pomocą funkcji
GET
, aby wyszukać zasób z możliwością strumieniowania według jegocontentId
. - Zmodyfikuj żądanie
LOAD
, podając adres URL strumienia. - Zmodyfikuj obiekt
MediaInformation
, aby ustawić parametry typu strumienia. - Przekazać żądanie do pakietu SDK w celu odtworzenia lub odrzucić polecenie, jeśli nie możemy wyszukać żądanego pliku multimedialnego.
Podany przykładowy interfejs API prezentuje hooki pakietu SDK do dostosowywania typowych zadań odbiornika, wciąż korzystając z bardziej gotowych rozwiązań.
Przykładowe interfejsy 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 plakatu w formacie png oraz 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 do pliku js/receiver.js
ten kod 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 wczytania na potrzeby treści DASH.
Korzystanie z przykładowego treści interfejsu API DASH
Teraz, gdy mamy już przygotowany przechwytujący ładunek, określimy typ treści dla odbiornika. Te informacje przekażą odbiorcy adres URL głównej playlisty i typ MIME strumienia. Dodaj ten kod do pliku js/receiver.js w LOAD
interceptor's 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ć stronę z treściami DASH. Jeśli chcesz przetestować wczytywanie treści HLS, wykonaj następny krok.
Korzystanie z pliku HLS z przykładowym 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
. Dodatkowo dodaj 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 za pomocą przycisku Przesyłaj.
Przejdź do okna „Load Media” (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 wszystko działa jak należy 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”, aby sprawdzić, czy multimedia są odtwarzane prawidłowo. 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 funkcją dotykowej, które umożliwiają aplikacjom obsługę elementów sterujących dotykowych.
W tej sekcji opisaliśmy, jak zoptymalizować aplikację odbiornika podczas uruchamiania na wyświetlaczach smart TV oraz jak dostosować elementy sterujące odtwarzaczem.
Dostęp do elementów sterujących w interfejsie
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 do pliku js/receiver.js
ten kod nad sekcją 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ć wartość touchScreenOptimizedApp
w sekcji 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.
--playback-logo-image
MediaMetadata.subtitle
MediaMetadata.title
MediaStatus.currentTime
MediaInformation.duration
ControlsSlot.SLOT_SECONDARY_1
:ControlsButton.QUEUE_PREV
ControlsSlot.SLOT_PRIMARY_1
:ControlsButton.SEEK_BACKWARD_30
PLAY/PAUSE
ControlsSlot.SLOT_PRIMARY_2
:ControlsButton.SEEK_FORWARD_30
ControlsSlot.SLOT_SECONDARY_2
:ControlsButton.QUEUE_NEXT
Elementy sterujące 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:
--playback-logo-image
MusicTrackMediaMetadata.albumName
MusicTrackMediaMetadata.title
MusicTrackMediaMetadata.albumArtist
MusicTrackMediaMetadata.images[0]
MediaStatus.currentTime
MediaInformation.duration
ControlsSlot.SLOT_SECONDARY_1
:ControlsButton.NO_BUTTON
ControlsSlot.SLOT_PRIMARY_1
:ControlsButton.QUEUE_PREV
PLAY/PAUSE
ControlsSlot.SLOT_PRIMARY_2
:ControlsButton.QUEUE_NEXT
ControlsSlot.SLOT_SECONDARY_2
:ControlsButton.NO_BUTTON
Aktualizuję obsługiwane polecenia multimedialne
Obiekt elementów sterujących interfejsem użytkownika określa też, czy element ControlsButton
ma być widoczny, czy nie, na podstawie elementu MediaStatus.supportedMediaCommands
.
Gdy wartość parametru supportedMediaCommands
jest równa ALL_BASIC_MEDIA
, domyślny układ elementu sterującego 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ść SupportMediaCommands jest równa PAUSE | QUEUE_PREV | QUEUE_NEXT
, domyślny układ elementów sterujących jest wyświetlany w ten sposób:
Gdy dostępne są ścieżki z tekstem, przycisk napisów będzie zawsze widoczny w SLOT_1
.
Aby dynamicznie zmienić wartość supportedMediaCommands
po uruchomieniu kontekstu odbiornika, możesz wywołać funkcję PlayerManager.setSupportedMediaCommands
, aby zastąpić wartość. Możesz też dodać nowe polecenie za pomocą addSupportedMediaCommands
lub usunąć istniejące polecenie za pomocą 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 dotknięciem, 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 w CAF Receiver, która umożliwia użytkownikom przeglądanie dodatkowych treści na urządzeniach z ekranem dotykowym. Aby to zaimplementować, użyj interfejsu PlayerDataBinder
do skonfigurowania BrowseContent
. Następnie możesz wypełnić go wartościami 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:
BrowseContent.title
BrowseContent.items
Współczynnik proporcji
Użyj opcji targetAspectRatio property
, aby wybrać najlepszy współczynnik proporcji 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:
BrowseItem.image
BrowseItem.duration
BrowseItem.title
BrowseItem.subtitle
Ustawianie danych przeglądania multimediów
Aby wyświetlić listę treści multimedialnych, zadzwoń 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 odbiorczych
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ć interfejs API, dodaj CastDebugLogger
skrypt źródłowy w pliku index.html. Źródło powinno być zadeklarowane w elemencie <head> po deklaracji pakietu 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 nagłówkiem 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 napisem DEBUG MODE
.
Zdarzenia z dziennika odtwarzacza
Za pomocą pakietu CastDebugLogger
możesz łatwo rejestrować zdarzenia odtwarzacza, które są wywoływane przez pakiet SDK odbiornika CAF, oraz używać różnych poziomów rejestrowania do rejestrowania danych zdarzeń. Konfiguracja loggerLevelByEvents
wykorzystuje parametry cast.framework.events.EventType
i cast.framework.events.category
, aby określić, które zdarzenia będą logowane.
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 API CastDebugLogger umożliwia tworzenie komunikatów logowania, które wyświetlają się na nakładce debugowania odbiornika w różnych kolorach. 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 uznasz za odpowiedni. CastDebugLogger
używa tagów do filtrowania dzienników. Poniżej znajdziesz szczegółowe informacje o używaniu tagów. Drugi parametr to wiadomość logowania.
Aby wyświetlić logi w działaniu, dodaj je 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 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 pod kątem poziomu rejestratora, wszystkie komunikaty dziennika będą wyświetlane w przesłonie debugowania.
Poniżej rejestratora zdarzeń CORE
dodaj ten kod:
// 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
Narzędzie do debugowania Google Cast udostępnia nakładkę debugowania na urządzeniu odbiorczym, aby wyświetlać niestandardowe komunikaty dzienników na urządzeniu Google Cast. 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();
}
});
13. Gratulacje
Teraz już wiesz, jak utworzyć własną aplikację internetową odbiornika za pomocą pakietu SDK odbiornika internetowego przesyłania.
Więcej informacji znajdziesz w przewodniku dla programistów dotyczącym odbiornika internetowego.