Reproduce transmisiones en vivo registradas con la API de Video Stitcher de Google Cloud
En esta guía, se muestra cómo usar el SDK de DAI de IMA para receptores web de CAF a fin de solicitar y reproducir una transmisión en vivo de un evento registrado con la API de Video Stitcher de Google Cloud y, luego, insertar una pausa publicitaria durante la reproducción.
En esta guía, se amplía el ejemplo básico de la DAI de servicio completo y se agrega compatibilidad con transmisiones registradas con la API de Video Stitcher de Google Cloud.
Asegúrate de que tu formato de transmisión sea compatible con los receptores web de CAF antes de continuar.
Para obtener información sobre la integración con otras plataformas o el uso de los SDK de IMA del cliente, consulta SDK de anuncios multimedia interactivos.
Formación
Antes de usar esta guía, familiarízate con el protocolo del receptor web del framework de la aplicación de Chromecast.
En esta guía, se asume un nivel básico de familiaridad con los conceptos del receptor de CAF, como los interceptores de mensajes y los objetos MediaInformation
, y el uso de la herramienta de comandos y control de transmisión para emular un remitente de CAF.
Componentes y arquitectura de la app
La implementación de la reproducción de transmisiones en vivo con la API de Video Stitcher de Google Cloud con el SDK de DAI de IMA CAF implica dos componentes principales, como se muestra en esta guía:
VideoStitcherLiveStreamRequest
: Es un objeto que define una solicitud de transmisión a los servidores de Google. La solicitud especifica una instancia de la API de Cloud Video Stitcher, un ID de configuración en vivo y otros parámetros opcionales.StreamManager
: Es un objeto que controla la comunicación entre la transmisión de video por Internet y el SDK de DAI de IMA, como activar pings de seguimiento y reenviar eventos de transmisión al publicador.
Requisitos previos
Necesitas las siguientes variables para el SDK de IMA:
ID de la configuración en vivo: Este es el ID de la configuración en vivo que especificaste cuando creaste la configuración en vivo de la API de Video Stitcher.
LIVE_CONFIG_ID
Ubicación: Es la región de Google Cloud en la que se creó tu configuración en vivo.
LOCATION
Número de proyecto: Es el número de proyecto de Google Cloud con la API de Video Stitcher.
PROJECT_NUMBER
Token de OAuth: El token de OAuth de corta duración de una cuenta de servicio con la función del usuario de Video Stitcher. Obtén más información sobre cómo crear credenciales de corta duración para cuentas de servicio.
OAUTH_TOKEN
Código de red: Es el código de red de Google Ad Manager para solicitar anuncios.
NETWORK_CODE
Clave de recurso personalizada: Es la clave de recurso personalizada de Google Ad Manager que se genera durante el proceso de creación de una configuración para un evento de transmisión en vivo con la API de Video Stitcher.
CUSTOM_ASSET_KEY
Necesitas lo siguiente para un receptor de transmisiones personalizado:
Una cuenta de Google Cast Developer Console con dispositivos de prueba en una lista de entidades permitidas
Una app de receptor web alojada que esté registrada en tu Play Console de Cast y que se pueda modificar a fin de alojar el código proporcionado en esta guía
Una app de envío configurada para usar tu app de receptor web. Para los fines de este ejemplo, en esta guía, se usa la herramienta de comando y control de transmisión como la emisora.
Prepara un remitente para pasar datos de transmisión al receptor
Primero, configura tu app emisora para que realice una solicitud de carga a tu receptor web, que contenga los siguientes campos del objeto MediaInformation
de la plataforma.
Campo | Contenido | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
contentId
|
Un identificador único para este elemento multimedia, como se define en la documentación de referencia de Cast. Este ID no se debe volver a usar para varios elementos de la misma cola de contenido multimedia.
|
||||||||||||||
contentUrl
|
URL de transmisión de copia de seguridad opcional para reproducir si no se puede cargar la transmisión de DAI.
|
||||||||||||||
contentType
|
Tipo MIME opcional de la URL de transmisión de copia de seguridad que se reproduce si no se puede cargar la transmisión de DAI.
|
||||||||||||||
streamType
|
El literal de string o la constante que se usa para este valor varía según la plataforma del remitente.
|
||||||||||||||
customData
|
El campo
|
A continuación, se incluyen algunas muestras de código que te ayudarán a comenzar:
Web
Para configurar estos valores en un remitente web de transmisión, primero crea un objeto MediaInfo
con los datos requeridos y, luego, realiza 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 transmisión, primero crea un objeto MediaInfo
con los datos requeridos y, luego, realiza 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 transmisión, primero crea un objeto GCKMediaInformation
con los datos requeridos y, luego, realiza 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 transmisión, primero crea un objeto GCKMediaInformation
con los datos requeridos y, luego, realiza 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 comando y control de Cast, haz clic en la pestaña Cargar contenido multimedia y establece el tipo de solicitud de carga personalizado en CARGAR. Luego, reemplaza los datos JSON en el área de texto con 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.
Cómo crear un receptor web de CAF personalizado
Crea un receptor web personalizado, como se ve en la Guía del receptor web personalizado del SDK de CAF.
El código de tu receptor debería verse de la siguiente manera:
<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>
Importa el SDK de IMA de DAI y obtén el Administrador del reproductor
Agrega una etiqueta de secuencia de comandos para importar el SDK de IMA de DAI para CAF a tu receptor web, justo después de que la secuencia de comandos cargue el CAF. Luego, en la etiqueta de la secuencia de comandos que sigue, almacena el contexto del receptor y el administrador del jugador 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>
Inicializa IMA Stream Manager
Inicializa 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>
Crea el Interceptor de carga de Stream Manager
Antes de que tus elementos multimedia se pasen a CAF, crea la solicitud de transmisión en un interceptor de mensajes de CARGA.
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();
Crea la solicitud de transmisión
Completa la función createStreamRequest
para crear una solicitud de transmisión en vivo de la API de Video Stitcher según 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;
};