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 des contenus depuis un appareil mobile sur un téléviseur. Les utilisateurs peuvent ainsi utiliser leur appareil mobile comme télécommande pour la lecture de contenus multimédias sur leur téléviseur.

Le SDK Google Cast vous permet d'étendre votre application afin de contrôler un téléviseur ou un système audio. Le SDK Cast vous permet d'ajouter les composants d'interface utilisateur nécessaires en fonction de la checklist de conception 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

Ce dont vous avez besoin

  • 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 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 nécessaire pour tester l'intégration de Cast Connect, mais cette option est facultative pour le reste de l'atelier de programmation. Si vous n'en avez pas, n'hésitez pas à passer l'étape Ajouter la compatibilité Cast Connect vers la fin de ce tutoriel.

Expérience

  • Vous devez disposer de connaissances préalables en 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 utiliser la fonction terminée, vous devez l'héberger.

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 et 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 de 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 dans le téléchargement de l'exemple de code.
  2. Exécutez l'application à l'aide de votre serveur et explorez l'interface utilisateur.

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

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'appli 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 plusieurs sections de vues, et 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 affiche les détails de la vidéo visible. Enfin, le div carousel affiche une liste de vidéos dans un div.

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

La plupart du contenu qui renseigne ces éléments est défini, injecté et contrôlé dans CastVideos.js. Jetons un coup d’œil à ça.

CastVideos.js

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

Plusieurs sections principales sont chargées ensemble de la gestion et de la lecture des vidéos, aussi bien en local qu'à 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, en configurant le lecteur, en sélectionnant des contenus multimédias et en associant les événements à PlayerHandler pour la lecture de contenus multimédias. CastPlayer.prototype.initializeCastPlayer est la méthode qui configure toutes les fonctionnalités Cast. CastPlayer.prototype.switchPlayer fait passer l'état du lecteur local au lecteur distant. 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. D'autres méthodes permettent de gérer en détail 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 indiqué 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 devez réhéberger l'exemple sur votre serveur en fonction du service concerné.

Initialisation

Le framework Cast dispose d'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, 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 mentionné ci-dessus.

Un objet JSON options doit être fourni lors de l'initialisation de CastContext. Cette classe contient des options qui affectent le comportement du framework. La plus importante d'entre elles est l'ID de l'application du récepteur, qui permet de filtrer la liste des appareils Cast disponibles pour n'afficher que ceux capables d'exécuter l'application spécifiée et de lancer l'application récepteur 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 maintenant ajouter une méthode dans CastVideos.js, qui correspond à la méthode que nous venons d'appeler dans index.html. Ajoutons une 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"". Pour l'ajouter à l'élément vidéo de l'application, il suffit d'ajouter 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. Vous devriez voir une icône Cast dans l'élément vidéo. Lorsque vous cliquez dessus, la liste des appareils Cast de votre réseau local s'affiche. La détection des 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.

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

De manière générale, si vous souhaitez lire un contenu multimédia sur un appareil Cast, procédez comme suit:

  1. Créez un objet MediaInfo JSON à 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 un élément 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 de la section précédente. L'étape 3 est simple à effectuer avec le SDK Cast.

L'application exemple CastPlayer fait déjà la distinction entre lecture en local et 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 devra être modifié de sorte qu'il soit compatible avec 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 nous trouvons dans ce contrôleur de vue, nous devons passer à la lecture en local. 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 : connexion à un appareil, lancement (ou connexion à une session existante), connexion à une application réceptrice et initialisation d'un canal de commandes multimédias, le cas échéant. Le canal de commande multimédia détermine la façon dont le framework Cast envoie et reçoit du récepteur les messages liés à la lecture de contenus multimédias.

La session Cast démarre automatiquement lorsque l'utilisateur sélectionne un appareil à partir de l'icône Cast et s'arrête automatiquement lorsqu'il se déconnecte. La reconnexion à une session réceptrice en raison de problèmes de mise en 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 notre application actuelle, toute la gestion des sessions et des états est gérée pour nous dans la méthode setupRemotePlayer. Commençons par configurer cette fonctionnalité dans votre application en ajoutant le code suivant à votre fichier 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 lier 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 pour gérer la lecture de contenus multimédias à distance sur le récepteur. Pour un 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 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 pour que le SDK traite et transmette 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é avec 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 : votre application Android TV joue le rôle de récepteur.

Dépendances

  • Navigateur Chrome version M87 ou ultérieure

Régler la compatibilité avec Android Receiver

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 qui rejoint la session. 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 lors du lancement ou de la connexion. Si vous la reconfigurez alors que vous êtes connecté, elle ne sera pas transmise à votre application Android TV.

Pour 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 pour la requête de chargement

Si vos applications Web Receiver et Android TV gèrent credentials différemment, vous devrez peut-être définir des identifiants distincts pour chacune d'elles. Pour vous en assurer, ajoutez le code suivant dans 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 vers laquelle l'émetteur diffuse du contenu, le SDK gère désormais automatiquement les identifiants à utiliser pour la session en cours.

Tester Cast Connect

Procédure d'installation du fichier APK d'Android TV sur Chromecast avec Google TV:

  1. Recherchez l'adresse IP de votre appareil Android TV. Elle se trouve généralement dans Paramètres > Réseau et Internet > (Nom du réseau auquel votre appareil est connecté). Les détails et l'adresse IP de votre appareil sur le réseau s'affichent à 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 celui-ci. Exemple :
$ cd Desktop/chrome_codelab_src
  1. Installez le fichier .apk qui se trouve dans ce dossier sur votre Android TV en exécutant la commande suivante:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
  1. Une application du nom de Caster des vidéos devrait maintenant s'afficher dans le menu Vos applications de votre appareil Android TV.
  2. Exécutez le nouveau code de l'expéditeur Web et établissez une session de diffusion avec votre appareil Android TV à l'aide de l'icône Cast ou en sélectionnant Cast.. dans le menu déroulant du navigateur Chrome. Cela devrait maintenant lancer l'application Android TV 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 mettre en œuvre 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 Web Sender (expéditeur Web).