Ta strona zawiera fragmenty kodu i opisy funkcji dostępnych w ramach aplikacji Custom Web Receiver.
- Element
cast-media-player
reprezentujący wbudowany interfejs odtwarzacza udostępniany z odbiornikiem internetowym. - niestandardowe stylizacje elementu
cast-media-player
, aby nadać styl różnym elementom interfejsu, takim jakbackground-image
,splash-image
ifont-family
; - Element skryptu do wczytywania modułu Web Receiver.
- kod JavaScriptu do przechwytywania wiadomości i obsługi zdarzeń;
- kolejka do automatycznego odtwarzania;
- Opcje konfiguracji odtwarzania.
- Opcje ustawiania kontekstu odbiornika internetowego.
- Opcje ustawiania poleceń obsługiwanych przez aplikację Web Receiver.
- Wywołanie JavaScriptu, które uruchamia aplikację Web Receiver.
Konfiguracja i opcje aplikacji
Konfigurowanie aplikacji
Klasa CastReceiverContext
to najzewnętrniejsza klasa udostępniana deweloperowi. Zarządza ona wczytywaniem bibliotek podrzędnych i obsługuje inicjowanie pakietu SDK odbiornika internetowego. Pakiet SDK udostępnia interfejsy API, które umożliwiają deweloperom konfigurowanie pakietu SDK za pomocą CastReceiverOptions
.
Te konfiguracje są oceniane raz na uruchomienie aplikacji i przekazywane do pakietu SDK podczas ustawiania opcjonalnego parametru w wywołaniu start
.
Przykład poniżej pokazuje, jak zastąpić domyślne zachowanie w przypadku wykrywania, czy połączenie nadawcy jest nadal aktywne. Jeśli odbiornik internetowy nie może się komunikować z nadawcą przez maxInactivity
sekund, wysyłane jest zdarzenie SENDER_DISCONNECTED
. Konfiguracja poniżej zastępuje ten czas oczekiwania. Może to być przydatne podczas debugowania problemów, ponieważ zapobiega zamykaniu sesji zdalnego debugera Chrome przez aplikację Web Receiver, gdy nie ma żadnych połączonych nadawców w stanie IDLE
.
const context = cast.framework.CastReceiverContext.getInstance();
const options = new cast.framework.CastReceiverOptions();
options.maxInactivity = 3600; // Development only
context.start(options);
Konfigurowanie odtwarzacza
Podczas wczytywania treści pakiet SDK Web Receiver umożliwia konfigurowanie zmiennych odtwarzania, takich jak informacje DRM, konfiguracje ponownych prób i obsługa żądań za pomocą cast.framework.PlaybackConfig
.
Te informacje są obsługiwane przez PlayerManager
i są oceniane w momencie tworzenia graczy. Odtwarzacze są tworzone za każdym razem, gdy do pakietu SDK odbiornika internetowego przekazywane jest nowe wczytanie. Zmiany w PlaybackConfig
wprowadzone po utworzeniu odtwarzacza są oceniane podczas następnego wczytania treści. Pakiet SDK udostępnia te metody służące do modyfikowania PlaybackConfig
:
CastReceiverOptions.playbackConfig
, aby zastąpić domyślne opcje konfiguracji podczas inicjowaniaCastReceiverContext
.PlayerManager.getPlaybackConfig()
, aby uzyskać bieżącą konfigurację.PlayerManager.setPlaybackConfig()
, aby zastąpić bieżącą konfigurację. To ustawienie jest stosowane do wszystkich kolejnych załadowań lub do czasu, gdy zostanie ponownie zastąpione.PlayerManager.setMediaPlaybackInfoHandler()
, aby zastosować dodatkowe konfiguracje tylko do wczytywanego zasobu multimedialnego, dodając je do bieżących konfiguracji. Obsługa jest wywoływana tuż przed utworzeniem odtwarzacza. Wprowadzone tutaj zmiany nie są trwałe i nie są uwzględniane w zapytaniach dogetPlaybackConfig()
. Gdy wczytany zostanie kolejny element multimedialny, ten moduł obsługi zostanie wywołany ponownie.
Przykład poniżej pokazuje, jak ustawić PlaybackConfig
podczas inicjowania CastReceiverContext
. Konfiguracja zastępuje wychodzące żądania pobierania plików manifestu. Obsługa określa, że żądania kontroli dostępu CORS powinny być wysyłane przy użyciu danych logowania, takich jak pliki cookie lub nagłówki autoryzacji.
const playbackConfig = new cast.framework.PlaybackConfig();
playbackConfig.manifestRequestHandler = requestInfo => {
requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});
Przykład poniżej pokazuje, jak zastąpić PlaybackConfig
za pomocą metody gettera i settera udostępnionej w PlayerManager
. To ustawienie konfiguruje odtwarzacz tak, aby wznowił odtwarzanie treści po załadowaniu 1 segmentu.
const playerManager =
cast.framework.CastReceiverContext.getInstance().getPlayerManager();
const playbackConfig = (Object.assign(
new cast.framework.PlaybackConfig(), playerManager.getPlaybackConfig()));
playbackConfig.autoResumeNumberOfSegments = 1;
playerManager.setPlaybackConfig(playbackConfig);
Przykład poniżej pokazuje, jak zastąpić wartość PlaybackConfig
w przypadku konkretnego żądania wczytania za pomocą obsługi informacji o odtwarzaniu multimediów. Obsługa wywołuje metodę getLicenseUrlForMedia
zaimplementowaną przez aplikację, aby uzyskać licenseUrl
z contentId
bieżącego elementu.
playerManager.setMediaPlaybackInfoHandler((loadRequestData, playbackConfig) => {
const mediaInformation = loadRequestData.media;
playbackConfig.licenseUrl = getLicenseUrlForMedia(mediaInformation.contentId);
return playbackConfig;
});
Detektor zdarzeń
Pakiet SDK odbiornika internetowego umożliwia aplikacji odbiornik internetowy obsługę zdarzeń odtwarzacza. Listener zdarzenia przyjmuje parametr cast.framework.events.EventType
(lub tablicę takich parametrów), który określa zdarzenia, które powinny go wywołać. Wstępnie skonfigurowane tablice elementówcast.framework.events.EventType
, które są przydatne podczas debugowania, można znaleźć w cast.framework.events.category
.
Parametr zdarzenia zawiera dodatkowe informacje o zdarzeniu.
Jeśli na przykład chcesz wiedzieć, kiedy następuje zmiana mediaStatus
, możesz użyć tej logiki do obsługi tego zdarzenia:
const playerManager =
cast.framework.CastReceiverContext.getInstance().getPlayerManager();
playerManager.addEventListener(
cast.framework.events.EventType.MEDIA_STATUS, (event) => {
// Write your own event handling code, for example
// using the event.mediaStatus value
});
Przechwytywanie wiadomości
Pakiet SDK odbiornika internetowego umożliwia aplikacji odbiornik internetowy przechwytywanie wiadomości i wykonywanie w nich niestandardowego kodu. Przechwytywanie wiadomości przyjmuje parametr cast.framework.messages.MessageType
, który określa, jakiego typu wiadomości ma być przechwytywane.
Przechwytujący powinien zwrócić zmodyfikowane żądanie lub obietnicę, która zwraca wartość zmodyfikowanego żądania. Zwrócenie wartości null
spowoduje, że nie zostanie wywołany domyślny moduł obsługi wiadomości. Więcej informacji znajdziesz w artykule Ładowanie multimediów.
Jeśli na przykład chcesz zmienić dane żądania wczytania, możesz je przechwycić i zmodyfikować, korzystając z tej logiki:
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, loadRequestData => {
const error = new cast.framework.messages.ErrorData(
cast.framework.messages.ErrorType.LOAD_FAILED);
if (!loadRequestData.media) {
error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
return error;
}
if (!loadRequestData.media.entity) {
return loadRequestData;
}
return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
loadRequestData.credentials)
.then(asset => {
if (!asset) {
throw cast.framework.messages.ErrorReason.INVALID_REQUEST;
}
loadRequestData.media.contentUrl = asset.url;
loadRequestData.media.metadata = asset.metadata;
loadRequestData.media.tracks = asset.tracks;
return loadRequestData;
}).catch(reason => {
error.reason = reason; // cast.framework.messages.ErrorReason
return error;
});
});
context.start();
Obsługa błędów
Gdy wystąpią błędy w przechwytywaniach wiadomości, aplikacja Web Receiver powinna zwrócić odpowiednią wartośćcast.framework.messages.ErrorType
i cast.framework.messages.ErrorReason
.
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, loadRequestData => {
const error = new cast.framework.messages.ErrorData(
cast.framework.messages.ErrorType.LOAD_CANCELLED);
if (!loadRequestData.media) {
error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
return error;
}
...
return fetchAssetAndAuth(loadRequestData.media.entity,
loadRequestData.credentials)
.then(asset => {
...
return loadRequestData;
}).catch(reason => {
error.reason = reason; // cast.framework.messages.ErrorReason
return error;
});
});
Przechwytywanie wiadomości a detektor zdarzeń
Oto najważniejsze różnice między przechwyceniem wiadomości a obsługą zdarzenia:
- Listener zdarzenia nie pozwala modyfikować danych żądania.
- Detektor zdarzeń najlepiej nadaje się do uruchamiania funkcji analitycznych lub niestandardowych.
playerManager.addEventListener(cast.framework.events.category.CORE,
event => {
console.log(event);
});
- Przechwytywanie wiadomości umożliwia odsłuchiwanie, przechwytywanie i modyfikowanie danych żądania.
- Przechwytywanie wiadomości najlepiej nadaje się do obsługi logiki niestandardowej w odniesieniu do danych żądania.
Wczytywanie multimediów
MediaInformation
zawiera wiele właściwości umożliwiających wczytywanie multimediów w wiadomości cast.framework.messages.MessageType.LOAD
, w tym entity
, contentUrl
i contentId
.
entity
to zalecana usługa do użycia w implementacji zarówno w aplikacji nadawcy, jak i odbiorcy. Usługa to adres URL precyzyjnego linku, który może być playlistą lub treścią multimedialną. Aplikacja powinna przeanalizować ten adres URL i wypełnić co najmniej jedno z tych 2 pozostałych pól.- Wartość
contentUrl
odpowiada adresowi URL odtwarzanego filmu, którego odtwarzacz użyje do załadowania treści. Adres URL może np. wskazywać plik manifestu DASH. contentId
może być adresem URL odtwarzanych treści (podobnym do tego w usłudzecontentUrl
) lub unikatowym identyfikatorem treści lub wczytywanej playlisty. Jeśli używasz tej właściwości jako identyfikatora, aplikacja powinna wypełnić adres URL odtwarzanego filmu w miejscucontentUrl
.
Zalecamy używanie parametru entity
do przechowywania rzeczywistego identyfikatora lub parametrów klucza, a parametru contentUrl
do przechowywania adresu URL multimediów. Przykład tego pokazano w następującym fragmencie kodu, w którym element entity
występuje w żądaniu LOAD
, a odtwarzalny element contentUrl
jest pobierany:
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, loadRequestData => {
...
if (!loadRequestData.media.entity) {
// Copy the value from contentId for legacy reasons if needed
loadRequestData.media.entity = loadRequestData.media.contentId;
}
return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
loadRequestData.credentials)
.then(asset => {
loadRequestData.media.contentUrl = asset.url;
...
return loadRequestData;
});
});
Funkcje urządzenia
Metoda getDeviceCapabilities
udostępnia informacje o podłączonym urządzeniu Cast oraz podłączonym do niego urządzeniu wideo lub audio. Metoda getDeviceCapabilities
zapewnia informacje o Asystencie Google, Bluetooth oraz podłączonych wyświetlaczach i urządzeniach audio.
Ta metoda zwraca obiekt, którego możesz użyć do wysłania zapytania, podając jeden z wymienionych typów, aby uzyskać informacje o możliwościach urządzenia. Wyliczenia są zdefiniowane w pliku cast.framework.system.DeviceCapabilities
.
Ten przykład sprawdza, czy urządzenie Web Receiver może odtwarzać HDR i Dolby Vision (DV) za pomocą odpowiednio klawiszy IS_HDR_SUPPORTED
i IS_DV_SUPPORTED
.
const context = cast.framework.CastReceiverContext.getInstance();
context.addEventListener(cast.framework.system.EventType.READY, () => {
const deviceCapabilities = context.getDeviceCapabilities();
if (deviceCapabilities &&
deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED]) {
// Write your own event handling code, for example
// using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED] value
}
if (deviceCapabilities &&
deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED]) {
// Write your own event handling code, for example
// using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED] value
}
});
context.start();
Obsługa interakcji z użytkownikiem
Użytkownik może korzystać z Twojej aplikacji Web Receiver za pomocą aplikacji nadawcy (w wersji internetowej, na Androida i iOS), poleceń głosowych na urządzeniach z Asystentem, elementów sterujących na inteligentnych ekranach oraz pilotów na urządzeniach z Androidem TV. Pakiet Cast SDK udostępnia różne interfejsy API, które umożliwiają aplikacji Web Receiver obsługę tych interakcji, aktualizowanie interfejsu użytkownika za pomocą stanów działań użytkownika oraz opcjonalne wysyłanie zmian do aktualizacji usług backendowych.
Obsługiwane polecenia dotyczące multimediów
Stany elementów sterujących w interfejsie są określane przez MediaStatus.supportedMediaCommands
w przypadku rozszerzonych kontrolerów nadawców na urządzeniach z iOS i Androidem, aplikacji odbiorczych i zdalnie sterujących na urządzeniach dotykowych oraz aplikacji odbiorczych na urządzeniach z Androidem TV. Gdy w usłudze włączona jest określona wartość binarna Command
, włączone są przyciski powiązane z tą akcją. Jeśli wartość nie zostanie ustawiona, przycisk będzie wyłączony. Te wartości można zmienić w Web Receiver:
- Użycie parametru
PlayerManager.setSupportedMediaCommands
do ustawienia konkretnego parametruCommands
- Dodawanie nowego polecenia za pomocą
addSupportedMediaCommands
- Usuwanie istniejącego polecenia za pomocą
removeSupportedMediaCommands
.
playerManager.setSupportedMediaCommands(cast.framework.messages.Command.SEEK |
cast.framework.messages.Command.PAUSE);
Gdy odbiorca przygotuje zaktualizowany plik MediaStatus
, będzie on zawierać zmiany w usłudze supportedMediaCommands
. Gdy stan zostanie wyemitowany, połączone aplikacje nadawców zaktualizują przyciski w interfejsie użytkownika.
Więcej informacji o obsługiwanych poleceniach multimedialnych i urządzeniach dotykowych znajdziesz w poradniku Accessing UI controls
.
Zarządzanie stanami działań użytkownika
Gdy użytkownicy korzystają z interfejsu lub wysyłają polecenia głosowe, mogą kontrolować odtwarzanie treści i właściwości powiązane z odtwarzanym elementem. Żądania dotyczące odtwarzania są obsługiwane automatycznie przez pakiet SDK. Prośby, które modyfikują właściwości odtwarzanego obecnie elementu, takie jak polecenie LIKE
, wymagają obsługi przez aplikację odbiorczą. Pakiet SDK udostępnia serię interfejsów API do obsługi tego typu żądań. Aby obsługiwać te prośby, musisz wykonać te czynności:
- Ustaw
MediaInformation
userActionStates
zgodnie z preferencjami użytkownika podczas wczytywania elementu multimedialnego. - Przechwytywanie wiadomości
USER_ACTION
i określanie wymaganego działania. - Zaktualizuj plik
MediaInformation
UserActionState
, aby zaktualizować interfejs.
Ten fragment kodu przechwytuje żądanie LOAD
i wypełnia pole MediaInformation
w obiekcie LoadRequestData
. W tym przypadku użytkownik lubi treści, które są wczytywane.
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, (loadRequestData) => {
const userActionLike = new cast.framework.messages.UserActionState(
cast.framework.messages.UserAction.LIKE);
loadRequestData.media.userActionStates = [userActionLike];
return loadRequestData;
});
Podany niżej fragment kodu przechwytuje wiadomość USER_ACTION
i zarządza wywołaniem backendu z żądaną zmianą. Następnie wywołuje funkcję aktualizacji UserActionState
na odbiorniku.
playerManager.setMessageInterceptor(cast.framework.messages.MessageType.USER_ACTION,
(userActionRequestData) => {
// Obtain the media information of the current content to associate the action to.
let mediaInfo = playerManager.getMediaInformation();
// If there is no media info return an error and ignore the request.
if (!mediaInfo) {
console.error('Not playing media, user action is not supported');
return new cast.framework.messages.ErrorData(messages.ErrorType.BAD_REQUEST);
}
// Reach out to backend services to store user action modifications. See sample below.
return sendUserAction(userActionRequestData, mediaInfo)
// Upon response from the backend, update the client's UserActionState.
.then(backendResponse => updateUserActionStates(backendResponse))
// If any errors occurred in the backend return them to the cast receiver.
.catch((error) => {
console.error(error);
return error;
});
});
Ten fragment kodu symuluje wywołanie usługi backendu. Funkcja sprawdza UserActionRequestData
, aby określić typ zmiany żądanej przez użytkownika, i wywołuje funkcję sieci tylko wtedy, gdy backend obsługuje tę czynność.
function sendUserAction(userActionRequestData, mediaInfo) {
return new Promise((resolve, reject) => {
switch (userActionRequestData.userAction) {
// Handle user action changes supported by the backend.
case cast.framework.messages.UserAction.LIKE:
case cast.framework.messages.UserAction.DISLIKE:
case cast.framework.messages.UserAction.FOLLOW:
case cast.framework.messages.UserAction.UNFOLLOW:
case cast.framework.messages.UserAction.FLAG:
case cast.framework.messages.UserAction.SKIP_AD:
let backendResponse = {userActionRequestData: userActionRequestData, mediaInfo: mediaInfo};
setTimeout(() => {resolve(backendResponse)}, 1000);
break;
// Reject all other user action changes.
default:
reject(
new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType.INVALID_REQUEST));
}
});
}
Ten fragment kodu pobiera element UserActionRequestData
i dodaje do niego element UserActionState
lub usuwa go z elementu MediaInformation
. Zmiana wartości parametru UserActionState
w elementach MediaInformation
zmienia stan przycisku powiązanego z wymaganym działaniem. Ta zmiana jest odzwierciedlana w interfejsie sterowania inteligentnym wyświetlaczem, aplikacji pilota i interfejsie Androida TV. Jest ona też rozpowszechniana za pomocą wychodzących wiadomości MediaStatus
, aby zaktualizować interfejs rozszerzonego kontrolera dla nadawców na iOS i Androida.
function updateUserActionStates(backendResponse) {
// Unwrap the backend response.
let mediaInfo = backendResponse.mediaInfo;
let userActionRequestData = backendResponse.userActionRequestData;
// If the current item playing has changed, don't update the UserActionState for the current item.
if (playerManager.getMediaInformation().entity !== mediaInfo.entity) {
return;
}
// Check for existing userActionStates in the MediaInformation.
// If none, initialize a new array to populate states with.
let userActionStates = mediaInfo.userActionStates || [];
// Locate the index of the UserActionState that will be updated in the userActionStates array.
let index = userActionStates.findIndex((currUserActionState) => {
return currUserActionState.userAction == userActionRequestData.userAction;
});
if (userActionRequestData.clear) {
// Remove the user action state from the array if cleared.
if (index >= 0) {
userActionStates.splice(index, 1);
}
else {
console.warn("Could not find UserActionState to remove in MediaInformation");
}
} else {
// Add the UserActionState to the array if enabled.
userActionStates.push(
new cast.framework.messages.UserActionState(userActionRequestData.userAction));
}
// Update the UserActionState array and set the new MediaInformation
mediaInfo.userActionStates = userActionStates;
playerManager.setMediaInformation(mediaInfo, true);
return;
}
Polecenia głosowe
Na urządzeniach z Asystentem obecnie obsługiwane są te komendy multimedialne w SDK Web Receiver. Domyślne implementacje tych poleceń można znaleźć w cast.framework.PlayerManager
.
Polecenie | Opis |
---|---|
Google Play | odtworzyć lub wznowić odtwarzanie wstrzymanego filmu; |
Wstrzymaj | Wstrzymaj aktualnie odtwarzane treści. |
Wstecz | Przejdź do poprzedniego elementu w kolejce multimediów. |
Dalej | Przejdź do następnego elementu multimediów w kolejce multimediów. |
Zatrzymaj | Zatrzymaj aktualnie odtwarzane multimedia. |
Nie powtarzaj | Po odtworzeniu ostatniego elementu w kolejce wyłącz powtarzanie multimediów w kolejce. |
Powtórz pojedynczo | powtarzać aktualnie odtwarzane multimedia w nieskończoność. |
Powtórz wszystko | powtórzyć wszystkie elementy w kolejce po odtworzeniu ostatniego elementu w kolejce; |
Powtórz wszystko i Odtwarzaj losowo | Gdy odtworzono ostatni element w kolejce, posortuj kolejność odtwarzania i powtórz wszystkie elementy. |
Losowo | Losowanie elementów multimediów w kolejce multimediów. |
Napisy włączone / wyłączone | Włącz lub wyłącz napisy do multimediów. Opcja Włącz / Wyłącz jest też dostępna w przypadku języka. |
Przejdź do bezwzględnego czasu. | Przechodzi do określonego bezwzględnego punktu czasowego. |
Przejdź do czasu względnego względem bieżącego czasu. | Przeskok do przodu lub do tyłu o określony okres czasu w stosunku do bieżącego czasu odtwarzania. |
Zagraj jeszcze raz | wznowić aktualnie odtwarzane multimedia lub odtworzyć ostatnio odtwarzany element multimedialny, jeśli nic nie jest obecnie odtwarzane. |
Ustawianie szybkości odtwarzania | zmieniać szybkość odtwarzania multimediów, To powinno być obsługiwane domyślnie. Aby zastąpić przychodzące żądania stawek, możesz użyć przechwytu wiadomości SET_PLAYBACK_RATE . |
Obsługiwane polecenia dotyczące multimediów z użyciem głosu
Aby zapobiec wywoływaniu poleceń dotyczących multimediów przez polecenia głosowe na urządzeniu z Asystentem, musisz najpierw skonfigurować obsługiwane polecenia dotyczące multimediów, które zamierzasz obsługiwać. Następnie musisz zastosować te polecenia, włączając usługę CastReceiverOptions.enforceSupportedCommands
. Interfejs użytkownika w nadajnikach i urządzeniach dotykowych z Cast SDK zmieni się, aby odzwierciedlić te konfiguracje. Jeśli flaga nie jest włączona, przychodzące polecenia głosowe będą wykonywane.
Jeśli na przykład zezwalasz na PAUSE
w aplikacjach nadawcy i na urządzeniach z ekranem dotykowym, musisz też skonfigurować odbiornik zgodnie z tymi ustawieniami. Po skonfigurowaniu wszystkie przychodzące polecenia głosowe zostaną odrzucone, jeśli nie są na liście obsługiwanych poleceń.
W przykładzie poniżej podajemy CastReceiverOptions
na początku CastReceiverContext
. Dodaliśmy obsługę polecenia PAUSE
i wymusiliśmy na odtwarzaczu obsługę tylko tego polecenia. Jeśli polecenie głosowe będzie wymagać wykonania innej operacji, np. SEEK
, zostanie odrzucone. Użytkownik zostanie powiadomiony, że polecenie nie jest jeszcze obsługiwane.
const context = cast.framework.CastReceiverContext.getInstance();
context.start({
enforceSupportedCommands: true,
supportedCommands: cast.framework.messages.Command.PAUSE
});
Możesz stosować oddzielną logikę w przypadku każdego polecenia, które chcesz ograniczyć. Usuń flagę enforceSupportedCommands
i w przypadku każdego polecenia, które chcesz ograniczyć, możesz przechwycić przychodzącą wiadomość. Przechwytujemy tutaj żądanie przesłane przez pakiet SDK, aby polecenia SEEK
wydawane urządzeniom z Asystentem nie powodowały przesunięcia w aplikacji Web Receiver.
W przypadku poleceń multimedialnych, których aplikacja nie obsługuje, należy zwrócić odpowiednią przyczynę błędu, np. NOT_SUPPORTED
.
playerManager.setMessageInterceptor(cast.framework.messages.MessageType.SEEK,
seekData => {
// Block seeking if the SEEK supported media command is disabled
if (!(playerManager.getSupportedMediaCommands() & cast.framework.messages.Command.SEEK)) {
let e = new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType
.INVALID_REQUEST);
e.reason = cast.framework.messages.ErrorReason.NOT_SUPPORTED;
return e;
}
return seekData;
});
Działania w tle związane z mową
Jeśli platforma Cast odtwarza dźwięk aplikacji w tle z powodu aktywności Asystenta, takiej jak słuchanie mowy użytkownika lub odpowiadanie na nią, po rozpoczęciu aktywności do aplikacji Web Receiver jest wysyłana wiadomość FocusState
z wartością NOT_IN_FOCUS
. Po zakończeniu aktywności wysyłana jest kolejna wiadomość z IN_FOCUS
.
W zależności od aplikacji i odtwarzanych multimediów możesz wstrzymać multimedia, gdy FocusState
jest NOT_IN_FOCUS
, przechwytując wiadomość typu FOCUS_STATE
.
Na przykład użytkownik może wstrzymać odtwarzanie audiobooka, jeśli Asystent odpowiada na jego zapytanie.
playerManager.setMessageInterceptor(cast.framework.messages.MessageType.FOCUS_STATE,
focusStateRequestData => {
// Pause content when the app is out of focus. Resume when focus is restored.
if (focusStateRequestData.state == cast.framework.messages.FocusState.NOT_IN_FOCUS) {
playerManager.pause();
} else {
playerManager.play();
}
return focusStateRequestData;
});
Język napisów określony głosem
Jeśli użytkownik nie określi języka napisów, język napisów będzie taki sam jak język polecenia.
W takich przypadkach parametr isSuggestedLanguage
przychodzącej wiadomości wskazuje, czy powiązany z nią język został zasugerowany czy wyraźnie wybrany przez użytkownika.
Na przykład isSuggestedLanguage
ma wartość true
w przypadku polecenia „OK Google, włącz napisy”, ponieważ język został określony na podstawie języka, w którym zostało wypowiedziane polecenie. Jeśli język jest wyraźnie określony, np. „OK Google, włącz napisy w języku angielskim”, isSuggestedLanguage
jest ustawione na false
.
Metadane i odtwarzanie głosem
Polecenia głosowe są domyślnie obsługiwane przez odbiornik internetowy, ale musisz zadbać o to, aby metadane Twoich treści były kompletne i dokładne. Dzięki temu polecenia głosowe są prawidłowo obsługiwane przez Asystenta, a metadane są wyświetlane prawidłowo w ramach nowych typów interfejsów, takich jak aplikacja Google Home czy inteligentne ekrany, np. Google Home Hub.
Przeniesienie odtwarzania
Zachowanie stanu sesji stanowi podstawę przenoszenia strumienia, dzięki czemu użytkownicy mogą przenosić istniejące strumienie audio i wideo między urządzeniami za pomocą poleceń głosowych, aplikacji Google Home lub inteligentnych ekranów. Multimedia przestają być odtwarzane na jednym urządzeniu (źródło) i kontynuują na drugim (miejsce docelowe). Źródłem lub celem przesyłania strumieniowego może być dowolne urządzenie Cast z najnowszą wersją oprogramowania układowego.
Przepływ zdarzeń w przypadku przesyłania strumienia:
- Na urządzeniu źródłowym:
- Multimedia przestaną się odtwarzać.
- Aplikacja Web Receiver otrzymuje polecenie zapisania bieżącego stanu multimediów.
- Aplikacja Web Receiver została zamknięta.
- Na urządzeniu docelowym:
- Wczytano aplikację Web Receiver.
- Aplikacja Web Receiver otrzymuje polecenie przywrócenia zapisanego stanu multimediów.
- Multimedia wznawiają odtwarzanie.
Elementy stanu multimediów:
- Konkretna pozycja lub sygnatura czasowa utworu, filmu lub elementu multimedialnego.
- jego miejsce w szerszej kolejce (np. na playliście lub w radiu wykonawcy);
- uwierzytelniony użytkownik;
- stan odtwarzania (np. odtwarzanie lub wstrzymanie).
Włączanie przenoszenia strumienia
Aby wdrożyć przenoszenie strumienia w odbiorniku internetowym:
- Zaktualizuj
supportedMediaCommands
za pomocą poleceniaSTREAM_TRANSFER
:playerManager.addSupportedMediaCommands( cast.framework.messages.Command.STREAM_TRANSFER, true);
- Opcjonalnie możesz zastąpić przechwytywacze wiadomości
SESSION_STATE
iRESUME_SESSION
zgodnie z opisem w sekcji Zachowywanie stanu sesji. Zastąp te wartości tylko wtedy, gdy dane niestandardowe mają być przechowywane w ramach migawki sesji. W przeciwnym razie domyślna implementacja do zachowania stanów sesji będzie obsługiwać przenoszenie strumienia.
Zachowanie stanu sesji
Pakiet SDK odbiornika internetowego udostępnia domyślną implementację dla aplikacji odbiornika internetowego, aby zachować stany sesji przez zrobienie migawki bieżącego stanu multimediów, przekształcenie go w żądanie wczytania i wznowienie sesji za pomocą tego żądania.
W razie potrzeby żądanie wczytania wygenerowane przez odbiornik internetowy można zastąpić w przechwytującym komunikat interfejsie SESSION_STATE
. Jeśli chcesz dodać do żądania przesłania dane niestandardowe, zalecamy umieszczenie ich w polu loadRequestData.customData
.
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.SESSION_STATE,
function (sessionState) {
// Override sessionState.loadRequestData if needed.
const newCredentials = updateCredentials_(sessionState.loadRequestData.credentials);
sessionState.loadRequestData.credentials = newCredentials;
// Add custom data if needed.
sessionState.loadRequestData.customData = {
'membership': 'PREMIUM'
};
return sessionState;
});
Dane niestandardowe można pobrać z loadRequestData.customData
w przechwytywaniach wiadomości RESUME_SESSION
.
let cred_ = null;
let membership_ = null;
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.RESUME_SESSION,
function (resumeSessionRequest) {
let sessionState = resumeSessionRequest.sessionState;
// Modify sessionState.loadRequestData if needed.
cred_ = sessionState.loadRequestData.credentials;
// Retrieve custom data.
membership_ = sessionState.loadRequestData.customData.membership;
return resumeSessionRequest;
});
Wstępny wczytywanie treści
Odbiornik internetowy obsługuje wstępne wczytywanie elementów multimediów po bieżącym odtwarzanym elemencie w kolejce.
Operacja wstępnego pobierania pobiera wstępnie kilka segmentów nadchodzących elementów. Specyfikacja jest wykonywana na podstawie wartości preloadTime w obiekcie QueueItem (wartość domyślna to 20 sekund, jeśli nie zostanie podana). Czas jest wyrażony w sekundach w stosunku do końca aktualnie odtwarzanego elementu . Dozwolone są tylko wartości dodatnie. Jeśli na przykład wartość wynosi 10 sekund, ten element zostanie wstępnie załadowany 10 sekund przed zakończeniem poprzedniego. Jeśli czas wstępnego ładowania jest dłuższy niż czas pozostały do zakończenia wyświetlania bieżącego elementu, wstępne ładowanie nastąpi tak szybko, jak to możliwe. Jeśli więc w elemencie kolejki podana jest bardzo duża wartość wstępnego wczytania, można uzyskać efekt, że gdy odtwarzamy bieżący element, jednocześnie wstępne wczytujemy następny. Jednak pozostawiamy wybór tego ustawienia deweloperowi, ponieważ może ono wpływać na przepustowość i wydajność strumieniowego przesyłania bieżąco odtwarzanego elementu.
Wstępne wczytywanie będzie domyślnie działać w przypadku treści strumieniowanych HLS, DASH i Smooth.
Standardowe pliki wideo MP4 i dźwiękowe, takie jak MP3, nie będą wstępnie wczytywane, ponieważ urządzenia Cast obsługują tylko 1 element multimedialny i nie można ich używać do wstępnego wczytywania, gdy odtwarzany jest już inny element.
Komunikaty niestandardowe
Wymiana wiadomości jest główną metodą interakcji w przypadku aplikacji Web Receiver.
Nadawca wysyła wiadomości do odbiornika internetowego, korzystając z interfejsów API nadawcy na platformie, na której działa (Android, iOS, internet). Obiekt zdarzenia (który jest manifestacją komunikatu) przekazywany odbiornikom zdarzeń zawiera element danych (event.data
), w którym dane przyjmują właściwości określonego typu zdarzenia.
Aplikacja Web Receiver może nasłuchiwać wiadomości w określonej przestrzeni nazw. W związku z tym aplikacja Web Receiver obsługuje ten protokół przestrzeni nazw. Następnie każdy połączony nadawca, który chce komunikować się w tej przestrzeni nazw, musi użyć odpowiedniego protokołu.
Wszystkie przestrzenie nazw są zdefiniowane przez ciąg znaków i muszą zaczynać się od „urn:x-cast:
”, a następnie dowolnego ciągu znaków. Przykład:
"urn:x-cast:com.example.cast.mynamespace
".
Oto fragment kodu dla odbiornika internetowego, który odbiera wiadomości niestandardowe od połączonych nadawców:
const context = cast.framework.CastReceiverContext.getInstance();
const CUSTOM_CHANNEL = 'urn:x-cast:com.example.cast.mynamespace';
context.addCustomMessageListener(CUSTOM_CHANNEL, function(customEvent) {
// handle customEvent.
});
context.start();
Podobnie aplikacje odbiornika internetowego mogą informować nadawców o stanie odbiornika internetowego, wysyłając wiadomości do połączonych nadawców. Aplikacja Web Receiver może wysyłać wiadomości za pomocą interfejsu sendCustomMessage(namespace, senderId, message)
na CastReceiverContext
.
Odbiornik internetowy może wysyłać wiadomości do konkretnego nadawcy, na przykład w odpowiedzi na otrzymaną wiadomość lub w wyniku zmiany stanu aplikacji. Oprócz przesyłania punkt-punkt (z ograniczeniem do 64 KB) odbiornik internetowy może też nadawać wiadomości do wszystkich połączonych nadawców.
Przesyłanie do urządzeń audio
Informacje o obsługiwanych formatach dźwięku znajdziesz w przewodniku Google Cast na temat urządzeń audio.
Android TV
W tej sekcji omawiamy sposób, w jaki odbiornik internetowy Google wykorzystuje dane wejściowe do odtwarzania, oraz zgodność z Androidem TV.
Integracja aplikacji z pilotem
Usługa Google Web Receiver działająca na urządzeniu z Androidem TV przekształca dane wejściowe z urządzenia (np. z pilota) w wiadomości dotyczące odtwarzania multimediów zdefiniowane w przestrzeni nazw urn:x-cast:com.google.cast.media
, zgodnie z opisem w sekcji Wiadomości dotyczące odtwarzania multimediów. Aplikacja musi obsługiwać te komunikaty, aby umożliwić sterowanie odtwarzaniem multimediów, a także podstawowe sterowanie odtwarzaniem za pomocą elementów sterujących Androida TV.
Wskazówki dotyczące zgodności z Androidem TV
Oto kilka zaleceń i częstych błędów, których należy unikać, aby aplikacja była zgodna z Androidem TV:
- Pamiętaj, że ciąg danych klienta zawiera zarówno „Android”, jak i „CrKey”. Niektóre witryny mogą przekierowywać do wersji mobilnej, ponieważ wykrywają etykietę „Android”. Nie zakładaj, że ciąg znaków „Android” w kliencie użytkownika zawsze wskazuje użytkownika mobilnego.
- Pakiet multimediów Androida może używać przezroczystego GZIP do pobierania danych. Upewnij się, że dane multimediów mogą odpowiadać na
Accept-Encoding: gzip
. - Zdarzenia multimedialne HTML5 na Androidzie TV mogą być wywoływane w innych momentach niż na Chromecastzie, co może ujawnić problemy, które były ukryte na Chromecastzie.
- Podczas aktualizowania multimediów używaj zdarzeń związanych z multimediami wywoływanych przez elementy
<audio>/<video>
, takie jaktimeupdate
,pause
iwaiting
. Unikaj zdarzeń związanych z siecią, takich jakprogress
,suspend
istalled
, ponieważ są one zwykle zależne od platformy. Więcej informacji o obsługiwaniu zdarzeń multimedialnych w odbiorniku znajdziesz w artykule Zdarzenia multimedialne. - Podczas konfigurowania certyfikatów HTTPS witryny odbiorcy pamiętaj, aby uwzględnić pośrednie certyfikaty urzędu certyfikacji. Aby to sprawdzić, otwórz stronę testu certyfikatu SSL Qualsys: jeśli zaufana ścieżka certyfikatów Twojej witryny zawiera certyfikat CA o nazwie „extra download”, może się ona nie wczytać na platformach z Androidem.
- Chromecast wyświetla stronę odbiornika w ramach płaszczyzny graficznej 720p, ale inne platformy Cast, w tym Android TV, mogą wyświetlać stronę w rozdzielczości do 1080p. Upewnij się, że strona odbiorcy skaluje się płynnie w różnych rozdzielczościach.