Utilizzare l'SDK IMA DAI su Chromecast

Riprodurre live streaming registrati con l'API Video Stitcher di Google Cloud

Questa guida mostra come utilizzare l'SDK IMA DAI per i ricevitori web CAF per richiedere e riprodurre un live streaming per un evento registrato con l'API Video Stitcher di Google Cloud, e inserire un'interruzione pubblicitaria durante la riproduzione.

Questa guida espande l'esempio di base di DAI con servizio completo, aggiungendo il supporto per gli stream registrati con l'API Video Stitcher di Google Cloud.

Prima di continuare, assicurati che il formato di streaming sia supportato dai ricevitori web CAF.

Per informazioni sull'integrazione con altre piattaforme o sull'utilizzo degli SDK IMA lato client, consulta SDK Interactive Media Ads.

Sfondo

Prima di utilizzare questa guida, acquisisci familiarità con il protocollo del ricevitore web di Chromecast Application Framework.

Questa guida presuppone un livello di familiarità di base con i concetti del ricevitore CAF, come gli intercettori di messaggi, MediaInformation oggetti, e l'utilizzo dello strumento Cast Command and Control per emulare un mittente CAF.

Componenti e architettura dell'app

L'implementazione della riproduzione di live streaming con l'API Google Cloud Video Stitcher con l'SDK IMA CAF DAI prevede due componenti principali, come illustrato in questa guida:

  • VideoStitcherLiveStreamRequest: un oggetto che definisce una richiesta di stream ai server di Google. La richiesta specifica un'istanza dell'API Cloud Video Stitcher, un ID di configurazione live e altri parametri facoltativi.
  • StreamManager: un oggetto che gestisce la comunicazione tra lo stream video e l'SDK IMA DAI, ad esempio l'attivazione dei ping di monitoraggio e l'inoltro degli eventi di stream al publisher.

Prerequisiti

Per l'SDK IMA sono necessarie le seguenti variabili:

  • ID configurazione live: è l'ID di configurazione live che hai specificato durante la creazione della configurazione live dell'API Video Stitcher.

    LIVE_CONFIG_ID

  • Località: la regione Google Cloud in cui è stata creata la configurazione live.

    LOCATION

  • Numero progetto: il numero del progetto Google Cloud che utilizza l'API Video Stitcher.

    PROJECT_NUMBER

  • Token OAuth: il token OAuth di breve durata di un account di servizio con il ruolo utente Video Stitcher. Scopri di più sulla creazione di credenziali di breve durata per gli account di servizio.

    OAUTH_TOKEN

  • Codice di rete: il codice di rete di Google Ad Manager per richiedere gli annunci.

    NETWORK_CODE

  • Chiave asset personalizzata: la chiave asset personalizzata di Google Ad Manager generata durante il processo di creazione di una configurazione per un evento di live streaming con l'API Video Stitcher.

    CUSTOM_ASSET_KEY

Per un ricevitore Cast personalizzato sono necessari i seguenti elementi:

Preparare un mittente per trasmettere i dati dello stream al ricevitore

Innanzitutto, configura l'app mittente in modo che effettui una richiesta di caricamento al ricevitore web, contenente i seguenti campi nell'oggetto della tua piattaforma MediaInformation.

Campo Contenuti
contentId Un identificatore univoco per questo elemento multimediale, come definito nella documentazione di riferimento di Cast. Questo ID non deve essere riutilizzato per più elementi nella stessa coda multimediale.

CONTENT_ID

contentUrl URL dello stream di backup facoltativo da riprodurre se il caricamento dello stream DAI non riesce.

BACKUP_STREAM_URL

contentType MIME type facoltativo dell'URL dello stream di backup da riprodurre se il caricamento dello stream DAI non riesce.

BACKUP_STREAM_MIMETYPE

streamType La stringa letterale o la costante utilizzata per questo valore varia in base alla piattaforma del mittente.

LIVE

customData

Il campo customData contiene un archivio chiave-valore di campi aggiuntivi obbligatori. In questo caso, customData contiene i dati dello stream DAI che hai raccolto.

Campo Contenuti
liveConfigID LIVE_CONFIG_ID
region LOCATION
projectNumber PROJECT_NUMBER
oAuthToken OAUTH_TOKEN
networkCode NETWORK_CODE
customAssetKey CUSTOM_ASSET_KEY

Ecco alcuni esempi di codice per aiutarti a iniziare:

Web

Per configurare questi valori in un mittente web Cast, crea prima un MediaInfo oggetto con i dati richiesti, quindi effettua una richiesta di caricamento al ricevitore web.

// 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

Per configurare questi valori in un mittente web Cast, crea prima un MediaInfo oggetto con i dati richiesti, quindi effettua una richiesta di caricamento al ricevitore web.

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)

Per configurare questi valori in un mittente web Cast, crea prima un GCKMediaInformation oggetto con i dati richiesti, quindi effettua una richiesta di caricamento al ricevitore web.

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)

Per configurare questi valori in un mittente web Cast, crea prima un GCKMediaInformation oggetto con i dati richiesti, quindi effettua una richiesta di caricamento al ricevitore web.

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
}

Strumento CAC

Per configurare questi valori nello strumento Cast Command and Control, fai clic sulla scheda Carica contenuti multimediali e imposta il tipo di richiesta di caricamento personalizzata su LOAD. Quindi, sostituisci i dati JSON nell'area di testo con questo JSON:

{
  "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"
    }
  }
}

Questa richiesta di caricamento personalizzata può essere inviata al ricevitore per testare il resto dei passaggi.

Creare un ricevitore web CAF personalizzato

Crea un ricevitore web personalizzato, come descritto nella Guida al ricevitore web personalizzato dell'SDK CAF.

Il codice del ricevitore dovrebbe essere simile al seguente:

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

Importare l'SDK IMA DAI e ottenere Player Manager

Aggiungi un tag script per importare l'SDK IMA DAI per CAF nel ricevitore web, subito dopo lo script di caricamento di CAF. Quindi, nel tag di script che segue, memorizza il contesto del ricevitore e Player Manager come costanti prima di avviare il ricevitore.

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

Inizializzare IMA Stream Manager

Inizializza 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>

Creare l'intercettore di caricamento di Stream Manager

Prima che gli elementi multimediali vengano passati a CAF, crea la richiesta di stream in un intercettore di messaggi LOAD.

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

Creare la richiesta di stream

Completa la funzione createStreamRequest per creare una richiesta di live streaming dell'API Video Stitcher, in base alla richiesta di caricamento CAF.

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

(Facoltativo) Aggiungere opzioni della sessione di streaming

Personalizza la richiesta di stream aggiungendo opzioni di sessione per sostituire la configurazione predefinita dell'API Cloud Video Stitcher utilizzando VideoStitcherLiveStreamRequest.videoStitcherSessionOptions. Se fornisci un'opzione non riconosciuta, l'API Cloud Video Stitcher risponderà con un errore HTTP 400. Per assistenza, consulta la guida alla risoluzione dei problemi.

Ad esempio, puoi sostituire le opzioni del manifest con il seguente snippet di codice, che richiede due manifest di stream con riproduzioni ordinate dal bitrate più basso a quello più alto.

...

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

streamManager.requestStream(streamRequest);