Ta strona zawiera fragmenty kodu i opisy funkcji dostępnych na potrzeby niestandardowej aplikacji odbiornika internetowego.
- Element
cast-media-player
reprezentujący wbudowany interfejs odtwarzacza udostępniany przez odbiornik internetowy. - Niestandardowe style elementu
cast-media-player
przypominające styl CSS, takie jakbackground-image
,splash-image
ifont-family
. - Element skryptu do wczytywania platformy Web Receiver.
- z kodem JavaScript do przechwytywania wiadomości i obsługi zdarzeń.
- Kolejka do autoodtwarzania.
- Opcje konfigurowania odtwarzania.
- Opcje ustawiania kontekstu odbiornika internetowego.
- Opcje ustawiania poleceń obsługiwanych przez aplikację Web Receiver.
- Wywołanie JavaScriptu do uruchomienia aplikacji Web Receiver.
Konfiguracja i opcje aplikacji
Konfigurowanie aplikacji
CastReceiverContext
to najbardziej zewnętrzna klasa widoczna dla programisty. Zajmuje się ładowaniem bazowych bibliotek i inicjowaniem pakietu SDK odbiornika internetowego. Pakiet SDK udostępnia interfejsy API, które umożliwiają deweloperom aplikacji 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
.
Poniższy przykład pokazuje, jak zastąpić domyślne działanie wykrywania, czy połączenie z nadawcą jest nadal aktywne. Gdy odbiornik internetowy nie może połączyć się z nadawcą przez maxInactivity
sekund, wysyłane jest zdarzenie SENDER_DISCONNECTED
. Poniższa konfiguracja zastępuje ten limit. Może to być przydatne podczas debugowania problemów, ponieważ uniemożliwia aplikacji Web Receiver zamknięcie sesji zdalnego debugowania Chrome, gdy w stanie IDLE
nie ma połączonych nadawców.
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 Web Receiver SDK umożliwia skonfigurowanie zmiennych odtwarzania, takich jak informacje o DRM, a także ponawianie konfiguracji i moduły obsługi żądań za pomocą cast.framework.PlaybackConfig
.
Te informacje są przetwarzane przez PlayerManager
i sprawdzane w momencie tworzenia odtwarzaczy. Odtwarzacze są tworzone za każdym razem, gdy do pakietu SDK odbiornika internetowego trafia nowe dane. Modyfikacje elementu PlaybackConfig
po utworzeniu odtwarzacza są sprawdzane przy następnym wczytywaniu treści. Pakiet SDK udostępnia te metody modyfikowania zasobu 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 we wszystkich kolejnych wczytywaniu lub dopóki nie zostanie ponownie zastąpione.PlayerManager.setMediaPlaybackInfoHandler()
, aby zastosować dodatkowe konfiguracje tylko do elementu multimedialnego wczytywanego na podstawie bieżących konfiguracji. Moduł obsługi jest wywoływany tuż przed utworzeniem odtwarzacza. Wprowadzone tutaj zmiany nie są trwałe i nie są uwzględniane w zapytaniach wysyłanych dogetPlaybackConfig()
. Po wczytaniu następnego elementu multimedialnego ten moduł obsługi jest wywoływany ponownie.
Poniższy przykład pokazuje, jak ustawić PlaybackConfig
podczas inicjowania CastReceiverContext
. Konfiguracja zastępuje żądania wychodzące dotyczące
uzyskiwania plików manifestu. Moduł obsługi 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});
Poniższy przykład pokazuje, jak zastąpić zmienną PlaybackConfig
za pomocą metod pobierania i ustawiania dostępnych w zasadzie PlayerManager
. To ustawienie powoduje, że odtwarzacz wznawia odtwarzanie treści po załadowaniu jednego segmentu.
const playerManager =
cast.framework.CastReceiverContext.getInstance().getPlayerManager();
const playbackConfig = (Object.assign(
new cast.framework.PlaybackConfig(), playerManager.getPlaybackConfig()));
playbackConfig.autoResumeNumberOfSegments = 1;
playerManager.setPlaybackConfig(playbackConfig);
Poniższy przykład pokazuje, jak zastąpić PlaybackConfig
w konkretnym żądaniu wczytywania za pomocą modułu obsługi informacji o odtwarzaniu multimediów. Moduł obsługi wywołuje zaimplementowane przez aplikację metodę getLicenseUrlForMedia
, aby uzyskać licenseUrl
z obiektu contentId
bieżącego elementu.
playerManager.setMediaPlaybackInfoHandler((loadRequestData, playbackConfig) => {
const mediaInformation = loadRequestData.media;
playbackConfig.licenseUrl = getLicenseUrlForMedia(mediaInformation.contentId);
return playbackConfig;
});
Detektor zdarzeń
Pakiet Web Receiver SDK umożliwia aplikacji odbiornik internetowy obsługę zdarzeń odtwarzacza. Detektor zdarzeń pobiera parametr cast.framework.events.EventType
(lub tablicę tych parametrów), który określa zdarzenia, które mają aktywować detektor. Wstępnie skonfigurowane tablice cast.framework.events.EventType
, które przydają się przy debugowaniu, znajdziesz w cast.framework.events.category
.
Parametr zdarzenia zawiera dodatkowe informacje o zdarzeniu.
Jeśli na przykład chcesz wiedzieć, kiedy jest transmitowana zmiana mediaStatus
, możesz obsłużyć zdarzenie, korzystając z tej logiki:
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 Web Receiver SDK umożliwia aplikacji odbiornik internetowy przechwytywanie wiadomości i wykonywanie w nich niestandardowego kodu. Funkcja przechwytująca wiadomości przyjmuje parametr cast.framework.messages.MessageType
, który określa typ wiadomości do przechwycenia.
Element przechwytujący powinien zwrócić zmodyfikowane żądanie lub obietnicę, która zakończy się ze zmodyfikowaną wartością żądania. Zwrócenie null
uniemożliwi wywołanie domyślnego modułu obsługi wiadomości. Więcej informacji znajdziesz w artykule Wczytywanie multimediów.
Jeśli np. chcesz zmienić dane żądania wczytywania, możesz skorzystać z tej logiki, aby je przechwycić i zmodyfikować:
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 w punkcie przechwytującym wiadomości wystąpią błędy, aplikacja Web Receiver powinna zwrócić odpowiednie 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 kilka kluczowych różnic między przechwytywaniem wiadomości a detektorem zdarzeń:
- Detektor zdarzeń nie pozwala na modyfikowanie danych żądania.
- Detektor zdarzeń najlepiej nadaje się do aktywowania analiz lub funkcji niestandardowych.
playerManager.addEventListener(cast.framework.events.category.CORE,
event => {
console.log(event);
});
- Przechwytywanie wiadomości pozwala odsłuchać wiadomość i przechwycić ją, a następnie samodzielnie zmodyfikować dane żądania.
- Przechwytywanie wiadomości sprawdza się najlepiej w przypadku niestandardowej logiki w przypadku danych żądań.
Wczytuję multimedia
MediaInformation
udostępnia 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 sugerowana właściwość do użycia w implementacji zarówno w przypadku aplikacji nadawcy, jak i odbiorcy. Właściwość to URL precyzyjnego linku, który może być playlistą lub treściami multimedialnymi. Aplikacja powinna przeanalizować ten adres URL i wypełnić co najmniej jedno z pozostałych 2 pól.contentUrl
odpowiada odtwarzanemu adresowi URL, którego odtwarzacz użyje do wczytania treści. Na przykład ten adres URL może wskazywać plik manifestu DASH.- Obiekt
contentId
może być adresem URL treści możliwych do odtworzenia (podobnym do właściwościcontentUrl
) albo unikalnym identyfikatorem wczytywanej treści lub playlisty. Jeśli używasz tej właściwości jako identyfikatora, aplikacja powinna uzupełniać w polucontentUrl
adres URL gry.
Zalecamy używanie właściwości entity
do przechowywania rzeczywistego identyfikatora lub kluczowych parametrów i używanie contentUrl
jako adresu URL multimediów. Oto przykładowy fragment kodu, który zawiera element entity
w żądaniu LOAD
i pobrany dostępny do odtworzenia contentUrl
:
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
przekazuje informacje z urządzenia podłączonego do urządzenia przesyłającego oraz podłączonego do niego urządzenia wideo lub audio. Metoda getDeviceCapabilities
udostępnia informacje pomocy dotyczące Asystenta Google, Bluetootha oraz połączonych urządzeń wyświetlających i audio.
Ta metoda zwraca obiekt, o który można wykonać zapytanie, przekazując jedną ze podanych wartości wyliczeniowych w celu uzyskania możliwości urządzenia w przypadku tej wartości wyliczeniowej. Wyliczenia są zdefiniowane w zadaniu cast.framework.system.DeviceCapabilities
.
Ten przykład pozwala sprawdzić, czy odbiornik internetowy może odtwarzać treści HDR i DolbyVision (DV) odpowiednio przy użyciu 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 użytkownika
Użytkownik może korzystać z aplikacji odbiornika internetowego, używając aplikacji nadawcy (w przeglądarce, na Androidzie lub iOS), poleceń głosowych na urządzeniach z Asystentem, sterowania dotykowego na inteligentnych ekranach i pilotów na urządzeniach z Androidem TV. SDK Cast udostępnia różne interfejsy API, które pozwalają aplikacji Web Receiver na obsługę tych interakcji, aktualizowanie interfejsu aplikacji za pomocą stanów działań użytkownika i opcjonalnie wysyłanie zmian w celu zaktualizowania usług backendu.
Obsługiwane polecenia multimedialne
Stany elementów sterujących interfejsu są określane przez parametr MediaStatus.supportedMediaCommands
w przypadku rozszerzonych kontrolerów dla nadawców na iOS i Androida, aplikacji odbiornika i zdalnego sterowania działającego na urządzeniach dotykowych oraz aplikacji odbiorników na urządzeniach z Androidem TV. Gdy we właściwości włączony jest określony tag bitowy Command
, przyciski związane z tym działaniem są włączone. Jeśli wartość nie jest ustawiona, przycisk jest wyłączony. Te wartości można zmienić w odbiorniku internetowym przez:
- Użycie właściwości
PlayerManager.setSupportedMediaCommands
do skonfigurowania konkretnego elementuCommands
- Dodaję nowe polecenie za pomocą
addSupportedMediaCommands
- Usunięcie dotychczasowego polecenia przy użyciu polecenia
removeSupportedMediaCommands
.
playerManager.setSupportedMediaCommands(cast.framework.messages.Command.SEEK |
cast.framework.messages.Command.PAUSE);
Gdy odbiorca przygotuje zaktualizowany MediaStatus
, uwzględni zmiany we właściwości supportedMediaCommands
. Gdy stan jest transmitowany, połączone aplikacje nadawców odpowiednio zaktualizują przyciski w swoim interfejsie.
Więcej informacji o obsługiwanych poleceniach multimedialnych i urządzeniach dotykowych znajdziesz w przewodniku Accessing UI controls
.
Zarządzanie stanami działań użytkowników
Gdy użytkownicy korzystają z interfejsu lub wysyłają polecenia głosowe, mogą kontrolować odtwarzanie treści i właściwości związane z odtwarzanym elementem. Pakiet SDK obsługuje żądania sterujące odtwarzaniem automatycznie. Żądania, które modyfikują właściwości odtwarzanego aktualnie elementu (np. polecenie LIKE
), wymagają, aby aplikacja odbierająca je obsługowała. Pakiet SDK udostępnia szereg interfejsów API
do obsługi tego typu żądań. W tym celu należy:
- Ustaw
MediaInformation
userActionStates
z preferencjami użytkownika podczas wczytywania elementu multimedialnego. - Przechwyć
USER_ACTION
wiadomości i określ wymagane działanie. - Aby zaktualizować interfejs użytkownika, zaktualizuj
MediaInformation
UserActionState
.
Ten fragment kodu przechwytuje żądanie LOAD
i wypełnia żądanie LoadRequestData
elementu MediaInformation
. W tym przypadku użytkownikowi podoba się wczytywana treść.
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;
});
Ten fragment kodu przechwytuje komunikat USER_ACTION
i obsługuje wywoływanie backendu z żądaną zmianą. Następnie wysyła wywołanie, by zaktualizować
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 w elemencie UserActionRequestData
typ zmiany, o którą prosił użytkownik, i wywołuje wywołanie sieci tylko wtedy, gdy działanie jest obsługiwane przez backend.
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 wykorzystuje UserActionRequestData
i dodaje lub usuwa UserActionState
z MediaInformation
. Zaktualizowanie UserActionState
elementu MediaInformation
zmienia stan przycisku powiązanego z żądanym działaniem. Ta zmiana jest widoczna w interfejsie do sterowania inteligentnym ekranie, aplikacji Pilot i interfejsie Androida TV. Jest też transmitowany przez wiadomości wychodzące MediaStatus
w celu zaktualizowania interfejsu rozwiniętego kontrolera dla nadawców na urządzeniach z iOS i Androidem.
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
Poniższe polecenia multimedialne są obecnie obsługiwane w pakiecie SDK Web Receiver na urządzenia z Asystentem. Domyślne implementacje tych poleceń znajdziesz tutaj: cast.framework.PlayerManager
.
Polecenie | Opis |
---|---|
Google Play | Odtwarzanie lub wznowienie odtwarzania od momentu wstrzymania. |
Wstrzymaj | Wstrzymaj odtwarzane treści. |
Wstecz | Przejdź do poprzedniego elementu multimedialnego w kolejce. |
Dalej | Przejdź do następnego elementu w kolejce multimediów. |
Zatrzymaj | Zatrzymaj odtwarzane multimedia. |
Nie powtarzaj niczego | Wyłącz powtarzanie elementów multimedialnych w kolejce po zakończeniu odtwarzania ostatniego elementu w kolejce. |
Powtórz jeden raz | Powtarzaj cały czas odtwarzane multimedia. |
Powtórz wszystko | Powtórz wszystkie elementy w kolejce po odtworzeniu ostatniego elementu w kolejce. |
Powtórz wszystko i odtwórz losowo | Po zakończeniu odtwarzania ostatniego elementu w kolejce należy je losowo odtwarzać, a następnie powtórzyć wszystkie elementy w kolejce. |
Odtwarzaj losowo | Losowe odtwarzanie elementów multimedialnych w kolejce multimediów. |
Napisy WŁĄCZONE / WYŁĄCZONE | Włącz / wyłącz napisy w multimediach. Opcje włączania i wyłączania są również dostępne w poszczególnych językach. |
Przewijanie do bezwzględnego czasu | Przechodzi do określonego czasu bezwzględnego. |
Przewiń do czasu w odniesieniu do czasu bieżącego | Przewija do przodu lub do tyłu o określony przedział czasu w stosunku do bieżącego czasu odtwarzania. |
Zagraj jeszcze raz | Uruchom ponownie aktualnie odtwarzane multimedia lub odtwórz ostatnio odtwarzany element, jeśli nic obecnie nie jest odtwarzane. |
Ustawianie szybkości odtwarzania | Zróżnicowanie szybkości odtwarzania multimediów. To ustawienie powinno być obsługiwane domyślnie. Do zastępowania przychodzących próśb o stawkę możesz użyć przechwytującego wiadomości SET_PLAYBACK_RATE . |
Obsługiwane polecenia multimedialne z użyciem głosu
Aby polecenie głosowe nie uruchamiało polecenia multimedialnego na urządzeniu z Asystentem, musisz najpierw ustawić obsługiwane polecenia multimedialne, które chcesz obsługiwać. Potem musisz wymusić te polecenia, włączając właściwość CastReceiverOptions.enforceSupportedCommands
. Interfejs nadawców i urządzeń obsługujących dotyk Cast SDK zmieni się, aby odzwierciedlał 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 urządzeniach dotykowych, musisz też skonfigurować odbiornik, aby uwzględniał te ustawienia. Po ich skonfigurowaniu wszystkie przychodzące polecenia głosowe będą usuwane, jeśli nie znajdują się na liście obsługiwanych poleceń.
W poniższym przykładzie podajemy CastReceiverOptions
, uruchamiając CastReceiverContext
. Dodaliśmy obsługę polecenia PAUSE
i zmusiliśmy odtwarzacz do obsługi tylko tego polecenia. Jeśli polecenie głosowe zażąda innej operacji, na przykład SEEK
, zostanie ono odrzucone. Użytkownik otrzyma powiadomienie, że to polecenie nie jest jeszcze obsługiwane.
const context = cast.framework.CastReceiverContext.getInstance();
context.start({
enforceSupportedCommands: true,
supportedCommands: cast.framework.messages.Command.PAUSE
});
Do każdego polecenia, które chcesz ograniczyć, możesz zastosować osobną logikę. Usuń flagę enforceSupportedCommands
i w przypadku każdego polecenia, dla którego chcesz wprowadzić ograniczenia, możesz przechwycić wiadomość przychodzącą. W tym miejscu przechwytujemy żądanie dostarczone przez pakiet SDK, dzięki czemu polecenia SEEK
wysyłane na urządzenia z Asystentem nie uruchamiają wyszukiwania w aplikacji Odbiornik internetowy.
W przypadku poleceń multimedialnych, których Twoja aplikacja nie obsługuje, zwracaj odpowiedni powód błędu, na przykład 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;
});
Tło z aktywności związanej z głosem
Jeśli platforma Cast odtwarza w tle dźwięk Twojej aplikacji w wyniku działania Asystenta, np. słuchania wypowiedzi użytkownika lub odpowiadania, po rozpoczęciu działania do aplikacji Web Receiver zostanie wysłany komunikat FocusState
o wartości NOT_IN_FOCUS
. Po zakończeniu aktywności otrzymasz kolejną wiadomość z adresem IN_FOCUS
.
W zależności od aplikacji i odtwarzanych multimediów możesz wstrzymać multimedia, gdy FocusState
ma wartość NOT_IN_FOCUS
, przechwytując wiadomość typu FOCUS_STATE
.
Na przykład dobrze jest wstrzymać odtwarzanie audiobooka, gdy Asystent odpowiada na zapytanie użytkownika.
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
Jeśli użytkownik nie określi wyraźnie języka napisów, używany będzie ten sam język, w którym padło polecenie.
W takich sytuacjach parametr isSuggestedLanguage
wiadomości przychodzącej wskazuje, czy powiązany język został zasugerowany czy wyraźnie zażądany przez użytkownika.
Na przykład pole isSuggestedLanguage
ma wartość true
w przypadku polecenia „OK Google, włącz napisy”, ponieważ język został ustalony na podstawie języka polecenia. Jeśli wymagane jest podanie języka, na przykład w „OK Google, włącz angielskie napisy”, isSuggestedLanguage
ma wartość false
.
Metadane i przesyłanie głosu
Choć polecenia głosowe są domyślnie obsługiwane przez odbiornik internetowy, upewnij się, że metadane Twoich treści są kompletne i dokładne. Dzięki temu będziesz mieć pewność, że Asystent prawidłowo obsługuje polecenia głosowe, a metadane wyświetlają się prawidłowo w nowych typach interfejsów, takich jak aplikacja Google Home i inteligentne ekrany, takie jak Google Home Hub.
Przenoszenie strumienia
Zachowanie stanu sesji jest podstawą przenoszenia strumienia, w ramach której 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 zatrzymują się na jednym urządzeniu (źródle) i na drugim (miejscu docelowym). Każde urządzenie przesyłające z najnowszym oprogramowaniem może służyć jako źródło lub miejsce docelowe podczas przesyłania strumienia.
Przepływ zdarzeń związanych z przeniesieniem strumienia wygląda tak:
- Na urządzeniu źródłowym:
- Odtwarzanie multimediów zostanie przerwane.
- Aplikacja odbiornika internetowego otrzymuje polecenie pozwalające zapisać bieżący stan multimediów.
- Aplikacja Web Receiver jest wyłączona.
- Na urządzeniu docelowym:
- Aplikacja odbiornika internetowego jest wczytana.
- Aplikacja odbiornika internetowego otrzymuje polecenie przywrócenia zapisanego stanu multimediów.
- Multimedia wznowią odtwarzanie.
Do elementów stanu multimediów należą:
- Konkretna pozycja lub sygnatura czasowa utworu, filmu lub elementu multimedialnego.
- umieszczenie go w szerszej kolejce (np. w playlisty lub w radiu wykonawcy).
- Uwierzytelniony użytkownik.
- Stan odtwarzania (np. odtwarzanie lub wstrzymanie).
Włączam przenoszenie strumienia
Aby wdrożyć przesyłanie strumienia na odbiorniku internetowym:
- Zaktualizuj
supportedMediaCommands
za pomocą poleceniaSTREAM_TRANSFER
:playerManager.addSupportedMediaCommands( cast.framework.messages.Command.STREAM_TRANSFER, true);
- Opcjonalnie zastąp przechwytniki komunikatów
SESSION_STATE
iRESUME_SESSION
zgodnie z opisem w sekcji Zachowywanie stanu sesji. Zastąp je tylko wtedy, gdy musisz przechowywać dane niestandardowe w ramach zrzutu sesji. W przeciwnym razie domyślna implementacja zachowywania stanów sesji będzie obsługiwać przenoszenie strumienia.
Zachowywanie stanu sesji
SDK odbiornika internetowego udostępnia domyślną implementację dla aplikacji odbiorników internetowych, aby zachowywał stany sesji przez utworzenie zrzutu bieżącego stanu multimediów, przekształcenie go w żądanie wczytania i wznawianie sesji z żądaniem wczytania.
Żądanie obciążenia wygenerowane przez odbiornik internetowy można w razie potrzeby zastąpić w SESSION_STATE
module do przechwytywania. Jeśli do żądania wczytywania chcesz dodać dane niestandardowe, zalecamy umieszczenie ich w narzędziu 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 poziomu loadRequestData.customData
w elemencie przechwytującym 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ępne wczytanie treści
Odbiornik internetowy obsługuje wstępne wczytywanie elementów multimedialnych po aktualnie odtwarzanym elemencie w kolejce.
Operacja wstępnego wczytywania pobiera wstępnie kilka segmentów nadchodzących elementów. Specyfikacja jest wykonywana na wartości preloadTime w obiekcie QueueItem (jeśli nie zostanie podana, domyślna wartość to 20 sekund). Czas jest wyrażony w sekundach w stosunku do końca odtwarzanego elementu . Prawidłowe są tylko wartości dodatnie. Jeśli np. wartość wynosi 10 sekund, element zostanie wstępnie wczytany 10 sekund przed zakończeniem poprzedniego elementu. Jeśli czas wstępnego wczytywania będzie dłuższy niż pozostały czas dla bieżącego elementu, wstępne wczytywanie nastąpi tak szybko, jak to możliwe. Jeśli więc określisz bardzo dużą wartość wstępnego wczytywania w elemencie containerItem, można osiągnąć efekt za każdym razem, gdy odtwarzamy bieżący element, a następny jest już wstępnie wczytywany. To ustawienie pozostawiamy jednak deweloperowi, ponieważ ta wartość może mieć wpływ na przepustowość i wydajność strumieniowania odtwarzanego elementu.
Wstępne wczytywanie będzie domyślnie działać w przypadku treści HLS, DASH i płynne przesyłanie strumieniowe treści.
Zwykłe pliki wideo i audio MP4, np. MP3, nie będą wstępnie wczytywane, ponieważ urządzenia przesyłające obsługują tylko jeden element multimedialny i nie można ich użyć do wstępnego wczytywania, gdy odtwarzany jest istniejący element treści.
Komunikaty niestandardowe
Wymiana wiadomości to kluczowa metoda interakcji w aplikacjach odbiornika internetowego.
Nadawca wysyła wiadomości do odbiornika internetowego, używając interfejsów API nadawcy (Android, iOS, internet). Obiekt zdarzenia (który jest plikiem manifestu wiadomości), który jest przekazywany do detektorów zdarzeń, zawiera element danych (event.data
), w którym dane przyjmują właściwości określonego typu zdarzenia.
Aplikacja odbiornika internetowego może zdecydować się na nasłuchiwanie wiadomości z określonej przestrzeni nazw. Dzięki temu aplikacja Web Receiver obsługuje ten protokół przestrzeni nazw. Wtedy to wszyscy połączeni nadawcy, którzy chcą komunikować się w tej przestrzeni nazw, korzystając z odpowiedniego protokołu.
Wszystkie przestrzenie nazw są zdefiniowane ciągiem znaków i muszą zaczynać się od ciągu „urn:x-cast:
”, po którym następuje dowolny ciąg. Przykład: „urn:x-cast:com.example.cast.mynamespace
”.
Oto fragment kodu, który umożliwia odbiornikowi internetowemu nasłuchiwanie niestandardowych wiadomości 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 odbiornika internetowego może wysyłać wiadomości za pomocą funkcji sendCustomMessage(namespace, senderId, message)
w CastReceiverContext
.
Odbiorca internetowy może wysyłać wiadomości do konkretnego nadawcy w odpowiedzi na odebraną wiadomość lub z powodu zmiany stanu aplikacji. Poza przesyłaniem danych z punktu do punktu (z limitem 64 KB) odbiornik internetowy może też wysyłać wiadomości do wszystkich połączonych nadawców.
Przesyłanie na urządzenia audio
Informacje na temat odtwarzania samego dźwięku znajdziesz w przewodniku po Google Cast na urządzenia audio.
Android TV
W tej sekcji omawiamy, jak odbiornik internetowy Google wykorzystuje Twoje dane wejściowe do odtwarzania, oraz omawia zgodność z Androidem TV.
Integracja aplikacji z pilotem
Odbiornik internetowy Google działający na urządzeniu z Androidem TV tłumaczy dane wejściowe z wejścia sterowania urządzenia (np. ręcznego pilota) jako komunikaty 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 sterować odtwarzaniem multimediów w aplikacji – aby możliwe było podstawowe sterowanie odtwarzaniem z wejścia sterującego Androida TV.
Wytyczne dotyczące zgodności z Androidem TV
Oto kilka zaleceń i typowych problemów, których należy unikać, aby zapewnić zgodność aplikacji z Androidem TV:
- Pamiętaj, że ciąg znaków klienta użytkownika zawiera zarówno ciąg „Android”, jak i „CrKey”. Niektóre witryny mogą przekierowywać użytkowników do witryn przeznaczonych tylko na urządzenia mobilne, ponieważ wykrywają etykietę „Android”. Nie zakładaj, że „Android” w ciągu znaków klienta użytkownika zawsze wskazuje użytkownika mobilnego.
- Stos multimediów na Androidzie może używać do pobierania danych przezroczystego GZIP. Upewnij się, że Twoje dane multimedialne mogą reagować na funkcję
Accept-Encoding: gzip
. - Zdarzenia dotyczące multimediów w Androidzie TV mogą być wywoływane w innych momentach niż Chromecast. Może to ujawnić problemy, które były na nim ukryte.
- Podczas aktualizowania multimediów używaj zdarzeń związanych z multimediami, które są wywoływane przez elementy
<audio>/<video>
, takie jaktimeupdate
,pause
iwaiting
. Unikaj używania zdarzeń związanych z siecią, takich jakprogress
,suspend
istalled
, ponieważ zwykle są one zależne od platformy. Więcej informacji o obsłudze zdarzeń multimediów w odbiorniku znajdziesz w artykule Zdarzenia multimedialne. - Podczas konfigurowania certyfikatów HTTPS witryny odbiorcy pamiętaj o dołączeniu certyfikatów pośrednich CA. Aby to sprawdzić, zapoznaj się ze stroną testową Qualsys SSL. Jeśli zaufana ścieżka certyfikacji Twojej witryny zawiera certyfikat CA oznaczony etykietą „extra download”, może się ona nie ładować na platformach opartych na Androidzie.
- Chromecast wyświetla stronę odbiornika na płaszczyźnie graficznej 720p, a inne platformy Cast, takie jak Android TV, mogą wyświetlać stronę w rozdzielczości do 1080p. Zadbaj o to, aby strona odbiorcy płynnie skalowała się w różnych rozdzielczościach.