IMA DAI SDK auf Chromecast verwenden

Mit der Google Cloud Video Stitcher API registrierte Livestreams abspielen

In diesem Leitfaden wird gezeigt, wie du mit dem IMA DAI SDK für CAF-Webempfänger einen Livestream für ein Ereignis anfordern und wiedergeben kannst, das bei der Google Cloud Video Stitcher API registriert ist, und während der Wiedergabe eine Werbeunterbrechung einfügen kannst.

In diesem Leitfaden wird das grundlegende Beispiel für die dynamische Anzeigenbereitstellung im Full-Service-Modell erweitert. Es wird Unterstützung für Streams hinzugefügt, die mit der Google Cloud Video Stitcher API registriert sind.

Achte darauf, dass dein Streamingformat von CAF-Webempfängern unterstützt wird, bevor du fortfährst.

Informationen zur Einbindung in andere Plattformen oder zur Verwendung der clientseitigen IMA SDKs finden Sie unter Interactive Media Ads SDKs.

Hintergrund

Bevor du diesen Leitfaden verwendest, solltest du dich mit dem Web-Empfängerprotokoll des Chromecast Application Framework vertraut machen.

In diesem Leitfaden werden grundlegende Kenntnisse der CAF-Empfängerkonzepte vorausgesetzt, z. B. Nachrichten-Interceptors, MediaInformation-Objekte und die Verwendung des Cast Command and Control-Tools zum Emulieren eines CAF-Senders.

App-Komponenten und -Architektur

Die Implementierung der Livestreamwiedergabe mit der Google Cloud Video Stitcher API und dem IMA CAF Media Delivery SDK umfasst zwei Hauptkomponenten, wie in dieser Anleitung gezeigt:

  • VideoStitcherLiveStreamRequest: Ein Objekt, das eine Streamanfrage an die Google-Server definiert. In der Anfrage werden eine Instanz der Cloud Video Stitcher API, eine Livekonfigurations-ID und andere optionale Parameter angegeben.
  • StreamManager: Ein Objekt, das die Kommunikation zwischen dem Videostream und dem IMA DAI SDK verwaltet, z. B. das Auslösen von Tracking-Pings und das Weiterleiten von Stream-Ereignissen an den Publisher.

Vorbereitung

Für das IMA SDK sind die folgenden Variablen erforderlich:

  • Live-Konfigurations-ID: Dies ist die Live-Konfigurations-ID, die du beim Erstellen der Live-Konfiguration der Video Stitcher API angegeben hast.

    LIVE_CONFIG_ID

  • Standort: Die Google Cloud-Region, in der Ihre Live-Konfiguration erstellt wurde.

    LOCATION

  • Projektnummer: Die Google Cloud-Projektnummer, die mit der Video Stitcher API verwendet wird.

    PROJECT_NUMBER

  • OAuth-Token: Das kurzlebige OAuth-Token eines Dienstkontos mit der Nutzerrolle „Video Stitcher“. Weitere Informationen zum Erstellen kurzlebiger Anmeldedaten für Dienstkonten

    OAUTH_TOKEN

  • Network Code: Google Ad Manager-Netzwerkcode zum Anfordern von Anzeigen.

    NETWORK_CODE

  • Benutzerdefinierter Asset-Schlüssel: Benutzerdefinierter Google Ad Manager-Asset-Schlüssel, der beim Erstellen einer Konfiguration für ein Livestream-Ereignis mit der Video Stitcher API generiert wird.

    CUSTOM_ASSET_KEY

Für einen benutzerdefinierten Cast-Empfänger benötigen Sie Folgendes:

  • Ein Cast Developer Console-Konto mit Testgeräten auf einer Zulassungsliste.

  • Eine gehostete Web-Empfänger-App, die in Ihrer Cast Developer Console registriert ist und so geändert werden kann, dass der in diesem Leitfaden bereitgestellte Code gehostet wird.

  • Eine Sender-App, die für die Verwendung deiner Web-Empfänger-App konfiguriert ist. In diesem Beispiel wird das Cast Command and Control-Tool als Sender verwendet.

Sender für die Weitergabe von Streamdaten an den Empfänger vorbereiten

Konfiguriere zuerst deine Sender-App so, dass sie eine Ladeanfrage an deinen Webempfänger sendet, die die folgenden Felder im MediaInformation-Objekt deiner Plattform enthält.

Feld Inhalt
contentId Eine eindeutige Kennung für dieses Medienelement, wie in der Cast-Referenzdokumentation definiert. Diese ID darf nicht für mehrere Elemente in derselben Medienwarteschlange wiederverwendet werden.

CONTENT_ID

contentUrl Optionale URL für den Back-up-Stream, der wiedergegeben wird, wenn der DAI-Stream nicht geladen werden kann.

BACKUP_STREAM_URL

contentType Optionaler Mime-Typ der URL des Back-up-Streams, der wiedergegeben werden soll, wenn der DAI-Stream nicht geladen werden kann.

BACKUP_STREAM_MIMETYPE

streamType Das für diesen Wert verwendete Stringliteral oder die Konstante variiert je nach Absenderplattform.

LIVE

customData

Das Feld customData enthält einen Schlüssel/Wert-Speicher mit zusätzlichen Pflichtfeldern. In diesem Fall enthält customData die von Ihnen erfassten Daten des dynamischen Anzeigenbereitstellungs-Streams.

Feld Inhalt
liveConfigID LIVE_CONFIG_ID
region LOCATION
projectNumber PROJECT_NUMBER
oAuthToken OAUTH_TOKEN
networkCode NETWORK_CODE
customAssetKey CUSTOM_ASSET_KEY

Hier sind einige Codebeispiele für den Einstieg:

Web

Wenn du diese Werte in einem Cast-Websender konfigurieren möchtest, erstellst du zuerst ein MediaInfo-Objekt mit den erforderlichen Daten und sendest dann eine Ladeanfrage an den Webempfänger.

// Create mediaInfo object
const mediaInfo = new chrome.cast.media.MediaInfo("CONTENT_ID");
mediaInfo.contentUrl = "BACKUP_STREAM_URL";
mediaInfo.contentType = "BACKUP_STREAM_MIMETYPE";
mediaInfo.streamType = chrome.cast.media.StreamType.LIVE;
mediaInfo.customData = {
liveConfigID: "LIVE_CONFIG_ID",
region: "LOCATION",
projectNumber: "PROJECT_NUMBER",
oAuthToken: "OAUTH_TOKEN",
networkCode: "NETWORK_CODE",
customAssetKey: "CUSTOM_ASSET_KEY"
};

// Make load request to cast web receiver
const castSession = cast.framework.CastContext.getInstance().getCurrentSession();
const request = new chrome.cast.media.LoadRequest(mediaInfo);
castSession.loadMedia(request).then(
  () => { console.log('Load succeed'); },
  (errorCode) => { console.log('Error code: ' + errorCode); });

Android

Wenn du diese Werte in einem Cast-Websender konfigurieren möchtest, erstellst du zuerst ein MediaInfo-Objekt mit den erforderlichen Daten und sendest dann eine Ladeanfrage an den Webempfänger.

JSONObject customData = new JSONObject()
  .put("liveConfigID", "LIVE_CONFIG_ID")
  .put("region", "LOCATION")
  .put("projectNumber", "PROJECT_NUMBER")
  .put("oAuthToken", "OAUTH_TOKEN")
  .put("networkCode", "NETWORK_CODE")
  .put("customAssetKey", "CUSTOM_ASSET_KEY");

MediaInfo mediaInfo = MediaInfo.Builder("CONTENT_ID")
  .setContentUrl("BACKUP_STREAM_URL")
  .setContentType("BACKUP_STREAM_MIMETYPE")
  .setStreamType(MediaInfo.STREAM_TYPE_LIVE)
  .setCustomData(customData)
  .build();

RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient();
remoteMediaClient.load(new MediaLoadRequestData.Builder().setMediaInfo(mediaInfo).build());

iOS (Obj-C)

Wenn du diese Werte in einem Cast-Websender konfigurieren möchtest, erstellst du zuerst ein GCKMediaInformation-Objekt mit den erforderlichen Daten und sendest dann eine Ladeanfrage an den Webempfänger.

NSURL url = [NSURL URLWithString:@"BACKUP_STREAM_URL"];
NSDictionary *customData = @{
  @"liveConfigID": @"LIVE_CONFIG_ID",
  @"region": @"LOCATION",
  @"projectNumber": @"PROJECT_NUMBER",
  @"oAuthToken": @"OAUTH_TOKEN",
  @"networkCode": @"NETWORK_CODE",
  @"customAssetKey": @"CUSTOM_ASSET_KEY"
};

GCKMediaInformationBuilder *mediaInfoBuilder =
  [[GCKMediaInformationBuilder alloc] initWithContentID: @"CONTENT_ID"];
mediaInfoBuilder.contentURL = url;
mediaInfoBuilder.contentType = @"BACKUP_STREAM_MIMETYPE";
mediaInfoBuilder.streamType = GCKMediaStreamTypeLive;
mediaInfoBuilder.customData = customData;
self.mediaInformation = [mediaInfoBuilder build];

GCKRequest *request = [self.sessionManager.currentSession.remoteMediaClient loadMedia:self.mediaInformation];
if (request != nil) {
  request.delegate = self;
}

iOS (Swift)

Wenn du diese Werte in einem Cast-Websender konfigurieren möchtest, erstellst du zuerst ein GCKMediaInformation-Objekt mit den erforderlichen Daten und sendest dann eine Ladeanfrage an den Webempfänger.

let url = URL.init(string: "BACKUP_STREAM_URL")
guard let mediaURL = url else {
  print("invalid mediaURL")
  return
}

let customData = [
  "liveConfigID": "LIVE_CONFIG_ID",
  "region": "LOCATION",
  "projectNumber": "PROJECT_NUMBER",
  "oAuthToken": "OAUTH_TOKEN",
  "networkCode": "NETWORK_CODE",
  "customAssetKey": "CUSTOM_ASSET_KEY"
]

let mediaInfoBuilder = GCKMediaInformationBuilder.init(contentId: "CONTENT_ID")
mediaInfoBuilder.contentURL = mediaUrl
mediaInfoBuilder.contentType = "BACKUP_STREAM_MIMETYPE"
mediaInfoBuilder.streamType = GCKMediaStreamType.Live
mediaInfoBuilder.customData = customData
mediaInformation = mediaInfoBuilder.build()

guard let mediaInfo = mediaInformation else {
  print("invalid mediaInformation")
  return
}

if let request = sessionManager.currentSession?.remoteMediaClient?.loadMedia(mediaInfo) {
  request.delegate = self
}

CAC-Tool

Wenn du diese Werte im Cast Command and Control-Tool konfigurieren möchtest, klicke auf den Tab „Load Media“ (Medien laden) und lege den Typ der benutzerdefinierten Ladeanfrage auf „LOAD“ fest. Ersetzen Sie dann die JSON-Daten im Textfeld durch Folgendes:

{
  "media": {
    "contentId": "CONTENT_ID",
    "contentUrl": "BACKUP_STREAM_URL",
    "contentType": "BACKUP_STREAM_MIMETYPE",
    "streamType": "LIVE",
    "customData": {
      "liveConfigID": "LIVE_CONFIG_ID",
      "region": "LOCATION",
      "projectNumber": "PROJECT_NUMBER",
      "oAuthToken": "OAUTH_TOKEN",
      "networkCode": "NETWORK_CODE",
      "customAssetKey": "CUSTOM_ASSET_KEY"
    }
  }
}

Diese benutzerdefinierte Ladeanfrage kann an den Empfänger gesendet werden, um die restlichen Schritte zu testen.

Benutzerdefinierten CAF-Webempfänger erstellen

Erstelle einen benutzerdefinierten Webreceiver, wie im Leitfaden für benutzerdefinierte Webreceiver des CAF SDK beschrieben.

Der Code des Empfängers sollte so aussehen:

<html>
<head>
  <script
      src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js">
  </script>
</head>
<body>
  <cast-media-player></cast-media-player>
  <script>
    const castContext = cast.framework.CastReceiverContext.getInstance()
    castContext.start();
  </script>
</body>
</html>

IMA DAI SDK importieren und Player Manager abrufen

Füge ein Script-Tag hinzu, um das IMA DAI SDK für CAF in deinen Webreceiver zu importieren, kurz nachdem das Script CAF geladen hat. Speichere dann im folgenden Script-Tag den Receiver-Kontext und den Player-Manager als Konstanten, bevor du den Receiver startest.

<html>
<head>
  <script
      src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
  <script src="//imasdk.googleapis.com/js/sdkloader/cast_dai.js"></script>
</head>
<body>
  <cast-media-player></cast-media-player>
  <script>
    const castContext = cast.framework.CastReceiverContext.getInstance();
    const playerManager = castContext.getPlayerManager();

    castContext.start();
  </script>
</body>
</html>

IMA Stream Manager initialisieren

Initialisiere den IMA Stream Manager.

<html>
<head>
  <script type="text/javascript"
      src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
  <script src="//imasdk.googleapis.com/js/sdkloader/cast_dai.js"></script>
</head>
<body>
  <cast-media-player></cast-media-player>
  <script>
    const castContext = cast.framework.CastReceiverContext.getInstance();
    const playerManager = castContext.getPlayerManager();
    const streamManager = new google.ima.cast.dai.api.StreamManager();

    castContext.start();
  </script>
</body>
</html>

Stream Manager Load Interceptor erstellen

Bevor deine Medienelemente an CAF übergeben werden, erstelle deine Streamanfrage in einem LOAD-Nachrichten-Interceptor.

    const castContext = cast.framework.CastReceiverContext.getInstance();
    const playerManager = castContext.getPlayerManager();
    const streamManager = new google.ima.cast.dai.api.StreamManager();

    /**
     * Creates a livestream request object for the Video Stitcher API.
     * @param {!LoadRequestData} castRequest The request object from the cast sender
     * @return {StreamRequest} an IMA stream request
     */
    const createStreamRequest = (castRequest) => { /* ... */};

    /**
     * Initates a DAI stream request for the final stream manifest.
     * @param {!LoadRequestData} castRequest The request object from the cast sender
     * @return {Promise<LoadRequestData>} a promise that resolves to an updated castRequest, containing the DAI stream manifest
     */
    const createDAICastRequest = (castRequest) => {
        return streamManager.requestStream(castRequest, createStreamRequest(castRequest))
          .then((castRequestWithStreamData) => {
            console.log('Successfully made DAI stream request.');
            return castRequestWithStreamData;
          })
          .catch((error) => {
            console.log('Failed to make DAI stream request.');
            // CAF will automatically fallback to the content URL
            // that it can read from the castRequest object.
            return castRequest;
          });
    };

    playerManager.setMessageInterceptor(
        cast.framework.messages.MessageType.LOAD, createDAICastRequest);

    castContext.start();

Streamanfrage erstellen

Vervollständige die Funktion createStreamRequest, um eine Livestream-Anfrage an die Video Stitcher API zu erstellen, die auf der CAF-Ladeanfrage basiert.

    /**
     * Creates a livestream request object for the Video Stitcher API.
     * @param {!LoadRequestData} castRequest The request object from the cast sender
     * @return {StreamRequest} an IMA stream request
     */
    const createStreamRequest = (castRequest) => {
      const streamRequest = new google.ima.cast.dai.api.VideoStitcherLiveStreamRequest();
      const customData = castRequest.media.customData;

      streamRequest.liveStreamEventId = customData.liveConfigID;
      streamRequest.region = customData.region;
      streamRequest.projectNumber = customData.projectNumber;
      streamRequest.oAuthToken = customData.oAuthToken;
      streamRequest.networkCode = customData.networkCode;
      streamRequest.customAssetKey = customData.customAssetKey;

      return streamRequest;
    };

(Optional) Optionen für die Streamingsitzung hinzufügen

Du kannst deine Streamanfrage anpassen, indem du Sitzungsoptionen hinzufügst, um die Standardkonfiguration der Cloud Video Stitcher API mit VideoStitcherLiveStreamRequest.videoStitcherSessionOptions zu überschreiben. Wenn du eine nicht erkannte Option angibst, antwortet die Cloud Video Stitcher API mit einem HTTP-Fehler 400. Weitere Informationen finden Sie in der Anleitung zur Fehlerbehebung.

Du kannst die Manifest-Optionen beispielsweise mit dem folgenden Code-Snippet überschreiben. Dabei werden zwei Streammanifeste mit Darstellungen angefordert, die von der niedrigsten bis zur höchsten Bitrate sortiert sind.

...

// The following session options are examples. Use session options
// that are compatible with your video stream.
streamRequest.videoStitcherSessionOptions = {
  "manifestOptions": {
    "bitrateOrder": "ascending"
  }
};

streamManager.requestStream(streamRequest);