Zentrale Funktionen zu Ihrem benutzerdefinierten Web-Receiver hinzufügen

Auf dieser Seite finden Sie Code-Snippets und Beschreibungen der Funktionen, die für eine benutzerdefinierte Web Receiver-App verfügbar sind.

  1. Ein cast-media-player-Element, das die integrierte Player-Benutzeroberfläche darstellt, die mit dem Web Receiver bereitgestellt wird.
  2. Benutzerdefinierte CSS-ähnliche Formatierung für das cast-media-player-Element zum Formatieren verschiedener UI-Elemente wie background-image, splash-image und font-family.
  3. Ein Skriptelement zum Laden des Web Receiver-Frameworks.
  4. JavaScript-Code zum Abfangen von Nachrichten und Verarbeiten von Ereignissen.
  5. Wiedergabeliste für die automatische Wiedergabe.
  6. Optionen zum Konfigurieren der Wiedergabe.
  7. Optionen zum Festlegen des Web Receiver-Kontexts.
  8. Optionen zum Festlegen von Befehlen, die von der Web Receiver-App unterstützt werden.
  9. Ein JavaScript-Aufruf zum Starten der Web Receiver-Anwendung.

Anwendungskonfiguration und ‑optionen

Anwendung konfigurieren

Die Klasse 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 sehen Sie, wie Sie das Standardverhalten für die Erkennung überschreiben, ob eine Senderverbindung noch aktiv ist. Wenn der Web Receiver maxInactivity Sekunden lang nicht mit einem Sender kommunizieren konnte, wird ein SENDER_DISCONNECTED-Ereignis gesendet. Mit der folgenden Konfiguration wird dieses Zeitlimit überschrieben. Das kann bei der Fehlerbehebung hilfreich sein, da verhindert wird, dass die Web Receiver-App die Chrome Remote Debugger-Sitzung schließt, wenn sich keine verbundenen Absender im Status IDLE befinden.

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, Konfigurationen für Wiederholungsversuche und Anfrage-Handler mit cast.framework.PlaybackConfig zu konfigurieren. Diese Informationen werden von PlayerManager verarbeitet und zum Zeitpunkt der Erstellung der Player ausgewertet. Player werden jedes Mal erstellt, wenn eine neue Last an das Web Receiver SDK übergeben wird. Änderungen an PlaybackConfig nach der Erstellung des Players werden beim nächsten Laden von Inhalten berücksichtigt. Das SDK bietet die folgenden Methoden zum Ändern der PlaybackConfig.

  • CastReceiverOptions.playbackConfig um die Standardkonfigurationsoptionen beim Initialisieren von 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 Media-Element anzuwenden, das zusätzlich zu den aktuellen Konfigurationen geladen wird. Der Handler wird kurz vor der Erstellung des Players aufgerufen. Änderungen, die Sie hier vornehmen, sind nicht dauerhaft und werden nicht in Anfragen an getPlaybackConfig() berücksichtigt. Wenn das nächste Medienelement geladen wird, wird dieser Handler noch einmal aufgerufen.

Im folgenden Beispiel sehen Sie, wie PlaybackConfig beim Initialisieren von CastReceiverContext festgelegt wird. Die Konfiguration überschreibt ausgehende Anfragen zum Abrufen von Manifesten. Der Handler gibt an, dass CORS-Access-Control-Anfragen mit Anmeldedaten wie Cookies oder Autorisierungsheadern gestellt werden sollen.

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

Das folgende Beispiel zeigt, wie Sie PlaybackConfig mit dem Getter und Setter in PlayerManager überschreiben. 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 Sie PlaybackConfig für eine bestimmte Ladeanfrage mit dem Handler für Medienwiedergabeinformationen überschreiben. Der Handler ruft eine von der Anwendung implementierte Methode getLicenseUrlForMedia auf, um das licenseUrl aus dem contentId des aktuellen Elements abzurufen.

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

  return playbackConfig;
});

Event-Listener

Mit dem Web Receiver SDK kann Ihre Web Receiver-App Player-Ereignisse verarbeiten. Der Event-Listener akzeptiert einen cast.framework.events.EventType-Parameter (oder ein Array dieser Parameter), der die Ereignisse angibt, die den Listener auslösen sollen. Vorkonfigurierte Arrays von cast.framework.events.EventType, die für das Debugging 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 von mediaStatus übertragen wird, können Sie das Ereignis mit der folgenden Logik 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
});

Abfangen von Nachrichten

Mit dem Web Receiver SDK kann Ihre Web Receiver-App Nachrichten abfangen und benutzerdefinierten Code für diese Nachrichten ausführen. Der Nachrichten-Interceptor verwendet einen cast.framework.messages.MessageType-Parameter, der angibt, welcher Nachrichtentyp 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 Standardnachrichten-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 im Message Interceptor Fehler auftreten, sollte Ihre Web Receiver-App einen entsprechenden cast.framework.messages.ErrorType- und cast.framework.messages.ErrorReason-Wert 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

Hier einige wichtige Unterschiede zwischen dem Abfangen von Nachrichten und dem Event-Listener:

  • Mit einem Event-Listener können Sie die Anforderungsdaten nicht ändern.
  • Ein Event-Listener eignet sich am besten zum Auslösen von Analysen oder einer benutzerdefinierten Funktion.
playerManager.addEventListener(cast.framework.events.category.CORE,
    event => {
        console.log(event);
    });
  • Mit dem Abfangen von Nachrichten können Sie sich eine Nachricht anhören, sie abfangen und die Anforderungsdaten selbst ändern.
  • Das Abfangen von Nachrichten eignet sich am besten für die Verarbeitung benutzerdefinierter Logik in Bezug auf Anfragedaten.

Medien werden geladen

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

  • Das Attribut entity ist das empfohlene Attribut für die Implementierung in Ihren Sender- und Empfänger-Apps. 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.
  • Die contentUrl entspricht der abspielbaren URL, die der Player zum Laden der Inhalte verwendet. Diese URL könnte beispielsweise auf ein DASH-Manifest verweisen.
  • Die contentId kann entweder eine URL für abspielbare Inhalte (ähnlich der contentUrl-Eigenschaft) oder eine eindeutige ID für die geladenen Inhalte oder die geladene Playlist sein. Wenn Sie diese Property als Kennzeichnung verwenden, sollte in Ihrer Anwendung eine abspielbare URL in contentUrl eingefügt werden.

Wir empfehlen, entity zum Speichern der tatsächlichen ID oder der Schlüsselparameter und contentUrl für die URL des Mediums zu verwenden. Ein Beispiel dafür ist im folgenden Snippet zu sehen, in dem entity in der LOAD-Anfrage vorhanden ist und das 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 Methode getDeviceCapabilities bietet Supportinformationen für Google Assistant, Bluetooth sowie das verbundene Display und die verbundenen Audiogeräte.

Diese Methode gibt ein Objekt zurück, das Sie abfragen können, indem Sie eines der angegebenen Enums übergeben, um die Gerätefunktion für dieses Enum abzurufen. Die Enums sind in cast.framework.system.DeviceCapabilities definiert.

In diesem Beispiel wird geprüft, ob das Web Receiver-Gerät HDR und DolbyVision (DV) mit den Tasten IS_HDR_SUPPORTED bzw. 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 mit Ihrer Web Receiver-Anwendung über Senderanwendungen (Web, Android und iOS), Sprachbefehle auf Assistant-fähigen Geräten, Touch-Steuerelemente auf Smart Displays und Fernbedienungen auf Android TV-Geräten interagieren. Das Cast SDK bietet verschiedene APIs, mit denen die Web Receiver-App diese Interaktionen verarbeiten, die Benutzeroberfläche der Anwendung über Nutzeraktionsstatus aktualisieren und die Änderungen optional senden kann, um Backend-Dienste zu aktualisieren.

Unterstützte Medienbefehle

Die Status der UI-Steuerelemente werden durch die MediaStatus.supportedMediaCommands für erweiterte Controller für iOS- und Android-Absender, Receiver- und Fernbedienungs-Apps auf Touchgeräten sowie Receiver-Apps auf Android TV-Geräten bestimmt. Wenn ein bestimmtes bitweises Command in der Property aktiviert ist, werden die Schaltflächen aktiviert, die sich auf diese Aktion beziehen. Wenn der Wert nicht festgelegt ist, wird die Schaltfläche deaktiviert. Diese Werte können auf dem Web Receiver geändert werden:

  1. PlayerManager.setSupportedMediaCommands verwenden, um die spezifische Commands festzulegen
  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 in das Attribut supportedMediaCommands aufgenommen. Wenn der Status übertragen wird, aktualisieren die verbundenen Sender-Apps die Schaltflächen in ihrer Benutzeroberfläche entsprechend.

Weitere Informationen zu unterstützten Medienbefehlen und Touch-Geräten finden Sie im Accessing UI controls-Leitfaden.

Status von Nutzeraktionen verwalten

Wenn Nutzer mit der Benutzeroberfläche interagieren oder Sprachbefehle senden, können sie die Wiedergabe der Inhalte und die Eigenschaften des wiedergegebenen Elements steuern. Anfragen zur Steuerung der Wiedergabe werden automatisch vom SDK verarbeitet. Anfragen, mit denen Eigenschaften für das aktuell wiedergegebene Element geändert werden, z. B. ein LIKE-Befehl, müssen von der Empfängeranwendung verarbeitet werden. Das SDK bietet eine Reihe von APIs für diese Arten von Anfragen. Damit diese Anfragen bearbeitet werden können, müssen folgende Voraussetzungen erfüllt sein:

  • Legen Sie MediaInformation userActionStates beim Laden eines Media-Elements mit den Einstellungen eines Nutzers fest.
  • Fange USER_ACTION-Nachrichten ab und ermittle die angeforderte Aktion.
  • Aktualisieren Sie die MediaInformation UserActionState, um die Benutzeroberfläche zu aktualisieren.

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

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

Das folgende Snippet fängt die USER_ACTION-Nachricht ab und ruft das Backend mit der angeforderten Änderung auf. Anschließend wird ein Aufruf ausgeführt, um das UserActionState auf dem Empfänger zu aktualisieren.

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

Das folgende Snippet simuliert einen Aufruf eines Backend-Dienstes. Die Funktion prüft UserActionRequestData, um den Typ der vom Nutzer angeforderten Änderung zu ermitteln, und führt nur dann einen Netzwerkaufruf aus, 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 die UserActionRequestData verwendet, um die UserActionState der MediaInformation hinzuzufügen oder daraus zu entfernen. Durch das Aktualisieren des UserActionState des MediaInformation wird der Status der Schaltfläche geändert, die mit der angeforderten Aktion verknüpft ist. Diese Änderung wird in der Benutzeroberfläche für die Smart-Display-Steuerung, in der App für die Fernbedienung und in der Android TV-Benutzeroberfläche angezeigt. Sie wird auch über ausgehende MediaStatus-Nachrichten übertragen, 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 Media-Befehle werden derzeit im Web Receiver SDK für Assistant-fähige Geräte unterstützt. Die Standardimplementierungen dieser Befehle finden Sie unter cast.framework.PlayerManager.

Befehl Beschreibung
Spielen Wiedergabe starten oder aus dem pausierten Zustand fortsetzen.
Pausieren Aktuell wiedergegebene Inhalte pausieren
Zurück Zum vorherigen Media-Element in der Media-Wiedergabeliste springen
Weiter Zum nächsten Media-Element in der Media-Wiedergabeliste springen
Beenden Die aktuell wiedergegebenen Medien werden beendet.
Kein Element wiederholen Wiederholung von Media-Elementen in der Warteschlange deaktivieren, sobald das letzte Element in der Warteschlange abgespielt wurde.
Einzelnen Titel wiederholen Die aktuell wiedergegebenen Medien werden unbegrenzt wiederholt.
Alle wiederholen Alle Elemente in der Warteschlange werden wiederholt, sobald das letzte Element in der Warteschlange abgespielt wurde.
Alle wiederholen und zufällige Reihenfolge Wenn das letzte Element in der Warteschlange abgespielt wurde, wird die Warteschlange gemischt und alle Elemente in der Warteschlange werden wiederholt.
Zufallsmix Media-Elemente in der Media-Warteschlange mischen.
Untertitel AN / AUS Aktivieren / Deaktivieren Sie Untertitel für Ihre Medien. Die Aktivierung / Deaktivierung ist auch nach Sprache möglich.
Springen zur absoluten Zeit Springt zur angegebenen absoluten Zeit.
Zeit relativ zur aktuellen Zeit suchen Springt relativ zur aktuellen Wiedergabezeit um den angegebenen Zeitraum vorwärts oder rückwärts.
Nochmal spielen Startet die aktuell wiedergegebenen Medien neu oder spielt das zuletzt wiedergegebene Media-Element ab, wenn gerade nichts wiedergegeben wird.
Wiedergaberate festlegen Wiedergabegeschwindigkeit von Medien ändern Das sollte standardmäßig erfolgen. Mit dem SET_PLAYBACK_RATE-Nachrichten-Interceptor können Sie eingehende Ratenanfragen überschreiben.

Unterstützte Medienbefehle per Sprachsteuerung

Damit ein Sprachbefehl nicht einen Medienbefehl auf einem Assistant-fähigen Gerät 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 auf Cast SDK-Absendern und Touch-Geräten ändert sich entsprechend diesen Konfigurationen. Wenn das Flag nicht aktiviert ist, werden die eingehenden Sprachbefehle ausgeführt.

Wenn Sie beispielsweise PAUSE von Ihren Senderanwendungen und Touch-Geräten zulassen, müssen Sie auch Ihren Receiver entsprechend konfigurieren. Wenn diese Option konfiguriert ist, werden alle eingehenden Sprachbefehle verworfen, die nicht in der Liste der unterstützten Befehle enthalten sind.

Im Beispiel unten wird CastReceiverOptions beim Starten von CastReceiverContext angegeben. Wir haben Unterstützung für den Befehl PAUSE hinzugefügt und den Player so konfiguriert, dass nur dieser Befehl unterstützt wird. Wenn nun per Sprachbefehl ein anderer Vorgang wie SEEK angefordert wird, wird dies 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 fangen Sie die eingehende Nachricht für jeden Befehl ab, den Sie einschränken möchten. Hier fangen wir die vom SDK bereitgestellte Anfrage ab, damit SEEK-Befehle, die an Assistant-fähige Geräte gesendet werden, in Ihrer Web Receiver-Anwendung keine Suche auslösen.

Gib für Media-Befehle, die von deiner Anwendung nicht unterstützt werden, einen entsprechenden 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;
  });

Hintergrundaktivitäten durch Sprachaktivität

Wenn die Cast-Plattform den Ton deiner Anwendung aufgrund von Assistant-Aktivitäten wie dem Zuhören auf die Sprache des Nutzers oder dem Zurücksprechen in den Hintergrund verschiebt, wird beim Start der Aktivität eine FocusState-Nachricht mit dem Wert NOT_IN_FOCUS an die Web Receiver-Anwendung gesendet. Eine weitere Nachricht mit IN_FOCUS wird gesendet, wenn die Aktivität beendet ist. Je nach Anwendung und den abgespielten Medien kann es sinnvoll sein, die Medien zu pausieren, wenn FocusState NOT_IN_FOCUS ist. Dazu fangen Sie den Nachrichtentyp FOCUS_STATE ab.

Es ist beispielsweise eine gute User Experience, die Wiedergabe von Hörbüchern zu pausieren, wenn der 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;
  });

Per Sprache angegebene Untertitelsprache

Wenn ein Nutzer die Sprache für die Untertitel nicht explizit angibt, wird für die Untertitel dieselbe 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 explizit angefordert wurde.

Wenn Sie beispielsweise den Befehl „Ok Google, Untertitel aktivieren“ aussprechen, wird isSuggestedLanguage auf true festgelegt, da die Sprache aus der Sprache abgeleitet wurde, in der der Befehl gesprochen wurde. Wenn die Sprache explizit angefordert wird, z. B. mit „Ok Google, aktiviere englische Untertitel“, wird isSuggestedLanguage auf false gesetzt.

Metadaten und Sprach-Casting

Sprachbefehle werden standardmäßig vom Web Receiver verarbeitet. Sie sollten jedoch darauf achten, dass die Metadaten für Ihre Inhalte vollständig und korrekt sind. So wird sichergestellt, dass Sprachbefehle von Assistant richtig verarbeitet werden und die Metadaten in neuen Arten von Benutzeroberflächen wie der Google Home App und Smart Displays wie dem Google Home Hub richtig angezeigt werden.

Stream-Übertragung

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

Der Ereignisablauf für die Streamübertragung ist:

  1. Auf dem Quellgerät:
    1. Die Medienwiedergabe wird beendet.
    2. Die Web Receiver-Anwendung empfängt einen Befehl zum Speichern des aktuellen Media-Status.
    3. Die Web Receiver-Anwendung wird beendet.
  2. Auf dem Zielgerät:
    1. Die Web Receiver-Anwendung wird geladen.
    2. Die Web Receiver-Anwendung empfängt einen Befehl zum Wiederherstellen des gespeicherten Media-Status.
    3. Die Medienwiedergabe wird fortgesetzt.

Zu den Elementen des Media-Status gehören:

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

Streamübertragung aktivieren

So implementierst du die Streamübertragung für deinen Web Receiver:

  1. Aktualisieren Sie supportedMediaCommands mit dem Befehl STREAM_TRANSFER:
    playerManager.addSupportedMediaCommands(
    cast.framework.messages.Command.STREAM_TRANSFER, true);
  2. Optional können Sie die SESSION_STATE- und RESUME_SESSION-Nachrichten-Interceptoren überschreiben, wie unter Sitzungsstatus beibehalten beschrieben. Überschreiben Sie diese nur, wenn benutzerdefinierte Daten als Teil des Sitzungssnapshots gespeichert werden müssen. Andernfalls wird der Streamtransfer durch die Standardimplementierung zum Beibehalten von Sitzungsstatus unterstützt.

Sitzungsstatus beibehalten

Das Web Receiver SDK bietet eine Standardimplementierung für Web Receiver-Apps, mit der Sitzungsstatus beibehalten werden können. Dazu wird eine Momentaufnahme des aktuellen Media-Status erstellt, der Status in eine Ladeanfrage konvertiert und die Sitzung mit der Ladeanfrage fortgesetzt.

Die vom Web Receiver generierte Ladeanfrage kann bei Bedarf im SESSION_STATE-Nachrichten-Interceptor überschrieben werden. Wenn Sie dem Ladeanfrage benutzerdefinierte Daten hinzufügen möchten, empfehlen wir, diese 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 aus loadRequestData.customData im RESUME_SESSION-Nachrichten-Interceptor 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 Web Receiver unterstützt das Vorabladen von Media-Elementen nach dem aktuellen Wiedergabeelement in der Warteschlange.

Beim Vorab-Download werden mehrere Segmente der bevorstehenden Elemente heruntergeladen. Die Angabe erfolgt über den Wert preloadTime im Objekt QueueItem (Standardwert: 20 Sekunden, wenn nicht angegeben). Die Zeit wird in Sekunden relativ zum Ende des aktuell wiedergegebenen Elements angegeben . Nur positive Werte sind gültig. Wenn der Wert beispielsweise 10 Sekunden beträgt, wird dieses Element 10 Sekunden vor dem Ende des vorherigen Elements vorab geladen. Wenn die Zeit für das Vorladen länger ist als die verbleibende Zeit für das aktuelle Element, wird das Vorladen so schnell wie möglich ausgeführt. Wenn also ein sehr großer Wert für „preload“ im „queueItem“ angegeben ist, kann man erreichen, dass das nächste Element bereits vorgeladen wird, während das aktuelle Element wiedergegeben wird. Die Einstellung und Auswahl dieses Werts überlassen wir jedoch dem Entwickler, da er sich auf die Bandbreite und Streaming-Leistung 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 Cast-Geräte nur ein Media-Element unterstützen und nicht zum Vorabladen verwendet werden können, während ein vorhandenes Inhaltselement noch wiedergegeben wird.

Benutzerdefinierte Nachrichten

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

Ein Absender sendet Nachrichten an einen Web Receiver über die Sender-APIs für die Plattform, auf der der Absender ausgeführt wird (Android, iOS, Web). Das Ereignisobjekt (die Manifestierung einer Nachricht), das an die Ereignis-Listener übergeben wird, hat ein Datenelement (event.data), in dem die Daten die Eigenschaften des jeweiligen Ereignistyps annehmen.

Eine Web Receiver-Anwendung kann Nachrichten in einem bestimmten Namespace empfangen. Dadurch wird gesagt, dass die Web Receiver-Anwendung dieses Namespace-Protokoll unterstützt. Es liegt dann an allen verbundenen Sendern, 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 Web Receiver, mit dem benutzerdefinierte Nachrichten von verbundenen Absendern empfangen werden können:

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

Web Receiver-Anwendungen können verbundene Absender über den Status des Web Receivers informieren, indem sie Nachrichten an sie senden. Eine Web Receiver-Anwendung kann Nachrichten über sendCustomMessage(namespace, senderId, message) auf CastReceiverContext senden. Ein Web Receiver kann Nachrichten an einen einzelnen Absender senden, entweder als Reaktion auf eine empfangene Nachricht oder aufgrund einer Änderung des Anwendungsstatus. Neben der Punkt-zu-Punkt-Nachrichtenübermittlung (mit einem Limit von 64 KB) kann ein Web Receiver auch Nachrichten an alle verbundenen Sender senden.

Auf Audiogeräte streamen

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

Android TV

In diesem Abschnitt wird erläutert, wie der Google Web Receiver Ihre Eingaben für die Wiedergabe verwendet und wie er mit Android TV kompatibel ist.

Anwendung in die Fernbedienung einbinden

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

Richtlinien für die Android TV-Kompatibilität

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

  • Der User-Agent-String enthält sowohl „Android“ als auch „CrKey“. Einige Websites leiten Nutzer möglicherweise auf eine reine Mobilgeräte-Website weiter, da sie das Label „Android“ erkennen. Gehen Sie nicht davon aus, dass „Android“ im User-Agent-String immer auf einen mobilen Nutzer hinweist.
  • Der Media-Stack von Android kann transparentes GZIP zum Abrufen von Daten verwenden. Achten Sie darauf, dass Ihre Mediendaten auf Accept-Encoding: gzip reagieren können.
  • Android TV-HTML5-Media-Ereignisse werden möglicherweise zu anderen Zeiten als auf Chromecast ausgelöst. Dadurch können Probleme aufgedeckt werden, die auf Chromecast verborgen waren.
  • Verwenden Sie beim Aktualisieren der Media-Elemente Media-bezogene Ereignisse, die von <audio>/<video>-Elementen wie timeupdate, pause und waiting ausgelöst werden. Vermeiden Sie die Verwendung von netzwerkbezogenen Ereignissen wie progress, suspend und stalled, da diese in der Regel plattformabhängig sind. Weitere Informationen zum Verarbeiten von Media-Ereignissen in deinem Receiver findest du unter Media-Ereignisse.
  • Achten Sie beim Konfigurieren der HTTPS-Zertifikate Ihrer Empfängerwebsite darauf, dass Sie Zwischenzertifikate der Zertifizierungsstelle einbeziehen. Auf der SSL-Testseite von Qualsys können Sie prüfen, ob der vertrauenswürdige Zertifizierungspfad für Ihre Website ein CA-Zertifikat mit dem Label „extra download“ enthält. Wenn dies der Fall ist, wird die Website auf Android-basierten Plattformen möglicherweise nicht geladen.
  • Während Chromecast die Empfängerseite auf einer 720p-Grafikebene anzeigt, kann die Seite auf anderen Cast-Plattformen wie Android TV mit bis zu 1080p angezeigt werden. Achte darauf, dass deine Empfängerseite bei verschiedenen Auflösungen gut skaliert wird.