Benutzerdefinierten Web-Receiver erstellen

Mit Sammlungen den Überblick behalten Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.

1. Übersicht

Google Cast-Logo

In diesem Codelab erfahren Sie, wie Sie eine benutzerdefinierte Web-Receiver-App erstellen, um Inhalte auf für Google Cast optimierten Geräten wiederzugeben.

Was ist Google Cast?

Mit Google Cast können Nutzer Inhalte von einem Mobilgerät auf einen Fernseher streamen. Nutzer können dann ihr Mobilgerät oder ihren Chrome-Browser als Fernbedienung für die Medienwiedergabe auf dem Fernseher verwenden.

Mit dem Google Cast SDK kann Ihre App Google Cast-fähige Geräte steuern, zum Beispiel einen Fernseher oder ein Soundsystem. Das Cast SDK bietet Ihnen die erforderlichen UI-Komponenten gemäß der Google Cast-Design-Checkliste.

Die Checkliste für das Design von Google Cast soll es Nutzern der Cast-Nutzung auf allen unterstützten Plattformen erleichtern. Weitere Informationen

Ziele

Wenn Sie dieses Codelab abgeschlossen haben, verfügen Sie über eine HTML5-App, die als Ihr eigener benutzerdefinierter Empfänger fungiert und in der Lage ist, Videoinhalte auf für Google Cast optimierten Geräten anzuzeigen.

Lerninhalte

  • Einrichtung für die Empfängerentwicklung
  • Die Grundlagen eines für Google Cast optimierten Empfängers, der auf dem Cast-Anwendungsframework basiert
  • So erhalten Sie ein gestreamtes Video:
  • Debug Logger einbinden
  • Empfänger für Smart Displays optimieren

Voraussetzungen

Plattform

  • Sie benötigen Vorkenntnisse in der Webentwicklung.
  • Außerdem benötigst du Vorkenntnisse zum Fernsehen.

Wie werden Sie diese Anleitung verwenden?

Nur Lesen Lesen und lesen

Wie würden Sie Ihre Erfahrungen im Erstellen von Webanwendungen bewerten?

Neuling Leicht fortgeschrittener Profi

Wie würdest du deine Erfahrung beim Fernsehen bewerten?

Neuling Fortgeschrittener Anfänger Profi

2. Beispielcode abrufen

Sie können den gesamten Beispielcode auf Ihren Computer herunterladen...

und entpacken Sie die heruntergeladene ZIP-Datei.

3. Empfänger lokal bereitstellen

Damit Sie Ihren Webempfänger mit einem Cast-Gerät verwenden können, muss es an einem Ort gehostet werden, an dem Ihr Cast-Gerät darauf zugreifen kann. Wenn Sie bereits einen Server haben, der HTTPS unterstützt, überspringen Sie die folgende Anleitung und schreiben Sie die URL, da Sie sie im nächsten Abschnitt benötigen.

Wenn Sie keinen Server zur Verfügung haben, können Sie Firebase Hosting oder ngrok verwenden.

Server ausführen

Nachdem du einen Dienst deiner Wahl eingerichtet hast, rufe app-start auf und starte deinen Server.

Notieren Sie sich die URL des gehosteten Empfängers. Sie benötigen ihn im nächsten Abschnitt.

4. Anwendung in der Cast Developer Console registrieren

Sie müssen Ihre Anwendung registrieren, um einen benutzerdefinierten Empfänger, wie in diesem Codelab erstellt, auf Chromecast-Geräten auszuführen. Nachdem Sie Ihre Anwendung registriert haben, erhalten Sie eine Anwendungs-ID, die Ihre Absenderanwendung zum Ausführen von API-Aufrufen verwenden muss, z. B. zum Starten einer Empfängeranwendung.

Abbildung der Google Cast SDK Developer Console mit hervorgehobener Schaltfläche „Neue App hinzufügen“

Klicken Sie auf „Neue App hinzufügen“.

Bild des Bildschirms „New Receiver Application“ (Neue Empfängeranwendung) mit markierter Option „Benutzerdefinierter Empfänger“

Wählen Sie „Benutzerdefinierter Empfänger“ aus.

Bild des Bildschirms „Neuer benutzerdefinierter Empfänger“ mit einer URL, die jemand in das Feld „URL der Empfängeranwendung“ eingibt

Geben Sie die Details zum neuen Empfänger ein und verwenden Sie dabei die URL,

im letzten Abschnitt. Notieren Sie sich die Anwendungs-ID, die Ihrem neuen Empfänger zugewiesen ist.

Sie müssen außerdem Ihr Google Cast-Gerät registrieren, damit es vor der Veröffentlichung auf die Empfängeranwendung zugreifen kann. Nachdem Sie die Receiver-App veröffentlicht haben, ist sie auf allen Google Cast-Geräten verfügbar. Für dieses Codelab sollten Sie eine nicht veröffentlichte Empfängeranwendung verwenden.

Abbildung der Google Cast SDK Developer Console mit hervorgehobener Schaltfläche „Neues Gerät hinzufügen“

Klicken Sie auf „Neues Gerät hinzufügen“.

Bild des Dialogfelds „Cast-Empfängergerät hinzufügen“

Geben Sie die Seriennummer auf der Rückseite Ihres Übertragungsgeräts ein und geben Sie ihr einen aussagekräftigen Namen. Sie können die Seriennummer auch finden, indem Sie Ihren Bildschirm über die Google Cast SDK Developer Console in Chrome streamen.

Es kann 5 bis 15 Minuten dauern, bis der Empfänger und das Gerät bereit zum Testen sind. Starten Sie das Cast-Gerät nach 5–15 Minuten neu.

5. Beispiel-App ausführen

Google Chrome-Logo

Während die neue Empfängeranwendung zum Testen bereit ist, möchten wir Ihnen zeigen, wie eine Beispielanwendung für einen Empfänger aussieht. Der Empfänger, den wir erstellen, kann Medien mit Streaming mit adaptiver Bitrate wiedergeben. Wir verwenden Beispielinhalte, die für dynamisches adaptives Streaming über HTTP (DASH) codiert sind.

Öffnen Sie in Ihrem Browser das Command and Control (CaC)-Tool.

Abbildung des Tabs „Cast Connect & amp; Logger Controls“ im Befehls- und Steuertool (CaC)

  1. Sie sollten das CaC-Tool sehen.
  2. Verwenden Sie die Standard-Beispiel-Empfänger-ID "CC1AD845" und klicken Sie auf die Schaltfläche "App-ID festlegen".
  3. Klicken Sie links oben auf das Cast-Symbol und wählen Sie Ihr Google Cast-Gerät aus.

Abbildung des Tabs „Cast Connect & amp; Logger Controls“ im Befehls- und Steuertool (CaC), das zeigt, dass es mit einer Empfänger-App verbunden ist

  1. Gehen Sie oben zum Tab „Medien laden“.

Abbildung des Tabs „Load Media“ des Befehls und der Steuerung (CaC)

  1. Klicke auf die Schaltfläche „Nach Inhalt laden“, um ein Beispielvideo anzusehen.
  2. Das Video wird auf Ihrem Google Cast-Gerät wiedergegeben, um zu zeigen, wie die grundlegenden Receiver-Funktionen unter Verwendung des Standardempfängers aussehen.

6. Startprojekt vorbereiten

Wir müssen die heruntergeladene Start-App für Google Cast unterstützen. Hier sind einige Google Cast-Begriffe, die wir in diesem Codelab verwenden werden:

  • Eine Absender-App wird auf einem Mobilgerät oder Laptop ausgeführt.
  • Eine Empfänger-App wird auf dem Google Cast-Gerät ausgeführt.

Jetzt können Sie mit Ihrem bevorzugten Texteditor auf das Startprojekt aufbauen:

  1. Wählen Sie das Verzeichnis Ordnersymbolapp-start aus dem Beispielcode aus.
  2. js/receiver.js und index.html öffnen

Hinweis: Während Sie dieses Codelab durcharbeiten, sollte http-server Ihre Änderungen übernehmen. Wenn dies nicht der Fall ist, versuchen Sie, http-server zu beenden und neu zu starten.

App-Design

Die Empfänger-App initialisiert die Streaming-Sitzung und wartet, bis eine LOAD-Anfrage (oder der Befehl zur Wiedergabe eines Medienelements) von einem Absender eingeht.

Die App besteht aus einer Hauptansicht, die in index.html definiert ist, und einer JavaScript-Datei namens js/receiver.js, die alle Logiken für unseren Empfänger enthält.

index.html

Diese HTML-Datei enthält die Benutzeroberfläche für unsere Empfänger-App. Sie ist momentan leer und wird im Code-Lab hinzugefügt.

Empfänger.js

Dieses Skript verwaltet die gesamte Logik für unsere Receiver-App. Im Moment ist es nur eine leere Datei, aber im nächsten Abschnitt werden wir sie mit ein paar Zeilen Code in einen voll funktionsfähigen Cast-Empfänger umwandeln.

7. Ein einfacher Cast-Empfänger

Ein einfacher Cast-Empfänger initialisiert die Cast-Sitzung beim Start. Dies ist erforderlich, um allen verbundenen Absenderanwendungen mitzuteilen, dass der Empfänger erfolgreich eingerichtet wurde. Außerdem ist das neue SDK vorkonfiguriert, um Streaming-Medien mit adaptiver Bitrate (mithilfe von DASH, HLS und Smooth Streaming) sowie MP4-Dateien direkt zu verarbeiten. Probieren wir es aus.

Initialisierung

Fügen Sie index.html im Header den folgenden Code hinzu:

<head>
  ...

  <script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
</head>

Fügen Sie index.html <body> vor dem <footer>, der receiver.js, lädt, den folgenden Code hinzu, um dem Empfänger-SDK Platz für die Standard-Empfänger-UI zu schaffen, die das gerade hinzugefügte Skript versendet.

<cast-media-player></cast-media-player>

Jetzt müssen wir das SDK in js/receiver.js initialisieren. Es besteht aus:

  • Bezug zu CastReceiverContext, dem primären Einstiegspunkt für das gesamte Receiver SDK
  • Speichern einer Referenz zu PlayerManager, der Wiedergabe von Objekten und Bereitstellen aller Hooks, die Sie zum Verbinden Ihrer eigenen benutzerdefinierten Logik benötigen
  • Initialisieren des SDK durch Aufrufen von start() für CastReceiverContext

Fügen Sie Folgendes zu js/receiver.js hinzu.

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

context.start();

8. Grundlegende Videoinhalte streamen

Verwenden Sie für dieses Codelab das CaC-Tool, um Ihren neuen Empfänger zu testen.

Rufen Sie in Ihrem Webbrowser das Command-and-Control-Tool (CaC) auf.

Abbildung des Tabs „Cast Connect & amp; Logger Controls“ im Befehls- und Steuertool (CaC)

Ersetzen Sie Ihre eigene App-ID, die zuvor im Feld registriert wurde, und klicken Sie auf „App-ID festlegen“. Dadurch wird das Tool angewiesen, den Receiver beim Starten der Streamingsitzung zu verwenden.

Medien streamen

Für die Wiedergabe von Medien auf einem Übertragungsgerät müssen folgende Voraussetzungen erfüllt sein:

  1. Der Absender erstellt ein MediaInfo-JSON-Objekt aus dem Cast SDK, mit dem ein Medienelement modelliert wird.
  2. Der Absender stellt eine Verbindung zum Übertragungsgerät her, um die Empfängeranwendung zu starten.
  3. Der Empfänger lädt das Objekt MediaInfo über eine LOAD-Anfrage, um den Inhalt wiederzugeben.
  4. Der Empfänger überwacht und verfolgt den Medienstatus.
  5. Der Absender sendet Wiedergabebefehle an den Empfänger, um die Wiedergabe basierend auf Nutzerinteraktionen mit der Absender-App zu steuern.

In diesem ersten einfachen Versuch werden wir MediaInfo mit einer spielbaren Asset-URL füllen, die in MediaInfo.contentUrl gespeichert ist.

Ein tatsächlicher Absender verwendet eine anwendungsspezifische Medienkennung in MediaInfo.contentId. Der Empfänger verwendet die contentId als Kennung für entsprechende Back-End-API-Aufrufe, um die tatsächliche Asset-URL aufzulösen und auf MediaInfo.contentUrl. zu setzen. Der Empfänger übernimmt auch Aufgaben wie die DRM-Lizenzakquise oder das Einfügen von Informationen zu Werbeunterbrechungen.

Im nächsten Abschnitt werden wir den Empfänger auf ähnliche Weise erweitern. Klicke zunächst auf das Cast-Symbol und wähle dein Gerät aus, um den Empfänger zu öffnen.

Abbildung des Tabs „Cast Connect & amp; Logger Controls“ im Befehls- und Steuertool (CaC), das zeigt, dass es mit einer Empfänger-App verbunden ist

Rufen Sie den Tab „Medien laden“ auf und klicken Sie auf die Schaltfläche „Nach Inhalt laden“. Der Empfänger sollte die Beispielinhalte abspielen.

Abbildung des Tabs „Load Media“ des Befehls und der Steuerung (CaC)

Sofort einsatzbereites Receiver SDK:

  • Streamingsitzung wird initialisiert
  • Eingehende LOAD-Anfragen von Absendern verarbeiten, die spielbare Assets enthalten
  • Stelle eine einfache Player-Benutzeroberfläche bereit, die auf dem großen Bildschirm angezeigt werden kann.

Sie können sich das CaC-Tool und den zugehörigen Code ansehen, bevor Sie mit dem nächsten Abschnitt fortfahren. Dort erweitern wir unseren Empfänger, um mit einer einfachen Beispiel-API zu sprechen, um eingehende LOAD-Anfragen von Absendern zu erfüllen.

9. In eine externe API einbinden

Gemäß der Art und Weise, wie die meisten Entwickler in realen Anwendungen mit ihren Cast-Receivern interagieren, ändern wir unseren Receiver so, dass er LOAD-Anfragen verarbeitet, die mit seinem API-Schlüssel auf den vorgesehenen Medieninhalt verweisen, anstatt eine abspielbare Asset-URL zu senden.

Dies ist in der Regel aus folgenden Gründen der Fall:

  • Möglicherweise kennt der Absender die Content-URL nicht.
  • Die Cast-Anwendung ist für die Authentifizierung, andere Geschäftslogik oder API-Aufrufe direkt auf dem Empfänger ausgelegt.

Diese Funktion wird hauptsächlich in der Methode PlayerManager setMessageInterceptor() implementiert. Dadurch können Sie eingehende Nachrichten nach Typ abfangen und ändern, bevor sie den internen Nachrichten-Handler des SDKs erreichen. In diesem Abschnitt werden LOAD-Anfragen behandelt. Dabei gehen wir so vor:

  • Lesen Sie die eingehende LOAD-Anfrage und die zugehörigen contentId.
  • GET-Aufruf an unsere API, um das Stream-Asset anhand seiner contentId zu suchen.
  • Ändern Sie die LOAD-Anfrage mit der URL des Streams.
  • Ändern Sie das MediaInformation-Objekt, um die Parameter des Streamtyps festzulegen.
  • Übergeben Sie die Anfrage zur Wiedergabe an das SDK oder lehnen Sie den Befehl ab, wenn die angeforderten Medien nicht gefunden werden können.

Die bereitgestellte Beispiel-API zeigt die SDK-Hooks zum Anpassen gängiger Empfängeraufgaben, während sie sich dabei auf eine Standardlösung verlassen.

Beispiel-API

Rufen Sie in Ihrem Browser die Seite https://storage.googleapis.com/cpe-sample-media/content.json auf und sehen Sie sich unseren Beispielvideokatalog an. Die Inhalte enthalten URLs für Posterbilder im PNG-Format sowie DASH- und HLS-Streams. Die DASH- und HLS-Streams verweisen auf abgewertete Video- und Audioquellen, die in fragmentierten MP4-Containern gespeichert sind.

{
  "bbb": {
    "author": "The Blender Project",
    "description": "Grumpy Bunny is grumpy",
    "poster": "https://[...]/[...]/BigBuckBunny/images/screenshot1.png",
    "stream": {
      "dash": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.mpd",
      "hls": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.m3u8",
    "title": "Big Buck Bunny"
  },
  "fbb_ad": {
    "author": "Google Inc.",
    "description": "Introducing Chromecast. The easiest way to enjoy [...]",
    "poster": "https://[...]/[...]/ForBiggerBlazes/images/screenshot8.png",
    "stream": {
      "dash": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.mpd",
      "hls": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.m3u8",
    "title": "For Bigger Blazes"
  },

  [...]

}

Im nächsten Schritt wird der Schlüssel jedes Eintrags (z. B. bbb, fbb_ad) der URL des Streams zugeordnet, nachdem der Empfänger mit einer LOAD-Anfrage aufgerufen wurde.

LOAD-Anfrage abfangen

In diesem Schritt erstellen wir einen Load-Abfangdienst mit einer Funktion, die eine XHR-Anfrage an die gehostete Datei JSON sendet. Sobald die JSON-Datei abgerufen wurde, parsen wir den Inhalt und legen die Metadaten fest. In den folgenden Abschnitten passen wir die MediaInformation-Parameter an, um den Inhaltstyp anzugeben.

Fügen Sie der Datei js/receiver.js direkt vor dem Aufruf von context.start() den folgenden Code hinzu.

function makeRequest (method, url) {
  return new Promise(function (resolve, reject) {
    let xhr = new XMLHttpRequest();
    xhr.open(method, url);
    xhr.onload = function () {
      if (this.status >= 200 && this.status < 300) {
        resolve(JSON.parse(xhr.response));
      } else {
        reject({
          status: this.status,
          statusText: xhr.statusText
        });
      }
    };
    xhr.onerror = function () {
      reject({
        status: this.status,
        statusText: xhr.statusText
      });
    };
    xhr.send();
  });
}

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      return new Promise((resolve, reject) => {
        // Fetch content repository by requested contentId
        makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json').then(function (data) {
          let item = data[request.media.contentId];
          if(!item) {
            // Content could not be found in repository
            reject();
          } else {
            // Add metadata
            let metadata = new
               cast.framework.messages.GenericMediaMetadata();
            metadata.title = item.title;
            metadata.subtitle = item.author;

            request.media.metadata = metadata;

            // Resolve request
            resolve(request);
          }
        });
      });
    });

Im nächsten Abschnitt wird beschrieben, wie Sie die media-Eigenschaft der Ladeanfrage für DASH-Inhalte konfigurieren.

DASH-Beispielinhalt für die API verwenden

Nachdem wir nun das Abfangen von Daten vorbereitet haben, legen wir den Inhaltstyp für den Empfänger fest. Diese Informationen geben dem Empfänger die URL der Masterplaylist und den MIME-Typ des Streams. Fügen Sie den folgenden Code in die Datei js/recipientr.js im LOAD-Abschnitt des Promise()-Abschnitts ein:

...
playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      return new Promise((resolve, reject) => {
          ...
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.dash;
            request.media.contentType = 'application/dash+xml';
            ...
          }
        });
      });
    });

Sobald Sie diesen Schritt abgeschlossen haben, können Sie mit „Test It It“ (Testen) fortfahren, um das Laden mit DASH-Content zu versuchen. Wenn Sie das Laden mit HLS-Inhalten testen möchten, fahren Sie mit dem nächsten Schritt fort.

HLS-Beispiel-API verwenden

Die Beispiel-API enthält HLS-Inhalte sowie DASH. Neben der Einstellung von contentType wie im vorherigen Schritt benötigt die Ladeanfrage weitere Attribute, um die HLS-URLs der Beispiel-API zu verwenden. Wenn der Empfänger für die Wiedergabe von HLS-Streams konfiguriert ist, wird als Transportcontainer (TS) der Standardcontainertyp erwartet. Wenn nur die Eigenschaft contentUrl geändert wird, versucht der Empfänger, die MP4-Beispielstreams im TS-Format zu öffnen. In der Ladeanfrage sollte das Objekt MediaInformation mit zusätzlichen Eigenschaften geändert werden, damit der Empfänger weiß, dass der Inhalt vom Typ MP4 und nicht vom Typ TS ist. Fügen Sie den folgenden Code in die Datei „js/receiver.js“ im Load Balancer ein, um die Attribute contentUrl und contentType zu ändern. Fügen Sie außerdem die Attribute HlsSegmentFormat und HlsVideoSegmentFormat hinzu.

...
playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      return new Promise((resolve, reject) => {
          ...
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.hls;
            request.media.contentType = 'application/x-mpegurl';
            request.media.hlsSegmentFormat = cast.framework.messages.HlsSegmentFormat.FMP4;
            request.media.hlsVideoSegmentFormat = cast.framework.messages.HlsVideoSegmentFormat.FMP4;
            ...
          }
        });
      });
    });

Testen

Öffnen Sie wieder das Command and Control (CaC)-Tool und legen Sie Ihre App-ID auf die App-ID des Empfängers fest. Wählen Sie Ihr Gerät über das Cast-Symbol aus.

Gehen Sie zum Tab „Medien laden“. Dieses Mal löscht der Text im Feld „Content-URL“ neben der Schaltfläche „Nach Inhalt laden“, wodurch unsere Anwendung eine LOAD-Anfrage mit nur dem contentId-Verweis auf unser Medium zwingt.

Abbildung des Tabs „Load Media“ des Befehls und der Steuerung (CaC)

Wenn alles reibungslos mit deinen Änderungen am Empfänger funktioniert hat, sollte der Interceptor das MediaInfo-Objekt so gestalten, dass es vom SDK auf dem Bildschirm wiedergegeben werden kann.

Klicke auf die Schaltfläche „Nach Inhalt laden“, um zu sehen, ob deine Medien korrekt wiedergegeben werden. Sie können die Content-ID in der Datei content.json durch eine andere ID ersetzen.

10. Optimierung für Smart Displays

Smart Displays sind Geräte mit Touchfunktion, mit denen Empfängeranwendungen per Touchbedienung gesteuert werden können.

In diesem Abschnitt wird erläutert, wie du die Empfängeranwendung beim Start auf Smart Displays optimieren und die Player-Steuerelemente anpassen kannst.

Auf UI-Steuerelemente zugreifen

Auf das UI-Steuerelementesobjekt für Smart Displays kann über cast.framework.ui.Controls.GetInstance() zugegriffen werden. Fügen Sie der Datei js/receiver.js über context.start() den folgenden Code hinzu:

...

// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();

context.start();

Wenn du das Element <cast-media-player> nicht verwendest, musst du touchScreenOptimizedApp in CastReceiverOptions festlegen. In diesem Codelab verwenden wir das Element <cast-media-player>.

context.start({ touchScreenOptimizedApp: true });

Jeder Anzeigenfläche werden basierend auf MetadataType und MediaStatus.supportedMediaCommands Standardsteuerungsschaltflächen zugewiesen.

Videosteuerelemente

Für MetadataType.MOVIE, MetadataType.TV_SHOW und MetadataType.GENERIC wird das UI-Steuerelementesobjekt für Smart Displays wie im Beispiel unten angezeigt.

Bild eines Videos, das mit UI-Steuerelementen eingeblendet wird

  1. --playback-logo-image
  2. MediaMetadata.subtitle
  3. MediaMetadata.title
  4. MediaStatus.currentTime
  5. MediaInformation.duration
  6. ControlsSlot.SLOT_SECONDARY_1: ControlsButton.QUEUE_PREV
  7. ControlsSlot.SLOT_PRIMARY_1: ControlsButton.SEEK_BACKWARD_30
  8. PLAY/PAUSE
  9. ControlsSlot.SLOT_PRIMARY_2: ControlsButton.SEEK_FORWARD_30
  10. ControlsSlot.SLOT_SECONDARY_2: ControlsButton.QUEUE_NEXT

Audiosteuerung

Bei MetadataType.MUSIC_TRACK wird das UI-Steuerungsobjekt für Smart Displays so angezeigt:

Bild von Musik, die über UI-Steuerelementen eingeblendet wird

  1. --playback-logo-image
  2. MusicTrackMediaMetadata.albumName
  3. MusicTrackMediaMetadata.title
  4. MusicTrackMediaMetadata.albumArtist
  5. MusicTrackMediaMetadata.images[0]
  6. MediaStatus.currentTime
  7. MediaInformation.duration
  8. ControlsSlot.SLOT_SECONDARY_1: ControlsButton.NO_BUTTON
  9. ControlsSlot.SLOT_PRIMARY_1: ControlsButton.QUEUE_PREV
  10. PLAY/PAUSE
  11. ControlsSlot.SLOT_PRIMARY_2: ControlsButton.QUEUE_NEXT
  12. ControlsSlot.SLOT_SECONDARY_2: ControlsButton.NO_BUTTON

Unterstützte Medienbefehle aktualisieren

Das UI-Steuerelementesobjekt bestimmt auch anhand von MediaStatus.supportedMediaCommands, ob ein ControlsButton angezeigt wird oder nicht.

Wenn der Wert von supportedMediaCommands gleich ALL_BASIC_MEDIA ist, wird das Standardlayout für die Steuerung so angezeigt:

Bild der Steuerelemente des Mediaplayers: Fortschrittsanzeige, Schaltfläche „Wiedergabe“, „Vorspulen“ und „Zurückspulen“ aktiviert

Wenn der Wert von supportedMediaCommands gleich ALL_BASIC_MEDIA | QUEUE_PREV | QUEUE_NEXT ist, wird das Standardlayout für die Steuerung so angezeigt:

Abbildung der Steuerelemente des Mediaplayers: Fortschrittsanzeige, Schaltfläche „Wiedergabe“, „Vorwärts springen“ und „Zurück“ und die Schaltflächen „Vorherige Warteschlange“ und „Nächstes Video“

Wenn der Wert der unterstützten mediaCommands gleich PAUSE | QUEUE_PREV | QUEUE_NEXT ist, wird das Standardsteuerelemente wie folgt angezeigt:

Abbildung der Steuerelemente des Mediaplayers: Fortschrittsanzeige, Schaltfläche „Wiedergabe“ und die Schaltflächen „Vorherige Warteschlange“ und „Nächstes Video“

Wenn Texttracks verfügbar sind, wird die Untertitelschaltfläche immer bei SLOT_1 angezeigt.

Bild der Steuerelemente des Mediaplayers: Fortschrittsanzeige, Schaltfläche „Wiedergabe“, „Vorspulen“ und „Zurückspulen“, Schaltflächen „Zurück“ und „Nächstes Video“ und „Untertitel“

Wenn Sie den Wert von supportedMediaCommands nach dem Start eines Empfängerkontexts dynamisch ändern möchten, können Sie PlayerManager.setSupportedMediaCommands aufrufen, um den Wert zu überschreiben. Sie können auch einen neuen Befehl mit addSupportedMediaCommands hinzufügen oder einen vorhandenen Befehl mit removeSupportedMediaCommands entfernen.

Steuerungsschaltflächen anpassen

Sie können die Steuerelemente mit PlayerDataBinder anpassen. Fügen Sie der Datei js/receiver.js unter den touchControls den folgenden Code hinzu, um den ersten Slot Ihrer Steuerelemente festzulegen:

...

// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);

playerDataBinder.addEventListener(
  cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
  (e) => {
    if (!e.value) return;

    // Clear default buttons and re-assign
    touchControls.clearDefaultSlotAssignments();
    touchControls.assignButton(
      cast.framework.ui.ControlsSlot.SLOT_PRIMARY_1,
      cast.framework.ui.ControlsButton.SEEK_BACKWARD_30
    );
  });

context.start();

11. Mediensuche auf Smart Displays implementieren

Media Browsing ist eine CAF-Empfängerfunktion, mit der Nutzer zusätzliche Inhalte auf Touchgeräten entdecken können. Zur Implementierung verwenden Sie PlayerDataBinder, um die BrowseContent-UI festzulegen. Anschließend können Sie ihn basierend auf dem Inhalt, den Sie anzeigen möchten, mit BrowseItems füllen.

Inhalte durchsuchen

Im Folgenden finden Sie ein Beispiel für die BrowseContent-UI und ihre Attribute:

Abbildung der Benutzeroberfläche von „BrowseContent“ mit zwei Video-Thumbnails und einem Drittel

  1. BrowseContent.title
  2. BrowseContent.items

Seitenverhältnis

Verwenden Sie targetAspectRatio property, um das beste Seitenverhältnis für Ihre Bild-Assets auszuwählen. Das CAF Receiver SDK unterstützt drei Seitenverhältnisse: SQUARE_1_TO_1, PORTRAIT_2_TO_3 und LANDSCAPE_16_TO_9.

Artikel ansehen

Verwende BrowseItem, um Titel, Untertitel, Dauer und Bilder für jedes Element anzuzeigen:

Abbildung der Benutzeroberfläche von „BrowseContent“ mit zwei Video-Thumbnails und einem Drittel

  1. BrowseItem.image
  2. BrowseItem.duration
  3. BrowseItem.title
  4. BrowseItem.subtitle

Media Browsing-Daten festlegen

Sie können eine Liste der Medieninhalte für das Surfen durch Aufrufen von setBrowseContent bereitstellen. Fügen Sie der Datei js/receiver.js unter dem playerDataBinder und im MEDIA_CHANGED-Ereignis-Listener den folgenden Code hinzu, um die Elemente zum Durchsuchen mit dem Titel „Nächstes Video“ festzulegen.

// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);

...

let browseItems = getBrowseItems();

function getBrowseItems() {
  let browseItems = [];
  makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
  .then(function (data) {
    for (let key in data) {
      let item = new cast.framework.ui.BrowseItem();
      item.entity = key;
      item.title = data[key].title;
      item.subtitle = data[key].description;
      item.image = new cast.framework.messages.Image(data[key].poster);
      item.imageType = cast.framework.ui.BrowseImageType.MOVIE;
      browseItems.push(item);
    }
  });
  return browseItems;
}

let browseContent = new cast.framework.ui.BrowseContent();
browseContent.title = 'Up Next';
browseContent.items = browseItems;
browseContent.targetAspectRatio = cast.framework.ui.BrowseImageAspectRatio.LANDSCAPE_16_TO_9;

playerDataBinder.addEventListener(
  cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
  (e) => {
    if (!e.value) return;

    ....

    // Media browse
    touchControls.setBrowseContent(browseContent);
  });

Durch Klicken auf einen Media Browsing-Element wird der LOAD-Abfangvorgang ausgelöst. Fügen Sie den folgenden Code zum Abfangen von LOAD hinzu, um die request.media.contentId dem Element „request.media.entity“ für die Mediensuche zuzuordnen:

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    request => {
      ...

      // Map contentId to entity
      if (request.media && request.media.entity) {
        request.media.contentId = request.media.entity;
      }

      return new Promise((resolve, reject) => {
            ...
        });
    });

Sie können das BrowseContent-Objekt auch auf null setzen, um die UI für die Mediensuche zu entfernen.

12. Fehler in Empfänger-Apps beheben

Mit dem Cast Receiver SDK haben Entwickler eine weitere Möglichkeit, Fehler in Empfänger-Apps zu beheben. Dafür werden die CastDebugLogger API und das zugehörige Command-and-Control-Tool (CaC) verwendet, um Protokolle zu erfassen.

Initialisierung

Fügen Sie das CastDebugLogger-Quellskript in die Datei „index.html“ ein, um die API einzubinden. Die Quelle sollte im <head>-Tag nach der Erklärung für das Cast Receiver SDK deklariert werden.

<head>
  ...
  <script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
  <!-- Cast Debug Logger -->
  <script src="//www.gstatic.com/cast/sdk/libs/devtools/debug_layer/caf_receiver_logger.js"></script>
</head>

Fügen Sie in der Datei js/receiver.js oben und unter der Datei playerManager den folgenden Code ein, um die Instanz CastDebugLogger abzurufen und den Logger zu aktivieren:

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

// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
const LOG_TAG = 'MyAPP.LOG';

// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
  if (!castDebugLogger.debugOverlayElement_) {
      castDebugLogger.setEnabled(true);
  }
});

Wenn die Debugging-Protokollierung aktiviert ist, wird auf dem Empfänger ein Overlay mit DEBUG MODE angezeigt.

Bild eines Videos, das mit der Meldung „FEHLERMODUS“ vor einem roten Hintergrund oben links im Rahmen angezeigt wird

Player-Ereignisse protokollieren

Mit CastDebugLogger kannst du Spielerereignisse, die vom CAF Receiver SDK ausgelöst werden, ganz einfach protokollieren und die Ereignisdaten mit verschiedenen Logger-Ebenen protokollieren. In der loggerLevelByEvents-Konfiguration werden cast.framework.events.EventType und cast.framework.events.category verwendet, um festzulegen, welche Ereignisse protokolliert werden.

Füge den folgenden Code unter der castDebugLogger-Deklaration hinzu, damit protokolliert wird, wenn ein CORE-Ereignis eines Spielers ausgelöst oder eine mediaStatus-Änderung übertragen wird:

// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();

// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
  if (!castDebugLogger.debugOverlayElement_) {
      castDebugLogger.setEnabled(true);
  }
});

// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
  'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
  'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}

Logeinträge und benutzerdefinierte Tags

Mit der CastDebugLogger API können Sie Lognachrichten mit verschiedenen Farben auf dem Debug-Overlay des Empfängers erstellen. Folgende Logmethoden sind verfügbar, aufsteigend sortiert:

  • castDebugLogger.error(custom_tag, message);
  • castDebugLogger.warn(custom_tag, message);
  • castDebugLogger.info(custom_tag, message);
  • castDebugLogger.debug(custom_tag, message);

Der erste Parameter für jede Logmethode ist ein benutzerdefiniertes Tag. Dabei kann es sich um eine beliebige Identifizierungszeichenfolge handeln. CastDebugLogger verwendet Tags, um die Logs zu filtern. Die Verwendung von Tags wird weiter unten ausführlich erläutert. Der zweite Parameter ist die Lognachricht.

Wenn Sie Logs in Aktion sehen möchten, fügen Sie Logs zum LOAD-Abfangdienst hinzu.

playerManager.setMessageInterceptor(
  cast.framework.messages.MessageType.LOAD,
  request => {
    castDebugLogger.info(LOG_TAG, 'Intercepting LOAD request');

    // Map contentId to entity
    if (request.media && request.media.entity) {
      request.media.contentId = request.media.entity;
    }

    return new Promise((resolve, reject) => {
      // Fetch content repository by requested contentId
      makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
        .then(function (data) {
          let item = data[request.media.contentId];
          if(!item) {
            // Content could not be found in repository
            castDebugLogger.error(LOG_TAG, 'Content not found');
            reject();
          } else {
            // Adjusting request to make requested content playable
            request.media.contentUrl = item.stream.dash;
            request.media.contentType = 'application/dash+xml';
            castDebugLogger.warn(LOG_TAG, 'Playable URL:', request.media.contentUrl);

            // Add metadata
            let metadata = new cast.framework.messages.MovieMediaMetadata();
            metadata.metadataType = cast.framework.messages.MetadataType.MOVIE;
            metadata.title = item.title;
            metadata.subtitle = item.author;

            request.media.metadata = metadata;

            // Resolve request
            resolve(request);
          }
      });
    });
  });

Sie können festlegen, welche Meldungen im Debug-Overlay angezeigt werden, indem Sie für jedes benutzerdefinierte Tag die Protokollebene in loggerLevelByTags festlegen. Wenn Sie beispielsweise ein benutzerdefiniertes Tag mit der Log-Ebene cast.framework.LoggerLevel.DEBUG aktivieren, werden alle Nachrichten mit den Fehler-, Warn-, Informations- und Fehlerbehebungsprotokoll-Meldungen angezeigt. Wenn Sie ein benutzerdefiniertes Tag auf der Ebene WARNING aktivieren, werden nur Fehler- und Logmeldungen angezeigt.

Die loggerLevelByTags-Konfiguration ist optional. Wenn ein benutzerdefiniertes Tag nicht für seine Logger-Ebene konfiguriert ist, werden alle Protokollmeldungen auf dem Debug-Overlay angezeigt.

Fügen Sie unter dem Ereignis-Logger CORE den folgenden Code ein:

// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
  'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
  'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}

// Set verbosity level for custom tags.
castDebugLogger.loggerLevelByTags = {
    [LOG_TAG]: cast.framework.LoggerLevel.DEBUG,
};

Debug-Overlay

Der Debug-Logger für die Übertragung bietet dem Empfänger ein Overlay für die Fehlerbehebung, mit dem Sie Ihre benutzerdefinierten Protokollnachrichten auf dem Übertragungsgerät anzeigen können. Verwenden Sie showDebugLogs, um das Debug-Overlay umzuschalten, und clearDebugLogs, um Lognachrichten im Overlay zu löschen.

Fügen Sie den folgenden Code hinzu, um eine Vorschau des Debug-Overlays auf dem Empfänger zu sehen.

context.addEventListener(cast.framework.system.EventType.READY, () => {
  if (!castDebugLogger.debugOverlayElement_) {
      // Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
      castDebugLogger.setEnabled(true);

      // Show debug overlay
      castDebugLogger.showDebugLogs(true);

      // Clear log messages on debug overlay
      castDebugLogger.clearDebugLogs();
  }
});

Bild mit dem Debug-Overlay, einer Liste von Debugging-Protokollmeldungen auf einem durchscheinenden Hintergrund über einem Videoframe

13. Glückwunsch

Jetzt wissen Sie, wie Sie mit dem Cast Web Receiver SDK eine benutzerdefinierte Anwendung für Webempfänger erstellen.

Weitere Informationen finden Sie im Entwicklerleitfaden Web Receiver.