Reproducir emisiones en directo registradas con la API Google Cloud Video Stitcher
En esta guía se muestra cómo usar el SDK de IMA DAI para Web Receivers de CAF para solicitar y reproducir una emisión en directo de un evento registrado con la API Video Stitcher de Google Cloud e insertar un bloque de anuncios durante la reproducción.
En esta guía se amplía el ejemplo básico de la inserción dinámica de anuncios de servicio completo, añadiendo compatibilidad con las emisiones registradas en la API Google Cloud Video Stitcher.
Antes de continuar, asegúrate de que tu formato de streaming sea compatible con los web receivers de CAF.
Para obtener información sobre cómo integrar otras plataformas o usar los SDKs de IMA del lado del cliente, consulte SDKs de anuncios multimedia interactivos.
Fondo
Antes de usar esta guía, familiarízate con el protocolo Web Receiver del framework de aplicaciones de Chromecast.
En esta guía se da por hecho que tienes un nivel básico de familiarización con los conceptos del receptor de CAF, como los interceptores de mensajes, los objetos MediaInformation
y el uso de la herramienta de control y comandos de Cast para emular un remitente de CAF.
Componentes y arquitectura de la aplicación
Para implementar la reproducción de emisiones en directo con la API Video Stitcher de Google Cloud y el SDK de inserción dinámica de anuncios de CAF de IMA, se necesitan dos componentes principales, tal como se muestra en esta guía:
VideoStitcherLiveStreamRequest
: objeto que define una solicitud de transmisión a los servidores de Google. La solicitud especifica una instancia de la API Cloud Video Stitcher, un ID de configuración en directo y otros parámetros opcionales.StreamManager
: objeto que gestiona la comunicación entre el flujo de vídeo y el SDK de inserción dinámica de anuncios de IMA, como enviar pings de seguimiento y reenviar eventos de flujo al editor.
Requisitos previos
Necesita las siguientes variables para el SDK de IMA:
ID de configuración en directo: es el ID de configuración en directo que especificaste al crear tu configuración en directo de la API Video Stitcher.
LIVE_CONFIG_ID
Ubicación: la región de Google Cloud en la que se creó tu Live Config.
LOCATION
Número de proyecto: número del proyecto de Google Cloud que usa la API Video Stitcher.
PROJECT_NUMBER
Token de OAuth: token de OAuth de corta duración de una cuenta de servicio con el rol de usuario de Video Stitcher. Consulta más información sobre cómo crear credenciales de cuentas de servicio de duración reducida.
OAUTH_TOKEN
Código de red: código de red de Google Ad Manager para solicitar anuncios.
NETWORK_CODE
Clave de recurso personalizada: clave de recurso personalizada de Google Ad Manager generada durante el proceso de creación de una configuración para un evento de emisión en directo con la API Video Stitcher.
CUSTOM_ASSET_KEY
Para crear un receptor Cast personalizado, necesitas lo siguiente:
Una cuenta de Consola para Desarrolladores de Cast con dispositivos de prueba en una lista de permitidos.
Una aplicación web de receptor alojada que esté registrada en tu Consola de Google Cast para Desarrolladores y que se pueda modificar para alojar el código proporcionado en esta guía.
Una aplicación de envío configurada para usar tu aplicación web de receptor. En este ejemplo, se usa la herramienta de control y comandos de Cast como aplicación de envío.
Preparar un remitente para que transfiera datos de la emisión al receptor
Primero, configura tu aplicación emisora para que haga una solicitud de carga a tu receptor web, que contenga los siguientes campos en el objeto MediaInformation
de tu plataforma.
Campo | Contenido | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
contentId
|
Identificador único de este elemento multimedia, tal como se define en la documentación de referencia de Cast. Este ID no se debe reutilizar para varios elementos de la misma cola multimedia.
|
||||||||||||||
contentUrl
|
URL de emisión de respaldo opcional que se reproducirá si no se puede cargar la emisión de inserción dinámica de anuncios.
|
||||||||||||||
contentType
|
Tipo MIME opcional de la URL de la emisión de respaldo que se reproducirá si no se puede cargar la emisión de inserción dinámica de anuncios.
|
||||||||||||||
streamType
|
La cadena literal o la constante que se usa para este valor varía según la plataforma del remitente.
|
||||||||||||||
customData
|
El campo
|
Aquí tienes algunos ejemplos de código para ayudarte a empezar:
Web
Para configurar estos valores en un remitente web de Cast, primero crea un objeto MediaInfo
con los datos necesarios y, a continuación, haz una solicitud de carga al receptor 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
Para configurar estos valores en un remitente web de Cast, primero crea un objeto MediaInfo
con los datos necesarios y, a continuación, haz una solicitud de carga al receptor 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)
Para configurar estos valores en un remitente web de Cast, primero crea un objeto GCKMediaInformation
con los datos necesarios y, a continuación, haz una solicitud de carga al receptor 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)
Para configurar estos valores en un remitente web de Cast, primero crea un objeto GCKMediaInformation
con los datos necesarios y, a continuación, haz una solicitud de carga al receptor 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
}
Herramienta CAC
Para configurar estos valores en la herramienta de control por voz de Cast, haz clic en la pestaña Cargar contenido multimedia y define el tipo de solicitud de carga personalizada como LOAD. A continuación, sustituye los datos JSON del área de texto por este 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"
}
}
}
Esta solicitud de carga personalizada se puede enviar al receptor para probar el resto de los pasos.
Crear un receptor web CAF personalizado
Crea un receptor web personalizado, como se indica en la guía del receptor web personalizado del SDK de CAF.
El código del receptor debería tener el siguiente aspecto:
<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>
Importar el SDK de IMA DAI y obtener el gestor de reproductores
Añada una etiqueta <script> para importar el SDK de IMA DAI para CAF a su receptor web, justo después de cargar el script de CAF. A continuación, en la etiqueta de secuencia de comandos que sigue, almacena el contexto del receptor y el gestor de reproductores como constantes antes de iniciar el receptor.
<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>
Inicializar el gestor de emisiones de IMA
Inicializa el gestor de emisiones de IMA.
<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>
Crear el interceptor de carga de Stream Manager
Antes de que tus elementos multimedia se transfieran a CAF, crea tu solicitud de emisión en un interceptor de mensajes 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();
Crear la solicitud de flujo
Completa la función createStreamRequest
para crear una solicitud de emisión en directo de la API Video Stitcher basada en la solicitud de carga de 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;
};
(Opcional) Añadir opciones de sesión de streaming
Personaliza tu solicitud de emisión añadiendo opciones de sesión para anular la configuración predeterminada de la API Cloud Video Stitcher mediante VideoStitcherLiveStreamRequest.videoStitcherSessionOptions
.
Si proporcionas una opción no reconocida, la API Cloud Video Stitcher responderá con un error HTTP 400. Consulta la guía de solución de problemas para obtener ayuda.
Por ejemplo, puedes anular las opciones del manifiesto con el siguiente fragmento de código, que solicita dos manifiestos de emisión con representaciones ordenadas de menor a mayor tasa de bits.
...
// The following session options are examples. Use session options
// that are compatible with your video stream.
streamRequest.videoStitcherSessionOptions = {
"manifestOptions": {
"bitrateOrder": "ascending"
}
};
streamManager.requestStream(streamRequest);