Agrega funciones avanzadas a tu app de remitente web

Pausas publicitarias

El SDK de Web Sender proporciona compatibilidad con pausas publicitarias y anuncios complementarios dentro de una transmisión multimedia determinada.

Consulta la descripción general de las pausas publicitarias del receptor web para obtener más información sobre su funcionamiento.

Si bien se pueden especificar las pausas tanto en el remitente como en el receptor, se recomienda que se especifiquen en el receptor web y en el receptor de Android TV para mantener un comportamiento coherente en todas las plataformas.

En la Web, especifica las pausas publicitarias en un comando de carga mediante BreakClip y Break:

let breakClip1 = new BreakClip('bc0');
breakClip1.title = 'Clip title'
breakClip1.posterUrl = 'https://www.some.url';
breakClip1.duration = 60;
breakClip.whenSKippable = 5;

let breakClip2 = ...
let breakClip3 = ...

let break1 = new Break('b0', ['bc0', 'bc1', 'bc2'], 10);

let mediaInfo = new chrome.cast.media.MediaInfo(<contentId>, '<contentType');
...
mediaInfo.breakClips = [breakClip1, breakClip2, breakClip3];
mediaInfo.breaks = [break1];

let request = new chrome.cast.media.LoadRequest(mediaInfo);

cast.framework.CastContext.getInstance().getCurrentSession().loadMedia(request)

Cómo usar las APIs de segmentos

Una pista puede ser un objeto de texto (subtítulos) o un objeto de transmisión de audio o video. Las APIs de Track te permiten trabajar con estos objetos en tu aplicación.

Un objeto Track representa un segmento en el SDK. Puedes configurar un segmento y asignarle un ID único de la siguiente manera:

var englishSubtitle = new chrome.cast.media.Track(1, // track ID
  chrome.cast.media.TrackType.TEXT);
englishSubtitle.trackContentId = 'https://some-url/caption_en.vtt';
englishSubtitle.trackContentType = 'text/vtt';
englishSubtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
englishSubtitle.name = 'English Subtitles';
englishSubtitle.language = 'en-US';
englishSubtitle.customData = null;

var frenchSubtitle = new chrome.cast.media.Track(2, // track ID
  chrome.cast.media.TrackType.TEXT);
frenchSubtitle.trackContentId = 'https://some-url/caption_fr.vtt';
frenchSubtitle.trackContentType = 'text/vtt';
frenchSubtitle.subtype = chrome.cast.media.TextTrackType.SUBTITLES;
frenchSubtitle.name = 'French Subtitles';
frenchSubtitle.language = 'fr';
frenchSubtitle.customData = null;

var frenchAudio = new chrome.cast.media.Track(3, // track ID
  chrome.cast.media.TrackType.AUDIO);
frenchAudio.trackContentId = 'trk0001';
frenchAudio.trackContentType = 'audio/mp3';
frenchAudio.subtype = null;
frenchAudio.name = 'French Audio';
frenchAudio.language = 'fr';
frenchAudio.customData = null;

Un elemento multimedia puede tener varias pistas. Por ejemplo, puede tener varios subtítulos (cada uno para un idioma diferente) o varias transmisiones de audio alternativas (para diferentes idiomas).

MediaInfo es la clase que modela un elemento multimedia. Para asociar una colección de objetos Track con un elemento multimedia, actualiza su propiedad tracks. Esta asociación debe realizarse antes de que el contenido multimedia se cargue en el receptor:

var tracks = [englishSubtitle, frenchSubtitle, frenchAudio];
var mediaInfo = new chrome.cast.media.MediaInfo(mediaURL);
mediaInfo.contentType = 'video/mp4';
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
mediaInfo.customData = null;
mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED;
mediaInfo.textTrackStyle = new chrome.cast.media.TextTrackStyle();
mediaInfo.duration = null;
mediaInfo.tracks = tracks;

Puedes configurar los segmentos activos en la solicitud de contenido multimedia activeTrackIds.

También puedes activar uno o más segmentos asociados con el elemento multimedia después de cargar el contenido multimedia. Para ello, llama a EditTracksInfoRequest(opt_activeTrackIds, opt_textTrackStyle) y pasa los IDs de los segmentos que se activarán en opt_activeTrackIds. Ten en cuenta que ambos parámetros son opcionales, y puedes elegir cuáles son las pistas o los estilos activos que quieras establecer a tu discreción. Por ejemplo, a continuación, se muestra cómo activar el subtítulo en francés (2) y el audio en francés (3):

var activeTrackIds = [2, 3];
var tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest(activeTrackIds);
media.editTracksInfo(tracksInfoRequest, successCallback, errorCallback);

Para quitar todas las pistas de audio o video del contenido multimedia actual, solo configura mediaInfo.tracks=null (un array vacío) y vuelve a cargar el contenido multimedia.

Para quitar todas las pistas de texto del contenido multimedia actual (por ejemplo, desactivar los subtítulos), realiza una de las siguientes acciones:

  • Actualiza var activeTrackIds = [2, 3]; (que se mostró anteriormente) para que solo incluya [3], la pista de audio.
  • Establece mediaInfo.tracks=null. Ten en cuenta que no es necesario volver a cargar los elementos multimedia para desactivar los subtítulos de texto (track.hidden). Si envías un array activeTracksId que no contiene un trackId habilitado previamente, se inhabilitará el seguimiento de texto.

Cómo aplicar estilo a pistas de texto

TextTrackStyle es el objeto que encapsula la información de estilo de un seguimiento de texto. Después de crear o actualizar un objeto TextTrackStyle existente, puedes aplicarlo al elemento multimedia que se está reproduciendo en ese momento llamando a su método editTrackInfo de la siguiente manera:

var textTrackStyle = new chrome.cast.media.TextTrackStyle();
var tracksInfoRequest = new chrome.cast.media.EditTracksInfoRequest(textTrackStyle);
media.editTracksInfo(tracksInfoRequest, successCallback, errorCallback);

Puedes hacer un seguimiento del estado de la solicitud con el resultado de las devoluciones de llamada, ya sean correctas o con errores, y actualizar el remitente de origen según corresponda.

Las aplicaciones deben permitir que los usuarios actualicen el estilo de los segmentos de texto mediante la configuración que proporciona el sistema o la aplicación misma.

Puedes aplicar ajustes de estilo a los siguientes elementos de estilo de seguimiento de texto:

  • Color y opacidad del primer plano (texto)
  • Color de fondo y opacidad
  • Tipo de borde
  • Color de borde
  • Escala de fuente
  • Familia de fuentes
  • Estilo de fuente

Por ejemplo, configura el color del texto en rojo con un 75% de opacidad, como se indica a continuación:

var textTrackStyle = new chrome.cast.media.TextTrackStyle();
textTrackStyle.foregroundColor = '#80FF0000';

Control de volumen

Puedes usar RemotePlayer y RemotePlayerController para configurar el volumen del receptor.

function changeVolume(newVolume) {
  player.volumeLevel = newVolume;
  playerController.setVolumeLevel();
  // Update sender UI to reflect change
}

La app emisora debe cumplir con los siguientes lineamientos para controlar el volumen:

  • La aplicación emisora debe sincronizarse con el receptor para que la IU del remitente siempre informe el volumen por el receptor. Usa las devoluciones de llamada RemotePlayerEventType.VOLUME_LEVEL_CHANGED y RemotePlayerEventType.IS_MUTED_CHANGED para mantener el volumen en el remitente. Consulta la sección Actualizaciones de estado para obtener más información.
  • Las apps emisoras no deben establecer el nivel de volumen en un nivel específico y predefinido ni establecer el nivel de volumen en el volumen del timbre o del contenido multimedia del dispositivo emisor cuando la app se carga en el receptor.

Consulta los controles de volumen del remitente en la lista de tareas de diseño.

Cómo enviar mensajes multimedia al receptor

Media Messages se puede enviar de un remitente a un receptor. Por ejemplo, para enviar un mensaje SKIP_AD al receptor, haz lo siguiente:

// Get a handle to the skip button element
const skipButton = document.getElementById('skip');
skipButton.addEventListener("click", function() {
  if (castSession) {
    const media = castSession.getMediaSession();
    castSession.sendMessage('urn:x-cast:com.google.cast.media', {
      type: 'SKIP_AD',
      requestId: 1,
      mediaSessionId: media.mediaSessionId
    });
  }
});

Actualizaciones de estado

Cuando se conectan varios remitentes al mismo receptor, es importante que cada uno esté al tanto de los cambios en el receptor, incluso si esos cambios se iniciaron desde otros remitentes.

Con ese fin, tu aplicación debe registrar todos los objetos de escucha necesarios en la RemotePlayerController. Si cambia el TextTrackStyle del contenido multimedia actual, se notificará a todos los remitentes conectados, y las propiedades correspondientes de la sesión multimedia actual, como activeTrackIds y textTrackStyle del campo MediaInfo, se enviarán a los remitentes en devoluciones de llamada. En ese caso, el SDK del receptor no verifica si el diseño nuevo es diferente del anterior y notifica a todos los remitentes conectados.

Indicador de progreso

Mostrar la ubicación de reproducción con un indicador de progreso en el remitente es un requisito para la mayoría de las apps. Las APIs de Cast usan el protocolo de contenido multimedia de transmisión, que optimiza el consumo de ancho de banda para esta y otras situaciones, de manera que no necesitas implementar tu propia sincronización de estado. Para conocer la implementación adecuada de un indicador de progreso para la reproducción de contenido multimedia con las APIs, consulta la app de ejemplo CastVideos-chrome.

Requisitos de CORS

Para la transmisión de contenido multimedia adaptable, Google Cast requiere la presencia de encabezados CORS, pero incluso las transmisiones de contenido multimedia en formato mp4 simples lo requieren si incluyen segmentos. Si quieres habilitar segmentos para cualquier contenido multimedia, debes habilitar CORS para las transmisiones de pistas y de medios. Por lo tanto, si no tienes encabezados CORS disponibles para tus medios mp4 simples en tu servidor y luego agregas una pista de subtítulos simple, no podrás transmitir tu contenido a menos que actualices tu servidor para incluir los encabezados CORS adecuados.

Necesitas los siguientes encabezados: Content-Type, Accept-Encoding y Range. Ten en cuenta que los dos últimos encabezados, Accept-Encoding y Range, son encabezados adicionales que quizás no hayas necesitado antes.

No se pueden usar comodines “*” para el encabezado Access-Control-Allow-Origin. Si la página tiene contenido multimedia protegido, debe usar un dominio en lugar de un comodín.

Cómo reanudar una sesión sin volver a cargar la página web

Para reanudar un CastSession existente, usa requestSessionById(sessionId) con el sessionId de la sesión a la que intentas unirte.

Se puede encontrar el sessionId en el CastSession activo usando getSessionId() después de llamar a loadMedia().

El enfoque recomendado es el siguiente:

  1. Llama a loadMedia() para iniciar la sesión.
  2. Almacena el sessionId de forma local
  3. Vuelve a unirte a la sesión con requestSessionById(sessionId) cuando sea necesario.
let sessionId;

function rejoinCastSession() {
  chrome.cast.requestSessionById(sessionId);

  // Add any business logic to load new content or only resume the session
}

document.getElementById('play-button').addEventListener(("click"), function() {
  if (sessionId == null) {
    let castSession = cast.framework.CastContext.getInstance().getCurrentSession();
    if (castSession) {
      let mediaInfo = createMediaInfo();
      let request = new chrome.cast.media.LoadRequest(mediaInfo);
      castSession.loadMedia(request)

      sessionId = CastSession.getSessionId();
    } else {
      console.log("Error: Attempting to play media without a Cast Session");
    }
  } else {
    rejoinCastSession();
  }
});

Próximos pasos

Con esto concluye las funciones que puedes agregar a tu app de remitente web. Ahora puedes compilar una app de remitente para otra plataforma (Android o iOS) o compilar una app receptora.