Rendre une application Web compatible avec Cast

1. Présentation

Logo Google Cast

Dans cet atelier de programmation, vous allez apprendre à modifier une application vidéo Web existante pour caster du contenu sur un appareil compatible Google Cast.

Qu'est-ce que Google Cast ?

Google Cast permet aux utilisateurs de caster du contenu multimédia depuis un appareil mobile sur un téléviseur, et d'utiliser leur appareil mobile comme télécommande lors de la diffusion.

Grâce au SDK Google Cast, vous pouvez étendre les fonctionnalités de votre application pour contrôler un téléviseur ou un système audio, et ajouter les composants d'interface utilisateur nécessaires selon la checklist de conception de Google Cast.

La checklist de conception de Google Cast a été conçue pour garantir une expérience utilisateur simple et prévisible sur toutes les plates-formes compatibles.

Qu'allons-nous créer ?

À la fin de cet atelier de programmation, vous disposerez d'une application vidéo Web Chrome capable de caster des vidéos sur un appareil Google Cast.

Points abordés

  • Comment ajouter le SDK Google Cast à un exemple d'application vidéo
  • Comment ajouter l'icône Cast permettant de sélectionner un appareil Google Cast
  • Comment se connecter à un appareil Cast et lancer un récepteur multimédia
  • Comment caster une vidéo
  • Intégrer Cast Connect

Prérequis

  • La dernière version du navigateur Google Chrome
  • Service d'hébergement HTTPS tel que Firebase Hosting ou ngrok.
  • Un appareil Google Cast, comme un Chromecast ou un Android TV, configuré pour accéder à Internet
  • Un téléviseur ou un moniteur doté d'une entrée HDMI
  • Un Chromecast avec Google TV est requis pour tester l'intégration de Cast Connect, mais c'est facultatif pour le reste de l'atelier de programmation. Si vous n'en avez pas, vous pouvez ignorer l'étape Ajouter la compatibilité Cast Connect vers la fin de ce tutoriel.

Expérience

  • Vous devez avoir une connaissance préalable du développement Web.
  • Vous devez également avoir une expérience préalable en tant que téléspectateur :)

Comment allez-vous utiliser ce tutoriel ?

Je vais le lire uniquement Je vais le lire et effectuer les exercices

Comment évalueriez-vous votre expérience en matière de création d'applications Web ?

Débutant Intermédiaire Expert

Comment évalueriez-vous votre expérience en tant que téléspectateur ?

Débutant Intermédiaire Expert

2. Obtenir l'exemple de code

Vous pouvez télécharger tout l'exemple de code sur votre ordinateur…

puis décompresser le fichier ZIP téléchargé.

3. Exécuter l'application exemple

Logo Google Chrome

Voyons d'abord comment se présente notre exemple d'application une fois terminée. L'appli est un lecteur vidéo de base. L'utilisateur peut sélectionner une vidéo à partir d'une liste, puis la lire en local sur l'appareil ou la caster sur un appareil Google Cast.

Pour que vous puissiez utiliser la version terminée, elle doit être hébergée.

Si vous ne disposez d'aucun serveur, vous pouvez utiliser Firebase Hosting ou ngrok.

Exécuter le serveur

Une fois le service de votre choix configuré, accédez à app-done et démarrez votre serveur.

Dans votre navigateur, accédez à l'URL https de l'exemple que vous avez hébergé.

  1. L'application vidéo devrait s'afficher.
  2. Cliquez sur l'icône Cast, puis sélectionnez votre appareil Google Cast.
  3. Sélectionnez une vidéo, puis cliquez sur le bouton de lecture.
  4. La vidéo démarrera alors sur votre appareil Google Cast.

Image d'une vidéo en cours de lecture sur un appareil Cast

Cliquez sur le bouton "Pause" dans l'élément vidéo pour mettre la vidéo en pause sur le récepteur. Cliquez sur le bouton de lecture dans l'élément vidéo pour reprendre la lecture de la vidéo.

Cliquez sur l'icône Cast pour arrêter de caster sur l'appareil Google Cast.

Avant de continuer, arrêtez le serveur.

4. Préparer le projet de départ

Image d'une vidéo en cours de lecture sur un appareil Cast

Nous objectif est de rendre l'application de départ que vous avez téléchargée compatible avec Google Cast. Voici quelques termes liés à Google Cast que nous utiliserons dans cet atelier de programmation:

  • Une appli de type émetteur s'exécute sur un appareil mobile ou un ordinateur portable.
  • Une appli de type récepteur s'exécute sur l'appareil Google Cast.

Vous êtes maintenant prêt à développer le projet de démarrage à l'aide de votre éditeur de texte préféré:

  1. Sélectionnez le répertoire Icône Dossierapp-start à partir de l'exemple de code téléchargé.
  2. Exécutez l'application à l'aide de votre serveur et explorez l'interface utilisateur.

Notez que, tout au long de cet atelier de programmation, vous devrez réhéberger l'exemple sur votre serveur en fonction du service.

Conception d'applications

L'application récupère une liste de vidéos à partir d'un serveur Web distant pour fournir une liste à parcourir à l'utilisateur. Ce dernier peut alors sélectionner une vidéo pour en afficher les détails ou la lire localement sur son appareil mobile.

L'application se compose d'une vue principale, définie dans index.html et du contrôleur principal, CastVideos.js..

index.html

Ce fichier HTML déclare la quasi-totalité de l'interface utilisateur de l'application Web.

Il y a quelques sections de vues. Nous avons notre div#main_video, qui contient l'élément vidéo. En lien avec notre div vidéo, nous avons div#media_control, qui définit toutes les commandes de l'élément vidéo. En dessous se trouve media_info, qui affiche les détails de la vidéo. Enfin, le div carousel affiche une liste de vidéos dans un div.

Le fichier index.html amorce également le SDK Cast et indique à la fonction CastVideos de se charger.

La plupart du contenu qui remplira ces éléments est défini, injecté et contrôlé dans CastVideos.js. Examinons cela de plus près.

CastVideos.js

Ce script gère toute la logique de l'application Web Cast Videos. La liste des vidéos et les métadonnées associées définies dans CastVideos.js sont contenues dans un objet nommé mediaJSON.

Plusieurs sections principales sont chargées de gérer et de lire la vidéo en local et à distance. Dans l'ensemble, il s'agit d'une application Web assez simple.

CastPlayer est la classe principale qui gère l'ensemble de l'application, configure le lecteur, sélectionne des contenus multimédias et associe des événements à PlayerHandler pour la lecture des contenus multimédias. CastPlayer.prototype.initializeCastPlayer est la méthode qui configure toutes les fonctionnalités Cast. CastPlayer.prototype.switchPlayer permet de basculer entre les lecteurs locaux et à distance. CastPlayer.prototype.setupLocalPlayer et CastPlayer.prototype.setupRemotePlayer initialisent les lecteurs locaux et distants.

PlayerHandler est la classe chargée de gérer la lecture des contenus multimédias. Il existe un certain nombre d'autres méthodes permettant de gérer les contenus multimédias et la lecture.

Questions fréquentes

5. Ajouter l'icône Cast

Image d'une application compatible Cast

Une application compatible Cast affiche l'icône Cast dans l'élément vidéo. Lorsque l'utilisateur clique sur cette icône, la liste des appareils Cast qu'il peut sélectionner s'affiche. Si un contenu était en cours de lecture localement sur l'appareil émetteur, le fait de sélectionner un appareil Cast démarre ou reprend cette même lecture directement sur l'appareil Cast sélectionné. À tout moment, l'utilisateur doit pouvoir cliquer sur l'icône Cast pour interrompre la diffusion émise à partir de votre application sur l'appareil Cast. L'utilisateur doit pouvoir se connecter à l'appareil Cast ou s'en déconnecter depuis n'importe quel écran de votre application, comme décrit dans la checklist de conception Google Cast.

Configuration

Le projet de démarrage nécessite les mêmes dépendances et la même configuration que pour l'application exemple terminée, mais héberge cette fois le contenu de app-start.

Dans votre navigateur, accédez à l'URL https de l'exemple que vous avez hébergé.

N'oubliez pas que lorsque vous apportez des modifications, vous devrez réhéberger l'exemple sur votre serveur, en fonction du service.

Initialisation

Le framework Cast comporte un objet singleton global, CastContext, qui coordonne toutes les activités du framework. Cet objet doit être initialisé au début du cycle de vie de l'application, généralement appelé à partir d'un rappel attribué à window['__onGCastApiAvailable'], qui est appelé après le chargement du SDK Cast et qui est disponible. Dans ce cas, CastContext est appelé dans CastPlayer.prototype.initializeCastPlayer, qui est appelé à partir du rappel susmentionné.

Un objet JSON options doit être fourni lors de l'initialisation de CastContext. Cette classe contient des options qui affectent le comportement du framework. Le plus important est l'ID de l'application réceptrice, qui sert à filtrer la liste des appareils Cast disponibles pour n'afficher que les appareils capables d'exécuter l'application spécifiée et pour lancer l'application réceptrice lorsqu'une session Cast est lancée.

Lorsque vous développez votre propre application compatible Cast, vous devez vous inscrire en tant que développeur Cast afin d'obtenir votre ID d'application. Cela dit, dans cet atelier de programmation, nous utiliserons un exemple d'ID d'application.

Ajoutez le code suivant à index.html à la fin de la section body:

<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>

Ajoutez le code suivant à index.html pour initialiser l'application CastVideos et CastContext:

<script src="CastVideos.js"></script>
<script type="text/javascript">
var castPlayer = new CastPlayer();
window['__onGCastApiAvailable'] = function(isAvailable) {
  if (isAvailable) {
    castPlayer.initializeCastPlayer();
  }
};
</script>

Nous devons maintenant ajouter une nouvelle méthode dans CastVideos.js, qui correspond à celle que nous venons d'appeler dans index.html. Ajoutons une nouvelle méthode, appelée initializeCastPlayer, qui définit les options sur CastContext, et initialise les nouveaux RemotePlayer et RemotePlayerControllers:

/**
 * This method sets up the CastContext, and a few other members
 * that are necessary to play and control videos on a Cast
 * device.
 */
CastPlayer.prototype.initializeCastPlayer = function() {

    var options = {};

    // Set the receiver application ID to your own (created in
    // the Google Cast Developer Console), or optionally
    // use the chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID
    options.receiverApplicationId = 'C0868879';

    // Auto join policy can be one of the following three:
    // ORIGIN_SCOPED - Auto connect from same appId and page origin
    // TAB_AND_ORIGIN_SCOPED - Auto connect from same appId, page origin, and tab
    // PAGE_SCOPED - No auto connect
    options.autoJoinPolicy = chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED;

    cast.framework.CastContext.getInstance().setOptions(options);

    this.remotePlayer = new cast.framework.RemotePlayer();
    this.remotePlayerController = new cast.framework.RemotePlayerController(this.remotePlayer);
    this.remotePlayerController.addEventListener(
        cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED,
        this.switchPlayer.bind(this)
    );
};

Enfin, nous devons créer les variables pour RemotePlayer et RemotePlayerController:

var CastPlayer = function() {
  //...
  /* Cast player variables */
  /** @type {cast.framework.RemotePlayer} */
  this.remotePlayer = null;
  /** @type {cast.framework.RemotePlayerController} */
  this.remotePlayerController = null;
  //...
};

Icône Cast

Après avoir initialisé CastContext, nous devons ajouter l'icône Cast pour permettre à l'utilisateur de choisir son appareil Cast. Le SDK Cast fournit un composant pour l'icône Cast appelé google-cast-launcher, dont l'ID est castbutton". Vous pouvez l'ajouter à l'élément vidéo de l'application en ajoutant simplement un button dans la section media_control.

L'élément de bouton se présentera comme suit:

<google-cast-launcher id="castbutton"></google-cast-launcher>

Ajoutez le code suivant à index.html dans la section media_control:

<div id="media_control">
  <div id="play"></div>
  <div id="pause"></div>
  <div id="progress_bg"></div>
  <div id="progress"></div>
  <div id="progress_indicator"></div>
  <div id="fullscreen_expand"></div>
  <div id="fullscreen_collapse"></div>
  <google-cast-launcher id="castbutton"></google-cast-launcher>
  <div id="audio_bg"></div>
  <div id="audio_bg_track"></div>
  <div id="audio_indicator"></div>
  <div id="audio_bg_level"></div>
  <div id="audio_on"></div>
  <div id="audio_off"></div>
  <div id="duration">00:00:00</div>
</div>

À présent, actualisez la page dans votre navigateur Chrome. Une icône Cast devrait s'afficher dans l'élément vidéo. Lorsque vous cliquez dessus, les appareils Cast de votre réseau local s'affichent. La détection d'appareils est gérée automatiquement par le navigateur Chrome. Sélectionnez ensuite votre appareil Cast pour y charger l'exemple de l'application récepteur.

Vous ne pouvez pas encore lire de vidéos sur l'appareil Cast, car nous n'avons pas encore connecté de support multimédia. Cliquez sur l'icône Cast pour arrêter la diffusion.

6. Diffuser du contenu vidéo

Image d&#39;une application compatible Cast avec le menu de sélection de l&#39;appareil Cast

Nous allons étendre notre exemple d'application à la lecture de vidéos à distance sur un appareil Cast. Pour ce faire, nous devons écouter les différents événements générés par le framework Cast.

Caster un contenu multimédia

En règle générale, si vous souhaitez lire un contenu multimédia sur un appareil Cast, voici ce qui doit se passer:

  1. Créez un objet JSON MediaInfo à partir du SDK Cast qui modélise un élément multimédia.
  2. L'utilisateur se connecte à l'appareil Cast pour lancer votre application réceptrice.
  3. Chargez l'objet MediaInfo sur votre récepteur et lisez son contenu.
  4. Suivez l'état du contenu multimédia.
  5. Envoyez des commandes de lecture au récepteur en fonction des interactions de l'utilisateur.

L'étape 1 consiste à mapper un objet à un autre. MediaInfo est quelque chose que le SDK Cast comprend, et mediaJSON est l'encapsulation de notre application pour un élément multimédia. nous pouvons facilement mapper un mediaJSON à un MediaInfo. Nous avons déjà effectué l'étape 2 dans la section précédente. L'étape 3 est facile à réaliser avec le SDK Cast.

L'application exemple CastPlayer fait déjà la distinction entre la lecture en local et la lecture à distance dans la méthode switchPlayer:

if (cast && cast.framework) {
  if (this.remotePlayer.isConnected) {
    //...

Dans cet atelier de programmation, vous n'avez pas besoin de comprendre exactement comment fonctionne la logique du lecteur de test. Toutefois, il est important de comprendre que le lecteur multimédia de votre application doit être modifié pour prendre en charge à la fois la lecture en local et à distance.

Pour le moment, notre lecteur local est toujours configuré à l'état de lecture locale puisque la possibilité de caster du contenu lui est encore inconnue. Nous devons donc mettre à jour l'interface utilisateur pour prendre en compte les transitions d'état qui se produisent dans le framework Cast. Par exemple, si nous commençons à caster un contenu, nous devons arrêter la lecture en local et désactiver certaines commandes. De même, si nous arrêtons la diffusion lorsque nous sommes dans ce contrôleur de vue, nous devons passer à la lecture locale. Pour cela, il nous faut écouter les différents événements générés par le framework Cast.

Gestion d'une session Cast

Dans le framework Cast, une session Cast combine plusieurs étapes : se connecter à un appareil, lancer une session (ou rejoindre une session existante), se connecter à une application réceptrice et initialiser un canal de commande multimédia, le cas échéant. Le canal de commande multimédia permet au framework Cast d'envoyer et de recevoir des messages liés à la lecture multimédia du récepteur.

La session Cast démarre automatiquement lorsque l'utilisateur sélectionne un appareil à partir de l'icône Cast. Elle s'arrête automatiquement lorsque l'utilisateur se déconnecte. La reconnexion à une session réceptrice en raison de problèmes de réseau est également gérée automatiquement par le framework Cast.

Les sessions Cast sont gérées par le CastSession, accessible via cast.framework.CastContext.getInstance().getCurrentSession(). Les rappels EventListener peuvent être utilisés pour surveiller les événements de session, tels que la création, la suspension, la reprise et l'arrêt.

Dans l'application actuelle, toute la gestion des sessions et des états est assurée pour nous dans la méthode setupRemotePlayer. Commençons à configurer cela dans votre application en ajoutant le code suivant à CastVideos.js:

/**
 * Set the PlayerHandler target to use the remote player
 */
CastPlayer.prototype.setupRemotePlayer = function () {
    var castSession = cast.framework.CastContext.getInstance().getCurrentSession();

    this.playerHandler.setTarget(playerTarget);

    // Setup remote player volume right on setup
    // The remote player may have had a volume set from previous playback
    if (this.remotePlayer.isMuted) {
        this.playerHandler.mute();
    }
    var currentVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
    var p = document.getElementById('audio_bg_level');
    p.style.height = currentVolume + 'px';
    p.style.marginTop = -currentVolume + 'px';

    this.hideFullscreenButton();

    this.playerHandler.play();
};

Nous devons toujours associer tous les événements des rappels et gérer tous les événements entrants. Cette opération étant assez simple, nous allons nous en occuper maintenant:

/**
 * Set the PlayerHandler target to use the remote player
 */
CastPlayer.prototype.setupRemotePlayer = function () {
    var castSession = cast.framework.CastContext.getInstance().getCurrentSession();

    // Add event listeners for player changes which may occur outside sender app
    this.remotePlayerController.addEventListener(
        cast.framework.RemotePlayerEventType.IS_PAUSED_CHANGED,
        function() {
            if (this.remotePlayer.isPaused) {
                this.playerHandler.pause();
            } else {
                this.playerHandler.play();
            }
        }.bind(this)
    );

    this.remotePlayerController.addEventListener(
        cast.framework.RemotePlayerEventType.IS_MUTED_CHANGED,
        function() {
            if (this.remotePlayer.isMuted) {
                this.playerHandler.mute();
            } else {
                this.playerHandler.unMute();
            }
        }.bind(this)
    );

    this.remotePlayerController.addEventListener(
        cast.framework.RemotePlayerEventType.VOLUME_LEVEL_CHANGED,
        function() {
            var newVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
            var p = document.getElementById('audio_bg_level');
            p.style.height = newVolume + 'px';
            p.style.marginTop = -newVolume + 'px';
        }.bind(this)
    );

    // This object will implement PlayerHandler callbacks with
    // remotePlayerController, and makes necessary UI updates specific
    // to remote playback
    var playerTarget = {};

    playerTarget.play = function () {
        if (this.remotePlayer.isPaused) {
            this.remotePlayerController.playOrPause();
        }

        var vi = document.getElementById('video_image');
        vi.style.display = 'block';
        var localPlayer = document.getElementById('video_element');
        localPlayer.style.display = 'none';
    }.bind(this);

    playerTarget.pause = function () {
        if (!this.remotePlayer.isPaused) {
            this.remotePlayerController.playOrPause();
        }
    }.bind(this);

    playerTarget.stop = function () {
         this.remotePlayerController.stop();
    }.bind(this);

    playerTarget.getCurrentMediaTime = function() {
        return this.remotePlayer.currentTime;
    }.bind(this);

    playerTarget.getMediaDuration = function() {
        return this.remotePlayer.duration;
    }.bind(this);

    playerTarget.updateDisplayMessage = function () {
        document.getElementById('playerstate').style.display = 'block';
        document.getElementById('playerstatebg').style.display = 'block';
        document.getElementById('video_image_overlay').style.display = 'block';
        document.getElementById('playerstate').innerHTML =
            this.mediaContents[ this.currentMediaIndex]['title'] + ' ' +
            this.playerState + ' on ' + castSession.getCastDevice().friendlyName;
    }.bind(this);

    playerTarget.setVolume = function (volumeSliderPosition) {
        // Add resistance to avoid loud volume
        var currentVolume = this.remotePlayer.volumeLevel;
        var p = document.getElementById('audio_bg_level');
        if (volumeSliderPosition < FULL_VOLUME_HEIGHT) {
            var vScale =  this.currentVolume * FULL_VOLUME_HEIGHT;
            if (volumeSliderPosition > vScale) {
                volumeSliderPosition = vScale + (pos - vScale) / 2;
            }
            p.style.height = volumeSliderPosition + 'px';
            p.style.marginTop = -volumeSliderPosition + 'px';
            currentVolume = volumeSliderPosition / FULL_VOLUME_HEIGHT;
        } else {
            currentVolume = 1;
        }
        this.remotePlayer.volumeLevel = currentVolume;
        this.remotePlayerController.setVolumeLevel();
    }.bind(this);

    playerTarget.mute = function () {
        if (!this.remotePlayer.isMuted) {
            this.remotePlayerController.muteOrUnmute();
        }
    }.bind(this);

    playerTarget.unMute = function () {
        if (this.remotePlayer.isMuted) {
            this.remotePlayerController.muteOrUnmute();
        }
    }.bind(this);

    playerTarget.isMuted = function() {
        return this.remotePlayer.isMuted;
    }.bind(this);

    playerTarget.seekTo = function (time) {
        this.remotePlayer.currentTime = time;
        this.remotePlayerController.seek();
    }.bind(this);

    this.playerHandler.setTarget(playerTarget);

    // Setup remote player volume right on setup
    // The remote player may have had a volume set from previous playback
    if (this.remotePlayer.isMuted) {
        this.playerHandler.mute();
    }
    var currentVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
    var p = document.getElementById('audio_bg_level');
    p.style.height = currentVolume + 'px';
    p.style.marginTop = -currentVolume + 'px';

    this.hideFullscreenButton();

    this.playerHandler.play();
};

Chargement de contenu multimédia

Dans le SDK Cast, RemotePlayer et RemotePlayerController fournissent un ensemble d'API pratiques permettant de gérer la lecture de contenus multimédias à distance sur le récepteur. Pour une CastSession compatible avec la lecture de contenus multimédias, des instances de RemotePlayer et RemotePlayerController seront créées automatiquement par le SDK. Vous pouvez y accéder en créant respectivement des instances de cast.framework.RemotePlayer et cast.framework.RemotePlayerController, comme indiqué précédemment dans cet atelier de programmation.

Nous devons ensuite charger la vidéo actuellement sélectionnée sur le récepteur en créant un objet MediaInfo que le SDK doit traiter et transmettre à la requête. Pour ce faire, ajoutez le code suivant à setupRemotePlayer:

/**
 * Set the PlayerHandler target to use the remote player
 */
CastPlayer.prototype.setupRemotePlayer = function () {
    //...

    playerTarget.load = function (mediaIndex) {
        console.log('Loading...' + this.mediaContents[mediaIndex]['title']);
        var mediaInfo = new chrome.cast.media.MediaInfo(
            this.mediaContents[mediaIndex]['sources'][0], 'video/mp4');

        mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
        mediaInfo.metadata.metadataType = chrome.cast.media.MetadataType.GENERIC;
        mediaInfo.metadata.title = this.mediaContents[mediaIndex]['title'];
        mediaInfo.metadata.images = [
            {'url': MEDIA_SOURCE_ROOT + this.mediaContents[mediaIndex]['thumb']}];

        var request = new chrome.cast.media.LoadRequest(mediaInfo);
        castSession.loadMedia(request).then(
            this.playerHandler.loaded.bind(this.playerHandler),
            function (errorCode) {
                this.playerState = PLAYER_STATE.ERROR;
                console.log('Remote media load error: ' +
                    CastPlayer.getErrorMessage(errorCode));
            }.bind(this));
    }.bind(this);

    //...
};

Ajoutez maintenant une méthode pour basculer entre la lecture locale et la lecture à distance:

/**
 * This is a method for switching between the local and remote
 * players. If the local player is selected, setupLocalPlayer()
 * is run. If there is a cast device connected we run
 * setupRemotePlayer().
 */
CastPlayer.prototype.switchPlayer = function() {
    this.stopProgressTimer();
    this.resetVolumeSlider();
    this.playerHandler.stop();
    this.playerState = PLAYER_STATE.IDLE;
    if (cast && cast.framework) {
        if (this.remotePlayer.isConnected) {
            this.setupRemotePlayer();
            return;
        }
    }
    this.setupLocalPlayer();
};

Enfin, ajoutez une méthode pour gérer les messages d'erreur Cast:

/**
 * Makes human-readable message from chrome.cast.Error
 * @param {chrome.cast.Error} error
 * @return {string} error message
 */
CastPlayer.getErrorMessage = function(error) {
  switch (error.code) {
    case chrome.cast.ErrorCode.API_NOT_INITIALIZED:
      return 'The API is not initialized.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.CANCEL:
      return 'The operation was canceled by the user' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.CHANNEL_ERROR:
      return 'A channel to the receiver is not available.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.EXTENSION_MISSING:
      return 'The Cast extension is not available.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.INVALID_PARAMETER:
      return 'The parameters to the operation were not valid.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.RECEIVER_UNAVAILABLE:
      return 'No receiver was compatible with the session request.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.SESSION_ERROR:
      return 'A session could not be created, or a session was invalid.' +
        (error.description ? ' :' + error.description : '');
    case chrome.cast.ErrorCode.TIMEOUT:
      return 'The operation timed out.' +
        (error.description ? ' :' + error.description : '');
  }
};

Exécutez maintenant l'application. Connectez-vous à votre appareil Cast et lancez la lecture d'une vidéo. Votre session Cast devrait maintenant commencer sur le récepteur.

7. Ajouter la compatibilité Cast Connect

La bibliothèque Cast Connect permet aux applications émettrices existantes de communiquer avec les applications Android TV via le protocole Cast. Cast Connect s'appuie sur l'infrastructure Cast, et votre application Android TV joue le rôle de récepteur.

Dépendances

  • Navigateur Chrome version M87 ou ultérieure

Définir la compatibilité du récepteur Android

Pour lancer l'application Android TV, également appelée Android Receiver, nous devons définir l'indicateur androidReceiverCompatible sur "true" dans l'objet CastOptions.

Ajoutez le code suivant à CastVideos.js dans la fonction initializeCastPlayer:

var options = {};
...
options.androidReceiverCompatible = true;

cast.framework.CastContext.getInstance().setOptions(options);

Définir les identifiants de lancement

Côté expéditeur, vous pouvez spécifier CredentialsData pour représenter qui rejoint la session. Le credentials est une chaîne qui peut être définie par l'utilisateur, à condition que votre application Android TV puisse la comprendre. Le CredentialsData n'est transmis à votre application Android TV que pendant le lancement ou l'heure de connexion. Si vous le configurez à nouveau alors que vous êtes connecté, il ne sera pas transmis à votre application Android TV.

Pour pouvoir définir les identifiants de lancement, CredentialsData doit être défini à tout moment une fois les options de lancement définies.

Ajoutez le code suivant à votre classe CastVideos.js sous la fonction initializeCastPlayer:

cast.framework.CastContext.getInstance().setOptions(options);
...
let credentialsData = new chrome.cast.CredentialsData("{\"userId\": \"abc\"}");
cast.framework.CastContext.getInstance().setLaunchCredentialsData(credentialsData);
...

Définir les identifiants lors de la requête de chargement

Si votre application Web Receiver et votre application Android TV gèrent credentials différemment, vous devrez peut-être définir des identifiants distincts pour chacune d'elles. Pour résoudre ce problème, ajoutez le code suivant dans votre CastVideos.js sous playerTarget.load dans la fonction setupRemotePlayer:

...
var request = new chrome.cast.media.LoadRequest(mediaInfo);
request.credentials = 'user-credentials';
request.atvCredentials = 'atv-user-credentials';
...

En fonction de l'application réceptrice sur laquelle l'émetteur diffuse du contenu, le SDK gère désormais automatiquement les identifiants à utiliser pour la session en cours.

Test de Cast Connect

Pour installer le fichier APK Android TV sur Chromecast avec Google TV:

  1. Recherchez l'adresse IP de votre appareil Android TV. Elle est généralement disponible sous Paramètres > Réseau et Internet > (nom du réseau auquel votre appareil est connecté). Les détails et l'adresse IP de l'appareil connecté au réseau s'affichent sur la droite.
  2. Utilisez l'adresse IP de votre appareil pour vous y connecter via ADB à l'aide du terminal:
$ adb connect <device_ip_address>:5555
  1. Dans la fenêtre de votre terminal, accédez au dossier de premier niveau contenant les exemples de l'atelier de programmation que vous avez téléchargés au début de cet atelier de programmation. Exemple :
$ cd Desktop/chrome_codelab_src
  1. Installez le fichier .apk de ce dossier sur votre Android TV en exécutant la commande suivante:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. Vous devriez à présent voir une application nommée Caster des vidéos dans le menu Vos applications de votre appareil Android TV.
  2. Exécutez le code Web d'expéditeur mis à jour et établissez une session Cast avec votre appareil Android TV à l'aide de l'icône Cast ou en sélectionnant Cast.. dans le menu déroulant de votre navigateur Chrome. L'application Android TV devrait maintenant être lancée sur votre récepteur Android et vous permettre de contrôler la lecture à l'aide de votre télécommande Android TV.

8. Félicitations

Vous savez maintenant comment rendre une application vidéo compatible Cast à l'aide des widgets du SDK Cast dans une application Web Chrome.

Pour en savoir plus, consultez le guide du développeur sur Web Sender.