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.
  • Un service d'hébergement HTTPS tel que Firebase Hosting ou ngrok.
  • Un appareil Google Cast, comme Chromecast ou 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 nécessaire pour tester l'intégration de Cast Connect, mais il est facultatif pour le reste de l'atelier de programmation. Si vous n'en avez pas, n'hésitez pas à ignorer l'étape Ajouter la compatibilité avec 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 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 pouvoir utiliser le formulaire finalisé, il doit être hébergé.

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.

Cliquez sur l'icône Cast pour arrêter la diffusion 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 pour l'application Web.

Il y a quelques sections de vues. Nous avons notre div#main_video, qui contient l'élément vidéo. En ce qui concerne 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 contient les détails de la vidéo dans la vue. Enfin, le div carousel affiche la liste des vidéos dans un div.

Le fichier index.html amorce également le SDK Cast et indique à la fonction CastVideos qu'elle doit se charger.

La plupart du contenu qui renseigne ces éléments est défini, injecté et contrôlé dans CastVideos.js. Voyons cela plus en détail.

CastVideos.js

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

Quelques sections importantes sont conjointement responsables de la gestion et de la lecture de la vidéo, en local et à distance. Globalement, il s'agit d'une application Web relativement 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 bascule l'état entre lecteurs locaux et lecteurs à distance. CastPlayer.prototype.setupLocalPlayer et CastPlayer.prototype.setupRemotePlayer initialisent les lecteurs locaux et à distance.

PlayerHandler est la classe responsable de la gestion de la lecture de contenus multimédias. Il existe d'autres méthodes pour 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 de Google Cast.

Configuration

Le projet de départ nécessite les mêmes dépendances et la même configuration que l'application exemple terminée, mais cette fois-ci, il héberge 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 devez 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é tôt dans le cycle de vie de l'application. Il est généralement appelé à partir d'un rappel attribué à window['__onGCastApiAvailable'], qui est appelé après le chargement du SDK Cast et qui peut être utilisé. 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 ont une incidence sur le comportement du framework. La plus importante de ces options est l'ID d'application du récepteur, utilisé pour filtrer la liste des appareils Cast disponibles afin de n'afficher que ceux capables d'exécuter l'application spécifiée et de 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, ainsi que pour initialiser 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 à présent ajouter une nouvelle méthode dans CastVideos.js, qui correspond à la méthode 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 et dont l'ID est castbutton". Il peut être ajouté à 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ésente 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 des appareils est automatiquement gérée par le navigateur Chrome. Sélectionnez ensuite votre appareil Cast pour y charger l'exemple de l'application récepteur.

Pour le moment, vous ne pouvez pas 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, la procédure est la suivante:

  1. Vous 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 l'application de récepteur.
  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 permet de mapper deux objets. Le SDK Cast peut comprendre MediaInfo, et mediaJSON est l'encapsulation de notre application pour un élément multimédia. Nous pouvons facilement mapper mediaJSON avec MediaInfo. Nous avons déjà effectué l'étape 2 à la section précédente. L'étape 3 est simple à 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. En revanche, il est important que vous compreniez que le lecteur multimédia de votre application doit être modifié de sorte à pouvoir également détecter la lecture locale 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 détermine la façon dont le framework Cast envoie et reçoit les messages liés à la lecture multimédia depuis le récepteur.

La session Cast démarre automatiquement lorsque l'utilisateur sélectionne un appareil à partir de l'icône Cast, puis 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 qui surviennent au cours d'une session, tels que la création, la suspension, la reprise et l'achèvement.

Dans notre application actuelle, la gestion des sessions et des états est entièrement gérée 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 encore associer tous les événements des rappels et gérer tous les événements entrants. Cette opération étant assez simple, occupons-nous en 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 pour gérer la lecture de contenus multimédias à distance sur le récepteur. Pour toute CastSession compatible avec la lecture de contenus multimédias, des instances de RemotePlayer et de RemotePlayerController seront créées automatiquement par le SDK. Pour y accéder, vous devez créer des instances de cast.framework.RemotePlayer et cast.framework.RemotePlayerController, respectivement, comme indiqué précédemment dans l'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. 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 : '');
  }
};

À présent, exécutez l'application. Connectez-vous à votre appareil Cast, puis 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é avec le 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

Du côté de l'expéditeur, vous pouvez spécifier CredentialsData pour représenter la personne qui rejoint la session. credentials est une chaîne pouvant être définie par l'utilisateur, à condition que votre application ATV puisse la comprendre. Le CredentialsData n'est transmis à votre application Android TV qu'au moment du lancement ou de la 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 des identifiants dans 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. Pour ce faire, 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 destinataire vers laquelle l'expéditeur effectue la diffusion, le SDK gère désormais automatiquement les identifiants à utiliser pour la session en cours.

Tester Cast Connect

Pour installer l'APK Android TV sur Chromecast avec Google TV:

  1. Recherchez l'adresse IP de votre appareil Android TV. Elle se trouve généralement sous Paramètres > Réseau et Internet > (nom du réseau auquel votre appareil est connecté). À droite, vous trouverez les détails et l'adresse IP de votre appareil sur le réseau.
  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 des exemples de l'atelier de programmation que vous avez téléchargés au début de cet atelier. 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 maintenant voir une application intitulée Cast Videos (Caster des vidéos) dans le menu Vos applications de votre appareil Android TV.
  2. Exécutez le code d'expéditeur Web mis à jour et établissez une session de casting 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 s'ouvrir sur votre Android Receiver 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 compatible Cast une application vidéo à l'aide des widgets du SDK Cast sur une application Web Chrome.

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