Agrega funciones principales a tu receptor web personalizado

En esta página, se incluyen fragmentos de código y descripciones de las funciones disponibles para una app personalizada de receptor web.

  1. Es un elemento cast-media-player que representa la IU del reproductor integrada que proporciona el receptor web.
  2. Estilo personalizado, similar a CSS, para el elemento cast-media-player a fin de dar estilo a varios elementos de la IU, como background-image, splash-image y font-family
  3. Un elemento de secuencia de comandos para cargar el marco del receptor web.
  4. Es el código JavaScript para interceptar mensajes y controlar eventos.
  5. En fila para la reproducción automática.
  6. Opciones para configurar la reproducción
  7. Opciones para establecer el contexto del receptor web
  8. Opciones para configurar comandos que son compatibles con la app de receptor web
  9. Una llamada de JavaScript para iniciar la aplicación del receptor web.

Configuración y opciones de la aplicación

CastReceiverContext es la clase más externa expuesta al desarrollador y administra la carga de bibliotecas subyacentes y controla la inicialización del SDK del receptor web.

Si la API del receptor web detecta que un remitente está desconectado, generará el evento SENDER_DISCONNECTED. Si el receptor web no pudo comunicarse con el remitente durante lo que describimos como maxInactivity segundos, también generará el evento SENDER_DISCONNECTED. Durante el desarrollo, se recomienda establecer maxInactivity en un valor alto para que la app del receptor web no se cierre cuando se depura la app con el Depurador remoto de Chrome:

const context = cast.framework.CastReceiverContext.getInstance();
const options = new cast.framework.CastReceiverOptions();
options.maxInactivity = 3600; //Development only
context.start(options);

Sin embargo, para una aplicación de receptor web publicada, es mejor no establecer maxInactivity y, en su lugar, depender del valor predeterminado. Ten en cuenta que las opciones del receptor web se configuran solo una vez en la aplicación.

La otra configuración es la cast.framework.PlaybackConfig. Puede configurarse de la siguiente manera:

const playbackConfig = new cast.framework.PlaybackConfig();
playbackConfig.manifestRequestHandler = requestInfo => {
  requestInfo.withCredentials = true;
};
context.start({playbackConfig: playbackConfig});

Esta configuración afecta la reproducción de cada contenido y proporciona esencialmente un comportamiento de anulación. Para obtener una lista de los comportamientos que los desarrolladores pueden anular, consulta la definición de cast.framework.PlaybackConfig. A fin de cambiar la configuración entre los contenidos, puedes usar el PlayerManager para obtener su playbackConfig actual, modificar o agregar una anulación y restablecer el playbackConfig de la siguiente manera:

const playerManager =
    cast.framework.CastReceiverContext.getInstance().getPlayerManager();
const playbackConfig = (Object.assign(
            new cast.framework.PlaybackConfig(), playerManager.getPlaybackConfig()));
playbackConfig.autoResumeNumberOfSegments = 1;
playerManager.setPlaybackConfig(playbackConfig);

Ten en cuenta que si PlaybackConfig no se anuló, getPlaybackConfig() muestra un objeto nulo. Y cualquier propiedad en PlaybackConfig that es undefined usará los valores predeterminados.

Objeto de escucha de eventos

El SDK de Web Receiver permite que su app de Web Receiver maneje los eventos del jugador. El objeto de escucha de eventos toma un parámetro cast.framework.events.EventType (o una matriz de estos parámetros) que especifica los eventos que deben activar el objeto de escucha. Los arreglos preconfigurados de cast.framework.events.EventType que son útiles para la depuración se pueden encontrar en cast.framework.events.category. El parámetro de evento proporciona información adicional sobre el evento.

Por ejemplo, si deseas saber cuándo se emite un cambio mediaStatus, puedes usar la siguiente lógica para controlar el evento:

const playerManager =
    cast.framework.CastReceiverContext.getInstance().getPlayerManager();
playerManager.addEventListener(
    cast.framework.events.EventType.MEDIA_STATUS, (event) => {
      // Write your own event handling code, for example
      // using the event.mediaStatus value
});

Intercepción de mensajes

El SDK de receptor web permite que la app de recepción web intercepte mensajes y ejecute código personalizado en esos mensajes. El interceptor de mensajes toma un parámetro cast.framework.messages.MessageType que especifica qué tipo de mensaje debe interceptarse.

El interceptor debería mostrar la solicitud modificada o una promesa que se resuelve con el valor de la solicitud modificado. Si se muestra null, no se podrá llamar al controlador de mensajes predeterminado. Consulta Carga de contenido multimedia para obtener más información.

Por ejemplo, si deseas cambiar los datos de la solicitud de carga, puedes usar la siguiente lógica para interceptarlos y modificarlos:

const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, loadRequestData => {
      const error = new cast.framework.messages.ErrorData(
                      cast.framework.messages.ErrorType.LOAD_FAILED);
      if (!loadRequestData.media) {
        error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
        return error;
      }

      if (!loadRequestData.media.entity) {
        return loadRequestData;
      }

      return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
                                          loadRequestData.credentials)
        .then(asset => {
          if (!asset) {
            throw cast.framework.messages.ErrorReason.INVALID_REQUEST;
          }

          loadRequestData.media.contentUrl = asset.url;
          loadRequestData.media.metadata = asset.metadata;
          loadRequestData.media.tracks = asset.tracks;
          return loadRequestData;
        }).catch(reason => {
          error.reason = reason; // cast.framework.messages.ErrorReason
          return error;
        });
    });

context.start();

Manejo de errores

Cuando se producen errores en el interceptor de mensajes, tu app de recepción web debe mostrar un cast.framework.messages.ErrorType y un cast.framework.messages.ErrorReason adecuados.

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, loadRequestData => {
      const error = new cast.framework.messages.ErrorData(
                      cast.framework.messages.ErrorType.LOAD_CANCELLED);
      if (!loadRequestData.media) {
        error.reason = cast.framework.messages.ErrorReason.INVALID_PARAM;
        return error;
      }

      ...

      return fetchAssetAndAuth(loadRequestData.media.entity,
                               loadRequestData.credentials)
        .then(asset => {
          ...
          return loadRequestData;
        }).catch(reason => {
          error.reason = reason; // cast.framework.messages.ErrorReason
          return error;
        });
    });

Intercepción de mensajes y objeto de escucha de eventos

Estas son algunas diferencias clave entre la intercepción de mensajes y el objeto de escucha de eventos:

  • Un objeto de escucha de eventos no te permite modificar los datos de la solicitud.
  • Un objeto de escucha de eventos se usa mejor para activar estadísticas o una función personalizada.
playerManager.addEventListener(cast.framework.events.category.CORE,
    event => {
        console.log(event);
    });
  • La intercepción de mensajes te permite escuchar un mensaje, interceptarlo y modificar los datos de la solicitud.
  • La interceptación de mensajes se usa mejor para controlar la lógica personalizada con respecto a los datos de solicitudes.

Carga de contenido multimedia

MediaInformation proporciona varias propiedades para cargar contenido multimedia en el mensaje cast.framework.messages.MessageType.LOAD, incluidos entity, contentUrl y contentId.

entity es la propiedad sugerida que se debe usar en la implementación para las apps de remitente y receptor. La propiedad es una URL de vínculo directo que puede ser una lista de reproducción o un contenido multimedia específico.

El contentUrl está diseñado para una URL reproducible y puede usarse cuando esté disponible.

contentId dejó de estar disponible debido a la ambigüedad de si el valor es una URL del contenido multimedia, un ID real o un parámetro clave para la búsqueda personalizada.

La sugerencia es usar entity para almacenar el ID real o los parámetros clave, y usar contentUrl para la URL del contenido multimedia. En el siguiente fragmento, se muestra un ejemplo de esto en el que entity está presente en la solicitud LOAD y se recupera el contentUrl reproducible:

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, loadRequestData => {
      ...

      if (!loadRequestData.media.entity) {
        // Copy the value from contentId for legacy reasons if needed
        loadRequestData.media.entity = loadRequestData.media.contentId;
      }

      return thirdparty.fetchAssetAndAuth(loadRequestData.media.entity,
                                          loadRequestData.credentials)
        .then(asset => {
          loadRequestData.media.contentUrl = asset.url;
          ...
          return loadRequestData;
        });
    });

Funciones del dispositivo

El método getDeviceCapabilities proporciona información sobre el dispositivo de transmisión conectado y el dispositivo de audio o video conectado a él. El método getDeviceCapabilities proporciona información de asistencia sobre el Asistente de Google, Bluetooth y los dispositivos conectados de pantalla y audio.

Este método muestra un objeto que puedes consultar pasando una de las enumeraciones especificadas a fin de obtener la capacidad del dispositivo para esa enumeración. Las enumeraciones se definen en cast.framework.system.DeviceCapabilities.

En este ejemplo, se verifica si el dispositivo del receptor web es capaz de reproducir HDR y DolbyVision (DV) con las claves IS_HDR_SUPPORTED y IS_DV_SUPPORTED, respectivamente.

const context = cast.framework.CastReceiverContext.getInstance();
context.addEventListener(cast.framework.system.EventType.READY, () => {
  const deviceCapabilities = context.getDeviceCapabilities();
  if (deviceCapabilities &&
      deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED]) {
    // Write your own event handling code, for example
    // using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_HDR_SUPPORTED] value
  }
  if (deviceCapabilities &&
      deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED]) {
    // Write your own event handling code, for example
    // using the deviceCapabilities[cast.framework.system.DeviceCapabilities.IS_DV_SUPPORTED] value
  }
});
context.start();

Cómo controlar la interacción del usuario

Un usuario puede interactuar con la app de tu receptor web a través de aplicaciones emisoras (Web, Android e iOS), comandos por voz en dispositivos compatibles con el Asistente, controles de tacto en pantallas inteligentes y controles remotos en dispositivos Android TV. El SDK de Cast proporciona varias API para permitir que la app receptora web controle estas interacciones, actualizar la IU de la aplicación mediante estados de acción del usuario y, de forma opcional, enviar los cambios a fin de actualizar cualquier servicio de backend.

Comandos de medios compatibles

Los estados de los controles de la IU se controlan mediante MediaStatus.supportedMediaCommands para los controladores expandidos de remitentes de iOS y Android, las apps de receptor y de control remoto que se ejecutan en dispositivos táctiles y las apps receptoras en dispositivos Android TV. Cuando se habilita un Command a nivel de bits en particular en la propiedad, los botones relacionados con esa acción se habilitan. Si no se establece, el botón se inhabilita. Estos valores se pueden cambiar en el receptor web de la siguiente manera:

  1. Usa PlayerManager.setSupportedMediaCommands para establecer la Commands específica
  2. Cómo agregar un comando nuevo con addSupportedMediaCommands
  3. Quita un comando existente con removeSupportedMediaCommands.
playerManager.setSupportedMediaCommands(cast.framework.messages.Command.SEEK |
  cast.framework.messages.Command.PAUSE);

Cuando el receptor prepare el MediaStatus actualizado, incluirá los cambios en la propiedad supportedMediaCommands. Cuando se transmite el estado, las apps emisoras conectadas actualizarán los botones en su IU según corresponda.

Para obtener más información sobre los comandos de contenido multimedia compatibles y los dispositivos táctiles, consulta la guía de Accessing UI controls.

Administra los estados de las acciones de los usuarios

Cuando los usuarios interactúan con la IU o envían comandos por voz, pueden controlar la reproducción del contenido y las propiedades relacionadas con la reproducción del elemento. El SDK controla automáticamente las solicitudes que controlan la reproducción. Las solicitudes que modifican propiedades del elemento actual que se está reproduciendo, como un comando LIKE, requieren que la aplicación receptora las controle. El SDK proporciona una serie de API para controlar estos tipos de solicitudes. Para admitir estas solicitudes, se debe hacer lo siguiente:

  • Intercepta USER_ACTION mensajes y determina la acción solicitada.
  • Actualiza el elemento UserActionState de MediaInformation para actualizar la IU.

El siguiente fragmento intercepta el mensaje USER_ACTION y controla la llamada al backend con el cambio solicitado. Luego, realiza una llamada para actualizar UserActionState en el receptor.

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.USER_ACTION,
  (userActionRequestData) => {
    // Obtain the media information of the current content to associate the action to.
    let mediaInfo = playerManager.getMediaInformation();

    // If there is no media info return an error and ignore the request.
    if (!mediaInfo) {
        console.error('Not playing media, user action is not supported');
        return new cast.framework.messages.ErrorData(messages.ErrorType.BAD_REQUEST);
    }

    // Reach out to backend services to store user action modifications. See sample below.
    return sendUserAction(userActionRequestData, mediaInfo)

    // Upon response from the backend, update the client's UserActionState.
    .then(backendResponse => updateUserActionStates(backendResponse))

    // If any errors occurred in the backend return them to the cast receiver.
    .catch((error) => {
      console.error(error);
      return error;
    });
});

El siguiente fragmento simula una llamada a un servicio de backend. La función verifica la UserActionRequestData para ver el tipo de cambio que el usuario solicitó y solo realiza una llamada a la red si el backend admite la acción.

function sendUserAction(userActionRequestData, mediaInfo) {
  return new Promise((resolve, reject) => {
    switch (userActionRequestData.userAction) {
      // Handle user action changes supported by the backend.
      case cast.framework.messages.UserAction.LIKE:
      case cast.framework.messages.UserAction.DISLIKE:
      case cast.framework.messages.UserAction.FOLLOW:
      case cast.framework.messages.UserAction.UNFOLLOW:
      case cast.framework.messages.UserAction.FLAG:
      case cast.framework.messages.UserAction.SKIP_AD:
        let backendResponse = {userActionRequestData: userActionRequestData, mediaInfo: mediaInfo};
        setTimeout(() => {resolve(backendResponse)}, 1000);
        break;
      // Reject all other user action changes.
      default:
        reject(
          new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType.INVALID_REQUEST));
    }
  });
}

El siguiente fragmento toma el elemento UserActionRequestData y agrega o quita el elemento UserActionState de MediaInformation. La actualización del UserActionState del MediaInformation cambia el estado del botón asociado con la acción solicitada. Este cambio se refleja en la IU de los controles de pantalla inteligente, la app de control remoto y la IU de Android TV. También se transmite a través de mensajes MediaStatus salientes a fin de actualizar la IU del controlador expandido para remitentes de iOS y Android.

function updateUserActionStates(backendResponse) {
  // Unwrap the backend response.
  let mediaInfo = backendResponse.mediaInfo;
  let userActionRequestData = backendResponse.userActionRequestData;

  // If the current item playing has changed, don't update the UserActionState for the current item.
  if (playerManager.getMediaInformation().entity !== mediaInfo.entity) {
    return;
  }

  // Check for existing userActionStates in the MediaInformation.
  // If none, initialize a new array to populate states with.
  let userActionStates = mediaInfo.userActionStates || [];

  // Locate the index of the UserActionState that will be updated in the userActionStates array.
  let index = userActionStates.findIndex((currUserActionState) => {
    return currUserActionState.userAction == userActionRequestData.userAction;
  });

  if (userActionRequestData.clear) {
    // Remove the user action state from the array if cleared.
    if (index >= 0) {
      userActionStates.splice(index, 1);
    }
    else {
      console.warn("Could not find UserActionState to remove in MediaInformation");
    }
  } else {
    // Add the UserActionState to the array if enabled.
    userActionStates.push(
      new cast.framework.messages.UserActionState(userActionRequestData.userAction));
  }

  // Update the UserActionState array and set the new MediaInformation
  mediaInfo.userActionStates = userActionStates;
  playerManager.setMediaInformation(mediaInfo, true);
  return;
}

Comandos por voz

Actualmente, se admiten los siguientes comandos de contenido multimedia en el SDK de Web Receiver para dispositivos compatibles con el Asistente. Las implementaciones predeterminadas de estos comandos se encuentran en cast.framework.PlayerManager.

Comando Descripción
Reproducir Reproducir o reanudar la reproducción desde el estado de pausa
Pausar Pausa el contenido que se está reproduciendo.
Anterior Ir al elemento multimedia anterior de la fila de contenido multimedia.
Siguiente Ir al siguiente elemento multimedia de la fila de contenido multimedia.
Detener Detén el contenido multimedia que se está reproduciendo.
No repetir Inhabilitar la repetición de elementos multimedia en la fila una vez que se termina de reproducir el último elemento de la cola
Repetir una sola vez Repite el contenido multimedia que se está reproduciendo de forma indefinida.
Repetir todo Repite todos los elementos de la fila una vez que se reproduzca el último elemento.
Repetir todo y reproducir aleatoriamente Cuando el último elemento termine de reproducirse, reprodúcelo de forma aleatoria y repite todos los elementos.
Reproducción aleatoria Reproduce aleatoriamente los elementos multimedia de la fila de contenido multimedia.
Subtítulos ACTIVADOS/DESACTIVADOS Habilita o inhabilita los subtítulos opcionales para tu contenido multimedia. Habilitar / Inhabilitar también está disponible por idioma.
Búsqueda a la hora absoluta Salta a la hora absoluta especificada.
Búsqueda a hora relativa a la hora actual Permite avanzar o retroceder según el período de tiempo especificado en relación con el tiempo de reproducción actual.
Volver a jugar Reinicia el contenido multimedia que se está reproduciendo o reproduce el último elemento si no se está reproduciendo contenido.
Configura la velocidad de reproducción Varía la velocidad de reproducción de contenido multimedia. Se debe controlar de forma predeterminada. Puedes usar el interceptor de mensajes SET_PLAYBACK_RATE para anular las solicitudes de tarifa entrantes.

Comandos de medios compatibles con la voz

Para evitar que un comando por voz active un comando multimedia en un dispositivo compatible con el Asistente, primero debes configurar los comandos multimedia compatibles que planeas admitir. Luego, debes aplicar esos comandos. Para ello, habilita la propiedad CastReceiverOptions.enforceSupportedCommands. La IU de los remitentes del SDK de Cast y los dispositivos compatibles con la tecnología táctil cambiarán para reflejar estas configuraciones. Si la marca no está habilitada, se ejecutarán los comandos por voz entrantes.

Por ejemplo, si permites el acceso de PAUSE desde las aplicaciones emisoras y los dispositivos táctiles, también debes configurar el receptor para que refleje esa configuración. Cuando se configura, cualquier comando de voz entrante se descarta si no se incluye en la lista de comandos compatibles.

En el siguiente ejemplo, proporcionamos el CastReceiverOptions cuando se inicia el CastReceiverContext. Se agregó compatibilidad con el comando PAUSE y se aplicó el reproductor para que sea compatible solo con ese comando. Ahora, si un comando por voz solicita otra operación, como SEEK, se rechazará. Se le notificará al usuario que el comando aún no es compatible.

const context = cast.framework.CastReceiverContext.getInstance();

context.start({
  enforceSupportedCommands: true,
  supportedCommands: cast.framework.messages.Command.PAUSE
});

Puedes aplicar una lógica distinta para cada comando que desees restringir. Quita la marca enforceSupportedCommands y, para cada comando que desees restringir, puedes interceptar el mensaje entrante. Aquí interceptamos la solicitud que proporciona el SDK para que los comandos de SEEK emitidos a dispositivos compatibles con el Asistente no activen una búsqueda en la aplicación del receptor web.

Para los comandos de contenido multimedia que tu aplicación no admite, muestra un motivo de error apropiado, como NOT_SUPPORTED.

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.SEEK,
  seekData => {
    // Block seeking if the SEEK supported media command is disabled
    if (!(playerManager.getSupportedMediaCommands() & cast.framework.messages.Command.SEEK)) {
      let e = new cast.framework.messages.ErrorData(cast.framework.messages.ErrorType
      .INVALID_REQUEST);
      e.reason = cast.framework.messages.ErrorReason.NOT_SUPPORTED;
      return e;
    }

    return seekData;
  });

Fondo de la actividad de voz

Si la plataforma de transmisión ejecuta en segundo plano el sonido de tu aplicación debido a la actividad del Asistente, como escuchar la voz del usuario o responder, se envía un mensaje FocusState de NOT_IN_FOCUS a la aplicación del receptor web cuando se inicia la actividad. Se envía otro mensaje con IN_FOCUS cuando finaliza la actividad. Según tu aplicación y el contenido multimedia que se reproduzca, es posible que quieras pausar el contenido multimedia cuando el valor de FocusState sea NOT_IN_FOCUS. Para ello, debes interceptar el tipo de mensaje FOCUS_STATE.

Por ejemplo, si el Asistente responde a una consulta del usuario, te recomendamos que detengas la reproducción de audiolibros.

playerManager.setMessageInterceptor(cast.framework.messages.MessageType.FOCUS_STATE,
  focusStateRequestData => {
    // Pause content when the app is out of focus. Resume when focus is restored.
    if (focusStateRequestData.state == cast.framework.messages.FocusState.NOT_IN_FOCUS) {
      playerManager.pause();
    } else {
      playerManager.play();
    }

    return focusStateRequestData;
  });

Idioma de los subtítulos especificados por voz

Cuando un usuario no indica de forma explícita el idioma de los subtítulos, el idioma que se usa para los subtítulos es el mismo que se usó en el comando. En estas situaciones, el parámetro isSuggestedLanguage del mensaje entrante indica si el usuario asociado indicó o sugirió el lenguaje asociado de manera explícita.

Por ejemplo, isSuggestedLanguage se establece en true para el comando "Ok Google, activa los subtítulos", porque el idioma en el que se pronunció el comando se infirió. Si el idioma se solicita de forma explícita, como en "Ok Google, activa los subtítulos en inglés", isSuggestedLanguage se establece en false.

Metadatos y transmisión de voz

Si bien el receptor web administra los comandos por voz de forma predeterminada, debes asegurarte de que los metadatos de tu contenido estén completos y sean precisos. Esto garantiza que el Asistente maneje los comandos por voz de manera adecuada y que los metadatos aparezcan correctamente en los nuevos tipos de interfaces, como la app de Google Home y las pantallas inteligentes, como Google Home Hub.

Transferencia de transmisión

Preservar el estado de la sesión es la base de la transferencia de transmisión, mediante la cual los usuarios pueden mover transmisiones de audio y video existentes a través de dispositivos mediante comandos por voz, la app de Google Home o pantallas inteligentes. El contenido multimedia deja de reproducirse en un dispositivo (la fuente) y continúa en otro (el destino). Cualquier dispositivo de transmisión con el firmware más reciente puede servir como fuentes o destinos en una transferencia de transmisión.

El flujo de eventos para la transferencia de transmisión es el siguiente:

  1. En el dispositivo de origen:
    1. El contenido multimedia deja de reproducirse.
    2. La aplicación del receptor web recibe un comando para guardar el estado multimedia actual.
    3. La aplicación del receptor web está cerrada.
  2. En el dispositivo de destino:
    1. Se cargó la aplicación del receptor web.
    2. La aplicación del receptor web recibe un comando para restablecer el estado de medios guardado.
    3. Se reanudará la reproducción de contenido multimedia.

Se incluyen los siguientes elementos de estado de medios:

  • Es la posición o la marca de tiempo específicas de la canción, el video o el elemento multimedia.
  • Se coloca en una fila más amplia (como una lista de reproducción o la radio del artista).
  • El usuario autenticado.
  • Estado de reproducción (por ejemplo, en reproducción o en pausa).

Habilita la transferencia de transmisión

A fin de implementar la transferencia de transmisión para tu receptor web, haz lo siguiente:

  1. Actualiza supportedMediaCommands con el comando STREAM_TRANSFER:
    playerManager.addSupportedMediaCommands(
    cast.framework.messages.Command.STREAM_TRANSFER, true);
  2. De manera opcional, anula los interceptores de mensajes SESSION_STATE y RESUME_SESSION como se describe en Preserva el estado de la sesión. Anula estas opciones solo si los datos personalizados deben almacenarse como parte de la instantánea de la sesión. De lo contrario, la implementación predeterminada para preservar los estados de sesión admitirá la transferencia de transmisión.

Preserva el estado de la sesión

El SDK de receptor web proporciona una implementación predeterminada para las apps de receptores web a fin de conservar los estados de sesión. Para ello, toma una instantánea del estado del contenido multimedia actual, convierte el estado en una solicitud de carga y reanuda la sesión con la solicitud de carga.

La solicitud de carga generada por el receptor web se puede anular en el interceptor de mensajes SESSION_STATE si es necesario. Si deseas agregar datos personalizados a la solicitud de carga, te sugerimos que los coloques en loadRequestData.customData.

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.SESSION_STATE,
    function (sessionState) {
        // Override sessionState.loadRequestData if needed.
        const newCredentials = updateCredentials_(sessionState.loadRequestData.credentials);
        sessionState.loadRequestData.credentials = newCredentials;

        // Add custom data if needed.
        sessionState.loadRequestData.customData = {
            'membership': 'PREMIUM'
        };

        return sessionState;
    });

Los datos personalizados se pueden recuperar de loadRequestData.customData en el interceptor de mensajes RESUME_SESSION.

let cred_ = null;
let membership_ = null;

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.RESUME_SESSION,
    function (resumeSessionRequest) {
        let sessionState = resumeSessionRequest.sessionState;

        // Modify sessionState.loadRequestData if needed.
        cred_ = sessionState.loadRequestData.credentials;

        // Retrieve custom data.
        membership_ = sessionState.loadRequestData.customData.membership;

        return resumeSessionRequest;
    });

Precarga de contenido

El receptor web admite la precarga de elementos multimedia después del elemento de reproducción actual en la cola.

La operación de precarga descarga varios segmentos de los próximos elementos. La especificación se realiza en el valor preloadTime en el objeto QueueItem (el valor predeterminado es 20 segundos si no se proporciona). El tiempo se expresa en segundos, en relación con el final del elemento que se está reproduciendo . Solo los valores positivos son válidos. Por ejemplo, si el valor es 10 segundos, este elemento se precargará 10 segundos antes de que finalice el elemento anterior. Si el tiempo de precarga es mayor que el tiempo restante en currentItem, la carga previa se realizará tan pronto como sea posible. Por lo tanto, si se especifica un valor de carga previa muy grande en queueItem, se podría lograr el efecto de que, cuando se reproduzca el elemento actual, ya se precargue el siguiente elemento. Sin embargo, dejamos esta configuración y la elección al desarrollador, ya que este valor puede afectar el ancho de banda y el rendimiento de transmisión del elemento de reproducción actual.

La carga previa funcionará para el contenido de transmisión de HLS, DASH y Smooth Streaming de manera predeterminada.

Los archivos de audio y video MP4 normales, como MP3, no se precargarán, ya que los dispositivos de transmisión solo admiten un elemento multimedia y no se pueden usar para precargar mientras un elemento de contenido existente aún se reproduce.

Mensajes personalizados

El intercambio de mensajes es el método de interacción clave para las aplicaciones de receptores web.

Un remitente emite mensajes a un receptor web mediante las API de remitente de la plataforma en la que se ejecuta el remitente (Android, iOS o la Web). El objeto de evento (que es la manifestación de un mensaje) que se pasa a los objetos de escucha de eventos tiene un elemento de datos (event.data) en el que los datos toman las propiedades del tipo de evento específico.

Una aplicación de app receptora puede optar por escuchar los mensajes en un espacio de nombres específico. En virtud de esta acción, se dice que la aplicación de recepción web admite ese protocolo de espacio de nombres. Luego, depende de los remitentes conectados que deseen comunicarse en ese espacio de nombres utilizar el protocolo adecuado.

Todos los espacios de nombres se definen con una string y deben comenzar con “urn:x-cast:” seguido de cualquier string. Por ejemplo, “urn:x-cast:com.example.cast.mynamespace”.

A continuación, se muestra un fragmento de código para que el receptor web escuche mensajes personalizados de remitentes conectados:

const context = cast.framework.CastReceiverContext.getInstance();

const CUSTOM_CHANNEL = 'urn:x-cast:com.example.cast.mynamespace';
context.addCustomMessageListener(CUSTOM_CHANNEL, function(customEvent) {
  // handle customEvent.
});

context.start();

Del mismo modo, las aplicaciones del receptor web pueden mantener informados a los remitentes sobre el estado del receptor web enviando mensajes a los remitentes conectados. Una aplicación de receptor web puede enviar mensajes mediante sendCustomMessage(namespace, senderId, message) en CastReceiverContext. Un receptor web puede enviar mensajes a un remitente individual, ya sea en respuesta a un mensaje recibido o debido a un cambio de estado de la aplicación. Además de los mensajes punto a punto (con un límite de 64 KB), un receptor web también puede transmitir mensajes a todos los remitentes conectados.

Cast para dispositivos de audio

Consulta la guía de Google Cast para dispositivos de audio a fin de obtener asistencia sobre la reproducción de solo audio.

Android TV

En esta sección, se explica cómo Google Web Receiver usa tus entradas como reproducción y la compatibilidad de Android TV.

Integrar tu aplicación en el control remoto

El receptor web de Google que se ejecuta en el dispositivo Android TV traduce las entradas de las entradas de control del dispositivo (es decir, el control remoto manual) como mensajes de reproducción de contenido multimedia definidos para el espacio de nombres urn:x-cast:com.google.cast.media, como se describe en Mensajes de reproducción multimedia. Tu aplicación debe admitir estos mensajes para controlar la reproducción de medios de la aplicación y permitir el control básico de la reproducción desde las entradas de control de Android TV.

Lineamientos para la compatibilidad con Android TV

Estas son algunas recomendaciones y errores comunes que debes evitar para asegurarte de que tu aplicación sea compatible con Android TV:

  • Ten en cuenta que la string usuario-agente contiene “Android” y “CrKey”. Algunos sitios pueden redireccionar a un sitio solo para dispositivos móviles porque detectan la etiqueta “Android”. No supongas que “Android” en la string del usuario-agente siempre indica un usuario de dispositivo móvil.
  • La pila de medios de Android puede usar GZIP transparente para obtener datos. Asegúrate de que tus datos multimedia puedan responder a Accept-Encoding: gzip.
  • Los eventos multimedia de HTML5 de Android TV pueden activarse en momentos diferentes a los de Chromecast, lo que podría revelar problemas ocultos en Chromecast.
  • Cuando actualizas el contenido multimedia, usa eventos relacionados con el contenido multimedia que activan los elementos <audio>/<video>, como timeupdate, pause y waiting. Evita usar eventos relacionados con las herramientas de redes, como progress, suspend y stalled, ya que tienden a depender de la plataforma. Consulta Eventos multimedia para obtener más información sobre cómo manejar eventos multimedia en tu receptor.
  • Cuando configures los certificados HTTPS del sitio receptor, asegúrate de incluir certificados de CA intermedios. Consulta la página de prueba de SSL de Qualsys para verificar: si la ruta de certificación de confianza de tu sitio incluye un certificado de CA etiquetado como "descarga adicional", es posible que no se cargue en las plataformas basadas en Android.
  • Mientras que Chromecast muestra la página receptora en un plano gráfico de 720p, otras plataformas de transmisión, como Android TV, pueden mostrarla hasta 1080p. Asegúrate de que la página del receptor se escale correctamente en diferentes resoluciones.