Dodaj podstawowe funkcje do niestandardowego odbiornika internetowego

Ta strona zawiera fragmenty kodu i opisy funkcji dostępnych w niestandardowej aplikacji odbiornika internetowego.

  1. Element cast-media-player reprezentujący wbudowany interfejs odtwarzacza dostarczany z odbiornikiem internetowym.
  2. Niestandardowy styl podobny do CSS dla elementu cast-media-player, który umożliwia stylizowanie różnych elementów interfejsu, takich jak background-image, splash-imagefont-family.
  3. Element skryptu do wczytywania platformy Web Receiver.
  4. kod JavaScript do przechwytywania wiadomości i obsługi zdarzeń.
  5. Dodaj do kolejki autoodtwarzania.
  6. Opcje konfiguracji odtwarzania.
  7. Opcje ustawiania kontekstu odbiornika internetowego.
  8. Opcje ustawiania poleceń obsługiwanych przez aplikację odbiornika internetowego.
  9. Wywołanie JavaScriptu, które uruchamia aplikację odbiornika internetowego.

Konfiguracja i opcje aplikacji

Konfigurowanie aplikacji

CastReceiverContext to najbardziej zewnętrzna klasa udostępniana deweloperowi. Zarządza ona wczytywaniem bibliotek bazowych i inicjowaniem pakietu Web Receiver SDK. Pakiet SDK udostępnia interfejsy API, które umożliwiają deweloperom aplikacji konfigurowanie pakietu SDK za pomocą CastReceiverOptions. Te konfiguracje są oceniane raz podczas uruchamiania aplikacji i przekazywane do pakietu SDK podczas ustawiania opcjonalnego parametru w wywołaniu funkcji start.

Przykład poniżej pokazuje, jak zastąpić domyślne działanie funkcji wykrywania, czy połączenie nadawcy jest nadal aktywne. Gdy odbiornik internetowy nie może się komunikować z nadawcą przez maxInactivity sekund, wysyłane jest zdarzenie SENDER_DISCONNECTED. Poniższa konfiguracja zastępuje ten czas oczekiwania. Może to być przydatne podczas debugowania problemów, ponieważ zapobiega zamknięciu sesji debugowania zdalnego w Chrome przez aplikację odbiornika internetowego, gdy w stanie IDLE nie ma podłą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 konfigurowanie zmiennych odtwarzania, takich jak informacje o DRM, konfiguracje ponawiania i procedury obsługi żądań, za pomocą cast.framework.PlaybackConfig. Te informacje są obsługiwane przez PlayerManager i oceniane w momencie tworzenia odtwarzaczy. Odtwarzacze są tworzone za każdym razem, gdy do pakietu Web Receiver SDK przekazywane jest nowe wczytanie. Zmiany w parametrze PlaybackConfig po utworzeniu odtwarzacza są oceniane podczas następnego wczytywania treści. Pakiet SDK udostępnia te metody modyfikowania parametru PlaybackConfig.

  • CastReceiverOptions.playbackConfig aby zastąpić domyślne opcje konfiguracji podczas inicjowania CastReceiverContext.
  • PlayerManager.getPlaybackConfig() aby uzyskać bieżącą konfigurację.
  • PlayerManager.setPlaybackConfig() aby zastąpić bieżącą konfigurację. To ustawienie jest stosowane do wszystkich kolejnych wczytań lub do momentu ponownego zastąpienia.
  • PlayerManager.setMediaPlaybackInfoHandler() aby zastosować dodatkowe konfiguracje tylko do elementu multimedialnego wczytywanego na podstawie bieżących konfiguracji. Funkcja obsługi jest wywoływana tuż przed utworzeniem odtwarzacza. Wprowadzone tu zmiany nie są trwałe i nie są uwzględniane w zapytaniach do getPlaybackConfig(). Gdy zostanie wczytany kolejny element multimedialny, ten moduł obsługi zostanie wywołany ponownie.

Poniższy przykład pokazuje, jak ustawić PlaybackConfig podczas inicjowania CastReceiverContext. Konfiguracja zastępuje wychodzące żądania uzyskania plików manifestu. Obsługa określa, że żądania CORS Access-Control 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ć wartość PlaybackConfig za pomocą funkcji pobierającej i ustawiającej udostępnionych w PlayerManager. To ustawienie konfiguruje odtwarzacz tak, aby wznawiał odtwarzanie treści po wczytaniu 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);

Poniższy przykład pokazuje, jak zastąpić wartość PlaybackConfig w przypadku konkretnej prośby o wczytanie za pomocą modułu obsługi informacji o odtwarzaniu multimediów. Procedura obsługi wywołuje metodę getLicenseUrlForMedia zaimplementowaną w aplikacji, aby uzyskać wartość licenseUrl z wartości 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 odbiornika internetowego obsługę zdarzeń odtwarzacza. Funkcja nasłuchiwania zdarzeń przyjmuje parametr cast.framework.events.EventType (lub tablicę tych parametrów), który określa zdarzenia, które powinny wywoływać funkcję nasłuchiwania. Wstępnie skonfigurowane tablice cast.framework.events.EventType, które są przydatne do debugowania, znajdziesz w sekcji cast.framework.events.category. Parametr zdarzenia zawiera dodatkowe informacje o zdarzeniu.

Jeśli na przykład chcesz wiedzieć, kiedy jest emitowana zmiana, możesz użyć tej logiki do obsługi zdarzenia:mediaStatus

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 odbiornika internetowego przechwytywanie wiadomości i wykonywanie w nich niestandardowego kodu. Przechwytywacz wiadomości przyjmuje parametr cast.framework.messages.MessageType, który określa, jaki typ wiadomości ma być przechwytywany.

Interceptor powinien zwrócić zmodyfikowane żądanie lub obiekt Promise, który zwraca zmodyfikowaną wartość żądania. Zwrócenie wartości null uniemożliwi wywołanie domyślnego modułu obsługi wiadomości. Więcej informacji znajdziesz w artykule Wczytywanie multimediów.

Jeśli na przykład chcesz zmienić dane żądania wczytania, możesz użyć 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 przechwytywaczu wiadomości wystąpią błędy, aplikacja odbiornika internetowego powinna zwrócić odpowiedni kod błędu cast.framework.messages.ErrorTypecast.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 przechwytywaniem wiadomości a funkcją nasłuchiwania zdarzeń:

  • Detektor zdarzeń nie umożliwia modyfikowania danych żądania.
  • Detektor zdarzeń najlepiej sprawdza się w przypadku uruchamiania funkcji analitycznych lub niestandardowych.
playerManager.addEventListener(cast.framework.events.category.CORE,
    event => {
        console.log(event);
    });
  • Przechwytywanie wiadomości umożliwia odsłuchanie wiadomości, przechwycenie jej i zmodyfikowanie danych żądania.
  • Przechwytywanie wiadomości najlepiej sprawdza się w przypadku obsługi niestandardowej logiki dotyczącej danych żądania.

Wczytuję multimedia

MediaInformation udostępnia wiele właściwości do wczytywania multimediów w wiadomości cast.framework.messages.MessageType.LOAD, w tym entity, contentUrlcontentId.

  • W przypadku aplikacji nadawcy i odbiorcy zalecamy używanie w implementacji właściwości entity. Właściwość 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 1 z pozostałych 2 pól.
  • contentUrl odpowiada adresowi URL, który odtwarzacz będzie używać do wczytywania treści. Na przykład ten adres URL może wskazywać manifest DASH.
  • contentId Może to być adres URL treści, którą można odtworzyć (podobny do adresu URL usługi contentUrl ) lub unikalny identyfikator wczytywanych treści lub playlisty. Jeśli używasz tej właściwości jako identyfikatora, Twoja aplikacja powinna wypełnić adres URL odtwarzania w polu contentUrl.

Zalecamy używanie entity do przechowywania prawdziwego identyfikatora lub kluczowych parametrów, a contentUrl do przechowywania adresu URL multimediów. Przykładem może być poniższy fragment kodu, w którym w żądaniu LOAD występuje parametr entity, a pobrany jest odtwarzalny element 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;
        });
    });

Możliwości urządzenia

Metoda getDeviceCapabilities dostarcza informacji o podłączonym urządzeniu Cast i urządzeniu wideo lub audio, które jest do niego podłączone. Metoda getDeviceCapabilities udostępnia informacje o pomocy dotyczące Asystenta Google, Bluetootha oraz podłączonych wyświetlaczy i urządzeń audio.

Ta metoda zwraca obiekt, o który możesz wysłać zapytanie, przekazując jeden z określonych wyliczeń, aby uzyskać możliwość urządzenia dla tego wyliczenia. Wyliczenia są zdefiniowane w cast.framework.system.DeviceCapabilities.

W tym przykładzie sprawdzamy, czy urządzenie Web Receiver może odtwarzać HDR i DolbyVision (DV) za pomocą 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 wchodzić w interakcję z aplikacją odbiornika internetowego za pomocą aplikacji nadawców (internetowych, na Androida i iOS), poleceń głosowych na urządzeniach z Asystentem, sterowania dotykowego na inteligentnych wyświetlaczach i pilotów na urządzeniach z Androidem TV. Pakiet Cast SDK udostępnia różne interfejsy API, które umożliwiają aplikacji odbiornika internetowego obsługę tych interakcji, aktualizowanie interfejsu aplikacji za pomocą stanów działań użytkownika i opcjonalnie wysyłanie zmian w celu aktualizowania usług backendu.

Obsługiwane polecenia multimedialne

Stany elementów sterujących interfejsu są określane przez MediaStatus.supportedMediaCommands w przypadku rozwiniętych kontrolerów nadawców na iOS i Androida, aplikacji odbiornika i pilota działających na urządzeniach dotykowych oraz aplikacji odbiornika na urządzeniach z Androidem TV. Gdy w tej właściwości włączony jest określony operator bitowy Command, włączane są przyciski powiązane z danym działaniem. Jeśli wartość nie jest ustawiona, przycisk jest wyłączony. Wartości te można zmienić w odbiorniku internetowym, wykonując te czynności:

  1. Używanie PlayerManager.setSupportedMediaCommands do ustawiania konkretnego Commands
  2. Dodawanie nowego polecenia za pomocą addSupportedMediaCommands
  3. Usuwanie istniejącego polecenia za pomocą removeSupportedMediaCommands.
playerManager.setSupportedMediaCommands(cast.framework.messages.Command.SEEK |
  cast.framework.messages.Command.PAUSE);

Gdy odbiorca przygotuje zaktualizowany MediaStatus, będzie on zawierać zmiany w usłudze supportedMediaCommands. Gdy stan jest transmitowany, połączone aplikacje nadawcy zaktualizują odpowiednio przyciski w swoim interfejsie.

Więcej informacji o obsługiwanych poleceniach multimediów i urządzeniach dotykowych znajdziesz w Accessing UI controlsprzewodniku.

Zarządzanie stanami działań użytkownika

Gdy użytkownicy wchodzą w interakcję z interfejsem lub wysyłają polecenia głosowe, mogą sterować odtwarzaniem treści i właściwościami związanymi z odtwarzanym elementem. Żądania sterujące odtwarzaniem są obsługiwane automatycznie przez pakiet SDK. Żądania, które modyfikują właściwości aktualnie odtwarzanego elementu, takie jak polecenie LIKE, wymagają obsługi przez aplikację odbiornika. Pakiet SDK udostępnia serię interfejsów API do obsługi tych typów żądań. Aby spełnić te prośby, należy wykonać te czynności:

  • Ustaw wartość parametru MediaInformation userActionStates zgodnie z ustawieniami użytkownika podczas wczytywania elementu multimedialnego.
  • Przechwytywanie wiadomości USER_ACTION i określanie żądanego działania.
  • Zaktualizuj MediaInformation UserActionState, aby zaktualizować interfejs.

Poniższy fragment kodu przechwytuje żądanie LOAD i wypełnia MediaInformation LoadRequestData. W tym przypadku użytkownik lubi wczytywane treści.

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;
    });

Poniższy fragment kodu przechwytuje wiadomość USER_ACTION i obsługuje wywoływanie backendu z żądaną zmianą. Następnie wywołuje funkcję aktualizacji UserActionState na urządzeniu odbiorcy.

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;
    });
});

Poniższy fragment kodu symuluje wywołanie usługi backendu. Funkcja sprawdza UserActionRequestData, aby określić typ zmiany, o którą prosi użytkownik, i wykonuje wywołanie sieciowe 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));
    }
  });
}

Poniższy fragment kodu pobiera UserActionRequestData i dodaje lub usuwa UserActionState z MediaInformation. Aktualizacja UserActionStateMediaInformation zmienia stan przycisku powiązanego z żądanym działaniem. Ta zmiana jest widoczna w interfejsie sterowania inteligentnym wyświetlaczem, aplikacji do sterowania pilotem i interfejsie Androida TV. Jest ona też przesyłana w MediaStatuswiadomościach wychodzącychMediaStatus, aby zaktualizować interfejs rozwiniętego kontrolera dla nadawców korzystających z 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

W pakiecie Web Receiver SDK na urządzenia z Asystentem obsługiwane są obecnie te polecenia multimedialne. Domyślne implementacje tych poleceń znajdują się w pliku cast.framework.PlayerManager.

Polecenie Opis
Google Play Odtwarzanie lub wznawianie odtwarzania po wstrzymaniu.
Wstrzymaj Wstrzymaj odtwarzanie bieżących treści.
Wstecz Przejdź do poprzedniego elementu w kolejce multimediów.
Dalej Przejdź do następnego elementu w kolejce multimediów.
Zatrzymaj Zatrzymaj odtwarzanie bieżących multimediów.
Nie powtarzaj Wyłącz powtarzanie elementów multimedialnych w kolejce po odtworzeniu ostatniego elementu.
Powtórz pojedynczy powtarzać aktualnie odtwarzane multimedia w nieskończoność;
Powtórz wszystko Powtarzanie wszystkich elementów w kolejce po odtworzeniu ostatniego elementu.
Powtórz wszystko i odtwarzaj losowo Gdy odtwarzanie ostatniego elementu w kolejce dobiegnie końca, kolejka zostanie przetasowana, a wszystkie elementy w niej zostaną odtworzone ponownie.
Odtwarzaj losowo Losowe odtwarzanie elementów multimedialnych w kolejce multimediów.
Napisy WŁ./WYŁ. Włączanie i wyłączanie napisów w przypadku multimediów. Włączanie i wyłączanie jest też dostępne w poszczególnych językach.
Przewiń do czasu bezwzględnego Przechodzi do określonego czasu bezwzględnego.
Przejdź do czasu względnego względem bieżącego czasu Przesuwa odtwarzanie do przodu lub do tyłu o określony czas względem bieżącego czasu odtwarzania.
Zagraj jeszcze raz Uruchamia ponownie aktualnie odtwarzane multimedia lub odtwarza ostatnio odtwarzany element, jeśli nic nie jest aktualnie odtwarzane.
Ustawianie szybkości odtwarzania zmieniać szybkość odtwarzania multimediów, Powinno to być obsługiwane domyślnie. Możesz użyć interfejsu SET_PLAYBACK_RATE do przechwytywania wiadomości, aby zastępować przychodzące żądania stawek.

Obsługiwane polecenia multimedialne za pomocą głosu

Aby polecenie głosowe nie wywoływało polecenia multimedialnego na urządzeniu z Asystentem, musisz najpierw ustawić obsługiwane polecenia multimedialne, które chcesz obsługiwać. Następnie musisz wymusić te polecenia, włączając usługę CastReceiverOptions.enforceSupportedCommands. Interfejs na nadajnikach SDK Cast i urządzeniach z obsługą dotykową 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 z aplikacji nadawców i urządzeń z obsługą dotyku, musisz też odpowiednio skonfigurować odbiornik. Po skonfigurowaniu wszystkie przychodzące polecenia głosowe, które nie znajdują się na liście obsługiwanych poleceń, będą odrzucane.

W przykładzie poniżej podajemy CastReceiverOptions podczas uruchamiania CastReceiverContext. Dodaliśmy obsługę polecenia PAUSE i wymusiliśmy, aby odtwarzacz obsługiwał tylko to polecenie. Jeśli polecenie głosowe zażąda innej operacji, np. SEEK, zostanie odrzucone. Użytkownik zostanie powiadomiony, że to polecenie nie jest jeszcze obsługiwane.

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

context.start({
  enforceSupportedCommands: true,
  supportedCommands: cast.framework.messages.Command.PAUSE
});

Możesz zastosować 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ść. W tym miejscu przechwytujemy żądanie dostarczone przez pakiet SDK, aby polecenia SEEK wydawane na urządzeniach z Asystentem nie powodowały przewijania w aplikacji Web Receiver.

W przypadku poleceń multimedialnych, których aplikacja nie obsługuje, zwróć odpowiedni powód 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;
  });

Przechodzenie do trybu tła na podstawie aktywności głosowej

Jeśli platforma Cast wyciszy dźwięk aplikacji z powodu aktywności Asystenta, np. słuchania mowy użytkownika lub odpowiadania, do aplikacji Web Receiver zostanie wysłana wiadomość FocusState NOT_IN_FOCUS, gdy aktywność się rozpocznie. Po zakończeniu aktywności wysyłana jest kolejna wiadomość z informacją IN_FOCUS. W zależności od aplikacji i odtwarzanych multimediów możesz chcieć wstrzymać odtwarzanie, gdy FocusState jest NOT_IN_FOCUS, przechwytując typ wiadomości FOCUS_STATE.

Na przykład wstrzymanie odtwarzania audiobooka, gdy Asystent odpowiada na zapytanie użytkownika, jest dobrym rozwiązaniem.

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łosowo

Jeśli użytkownik nie określi języka napisów, będzie on taki sam jak język, w którym zostało wypowiedziane polecenie. W takich przypadkach parametr isSuggestedLanguage w wiadomości przychodzącej wskazuje, czy powiązany język został zasugerowany, czy wyraźnie zażądany przez użytkownika.

Na przykład w przypadku polecenia „OK Google, włącz napisy” parametr isSuggestedLanguage jest ustawiony na true, ponieważ język został wywnioskowany na podstawie języka, w którym zostało wypowiedziane polecenie. Jeśli język jest wyraźnie określony, np. w poleceniu „OK Google, włącz napisy w języku angielskim”, wartość isSuggestedLanguage jest ustawiona na false.

Metadane i obsada głosowa

Domyślnie polecenia głosowe są obsługiwane przez odbiornik internetowy, ale musisz zadbać o to, aby metadane treści były kompletne i dokładne. Dzięki temu Asystent będzie prawidłowo obsługiwać polecenia głosowe, a metadane będą prawidłowo wyświetlane w nowych typach interfejsów, takich jak aplikacja Google Home i inteligentne wyświetlacze, np. Google Home Hub.

Przeniesienie odtwarzania

Zachowanie stanu sesji jest podstawą przenoszenia strumieni, 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. Odtwarzanie multimediów zatrzymuje się na jednym urządzeniu (źródłowym) i jest kontynuowane na innym (docelowym). Każde urządzenie Cast z najnowszym oprogramowaniem może być źródłem lub miejscem docelowym podczas przesyłania strumieniowego.

Przepływ zdarzeń w przypadku przesyłania strumieniowego jest następujący:

  1. Na urządzeniu źródłowym:
    1. Odtwarzanie multimediów zostanie zatrzymane.
    2. Aplikacja odbiornika internetowego otrzymuje polecenie zapisania bieżącego stanu multimediów.
    3. Aplikacja Web Receiver zostanie zamknięta.
  2. Na urządzeniu docelowym:
    1. Aplikacja Web Receiver jest wczytywana.
    2. Aplikacja odbiornika internetowego otrzymuje polecenie przywrócenia zapisanego stanu multimediów.
    3. Odtwarzanie multimediów zostanie wznowione.

Elementy stanu multimediów:

  • Określona pozycja lub sygnatura czasowa utworu, filmu lub elementu multimedialnego.
  • miejsce w szerszej kolejce (np. na playliście lub w radiu wykonawcy);
  • Uwierzytelniony użytkownik.
  • Stan odtwarzania (np. odtwarzanie lub wstrzymanie).

Włączanie przeniesienia odtwarzania

Aby wdrożyć przesyłanie strumienia w odbiorniku internetowym:

  1. Zaktualizuj supportedMediaCommands za pomocą polecenia STREAM_TRANSFER:
    playerManager.addSupportedMediaCommands(
    cast.framework.messages.Command.STREAM_TRANSFER, true);
  2. Opcjonalnie możesz zastąpić interfejsy SESSION_STATERESUME_SESSION, jak opisano w sekcji Zachowywanie stanu sesji. Zastąp te ustawienia tylko wtedy, gdy dane niestandardowe mają być przechowywane jako część migawki sesji. W przeciwnym razie domyślna implementacja zachowywania stanów sesji będzie obsługiwać przesyłanie strumieniowe.

Zachowywanie stanu sesji

Pakiet Web Receiver SDK udostępnia domyślne wdrożenie aplikacji Web Receiver, które umożliwia zachowywanie stanów sesji przez utworzenie migawki bieżącego stanu multimediów, przekształcenie stanu w żądanie wczytania i wznowienie sesji za pomocą tego żądania.

Żądanie wczytania wygenerowane przez odbiornik internetowy można w razie potrzeby zastąpić w SESSION_STATEprzechwytywaczu wiadomości. Jeśli chcesz dodać do żądania wczytania dane niestandardowe, zalecamy umieszczenie ich w elemencie 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.customDataRESUME_SESSION przechwytującym wiadomości.

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 wczytywanie treści

Odbiornik internetowy obsługuje wstępne wczytywanie elementów multimedialnych po bieżącym elemencie odtwarzania w kolejce.

Operacja wstępnego wczytywania wstępnie pobiera kilka segmentów nadchodzących elementów. Specyfikacja jest wykonywana na podstawie wartości preloadTime w obiekcie QueueItem (jeśli nie zostanie podana, domyślnie wynosi 20 sekund). Czas jest wyrażony w sekundach w odniesieniu 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 wczytany 10 sekund przed zakończeniem poprzedniego elementu. Jeśli czas wstępnego wczytywania jest dłuższy niż czas pozostały w bieżącym elemencie, wstępne wczytywanie rozpocznie się tak szybko, jak to możliwe. Jeśli w przypadku elementu queueItem określono bardzo dużą wartość wstępnego wczytywania, można uzyskać efekt polegający na tym, że podczas odtwarzania bieżącego elementu następny element jest już wstępnie wczytywany. Jednak pozostawiamy to ustawienie i wybór deweloperowi, ponieważ ta wartość może wpływać na przepustowość i wydajność przesyłania strumieniowego aktualnie odtwarzanego elementu.

Wstępne wczytywanie będzie domyślnie działać w przypadku treści HLS, DASH i Smooth Streaming.

Zwykłe pliki wideo MP4 i audio, 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ż element treści.

Wiadomości niestandardowe

Wymiana wiadomości to główna metoda interakcji w przypadku aplikacji odbiornika internetowego.

Nadawca wysyła wiadomości do odbiornika internetowego za pomocą interfejsów API nadawcy dla platformy, na której działa nadawca (Android, iOS, internet). Obiekt zdarzenia (który jest przejawem wiadomości) przekazywany do odbiornikó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 nasłuchiwać wiadomości w określonej przestrzeni nazw. W ten sposób aplikacja odbiornika internetowego obsługuje protokół tej przestrzeni nazw. Nadawcy, którzy chcą komunikować się w tej przestrzeni nazw, muszą używać odpowiedniego protokołu.

Wszystkie przestrzenie nazw są definiowane przez ciąg znaków i muszą zaczynać się od „urn:x-cast:”, po którym następuje dowolny ciąg znaków. np. „urn:x-cast:com.example.cast.mynamespace”.

Oto fragment kodu odbiornika internetowego, który umożliwia 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) na urządzeniu CastReceiverContext. Odbiornik internetowy może wysyłać wiadomości do poszczególnych nadawców w odpowiedzi na otrzymaną wiadomość lub w wyniku zmiany stanu aplikacji. Oprócz przesyłania wiadomości między dwoma punktami (z limitem 64 KB) odbiornik internetowy może też rozsyłać wiadomości do wszystkich połączonych nadawców.

Przesyłanie na urządzenia audio

Więcej informacji o odtwarzaniu dźwięku znajdziesz w przewodniku po Google Cast dla urządzeń audio.

Android TV

W tej sekcji omawiamy, jak Odbiornik internetowy Google wykorzystuje Twoje dane wejściowe do odtwarzania oraz jak wygląda 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 elementów sterujących urządzenia (np. pilota) na komunikaty odtwarzania multimediów zdefiniowane dla przestrzeni nazw urn:x-cast:com.google.cast.media, zgodnie z opisem w sekcji Komunikaty odtwarzania multimediów. Aby umożliwić podstawowe sterowanie odtwarzaniem za pomocą elementów sterujących Androida TV, aplikacja musi obsługiwać te wiadomości w celu sterowania odtwarzaniem multimediów.

Wskazówki dotyczące zgodności z Androidem TV

Oto kilka zaleceń i częstych błędów, których należy unikać, aby mieć pewność, że aplikacja jest zgodna z Androidem TV:

  • Pamiętaj, że ciąg klienta zawiera zarówno „Android”, jak i „CrKey”. Niektóre witryny mogą przekierowywać użytkowników do wersji mobilnej, ponieważ wykrywają etykietę „Android”. Nie zakładaj, że „Android” w ciągu znaków klienta użytkownika zawsze oznacza użytkownika mobilnego.
  • Stos multimedialny Androida może używać transparentnego GZIP do pobierania danych. Upewnij się, że dane multimedialne mogą odpowiadać na Accept-Encoding: gzip.
  • Zdarzenia multimedialne HTML5 na Androidzie TV mogą być wywoływane w innych momentach niż na urządzeniu Chromecast. Może to ujawnić problemy, które były ukryte na urządzeniu Chromecast.
  • Podczas aktualizowania multimediów używaj zdarzeń związanych z multimediami wywoływanych przez elementy <audio>/<video>, takie jak timeupdate, pausewaiting. Unikaj zdarzeń związanych z siecią, takich jak progress, suspendstalled, ponieważ zwykle zależą one od platformy. Więcej informacji o obsłudze zdarzeń multimedialnych w odbiorniku znajdziesz w artykule Zdarzenia multimedialne.
  • Podczas konfigurowania certyfikatów HTTPS witryny odbiorcy pamiętaj, aby uwzględnić certyfikaty pośredniego urzędu certyfikacji. Aby sprawdzić, czy zaufana ścieżka certyfikacji Twojej witryny zawiera certyfikat urzędu certyfikacji oznaczony jako „dodatkowe pobieranie”, otwórz stronę testową SSL Qualsys. Jeśli tak jest, witryna może nie wczytywać się na platformach opartych na Androidzie.
  • Chromecast wyświetla stronę odbiornika na płaszczyźnie graficznej 720p, ale inne platformy Cast, w tym Android TV, mogą wyświetlać stronę w rozdzielczości do 1080p. Upewnij się, że strona odbiorcy dobrze się skaluje w różnych rozdzielczościach.