Benutzerdefinierten Web Receiver erstellen

1. Übersicht

Google Cast-Logo

In diesem Codelab erfährst du, wie du eine App mit benutzerdefinierten Webempfängern erstellst, um Inhalte auf für Google Cast optimierten Geräten wiederzugeben.

Was ist Google Cast?

Mit Google Cast können Nutzer Inhalte von Mobilgeräten auf einen Fernseher streamen. Nutzer können dann ihr Mobilgerät oder ihren Computer im 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, z. B. einen Fernseher oder ein Soundsystem. Das Cast SDK stellt Ihnen die erforderlichen UI-Komponenten gemäß der Checkliste für das Google Cast-Design zur Verfügung.

Die Design-Checkliste für Google Cast soll die Nutzung von Cast auf allen unterstützten Plattformen einfach und vorhersehbar machen. Weitere Informationen

Ziele

Wenn Sie dieses Codelab abgeschlossen haben, haben Sie eine HTML5-App als Ihren eigenen benutzerdefinierten Receiver eingerichtet, mit dem Sie Videoinhalte auf für Google Cast optimierten Geräten wiedergeben können.

Lerninhalte

  • So richtest du die Receiver-Entwicklung ein.
  • Grundlagen eines Cast-fähigen Empfängers, der auf dem Cast Application Framework basiert
  • So empfangen Sie ein gestreamtes Video.
  • Integration des Debug-Protokolls
  • Optimiere deinen Receiver für Smart Displays.

Voraussetzungen

Erfahrung

  • Sie müssen über Vorkenntnisse in der Webentwicklung verfügen.
  • Außerdem benötigen Sie Vorkenntnisse in Bezug auf Fernsehen. :)

Wie möchten Sie diese Anleitung nutzen?

<ph type="x-smartling-placeholder"></ph> Nur bis zum Ende lesen Lies sie dir durch und absolviere die Übungen

Wie würden Sie Ihre Erfahrungen mit der Erstellung von Web-Apps bewerten?

<ph type="x-smartling-placeholder"></ph> Neuling Leicht fortgeschritten Kompetent

Wie würden Sie Ihre Erfahrungen mit Fernsehen bewerten?

<ph type="x-smartling-placeholder"></ph> Neuling Leicht fortgeschritten Kompetent

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 Web Receiver mit einem Übertragungsgerät verwenden können, muss es an einem Ort gehostet werden, an dem Ihr Cast-Gerät darauf zugreifen kann. Falls Sie bereits einen Server haben, der HTTPS unterstützt, überspringen Sie die folgende Anleitung und merken Sie sich die URL, da Sie sie im nächsten Abschnitt benötigen.

Wenn Sie keinen Server haben, können Sie Firebase Hosting oder ngrok verwenden.

Server ausführen

Sobald Sie den Dienst Ihrer Wahl eingerichtet haben, rufen Sie app-start auf und starten Sie Ihren Server.

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

4. App in der Cast Developer Console registrieren

Sie müssen Ihre Anwendung registrieren, um einen benutzerdefinierten Receiver, wie in diesem Codelab integriert, auf Chromecast-Geräten ausführen zu können. Nachdem Sie Ihre Anwendung registriert haben, erhalten Sie eine Anwendungs-ID, die die Absenderanwendung verwenden muss, um API-Aufrufe auszuführen, z. B. um eine Empfängeranwendung zu starten.

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

Klicken Sie auf „Neue Anwendung hinzufügen“.

Bild von „New Receiver Application“ (Neue Receiver-Anwendung) mit der Option &quot;Benutzerdefinierter Receiver&quot; Option hervorgehoben

Wählen Sie "Benutzerdefinierter Receiver" Und genau das machen wir.

Bild von „Neuer benutzerdefinierter Receiver“ Bildschirm mit einer URL, die jemand in die URL der Empfängeranwendung eingibt Feld

Geben Sie die Details Ihres neuen Empfängers ein und verwenden Sie dabei die URL, die Sie erhalten haben.

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

Außerdem müssen Sie Ihr Google Cast-Gerät registrieren, damit es vor der Veröffentlichung auf die Receiver App zugreifen kann. Sobald Sie die Receiver-App veröffentlicht haben, ist sie für alle Google Cast-Geräte verfügbar. Für dieses Codelab empfehlen wir, mit einer nicht veröffentlichten Empfängeranwendung zu arbeiten.

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

Klicke auf „Neues Gerät hinzufügen“.

Bild von „Cast-Receiver hinzufügen“ Dialogfeld

Geben Sie die Seriennummer ein, die auf der Rückseite Ihres Übertragungsgeräts aufgedruckt ist, und geben Sie einen aussagekräftigen Namen ein. Sie können Ihre Seriennummer auch ermitteln, indem Sie Ihren Bildschirm in Chrome streamen, wenn Sie die Google Cast SDK-Entwicklerkonsole aufrufen.

Es dauert 5 bis 15 Minuten, bis Receiver und Gerät bereit zum Testen sind. Warten Sie 5 bis 15 Minuten und starten Sie das Übertragungsgerät neu.

5. Beispiel-App ausführen

Google Chrome-Logo

Während wir warten, bis die neue Empfängeranwendung zum Testen bereit ist, schauen wir uns nun an, wie eine fertige Empfänger-App aussieht. Der Empfänger, den wir erstellen werden, kann Medien mit adaptivem Bitrate-Streaming wiedergeben. Wir verwenden Beispielinhalte, die für Dynamic Adaptive Streaming over HTTP (DASH) codiert sind.

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

Bild von „Cast Connect“ und Protokollierungssteuerelemente Tab des CAC-Tools (Command and Control)

  1. Sie sollten unser CaC-Tool sehen.
  2. Standardeinstellung „CC1AD845“ verwenden Beispielempfänger-ID und klicken Sie auf „App-ID festlegen“ Schaltfläche.
  3. Klicken Sie links oben auf das Cast-Symbol und wählen Sie Ihr Google Cast-Gerät aus.

Bild von „Cast Connect“ und Protokollierungssteuerelemente Tab des CAC-Tools (Command and Control) gibt an, dass es mit einer Empfänger-App verbunden ist

  1. Gehen Sie zur Seite „Medien laden“ .

Bild von „Medien laden“ Tab des CAC-Tools (Command and Control)

  1. Klicke auf die Schaltfläche „Nach Inhalt laden“ um ein Beispielvideo abzuspielen.
  2. Das Video wird auf Ihrem Google Cast-Gerät wiedergegeben und zeigt die grundlegenden Empfängerfunktionen bei Verwendung des Standardempfängers.

6. Startprojekt vorbereiten

Wir müssen der heruntergeladenen Start-App Unterstützung für Google Cast hinzufügen. Im Folgenden finden Sie einige Google Cast-Terminologie, die wir in diesem Codelab verwenden:

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

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

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

Hinweis: Während Sie dieses Codelab durcharbeiten, sollte http-server Ihre Änderungen erfassen. Sollte dies nicht der Fall sein, beenden Sie die Anwendung und starten Sie http-server neu.

App-Design

Die Empfänger-App initialisiert die Übertragungssitzung und bleibt im Stand-by-Modus, bis eine LOAD-Anfrage (d. h. der Befehl zur Wiedergabe eines Medieninhalts) von einem Absender eintrifft.

Die App besteht aus einer Hauptansicht, die in index.html definiert ist, und einer JavaScript-Datei namens js/receiver.js, die die gesamte Logik für die Funktionsweise des Empfängers enthält.

index.html

Diese HTML-Datei enthält die Benutzeroberfläche der Empfänger-App. Im Moment ist er leer, den wir im Laufe des Code-Labs ergänzen werden.

receiver.js

Über dieses Skript wird die gesamte Logik für die Empfänger-App verwaltet. Im Moment ist es nur eine leere Datei, aber im nächsten Abschnitt werden wir sie mit nur wenigen Codezeilen in einen voll funktionsfähigen Cast-Empfänger umwandeln.

7. Einen einfachen Cast-Empfänger

Ein einfacher Übertragungsempfänger initialisiert die Übertragungssitzung beim Start. Dies ist erforderlich, um allen verbundenen Absenderanwendungen mitzuteilen, dass der Empfänger erfolgreich aufgerufen wurde. Darüber hinaus ist das neue SDK vorkonfiguriert, um Medien mit adaptiver Bitrate (mit DASH, HLS und Smooth Streaming) sowie einfache MP4-Dateien zu verarbeiten. Probieren wir es aus.

Initialisierung

Fügen Sie im Header zu index.html 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 den folgenden Code in index.html <body> vor <footer>, der receiver.js, lädt, ein, um dem Empfänger-SDK Platz zum Aufrufen der Standard-Benutzeroberfläche für Empfänger bereitzustellen, die mit dem soeben hinzugefügten Skript ausgeliefert wird.

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

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

  • einen Verweis auf CastReceiverContext, deinen primären Einstiegspunkt für das gesamte Receiver SDK,
  • mit einem Verweis auf PlayerManager, dem Objekt, das die Wiedergabe verarbeitet und alle Hooks bereitstellt, die Sie für das Plug-in Ihrer eigenen benutzerdefinierten Logik benötigen
  • SDK durch Aufrufen von start() auf CastReceiverContext initialisieren

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

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

context.start();

8. „Basic“ streamen Videoinhalte

Verwende für dieses Codelab das CaC-Tool, um deinen neuen Empfänger zu testen.

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

Bild von „Cast Connect“ und Protokollierungssteuerelemente Tab des CAC-Tools (Command and Control)

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

Medien werden gestreamt

Wenn Sie Medien auf einem Übertragungsgerät wiedergeben möchten, müssen folgende Voraussetzungen erfüllt sein:

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

Bei diesem ersten einfachen Versuch geben wir in MediaInfo eine abspielbare Asset-URL ein, die in MediaInfo.contentUrl gespeichert ist.

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

Im nächsten Abschnitt erweitern wir deinen Receiver, damit dieser Vorgang erfolgt. Klicke erst einmal auf das Cast-Symbol und wähle dein Gerät aus, um den Receiver zu öffnen.

Bild von „Cast Connect“ und Protokollierungssteuerelemente Tab des CAC-Tools (Command and Control) gibt an, dass es mit einer Empfänger-App verbunden ist

Gehen Sie zur Seite „Medien laden“ und klicken Sie auf die Registerkarte „Nach Inhalt laden“. Schaltfläche. Der Receiver sollte jetzt mit der Wiedergabe des Beispielinhalts beginnen.

Bild von „Medien laden“ Tab des CAC-Tools (Command and Control)

Das Receiver SDK ermöglicht also Folgendes:

  • Streaming-Sitzung starten
  • Eingehende LOAD-Anfragen von Absendern mit abspielbaren Assets verarbeiten
  • Stellen Sie eine einfache Player-Benutzeroberfläche bereit, die auf dem großen Bildschirm angezeigt werden kann.

Sehen Sie sich das CaC-Tool und seinen Code an, bevor Sie mit dem nächsten Abschnitt fortfahren. In diesem Abschnitt wird der Empfänger um eine einfache Beispiel-API erweitert, um eingehende LOAD-Anfragen von Absendern zu bearbeiten.

9. In eine externe API einbinden

Entsprechend der Art und Weise, wie die meisten Entwickler in realen Anwendungen mit ihren Cast Receivern interagieren, ändern wir den Empfänger so, dass LOAD-Anfragen verarbeitet werden, die über den API-Schlüssel auf die gewünschten Medieninhalte verweisen, anstatt eine abspielbare Asset-URL zu senden.

In der Regel geschieht dies bei Anwendungen aus folgenden Gründen:

  • Der Absender kennt die URL des Inhalts möglicherweise nicht.
  • Die Cast-App wurde entwickelt, um Authentifizierung, andere Geschäftslogik oder API-Aufrufe direkt am Empfänger abzuwickeln.

Diese Funktion wird hauptsächlich in der PlayerManager-Methode setMessageInterceptor() implementiert. Dadurch können Sie eingehende Nachrichten nach Typ abfangen und ändern, bevor sie den internen Nachrichten-Handler des SDK erreichen. In diesem Abschnitt geht es um LOAD-Anfragen, in denen wir Folgendes tun:

  • Lesen Sie die eingehende LOAD-Anfrage und die zugehörigen benutzerdefinierten contentId.
  • Sende einen GET-Aufruf an unsere API, um das streamfähige 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 abgerufen werden können.

Die bereitgestellte Beispiel-API zeigt die Hooks des SDK zum Anpassen gängiger Empfängeraufgaben, verwendet jedoch eine überwiegend vorkonfigurierte Umgebung.

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. Dazu gehören URLs für Posterbilder im PNG-Format sowie DASH- und HLS-Streams. Die DASH- und HLS-Streams verweisen auf aufgeteilte 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 ordnen wir den Schlüssel jedes Eintrags (z. B. bbb, fbb_ad) der URL des Streams zu, nachdem der Empfänger mit einer LOAD-Anfrage aufgerufen wurde.

LOAD-Anfrage abfangen

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

Fügen Sie der Datei js/receiver.js den folgenden Code direkt vor dem Aufruf von context.start() 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 Eigenschaft media der Ladeanfrage für DASH-Inhalte konfigurieren.

Verwenden der DASH-Inhalte der Beispiel-API

Nachdem wir den Load-Abfangende vorbereitet haben, geben wir den Inhaltstyp für den Empfänger an. Über diese Informationen erhält der Empfänger die URL der Masterplaylist und den Stream-MIME-Typ. Fügen Sie der js/Receiver.js-Datei im Promise() des LOAD-Abfangendes den folgenden Code 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.dash;
            request.media.contentType = 'application/dash+xml';
            ...
          }
        });
      });
    });

Nachdem Sie diesen Schritt abgeschlossen haben, können Sie zu „Testen“ gehen und versuchen, den Ladevorgang mit DASH-Content zu testen. Wenn Sie das Laden mit HLS-Inhalten testen möchten, lesen Sie den nächsten Schritt.

HLS-Inhalte der Sample API verwenden

Die Beispiel-API enthält sowohl HLS-Content als auch DASH. Neben dem Festlegen von contentType wie im vorherigen Schritt sind für die Ladeanfrage einige zusätzliche Properties erforderlich, damit die HLS-URLs der Beispiel-API verwendet werden können. Wenn der Empfänger für die Wiedergabe von HLS-Streams konfiguriert ist, wird als standardmäßiger Containertyp der Transportstream (TS) erwartet. Daher versucht der Empfänger, die Beispiel-MP4-Streams im TS-Format zu öffnen, wenn nur das Attribut contentUrl geändert wird. In der Ladeanfrage sollte das MediaInformation-Objekt mit zusätzlichen Attributen geändert werden, damit der Empfänger erkennt, dass der Inhalt vom Typ MP4 und nicht vom Typ TS ist. Fügen Sie der js/Receiver.js-Datei im Load-Abfangende den folgenden Code hinzu, 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 noch einmal das Command-and-Control-Tool (CaC) und legen Sie Ihre App-ID auf die App-ID des Empfängers fest. Wähle dein Gerät mithilfe des Cast-Symbols aus.

Gehen Sie zur Seite „Medien laden“ . Löschen Sie diesmal den Text im Feld "Content-URL". neben dem Feld Dadurch wird unsere Anwendung gezwungen, eine LOAD-Anfrage zu senden, die nur den contentId-Verweis auf unsere Medien enthält.

Bild von „Medien laden“ Tab des CAC-Tools (Command and Control)

Wenn die Änderungen am Empfänger wie gewünscht funktionieren, sollte das MediaInfo-Objekt vom Interceptor so angepasst werden, dass es vom SDK auf dem Bildschirm wiedergegeben werden kann.

Klicke auf die Schaltfläche „Nach Inhalt laden“ um zu prüfen, ob die Medien korrekt wiedergegeben werden. Du kannst die Content ID in der Datei content.json in eine andere ID ändern.

10. Optimierung für Smart Displays

Smart Displays sind Geräte mit Touchfunktion, die es Empfängeranwendungen ermöglichen, Touchbedienung zu unterstützen.

In diesem Abschnitt erfährst du, wie du die Receiver-App beim Starten auf Smart Displays optimieren und die Steuerelemente des Videoplayers anpassen kannst.

Auf UI-Steuerelemente zugreifen

Auf das UI-Steuerelemente-Objekt 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 Sie <cast-media-player> nicht verwenden -Element enthält, müssen Sie touchScreenOptimizedApp in CastReceiverOptions festlegen. In diesem Codelab verwenden wir das Format <cast-media-player>. -Elements.

context.start({ touchScreenOptimizedApp: true });

Jedem Slot werden basierend auf MetadataType und MediaStatus.supportedMediaCommands Standardsteuerungstasten zugewiesen.

Videosteuerelemente

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

Bild eines Videos, das mit eingeblendeten UI-Steuerelementen wiedergegeben 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

Für MetadataType.MUSIC_TRACK wird das UI-Steuerelemente-Objekt für Smart Displays so angezeigt:

Bild von Musik mit überlagerter UI-Steuerung

  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-Control-Objekt bestimmt auch, ob ein ControlsButton angezeigt wird oder nicht, und zwar basierend auf MediaStatus.supportedMediaCommands.

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

Bild der Steuerelemente des Mediaplayers: Fortschrittsanzeige, Wiedergabe Schaltfläche „Vorwärts springen“ und „Zurückspringen“ Schaltflächen aktiviert

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

Bild der Steuerelemente des Mediaplayers: Fortschrittsanzeige, Wiedergabe Schaltfläche „Vorwärts springen“ und „Zurückspringen“ und &quot;Vorherige Warteschlange&quot; und „Nächste Warteschlange“ Schaltflächen aktiviert

Wenn der Wert von supportedMediaCommands gleich PAUSE | QUEUE_PREV | QUEUE_NEXT ist, wird das Standardlayout der Steuerelemente so angezeigt:

Bild der Steuerelemente des Mediaplayers: Fortschrittsanzeige, Wiedergabe und &quot;Zurück in die Warteschlange&quot;. und „Nächste Warteschlange“ Schaltflächen aktiviert

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

Bild der Steuerelemente des Mediaplayers: Fortschrittsanzeige, Wiedergabe Schaltfläche „Vorwärts springen“ und „Zurückspringen“ Schaltflächen, &quot;Vorherige Warteschlange&quot; und „Nächste Warteschlange“ und &quot;Untertitel&quot; Schaltflächen aktiviert

Wenn Sie den Wert von supportedMediaCommands nach dem Starten 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.

Anpassen der Steuerungsschaltflächen

Sie können die Steuerelemente mit PlayerDataBinder anpassen. Füge den folgenden Code in die Datei js/receiver.js unter den „touchControls“ ein, um den ersten Slot für deine 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

Die Mediensuche ist eine CAF-Empfängerfunktion, mit der Nutzer zusätzliche Inhalte auf Touchgeräten erkunden können. Zur Implementierung verwenden Sie PlayerDataBinder, um die BrowseContent-UI festzulegen. Sie können sie dann je nach Inhalt, den Sie anzeigen möchten, mit BrowseItems füllen.

BrowseContent

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

Bild der Benutzeroberfläche „BrowseContent“ (Inhalte durchsuchen) mit zwei Video-Thumbnails und einem Teil eines dritten Video-Thumbnails

  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.

BrowseItem

Verwenden Sie BrowseItem, um Titel, Untertitel, Dauer und Bild für jedes Element anzuzeigen:

Bild der Benutzeroberfläche „BrowseContent“ (Inhalte durchsuchen) mit zwei Video-Thumbnails und einem Teil eines dritten Video-Thumbnails

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

Media Browse-Daten festlegen

Du kannst eine Liste mit Medieninhalten erstellen, die du durchsuchen kannst, indem du setBrowseContent aufrufst. Fügen Sie den folgenden Code in die Datei js/receiver.js unter dem playerDataBinder und in den Event-Listener für MEDIA_CHANGED ein, um die Suchelemente mit dem Titel „Nächstes Video“ zu versehen.

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

Wenn Sie auf ein Element zur Mediensuche klicken, wird der LOAD-Abfangfunktion ausgelöst. Fügen Sie dem LOAD-Abfangfunktion den folgenden Code hinzu, um request.media.contentId der request.media.entity aus dem Mediensuchelement 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) => {
            ...
        });
    });

Du kannst das BrowseContent-Objekt auch auf null setzen, um die Media Browse-UI zu entfernen.

12. Fehler bei Empfänger-Apps beheben

Das Cast Receiver SDK bietet Entwicklern eine weitere Option zur einfachen Fehlerbehebung in Empfangs-Apps, indem sie die CastDebugProtokollierung API und das zugehörige Command and Control (CaC) Tool verwenden, um Protokolle zu erfassen.

Initialisierung

Fügen Sie das CastDebugLogger-Quellskript der Datei „index.html“ hinzu, um die API einzubinden. Die Quelle muss im <head>-Element deklariert werden. nach der Deklaration des Cast Receiver SDK einfügen.

<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 js/receiver.js oben in der Datei und unter playerManager den folgenden Code hinzu, um die Instanz CastDebugLogger abzurufen und den Protokollierungsvorgang 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 dem FEHLERMODUS wiedergegeben wird Nachricht, die auf einem roten Hintergrund in der oberen linken Ecke des Frames angezeigt wird.

Log Player-Ereignisse

Mit CastDebugLogger kannst du problemlos Spielerereignisse protokollieren, die vom CAF Receiver SDK ausgelöst werden, und verschiedene Protokollierungsstufen verwenden, um die Ereignisdaten zu protokollieren. Die loggerLevelByEvents-Konfiguration verwendet cast.framework.events.EventType und cast.framework.events.category, um anzugeben, welche Ereignisse protokolliert werden.

Füge den folgenden Code unter der castDebugLogger-Deklaration hinzu, um zu protokollieren, wenn ein CORE-Ereignis des 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 CastDebugProtokollierung API können Sie Protokollmeldungen erstellen, die auf dem Debug-Overlay des Empfängers in verschiedenen Farben angezeigt werden. Die folgenden Logmethoden sind verfügbar (von der höchsten zur niedrigsten Priorität geordnet):

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

Bei jeder Logmethode ist der erste Parameter ein benutzerdefiniertes Tag. Dies kann eine beliebige Zeichenfolge sein, die Sie aussagekräftig finden. CastDebugLogger verwendet Tags, um die Logs zu filtern. Die Verwendung von Tags wird weiter unten ausführlich erläutert. Der zweite Parameter ist die Protokollmeldung.

Wenn Sie Logs in Aktion sehen möchten, fügen Sie Ihrem LOAD-Interceptor Logs 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 in loggerLevelByTags die Protokollebene für jedes benutzerdefinierte Tag festlegen. Wenn Sie beispielsweise ein benutzerdefiniertes Tag mit der Logebene cast.framework.LoggerLevel.DEBUG aktivieren, werden alle hinzugefügten Meldungen mit Fehler-, Warnungs-, Info- und Fehlerbehebungsprotokollmeldungen angezeigt. Wenn Sie ein benutzerdefiniertes Tag mit der Ebene WARNING aktivieren, werden nur Logmeldungen mit Fehlern und Warnungen angezeigt.

Die Konfiguration von loggerLevelByTags ist optional. Wenn ein benutzerdefiniertes Tag nicht für seine Protokollierungsebene konfiguriert ist, werden alle Protokollmeldungen im Debug-Overlay angezeigt.

Fügen Sie unter dem CORE-Ereignisprotokoll 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 Cast-Fehlerprotokollierung stellt auf dem Empfänger ein Debug-Overlay bereit, mit dem Ihre benutzerdefinierten Protokollnachrichten auf dem Übertragungsgerät angezeigt werden können. Mit showDebugLogs kannst du das Debug-Overlay ein- und ausblenden und mit clearDebugLogs Logeinträge im Overlay löschen.

Füge den folgenden Code hinzu, um eine Vorschau des Debug-Overlays auf deinem Empfänger anzuzeigen.

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

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

13. Glückwunsch

Jetzt wissen Sie, wie Sie mit dem Cast Web Receiver SDK eine benutzerdefinierte Web-Receiver-App erstellen.

Weitere Informationen finden Sie im Entwicklerleitfaden zu Web Receiver.