Ajouter des fonctionnalités de base à votre récepteur Web personnalisé

Cette page contient des extraits de code et des descriptions des fonctionnalités disponibles pour une application de récepteur Web personnalisé.

  1. Un élément cast-media-player qui représente l'UI du lecteur intégré fourni avec Web Receiver.
  2. Style personnalisé de type CSS pour l'élément cast-media-player afin de définir le style de divers éléments d'interface utilisateur tels que background-image, splash-image et font-family
  3. Un élément de script permettant de charger le framework du récepteur Web.
  4. Le code JavaScript permettant d'intercepter les messages et de gérer les événements
  5. File d'attente pour la lecture automatique.
  6. Options pour configurer la lecture.
  7. Options permettant de définir le contexte du récepteur Web.
  8. Options permettant de définir des commandes compatibles avec l'application Web Receiver.
  9. Un appel JavaScript pour démarrer l'application Web Receiver.

Configuration et options de l'application

CastReceiverContext est la classe externe exposée au développeur. Elle gère le chargement des bibliothèques sous-jacentes et gère l'initialisation du SDK Web Receiver.

Si l'API Web Receiver détecte qu'un expéditeur est déconnecté, il déclenche l'événement SENDER_DISCONNECTED. Si le récepteur Web n'a pas réussi à communiquer avec l'expéditeur pendant ce que nous avons décrit comme maxInactivity secondes, il déclenchera également l'événement SENDER_DISCONNECTED. Lors du développement, nous vous recommandons de définir maxInactivity sur une valeur élevée afin que l'application Web Receiver ne se ferme pas lors du débogage de l'application avec Chrome Remote Debugger:

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

Toutefois, pour une application Web receiver publiée, il est préférable de ne pas définir maxInactivity et d'utiliser la valeur par défaut. Notez que les options du destinataire Web ne sont définies qu'une seule fois dans l'application.

L'autre configuration est le cast.framework.PlaybackConfig. Ce paramètre peut être défini comme suit:

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

Cette configuration affecte chaque lecture de contenu et fournit principalement un remplacement de comportement. Pour obtenir la liste des comportements que les développeurs peuvent ignorer, consultez la définition de cast.framework.PlaybackConfig. Pour modifier la configuration entre les contenus, vous pouvez utiliser PlayerManager afin d'obtenir son playbackConfig actuel, modifier ou ajouter un forçage et réinitialiser le playbackConfig comme suit:

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

Notez que si PlaybackConfig n'a pas été remplacé, getPlaybackConfig() renvoie un objet nul. Et toute propriété sur PlaybackConfig that est undefined utilisera les valeurs par défaut.

Écouteur d'événements

Le SDK Web Receiver permet à votre application Web Receiver de gérer les événements du lecteur. L'écouteur d'événements utilise un paramètre cast.framework.events.EventType (ou un tableau de ces paramètres) qui spécifie le ou les événements qui doivent déclencher l'écouteur. Les tableaux préconfigurés de cast.framework.events.EventType utiles pour le débogage sont disponibles dans cast.framework.events.category. Le paramètre "event" fournit des informations supplémentaires sur l'événement.

Par exemple, si vous souhaitez savoir quand une modification mediaStatus est diffusée, vous pouvez utiliser la logique suivante pour gérer l'événement:

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

Interception de message

Le SDK Web Receiver permet à votre application Web Receiver d'intercepter les messages et d'exécuter du code personnalisé sur ces messages. L'intercepteur de message utilise un paramètre cast.framework.messages.MessageType qui spécifie le type de message à intercepter.

L'intercepteur doit renvoyer la requête modifiée ou une promesse qui se résout avec la valeur de requête modifiée. Le renvoi de null empêche l'appel du gestionnaire de messages par défaut. Pour en savoir plus, consultez Charger un contenu multimédia.

Par exemple, si vous souhaitez modifier les données de la requête de chargement, vous pouvez utiliser la logique suivante pour l'intercepter et le modifier:

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

Gestion des exceptions

Lorsque des erreurs se produisent dans l'intercepteur de messages, votre application Web Receiver doit renvoyer les valeurs cast.framework.messages.ErrorType et cast.framework.messages.ErrorReason appropriées.

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

Interception de message ou écouteur d'événements

Voici les principales différences entre l'interception des messages et l'écouteur d'événements:

  • Un écouteur d'événements ne vous permet pas de modifier les données de la requête.
  • Il est préférable d'utiliser un écouteur d'événements pour déclencher des analyses ou une fonction personnalisée.
playerManager.addEventListener(cast.framework.events.category.CORE,
    event => {
        console.log(event);
    });
  • L'interception de message vous permet d'écouter un message, de l'intercepter et de modifier les données de requête proprement dite.
  • Il est préférable d'intercepter les messages pour gérer la logique personnalisée concernant les données de requête.

Chargement de contenu multimédia

MediaInformation fournit de nombreuses propriétés pour charger des contenus multimédias dans le message cast.framework.messages.MessageType.LOAD, y compris entity, contentUrl et contentId.

entity est la propriété suggérée à utiliser pour votre implémentation à la fois pour les applications expéditeurs et réceptrices. La propriété est une URL de lien profond qui peut être une playlist ou un contenu multimédia spécifique.

Le contentUrl est conçu pour une URL lisible et peut être utilisé une fois disponible.

Abandon de contentId, car il est difficile de déterminer si la valeur est une URL du média, un ID réel ou un paramètre de clé pour une recherche personnalisée.

Nous vous suggérons d'utiliser entity pour stocker l'ID réel ou les paramètres clés, et d'utiliser contentUrl pour l'URL du support. En voici un exemple dans l'extrait de code suivant, où entity est présent dans la requête LOAD et où contentUrl est récupéré:

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

Fonctionnalités de l'appareil

La méthode getDeviceCapabilities fournit des informations sur l'appareil Cast connecté et l'appareil vidéo ou audio qui lui est associé. La méthode getDeviceCapabilities fournit des informations d'assistance pour l'Assistant Google, le Bluetooth, ainsi que les appareils d'affichage et audio connectés.

Cette méthode renvoie un objet que vous pouvez interroger en transmettant l'une des énumérations spécifiées pour obtenir la fonctionnalité de l'appareil correspondant à cette énumération. Les énumérations sont définies dans cast.framework.system.DeviceCapabilities.

Cet exemple vérifie si le récepteur Web peut lire du contenu HDR et DolbyVision (DV) avec les clés IS_HDR_SUPPORTED et IS_DV_SUPPORTED, respectivement.

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

Gérer les interactions des utilisateurs

Un utilisateur peut interagir avec votre application Web Receiver via des applications expéditeurs (Web, Android et iOS), des commandes vocales sur les appareils avec Assistant Google intégré, des commandes tactiles sur les écrans connectés et des commandes à distance sur les appareils Android TV. Le SDK Cast fournit différentes API pour permettre à l'application Web Receiver de gérer ces interactions, de mettre à jour l'interface utilisateur de l'application via les états des actions utilisateur et, éventuellement, d'envoyer les modifications pour mettre à jour les services de backend.

Commandes multimédias compatibles

Les états des commandes de l'interface utilisateur sont basés sur la commande MediaStatus.supportedMediaCommands pour les manettes étendues iOS et Android, ainsi que sur les applications de récepteur et de télécommande s'exécutant sur les appareils tactiles, et sur les appareils Android TV. Lorsqu'un élément Command bit à bit particulier est activé dans la propriété, les boutons associés à cette action sont activés. Si la valeur n'est pas définie, le bouton est désactivé. Ces valeurs peuvent être modifiées sur le récepteur Web:

  1. En utilisant PlayerManager.setSupportedMediaCommands pour définir le Commands spécifique
  2. Ajouter une commande à l'aide de addSupportedMediaCommands
  3. Supprimer une commande existante à l'aide de removeSupportedMediaCommands
playerManager.setSupportedMediaCommands(cast.framework.messages.Command.SEEK |
  cast.framework.messages.Command.PAUSE);

Lorsque le receiver prépare les MediaStatus mises à jour, il inclut les modifications apportées à la propriété supportedMediaCommands. Lorsque l'état est diffusé, les applications d'expéditeurs connectés mettent à jour les boutons dans leur interface utilisateur en conséquence.

Pour en savoir plus sur les commandes multimédias et les appareils tactiles compatibles, consultez le guide Accessing UI controls.

Gérer les états des actions des utilisateurs

Lorsque les utilisateurs interagissent avec l'UI ou envoient des commandes vocales, ils peuvent contrôler la lecture du contenu et des propriétés liés à l'élément en cours de lecture. Les requêtes qui contrôlent la lecture sont gérées automatiquement par le SDK. Les requêtes qui modifient les propriétés de l'élément en cours de lecture, comme une commande LIKE, nécessitent que l'application réceptrice les gère. Le SDK fournit une série d'API pour gérer ces types de requêtes. Pour accepter ces requêtes, procédez comme suit:

  • Interceptez USER_ACTION messages et déterminez l'action demandée.
  • Mettez à jour le UserActionState de MediaInformation pour mettre à jour l'UI.

L'extrait ci-dessous intercepte le message USER_ACTION et gère l'appel du backend avec la modification demandée. Elle appelle ensuite la méthode UserActionState sur le récepteur.

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

L'extrait ci-dessous simule un appel à un service de backend. La fonction vérifie le UserActionRequestData pour voir le type de modification demandé par l'utilisateur et n'effectue un appel réseau que si l'action est prise en charge par le backend.

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

L'extrait ci-dessous accepte le UserActionRequestData et ajoute ou supprime le UserActionState du MediaInformation. La mise à jour du UserActionState de MediaInformation modifie l'état du bouton associé à l'action demandée. Cette modification est répercutée dans l'UI des commandes d'affichage intelligentes, l'application de la télécommande et l'UI d'Android TV. Il est également diffusé via les messages MediaStatus sortants pour mettre à jour l'interface utilisateur de la manette étendue pour les expéditeurs iOS et 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;
}

Commandes vocales

Les commandes multimédias suivantes sont actuellement compatibles avec le SDK Web Receiver pour les appareils avec Assistant Google intégré. Les implémentations par défaut de ces commandes sont disponibles dans cast.framework.PlayerManager.

Commande Description
Lire Lire ou reprendre la lecture en pause.
Pause Mettre en pause le contenu en cours de lecture.
Précédent Passer à l'élément multimédia précédent dans votre file d'attente multimédia
Suivant Passer à l'élément multimédia suivant dans votre file d'attente multimédia
Arrêter Arrête le contenu multimédia en cours de lecture.
Aucune répétition Désactiver la répétition des éléments multimédias de la file d'attente une fois la lecture du dernier élément terminée.
Répéter un seul Répéter indéfiniment le contenu multimédia en cours de lecture.
Tout répéter Répéter tous les éléments de la file d'attente une fois que le dernier élément a été lu
Tout lire et lire en mode aléatoire Lorsque la lecture du dernier élément de la file d'attente est terminée, brassez la file d'attente et répétez tous les éléments.
Brassage Cette option permet de lire les éléments multimédias en mode aléatoire dans votre file d'attente.
Activer / Désactiver les sous-titres Activez ou désactivez les sous-titres sur vos contenus multimédias. L'option "Activer / Désactiver" est également disponible par langue.
Rechercher jusqu'à l'heure absolue Passer à l'heure absolue spécifiée.
Rechercher par rapport à l'heure actuelle Avancer ou reculer d'une période donnée par rapport à la durée de lecture actuelle.
Rejouer Redémarrez le contenu multimédia en cours de lecture. Si le contenu en cours de lecture est en cours, relancez le dernier élément.
Définir la vitesse de lecture Varie la vitesse de lecture des contenus multimédias. Cette option doit être gérée par défaut. Vous pouvez utiliser l'intercepteur de message SET_PLAYBACK_RATE pour ignorer les requêtes de débit entrantes.

Commandes multimédias compatibles par commande vocale

Pour empêcher une commande vocale de déclencher une commande multimédia sur un appareil avec Assistant Google intégré, vous devez d'abord définir les commandes multimédias compatibles que vous prévoyez de prendre en charge. Vous devez ensuite appliquer ces commandes en activant la propriété CastReceiverOptions.enforceSupportedCommands. L'interface utilisateur des expéditeurs du SDK Cast et des appareils tactiles sera modifiée pour refléter ces configurations. Si l'option n'est pas activée, les commandes vocales entrantes sont exécutées.

Par exemple, si vous autorisez PAUSE à partir de vos applications expéditeurs et de vos appareils tactiles, vous devez également configurer votre récepteur en conséquence. Lorsqu'elles sont configurées, toutes les commandes vocales entrantes sont supprimées si elles ne figurent pas dans la liste des commandes compatibles.

Dans l'exemple ci-dessous, nous fournissons CastReceiverOptions lors du démarrage de CastReceiverContext. La commande PAUSE est désormais prise en charge et exige que le lecteur n'accepte que cette commande. Si une commande vocale demande une autre opération (telle que SEEK), elle sera refusée. L'utilisateur sera informé que la commande n'est pas encore compatible.

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

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

Vous pouvez appliquer une logique distincte pour chaque commande que vous souhaitez restreindre. Supprimez l'option enforceSupportedCommands. Pour chaque commande que vous souhaitez restreindre, vous pouvez intercepter le message entrant. Ici, nous interceptons la requête fournie par le SDK afin que les commandes SEEK envoyées aux appareils avec Assistant Google intégré ne déclenchent pas de recherche dans votre application Web Receiver.

Pour les commandes multimédias non compatibles avec votre application, renvoyez un motif d'erreur approprié, tel que 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;
  });

Mise en arrière-plan de l'activité vocale

Si la plate-forme Cast diffuse le son de votre application en arrière-plan en raison de l'activité de l'Assistant, comme écouter la voix d'un utilisateur ou s'exprimer, un message FocusState NOT_IN_FOCUS est envoyé à l'application Web Receiver au démarrage de l'activité. Un autre message avec IN_FOCUS est envoyé à la fin de l'activité. En fonction de votre application et du contenu multimédia en cours de lecture, vous pouvez mettre en pause le contenu multimédia lorsque le FocusState est NOT_IN_FOCUS en interceptant le type de message FOCUS_STATE.

Par exemple, mettre en pause la lecture de livres audio est une bonne expérience si l'Assistant répond à une requête utilisateur.

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

Langue des sous-titres spécifiés par la voix

Lorsqu'un utilisateur n'indique pas explicitement la langue des sous-titres, celle des sous-titres est la même que celle de la commande vocale. Dans ces scénarios, le paramètre isSuggestedLanguage du message entrant indique si la langue associée a été suggérée ou demandée par l'utilisateur.

Par exemple, isSuggestedLanguage est défini sur true pour la commande "Hey Google, active les sous-titres", car la langue a été déduite de la langue parlée. Si la langue est explicitement demandée, par exemple dans "Hey Google, active les sous-titres en anglais", isSuggestedLanguage est défini sur false.

Métadonnées et diffusion vocale

Bien que les commandes vocales soient gérées par défaut par le récepteur Web, vous devez vous assurer que les métadonnées de votre contenu sont complètes et exactes. Cela garantit que les commandes vocales sont gérées correctement par l'Assistant et que les métadonnées s'affichent correctement dans les nouveaux types d'interfaces tels que l'application Google Home et les écrans connectés comme Google Home Hub.

Transfert de diffusion

Conserver l'état de la session est la base du transfert de flux, où les utilisateurs peuvent déplacer des flux audio et vidéo existants sur des appareils à l'aide de commandes vocales, de l'application Google Home ou d'écrans connectés. La lecture du contenu multimédia s'arrête sur un appareil (la source) et se poursuit sur un autre (la destination). Tout appareil Cast doté du dernier micrologiciel peut servir de sources ou de destinations dans un transfert de diffusion.

Le flux d'événements pour le transfert de diffusion est le suivant:

  1. Sur l'appareil source :
    1. Le contenu multimédia s'arrête.
    2. L'application Web Receiver reçoit une commande permettant d'enregistrer l'état multimédia actuel.
    3. L'application Web Receiver est arrêtée.
  2. Sur l'appareil de destination :
    1. L'application Web Receiver est chargée.
    2. L'application Web Receiver reçoit une commande pour restaurer l'état du contenu multimédia enregistré.
    3. La lecture du contenu multimédia reprend.

Les éléments d'état multimédia sont les suivants:

  • Position ou horodatage spécifique du titre, de la vidéo ou de l'élément multimédia.
  • Elles sont placées dans une file d'attente plus large (une playlist ou une radio d'artiste, par exemple).
  • Utilisateur authentifié.
  • État de la lecture (lecture ou pause, par exemple)

Activer le transfert de diffusion

Pour implémenter le transfert de flux pour votre récepteur Web:

  1. Mettez à jour supportedMediaCommands à l'aide de la commande STREAM_TRANSFER :
    playerManager.addSupportedMediaCommands(
    cast.framework.messages.Command.STREAM_TRANSFER, true);
  2. Si vous le souhaitez, remplacez les intercepteurs de messages SESSION_STATE et RESUME_SESSION, comme décrit dans la section Conserver l'état de la session. Ne les remplacez que si les données personnalisées doivent être stockées dans l'instantané de session. Sinon, l'implémentation par défaut pour conserver les états de session prend en charge le transfert de flux.

Conserver l'état de la session

Le SDK Web Receiver fournit une implémentation par défaut pour que les applications Web Receiver conservent les états de session en prenant un instantané de l'état actuel du contenu multimédia, en convertissant l'état en requête de chargement et en reprenant la session avec la requête de chargement.

Si nécessaire, la requête de chargement générée par le récepteur Web peut être remplacée dans l'intercepteur de message SESSION_STATE. Si vous souhaitez ajouter des données personnalisées à la requête de chargement, nous vous suggérons de les placer dans 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;
    });

Les données personnalisées peuvent être extraites de loadRequestData.customData dans l'intercepteur du message 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;
    });

Préchargement du contenu

Le récepteur Web prend en charge le préchargement des éléments multimédias après l'élément de lecture actuel dans la file d'attente.

L'opération de préchargement précharge plusieurs segments d'éléments à venir. La spécification est effectuée sur la valeur preloadTime de l'objet QueueItem (la valeur par défaut est de 20 secondes si elle n'est pas fournie). Le temps est exprimé en secondes par rapport à la fin de l'élément en cours de lecture . Seules les valeurs positives sont valides. Par exemple, si la valeur est de 10 secondes, cet élément est préchargé 10 secondes avant la fin de l'élément précédent. Si le délai de préchargement est plus long que le temps restant pour l'élément actuel, le préchargement s'effectue au plus vite. Ainsi, si une valeur de préchargement très importante est spécifiée dans une file d'attente, il est possible que l'élément en cours soit préchargé à partir de l'élément en cours. Toutefois, nous laissons le paramètre et le choix de cette option au développeur, car cette valeur peut affecter la bande passante et les performances de streaming de l'élément en cours de lecture.

Le préchargement fonctionne par défaut avec le contenu de streaming HLS, DASH et lissage.

Les fichiers audio et vidéo MP4 standards (MP3, par exemple) ne sont pas préchargés, car les appareils Cast n'acceptent qu'un seul élément multimédia et ne peuvent pas être utilisés pour le préchargement pendant la lecture d'un élément de contenu existant.

Messages personnalisés

L'échange de messages constitue la méthode d'interaction clé pour les applications Web Receiver.

Un expéditeur envoie des messages à un destinataire Web à l'aide des API d'expéditeur pour la plate-forme qu'il exécute (Android, iOS, Web). L'objet d'événement (qui est la manifestation d'un message) transmis aux écouteurs d'événements possède un élément de données (event.data) dans lequel les données adoptent les propriétés du type d'événement spécifique.

Une application Web Receiver peut choisir d'écouter des messages sur un espace de noms spécifié. De cette manière, l'application Web Receiver est considérée comme compatible avec ce protocole d'espace de noms. Il appartient ensuite à tous les expéditeurs connectés de communiquer sur cet espace de noms pour utiliser le protocole approprié.

Tous les espaces de noms sont définis par une chaîne et doivent commencer par "urn:x-cast:", suivi d'une chaîne. Exemple : "urn:x-cast:com.example.cast.mynamespace".

Voici un extrait de code permettant au récepteur Web d'écouter les messages personnalisés des expéditeurs connectés:

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

De même, les applications Web Receiver peuvent informer les expéditeurs de l'état du destinataire en envoyant des messages aux expéditeurs connectés. Une application Web Receiver peut envoyer des messages à l'aide de sendCustomMessage(namespace, senderId, message) sur CastReceiverContext. Un récepteur Web peut envoyer des messages à un expéditeur individuel, en réponse à un message reçu ou en raison d'un changement d'état de l'application. Au-delà de la messagerie point à point (avec une limite de 64 Ko), un récepteur Web peut également diffuser des messages à tous les expéditeurs connectés.

Caster du contenu pour des appareils audio

Pour en savoir plus sur la lecture uniquement audio, consultez le Guide Google Cast pour les appareils audio.

Android TV

Cette section explique comment Google Web Receiver utilise vos entrées pour la lecture et la compatibilité avec Android TV.

Intégrer votre application à la télécommande

Le récepteur Web Google exécuté sur l'appareil Android TV traduit les entrées des entrées de commande de l'appareil (à savoir la télécommande portable) en messages de lecture multimédia définis pour l'espace de noms urn:x-cast:com.google.cast.media, comme décrit dans la section Messages de lecture de contenus multimédias. Votre application doit accepter ces messages pour contrôler la lecture du contenu multimédia afin de permettre un contrôle de lecture de base à partir des entrées de contrôle d'Android TV.

Consignes de compatibilité avec Android TV

Voici quelques recommandations et pièges courants à éviter pour vous assurer que votre application est compatible avec Android TV:

  • Notez que la chaîne user-agent contient à la fois "Android" et "CSlide". Certains sites peuvent rediriger les utilisateurs vers un site réservé aux mobiles parce qu'ils détectent le libellé "Android". Ne partez pas du principe qu'"Android" dans la chaîne user-agent indique toujours un utilisateur mobile.
  • La pile multimédia d'Android peut utiliser un fichier GZIP transparent pour récupérer les données. Assurez-vous que vos données multimédias peuvent répondre à Accept-Encoding: gzip.
  • Les événements multimédias HTML5 Android TV peuvent être déclenchés à des délais différents de ceux de Chromecast. Cela peut révéler des problèmes qui ont été masqués sur Chromecast.
  • Lorsque vous mettez à jour le contenu multimédia, utilisez des événements liés aux médias déclenchés par des éléments <audio>/<video> tels que timeupdate, pause et waiting. Évitez d'utiliser des événements liés à la mise en réseau tels que progress, suspend et stalled, car ils dépendent généralement de la plate-forme. Pour en savoir plus sur la gestion des événements multimédias dans votre récepteur, consultez la section Événements multimédias.
  • Lorsque vous configurez les certificats HTTPS de votre site récepteur, veillez à inclure les certificats CA intermédiaires. Consultez la page de test SSL de Qualsys pour vérifier que si le chemin de certification de confiance pour votre site inclut un certificat CA intitulé "Téléchargement supplémentaire", il est possible qu'il ne se charge pas sur les plates-formes Android.
  • Bien que Chromecast affiche la page du récepteur sur un plan graphique 720p, les autres plates-formes Cast, y compris Android TV, peuvent afficher la page jusqu'à 1080p. Assurez-vous que la page du récepteur s'adapte de manière fluide aux différentes résolutions.