Zentrale Funktionen zu Ihrem benutzerdefinierten Web-Receiver hinzufügen

Diese Seite enthält Code-Snippets und Beschreibungen der Funktionen, die für eine benutzerdefinierte Web-Empfänger-App verfügbar sind.

  1. Ein cast-media-player-Element, das die integrierte Player-Benutzeroberfläche des Webreceivers darstellt.
  2. Benutzerdefiniertes CSS-ähnliches Styling für das cast-media-player-Element zum Stylen verschiedener UI-Elemente wie background-image, splash-image und font-family.
  3. Ein Script-Element zum Laden des Web Receiver-Frameworks.
  4. JavaScript-Code zum Abfangen von Nachrichten und zum Verarbeiten von Ereignissen.
  5. Zur Wiedergabeliste für die automatische Wiedergabe hinzufügen
  6. Optionen zum Konfigurieren der Wiedergabe.
  7. Optionen zum Festlegen des Web-Empfänger-Kontexts.
  8. Optionen zum Festlegen von Befehlen, die von der Web-Empfänger-App unterstützt werden.
  9. Ein JavaScript-Aufruf zum Starten der Web-Empfängeranwendung.

Anwendungskonfiguration und -optionen

Anwendung konfigurieren

Die CastReceiverContext ist die äußerste Klasse, die dem Entwickler zur Verfügung steht. Sie verwaltet das Laden der zugrunde liegenden Bibliotheken und die Initialisierung des Web Receiver SDK. Das SDK bietet APIs, mit denen App-Entwickler das SDK über CastReceiverOptions konfigurieren können. Diese Konfigurationen werden einmal pro Anwendungsstart ausgewertet und an das SDK übergeben, wenn der optionale Parameter im Aufruf von start festgelegt wird.

Im folgenden Beispiel wird gezeigt, wie das Standardverhalten für die Erkennung einer aktiven Verbindung überschrieben wird. Wenn der Webempfänger seit maxInactivity Sekunden nicht mit einem Absender kommunizieren konnte, wird ein SENDER_DISCONNECTED-Ereignis gesendet. Mit der folgenden Konfiguration wird diese Zeitüberschreitung überschrieben. Das kann bei der Fehlerbehebung nützlich sein, da die Web Receiver App die Chrome Remote Debugger-Sitzung nicht schließt, wenn keine verbundenen Sender im Status IDLE vorhanden sind.

const context = cast.framework.CastReceiverContext.getInstance();
const options = new cast.framework.CastReceiverOptions();
options.maxInactivity = 3600; // Development only
context.start(options);

Player konfigurieren

Beim Laden von Inhalten bietet das Web Receiver SDK die Möglichkeit, Wiedergabevariablen wie DRM-Informationen, Wiederholungskonfigurationen und Anfrage-Handler mit cast.framework.PlaybackConfig zu konfigurieren. Diese Informationen werden von PlayerManager verarbeitet und beim Erstellen der Spieler ausgewertet. Es werden jedes Mal neue Player erstellt, wenn eine neue Ladung an das Web Receiver SDK übergeben wird. Änderungen an PlaybackConfig nach dem Erstellen des Players werden bei der nächsten Inhaltsladevorgang ausgewertet. Das SDK bietet die folgenden Methoden zum Ändern der PlaybackConfig.

  • CastReceiverOptions.playbackConfig, um die Standardkonfigurationsoptionen bei der Initialisierung des CastReceiverContext zu überschreiben.
  • PlayerManager.getPlaybackConfig(), um die aktuelle Konfiguration abzurufen.
  • PlayerManager.setPlaybackConfig(), um die aktuelle Konfiguration zu überschreiben. Diese Einstellung wird auf alle nachfolgenden Ladevorgänge angewendet, bis sie wieder überschrieben wird.
  • PlayerManager.setMediaPlaybackInfoHandler(), um zusätzliche Konfigurationen nur für das geladene Medienelement anzuwenden. Der Handler wird kurz vor der Erstellung des Players aufgerufen. Hier vorgenommene Änderungen sind nicht dauerhaft und werden nicht in Abfragen an getPlaybackConfig() einbezogen. Wenn das nächste Medienelement geladen wird, wird dieser Handler noch einmal aufgerufen.

Das folgende Beispiel zeigt, wie PlaybackConfig beim Initialisieren von CastReceiverContext festgelegt wird. Die Konfiguration überschreibt ausgehende Anfragen zum Abrufen von Manifesten. Der Handler gibt an, dass CORS-Zugriffssteuerungsanfragen mit Anmeldedaten wie Cookies oder Autorisierungsheadern erfolgen sollen.

const playbackConfig = new cast.framework.PlaybackConfig();
playbackConfig.manifestRequestHandler = requestInfo => {
  requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});

Das folgende Beispiel zeigt, wie PlaybackConfig mithilfe des in PlayerManager bereitgestellten Getters und Setters überschrieben wird. Mit dieser Einstellung wird der Player so konfiguriert, dass die Wiedergabe von Inhalten fortgesetzt wird, nachdem ein Segment geladen wurde.

const playerManager =
    cast.framework.CastReceiverContext.getInstance().getPlayerManager();
const playbackConfig = (Object.assign(
            new cast.framework.PlaybackConfig(), playerManager.getPlaybackConfig()));
playbackConfig.autoResumeNumberOfSegments = 1;
playerManager.setPlaybackConfig(playbackConfig);

Im folgenden Beispiel wird gezeigt, wie du PlaybackConfig für eine bestimmte Ladeanfrage mit dem Handler für Informationen zur Medienwiedergabe überschreibst. Der Handler ruft eine von der Anwendung implementierte Methode getLicenseUrlForMedia auf, um die licenseUrl aus der contentId des aktuellen Elements abzurufen.

playerManager.setMediaPlaybackInfoHandler((loadRequestData, playbackConfig) => {
  const mediaInformation = loadRequestData.media;
  playbackConfig.licenseUrl = getLicenseUrlForMedia(mediaInformation.contentId);

  return playbackConfig;
});

Ereignis-Listener

Mit dem Web Receiver SDK kann deine Web Receiver App Player-Ereignisse verarbeiten. Der Ereignis-Listener nimmt einen cast.framework.events.EventType-Parameter (oder ein Array dieser Parameter) an, der die Ereignisse angibt, die den Listener auslösen sollen. Vorkonfigurierte Arrays von cast.framework.events.EventType, die für die Fehlerbehebung nützlich sind, finden Sie unter cast.framework.events.category. Der Ereignisparameter enthält zusätzliche Informationen zum Ereignis.

Wenn Sie beispielsweise wissen möchten, wann eine Änderung an mediaStatus übertragen wird, können Sie die folgende Logik verwenden, um das Ereignis zu verarbeiten:

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

Nachrichtenabfang

Mit dem Web Receiver SDK kann Ihre Web Receiver App Nachrichten abfangen und benutzerdefinierten Code auf diesen Nachrichten ausführen. Der Nachrichten-Abfangmechanismus nimmt einen Parameter cast.framework.messages.MessageType entgegen, der angibt, welche Art von Nachricht abgefangen werden soll.

Der Interceptor sollte die geänderte Anfrage oder ein Promise zurückgeben, das mit dem geänderten Anfragewert aufgelöst wird. Wenn Sie null zurückgeben, wird der Standard-Nachrichten-Handler nicht aufgerufen. Weitere Informationen finden Sie unter Medien laden.

Wenn Sie beispielsweise die Daten der Ladeanfrage ändern möchten, können Sie sie mit der folgenden Logik abfangen und ändern:

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

Fehlerbehandlung

Wenn beim Nachrichten-Interceptor Fehler auftreten, sollte Ihre Web-Empfänger-App einen geeigneten cast.framework.messages.ErrorType und cast.framework.messages.ErrorReason zurückgeben.

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

Nachrichtenabfang im Vergleich zu Event-Listener

Die wichtigsten Unterschiede zwischen Nachrichtenabfang und Ereignislistenern:

  • Mit einem Ereignis-Listener können Sie die Anfragedaten nicht ändern.
  • Ereignis-Listener eignen sich am besten zum Auslösen von Analysen oder benutzerdefinierten Funktionen.
playerManager.addEventListener(cast.framework.events.category.CORE,
    event => {
        console.log(event);
    });
  • Mit dem Abfangen von Nachrichten können Sie eine Nachricht abhören, abfangen und die Anfragedaten selbst ändern.
  • Die Nachrichtenabfangung eignet sich am besten für die Verarbeitung benutzerdefinierter Logik im Hinblick auf Anfragedaten.

Medien werden geladen

MediaInformation bietet zahlreiche Properties zum Laden von Medien in der cast.framework.messages.MessageType.LOAD-Nachricht, darunter entity, contentUrl und contentId.

  • Die entity sollte sowohl in der Implementierung Ihrer Sender- als auch Ihrer Empfänger-App verwendet werden. Die Property ist eine Deeplink-URL, die entweder eine Playlist oder Medieninhalte sein kann. Ihre Anwendung sollte diese URL parsen und mindestens eines der beiden anderen Felder ausfüllen.
  • contentUrl entspricht der URL, über die der Player die Inhalte abspielt. Diese URL kann beispielsweise auf ein DASH-Manifest verweisen.
  • Die contentId kann entweder eine URL für abspielbare Inhalte (ähnlich der URL für die contentUrl-Eigenschaft) oder eine eindeutige Kennung für die geladenen Inhalte oder Playlists sein. Wenn du diese Property als Kennung verwendest, sollte deine Anwendung eine abspielbare URL in contentUrl einfügen.

Wir empfehlen, entity zum Speichern der tatsächlichen ID oder der Schlüsselparameter und contentUrl für die URL der Medien zu verwenden. Ein Beispiel dafür findest du im folgenden Snippet, in dem die entity in der LOAD-Anfrage vorhanden ist und die abspielbare contentUrl abgerufen wird:

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

Gerätefunktionen

Die Methode getDeviceCapabilities liefert Geräteinformationen zum verbundenen Cast-Gerät und zum daran angeschlossenen Video- oder Audiogerät. Die getDeviceCapabilities-Methode bietet Supportinformationen für Google Assistant, Bluetooth sowie die verbundenen Display- und Audiogeräte.

Diese Methode gibt ein Objekt zurück, das du abfragen kannst, indem du einen der angegebenen Enumerationen übergibst, um die Gerätefunktion für diese Enumeration abzurufen. Die Enumerationen sind in cast.framework.system.DeviceCapabilities definiert.

In diesem Beispiel wird geprüft, ob das Webreceiver-Gerät HDR und DolbyVision (DV) mit den Tasten IS_HDR_SUPPORTED und IS_DV_SUPPORTED wiedergeben kann.

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

Nutzerinteraktionen verarbeiten

Nutzer können über Sender-Apps (Web, Android und iOS), Sprachbefehle auf Geräten mit integriertem Assistant, Touchbedienung auf Smart Displays und Fernbedienungen auf Android TV-Geräten mit deiner Webreceiver-App interagieren. Das Cast SDK bietet verschiedene APIs, mit denen die Web-Empfänger-App diese Interaktionen verarbeiten, die Benutzeroberfläche der Anwendung über Nutzeraktionsstatus aktualisieren und optional die Änderungen zum Aktualisieren von Backend-Diensten senden kann.

Unterstützte Medienbefehle

Die Status der UI-Steuerelemente werden vom MediaStatus.supportedMediaCommands für erweiterte Sender-Controller, Receiver- und Fernbedienungs-Apps auf iOS- und Android-Geräten sowie Receiver-Apps auf Android TV-Geräten gesteuert. Wenn eine bestimmte binäre Command in der Property aktiviert ist, werden die Schaltflächen für diese Aktion aktiviert. Wenn der Wert nicht festgelegt ist, ist die Schaltfläche deaktiviert. So kannst du diese Werte im Webreceiver ändern:

  1. Mit PlayerManager.setSupportedMediaCommands die spezifische Commands festlegen
  2. Neuen Befehl mit addSupportedMediaCommands hinzufügen
  3. Entfernen eines vorhandenen Befehls mit removeSupportedMediaCommands
playerManager.setSupportedMediaCommands(cast.framework.messages.Command.SEEK |
  cast.framework.messages.Command.PAUSE);

Wenn der Empfänger die aktualisierte MediaStatus vorbereitet, werden die Änderungen an der Property supportedMediaCommands berücksichtigt. Wenn der Status gesendet wird, aktualisieren die verbundenen Sender-Apps die Schaltflächen in ihrer Benutzeroberfläche entsprechend.

Weitere Informationen zu unterstützten Medienbefehlen und Touchbedienung finden Sie im Leitfaden für Accessing UI controls.

Status von Nutzeraktionen verwalten

Wenn Nutzer mit der Benutzeroberfläche interagieren oder Sprachbefehle senden, können sie die Wiedergabe der Inhalte und Eigenschaften steuern, die sich auf das wiedergegebene Element beziehen. Anfragen, die die Wiedergabe steuern, werden vom SDK automatisch verarbeitet. Anfragen, die Eigenschaften für das aktuell wiedergegebene Element ändern, z. B. ein LIKE-Befehl, müssen von der Empfängeranwendung verarbeitet werden. Das SDK bietet eine Reihe von APIs zur Verarbeitung dieser Arten von Anfragen. Für diese Anfragen müssen folgende Voraussetzungen erfüllt sein:

  • Lege beim Laden eines Medienelements die MediaInformation userActionStates mit den Einstellungen des Nutzers fest.
  • USER_ACTION-Nachrichten abfangen und die angeforderte Aktion ermitteln
  • Aktualisieren Sie die MediaInformation UserActionState, um die Benutzeroberfläche zu aktualisieren.

Im folgenden Snippet wird die LOAD-Anfrage abgefangen und die MediaInformation von LoadRequestData ausgefüllt. In diesem Fall gefällt dem Nutzer der Inhalt, der geladen wird.

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

Im folgenden Snippet wird die USER_ACTION-Nachricht abgefangen und das Backend mit der angeforderten Änderung aufgerufen. Anschließend wird ein Aufruf zum Aktualisieren des UserActionState auf dem Empfänger ausgeführt.

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

Im folgenden Snippet wird ein Aufruf eines Backend-Dienstes simuliert. Die Funktion prüft die UserActionRequestData, um die Art der Änderung zu ermitteln, die der Nutzer angefordert hat, und ruft nur dann einen Netzwerkaufruf auf, wenn die Aktion vom Backend unterstützt wird.

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

Im folgenden Snippet wird der UserActionRequestData verwendet, um dem MediaInformation entweder den UserActionState hinzuzufügen oder ihn daraus zu entfernen. Wenn Sie die UserActionState des MediaInformation aktualisieren, ändert sich der Status der Schaltfläche, die mit der angeforderten Aktion verknüpft ist. Diese Änderung ist in der Benutzeroberfläche der Smart-Display-Steuerung, in der Fernbedienungs-App und in der Android TV-Benutzeroberfläche zu sehen. Außerdem wird er über ausgehende MediaStatus-Nachrichten gesendet, um die Benutzeroberfläche des erweiterten Controllers für iOS- und Android-Absender zu aktualisieren.

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

Sprachbefehle

Die folgenden Medienbefehle werden derzeit im Web Receiver SDK für Geräte mit integriertem Assistant unterstützt. Die Standardimplementierungen dieser Befehle finden Sie unter cast.framework.PlayerManager.

Befehl Beschreibung
Spielen Wiedergabe starten oder fortsetzen, wenn sie pausiert wurde.
Pausieren Pausieren Sie die aktuell wiedergegebenen Inhalte.
Zurück Zum vorherigen Medienelement in der Medienwarteschlange springen.
Weiter Zum nächsten Medienelement in der Medienwarteschlange springen.
Beenden Beenden Sie die Wiedergabe der aktuell abgespielten Medien.
Kein Element wiederholen Deaktivieren Sie die Wiederholung von Medienelementen in der Warteschlange, sobald das letzte Element in der Warteschlange wiedergegeben wurde.
Einzelne Wiederholung Die aktuell abgespielten Medien werden unbegrenzt wiederholt.
Alle wiederholen Alle Elemente in der Warteschlange werden wiederholt, sobald der letzte Artikel in der Warteschlange abgespielt wurde.
Alle wiedergeben und Zufallsmix Sobald das letzte Element in der Warteschlange abgespielt wurde, wird die Warteschlange neu gemischt und alle Elemente werden wiederholt.
Zufallsmix Medienelemente in der Medienwarteschlange werden zufällig abgespielt.
Untertitel AN / AUS Untertitel für Ihre Medien aktivieren oder deaktivieren Die Optionen „Aktivieren“ und „Deaktivieren“ sind auch nach Sprache verfügbar.
Springen zu absoluter Zeit Springt zur angegebenen absoluten Zeit.
Zu einer Zeit springen, die relativ zur aktuellen Zeit ist Springt relativ zur aktuellen Wiedergabezeit um den angegebenen Zeitraum vor- oder zurück.
Noch einmal spielen Die aktuell abgespielten Medien neu starten oder das zuletzt abgespielte Medienelement wiedergeben, falls gerade nichts abgespielt wird.
Wiedergabegeschwindigkeit festlegen Die Wiedergabegeschwindigkeit von Medien variieren Das sollte standardmäßig der Fall sein. Mit dem Nachrichten-Interceptor SET_PLAYBACK_RATE kannst du eingehende Preisanfragen überschreiben.

Unterstützte Sprachbefehle für Medien

Wenn Sie verhindern möchten, dass ein Sprachbefehl einen Medienbefehl auf einem Gerät mit integriertem Assistant auslöst, müssen Sie zuerst die unterstützten Medienbefehle festlegen, die Sie unterstützen möchten. Anschließend müssen Sie diese Befehle erzwingen, indem Sie die Property CastReceiverOptions.enforceSupportedCommands aktivieren. Die Benutzeroberfläche von Cast SDK-Sendern und Touch-fähigen Geräten wird entsprechend angepasst. Wenn das Flag nicht aktiviert ist, werden eingehende Sprachbefehle ausgeführt.

Wenn Sie beispielsweise PAUSE von Ihren Absenderanwendungen und Touch-fähigen Geräten zulassen, müssen Sie auch Ihren Empfänger entsprechend konfigurieren. Wenn die Funktion konfiguriert ist, werden alle eingehenden Sprachbefehle abgelehnt, die nicht in der Liste der unterstützten Befehle enthalten sind.

Im folgenden Beispiel wird CastReceiverOptions beim Starten von CastReceiverContext angegeben. Wir haben den Befehl PAUSE hinzugefügt und den Player so konfiguriert, dass er nur diesen Befehl unterstützt. Wenn jetzt ein Sprachbefehl einen anderen Vorgang wie SEEK anfordert, wird er abgelehnt. Der Nutzer wird darüber informiert, dass der Befehl noch nicht unterstützt wird.

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

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

Sie können für jeden Befehl, den Sie einschränken möchten, eine separate Logik anwenden. Entfernen Sie das enforceSupportedCommands-Flag und für jeden Befehl, den Sie einschränken möchten, können Sie die eingehende Nachricht abfangen. Hier wird die vom SDK bereitgestellte Anfrage abgefangen, damit SEEK-Befehle, die an Assistant-kompatible Geräte gesendet werden, keine Suche in Ihrer Web-Empfängeranwendung auslösen.

Gib für Medienbefehle, die von deiner Anwendung nicht unterstützt werden, einen geeigneten Fehlergrund zurück, z. B. 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;
  });

Hintergrundmodus bei Sprachaktivitäten

Wenn die Cast-Plattform den Ton Ihrer Anwendung aufgrund von Assistant-Aktivitäten wie dem Zuhören auf Nutzersprache oder dem Beantworten von Fragen stummschaltet, wird beim Starten der Aktivität eine FocusState-Nachricht mit NOT_IN_FOCUS an die Web-Empfängeranwendung gesendet. Wenn die Aktivität endet, wird eine weitere Nachricht mit IN_FOCUS gesendet. Je nach Anwendung und abgespielten Medien können Sie die Medien pausieren, wenn FocusState = NOT_IN_FOCUS ist, indem Sie den Nachrichtentyp FOCUS_STATE abfangen.

Beispielsweise ist es für die Nutzerfreundlichkeit vorteilhaft, die Hörbuchwiedergabe zu pausieren, wenn Assistant auf eine Nutzeranfrage antwortet.

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

Von der Stimme angegebene Untertitelsprache

Wenn ein Nutzer die Sprache für die Untertitel nicht explizit angibt, wird die Sprache verwendet, in der der Befehl gesprochen wurde. In diesen Fällen gibt der Parameter isSuggestedLanguage der eingehenden Nachricht an, ob die zugehörige Sprache vom Nutzer vorgeschlagen oder ausdrücklich angefordert wurde.

Für den Befehl „Hey Google, aktiviere die Untertitel“ ist isSuggestedLanguage beispielsweise auf true festgelegt, weil die Sprache anhand der Sprache abgeleitet wurde, in der der Befehl gesprochen wurde. Wenn die Sprache explizit angefordert wird, z. B. mit „Hey Google, aktiviere englische Untertitel“, wird isSuggestedLanguage auf false gesetzt.

Metadaten und Sprachstreams

Sprachbefehle werden standardmäßig vom Webreceiver verarbeitet. Die Metadaten für deine Inhalte sollten jedoch vollständig und korrekt sein. So werden Sprachbefehle von Assistant richtig verarbeitet und die Metadaten werden in neuen Benutzeroberflächen wie der Google Home App und Smart Displays wie Google Home Hub korrekt angezeigt.

Stream-Übertragung

Die Aufrechterhaltung des Sitzungsstatus ist die Grundlage der Streamübertragung, bei der Nutzer vorhandene Audio- und Videostreams per Sprachbefehl, über die Google Home App oder über Smart Displays zwischen Geräten verschieben können. Die Medienwiedergabe wird auf einem Gerät (der Quelle) beendet und auf einem anderen (dem Ziel) fortgesetzt. Jedes Cast-Gerät mit der neuesten Firmware kann als Quelle oder Ziel in einer Streamübertragung dienen.

Die Ereignisabfolge für die Streamübertragung ist:

  1. Auf dem Quellgerät:
    1. Die Medienwiedergabe wird beendet.
    2. Die Web-Empfängeranwendung erhält einen Befehl zum Speichern des aktuellen Medienstatus.
    3. Die Web-Empfängeranwendung wird geschlossen.
  2. Auf dem Zielgerät:
    1. Die Web-Empfängeranwendung wird geladen.
    2. Die Webanwendung für den Empfänger erhält einen Befehl, den gespeicherten Medienstatus wiederherzustellen.
    3. Die Medienwiedergabe wird fortgesetzt.

Zu den Elementen des Medienstatus gehören:

  • Bestimmte Position oder Zeitstempel des Songs, Videos oder Medienelements.
  • Seine Position in einer größeren Wiedergabeliste (z. B. einer Playlist oder einem Künstlerradio)
  • Der authentifizierte Nutzer.
  • Wiedergabestatus (z. B. „Wiedergabe“ oder „Pausiert“)

Streamübertragung aktivieren

So implementierst du die Streamübertragung für deinen Webempfänger:

  1. Aktualisieren Sie supportedMediaCommands mit dem Befehl STREAM_TRANSFER:
    playerManager.addSupportedMediaCommands(
    cast.framework.messages.Command.STREAM_TRANSFER, true);
  2. Optional kannst du die SESSION_STATE- und RESUME_SESSION-Nachrichten-Interceptors überschreiben, wie unter Sitzungsstatus beibehalten beschrieben. Überschreiben Sie diese nur, wenn benutzerdefinierte Daten als Teil des Sitzungs-Snapshots gespeichert werden müssen. Andernfalls wird die Streamübertragung von der Standardimplementierung zum Speichern von Sitzungsstatus unterstützt.

Sitzungsstatus beibehalten

Das Web Receiver SDK bietet eine Standardimplementierung für Web Receiver-Apps, mit der Sitzungsstatus beibehalten werden. Dazu wird ein Snapshot des aktuellen Medienstatus erstellt, der Status in eine Ladeanfrage umgewandelt und die Sitzung mit der Ladeanfrage fortgesetzt.

Die vom Webreceiver generierte Ladeanfrage kann bei Bedarf im SESSION_STATE-Nachrichten-Interceptor überschrieben werden. Wenn Sie benutzerdefinierte Daten in die Ladeanfrage einfügen möchten, empfehlen wir, sie in loadRequestData.customData einzufügen.

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

Die benutzerdefinierten Daten können im RESUME_SESSION-Nachrichten-Interceptor aus loadRequestData.customData abgerufen werden.

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

Vorabladen von Inhalten

Der Webreceiver unterstützt das Vorabladen von Medienelementen nach dem aktuellen Wiedergabeelement in der Wiedergabeliste.

Beim Vorabladen werden mehrere Segmente der anstehenden Elemente vorab heruntergeladen. Die Angabe erfolgt über den Wert preloadTime im Objekt QueueItem. Wenn dieser Wert nicht angegeben ist, wird standardmäßig 20 Sekunden verwendet. Die Zeit wird in Sekunden relativ zum Ende des aktuell wiedergegebenen Elements angegeben . Nur positive Werte sind zulässig. Wenn der Wert beispielsweise 10 Sekunden beträgt, wird dieser Artikel 10 Sekunden vor dem Ende des vorherigen Artikels vorab geladen. Wenn die Zeit für das Vorladen länger ist als die verbleibende Zeit für das aktuelle Element, erfolgt das Vorladen so bald wie möglich. Wenn also für das QueueItem ein sehr hoher Wert für „preload“ angegeben wird, kann das dazu führen, dass beim Abspielen des aktuellen Elements bereits das nächste Element vorab geladen wird. Die Einstellung und Auswahl dieser Option obliegt jedoch dem Entwickler, da sich dieser Wert auf die Bandbreite und Streamingleistung des aktuell wiedergegebenen Elements auswirken kann.

Das Vorladen funktioniert standardmäßig für HLS-, DASH- und Smooth-Streaming-Inhalte.

Normale MP4-Video- und Audiodateien wie MP3 werden nicht vorab geladen, da Streaminggeräte nur ein Medienelement unterstützen und nicht zum Vorladen verwendet werden können, während ein vorhandener Inhalt noch wiedergegeben wird.

Benutzerdefinierte Nachrichten

Der Nachrichtenaustausch ist die wichtigste Interaktionsmethode für Web Receiver-Anwendungen.

Ein Absender sendet Nachrichten an einen Webempfänger mithilfe der Absender-APIs für die Plattform, die der Absender verwendet (Android, iOS, Web). Das Ereignisobjekt (die Manifestierung einer Nachricht), das an die Ereignis-Listener übergeben wird, enthält ein Datenelement (event.data), in dem die Daten die Eigenschaften des jeweiligen Ereignistyps annehmen.

Eine Web-Empfängeranwendung kann Nachrichten in einem bestimmten Namespace abhören. Dadurch wird die Web-Empfängeranwendung als Unterstützer dieses Namespace-Protokolls bezeichnet. Es liegt dann an den verbundenen Absendern, die in diesem Namespace kommunizieren möchten, das entsprechende Protokoll zu verwenden.

Alle Namespaces werden durch einen String definiert und müssen mit „urn:x-cast:“ beginnen, gefolgt von einem beliebigen String. Beispiel: „urn:x-cast:com.example.cast.mynamespace“.

Hier ist ein Code-Snippet für den Webempfänger, um benutzerdefinierte Nachrichten von verbundenen Absendern zu empfangen:

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

Webreceiver-Anwendungen können Absender auch über den Status des Webreceivers informieren, indem sie Nachrichten an verbundene Absender senden. Eine Web-Empfängeranwendung kann Nachrichten über sendCustomMessage(namespace, senderId, message) auf CastReceiverContext senden. Ein Web-Empfänger kann Nachrichten an einen einzelnen Absender senden, entweder als Antwort auf eine empfangene Nachricht oder aufgrund einer Änderung des Anwendungsstatus. Neben Point-to-Point-Messaging (mit einer Beschränkung von 64 KB) kann ein Webempfänger auch Nachrichten an alle verbundenen Absender senden.

Für Audiogeräte streamen

Weitere Informationen zur reinen Audiowiedergabe findest du im Leitfaden für Google Cast auf Audiogeräten.

Android TV

In diesem Abschnitt wird erläutert, wie der Google Web-Receiver deine Eingaben für die Wiedergabe verwendet, und es wird auf die Kompatibilität mit Android TV eingegangen.

Anwendung in die Fernbedienung einbinden

Der Google Webreceiver, der auf dem Android TV-Gerät ausgeführt wird, übersetzt Eingaben von den Steuereingängen des Geräts (z.B. die Handfernbedienung) in Nachrichten zur Medienwiedergabe, die für den urn:x-cast:com.google.cast.media-Namespace definiert sind, wie unter Nachrichten zur Medienwiedergabe beschrieben. Ihre Anwendung muss diese Nachrichten unterstützen, um die Medienwiedergabe der Anwendung zu steuern und eine grundlegende Wiedergabesteuerung über die Steuereingaben von Android TV zu ermöglichen.

Richtlinien für die Kompatibilität mit Android TV

Hier sind einige Empfehlungen und häufige Fallstricke, die Sie vermeiden sollten, damit Ihre App mit Android TV kompatibel ist:

  • Der User-Agent-String enthält sowohl „Android“ als auch „CrKey“. Einige Websites werden möglicherweise auf eine nur für Mobilgeräte optimierte Website weitergeleitet, weil das Label „Android“ erkannt wird. Anhand des User-Agent-Strings kann nicht immer davon ausgegangen werden, dass es sich um einen mobilen Nutzer handelt.
  • Der Media-Stack von Android verwendet möglicherweise transparentes GZIP zum Abrufen von Daten. Achte darauf, dass deine Mediendaten auf Accept-Encoding: gzip reagieren können.
  • HTML5-Medienereignisse auf Android TV werden möglicherweise zu anderen Zeitpunkten als auf Chromecast ausgelöst. Dadurch können Probleme aufgedeckt werden, die auf Chromecast nicht sichtbar waren.
  • Verwende beim Aktualisieren der Medien medienbezogene Ereignisse, die von <audio>/<video>-Elementen wie timeupdate, pause und waiting ausgelöst werden. Verwenden Sie keine netzwerkbezogenen Ereignisse wie progress, suspend und stalled, da diese in der Regel plattformabhängig sind. Weitere Informationen zum Umgang mit Medienereignissen in deinem Receiver findest du unter Medienereignisse.
  • Achten Sie beim Konfigurieren der HTTPS-Zertifikate Ihrer Empfängerwebsite darauf, Zwischenzertifizierungsstellenzertifikate anzugeben. Auf der Qualsys-SSL-Testseite können Sie prüfen, ob der vertrauenswürdige Zertifizierungspfad für Ihre Website ein CA-Zertifikat mit dem Label „Zusätzlicher Download“ enthält. Wenn das der Fall ist, wird es möglicherweise nicht auf Android-basierten Plattformen geladen.
  • Während Chromecast die Seite des Empfängers auf einer 720p-Grafikebene anzeigt, kann die Seite auf anderen Streaming-Plattformen wie Android TV mit bis zu 1080p angezeigt werden. Achte darauf, dass deine Empfängerseite bei verschiedenen Auflösungen flüssig skaliert.