Rendre une application Web compatible avec Cast

1. Présentation

Logo Google Cast

Cet atelier de programmation vous explique comment 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 ensuite utiliser leur appareil mobile comme télécommande pour lire des contenus multimédias sur le 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, 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 qui pourra 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
  • Service d'hébergement HTTPS tel que Firebase Hosting ou ngrok.
  • Un appareil Google Cast, tel qu'un Chromecast ou un Android TV, configuré pour accéder à Internet
  • Un téléviseur ou un moniteur doté d'une entrée HDMI
  • Chromecast avec Google TV est nécessaire pour tester l'intégration de Cast Connect, mais cette option reste facultative pour le reste de l'atelier de programmation. Si vous n'en avez pas, n'hésitez pas à ignorer l'étape Ajouter la compatibilité Cast Connect à la fin de ce tutoriel.

Expérience

  • Vous devez avoir des 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 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 pouvoir utiliser l'état "terminé", 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. Vous devriez voir l'application vidéo 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 de mise en 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 relancer 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 la terminologie 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 que vous avez 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'appli se compose d'une vue principale, définie dans index.html, et d'une manette principale, CastVideos.js.

index.html

Ce fichier HTML déclare presque toute l'interface utilisateur de l'application Web.

Il y a quelques 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, media_info, qui affiche les détails de la vidéo active. Enfin, l'élément div carousel affiche une liste de vidéos dans un élément div.

Le fichier index.html amorce é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 à cela.

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 définies dans CastVideos.js se trouve dans un objet nommé mediaJSON.

Plusieurs sections principales sont ensemble responsables de la gestion et de la lecture de 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 les contenus multimédias et associe 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 bascule l'état entre les lecteurs locaux et les lecteurs distants. CastPlayer.prototype.setupLocalPlayer et CastPlayer.prototype.setupRemotePlayer initialisent les lecteurs locaux et à distance.

PlayerHandler est la classe chargée de gérer la lecture des contenus multimédias. D'autres méthodes permettent 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 de 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.

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 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 d'application du récepteur, qui permet de filtrer la liste des appareils Cast disponibles afin de n'afficher que les appareils 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 maintenant ajouter une nouvelle 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". 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>

Maintenant, actualisez la page dans votre navigateur Chrome. Vous devriez voir une icône Cast 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 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 de l&#39;application compatible Cast avec le menu de sélection des appareils 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 l'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.

La première étape consiste à mapper un objet à un autre. Le SDK Cast comprend MediaInfo, et mediaJSON est l'encapsulation de notre application pour un élément multimédia. Nous pouvons facilement mapper mediaJSON à MediaInfo. Nous avons déjà effectué l'étape 2 dans 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 à 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é 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 sommes 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 commande multimédia, le cas échéant. Le canal de commande multimédia correspond à la manière dont le framework Cast envoie et reçoit les messages liés à la lecture des contenus multimédias du récepteur.

La session Cast démarre automatiquement lorsque l'utilisateur sélectionne un appareil à l'aide 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 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 d'une session tels que la création, la suspension, la reprise et l'arrêt.

Dans notre application actuelle, la gestion des sessions et des états est entièrement gérée dans la méthode setupRemotePlayer. Commençons par configurer cela dans votre application en ajoutant le code suivant à votre 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 provenant des rappels et gérer tous les événements entrants. Cette opération est assez simple. Nous allons donc 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 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 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 transmet 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 en local 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, l'application Android TV faisant office de récepteur.

Dépendances

  • Navigateur Chrome version M87 ou ultérieure

Compatible 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 indiquer 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 lors du lancement ou de la connexion. Si vous la redéfinissez alors que vous êtes connecté, elle ne sera pas transmise à l'appli 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 lors de 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 chacun d'eux. Pour ce faire, 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';
...

Selon 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.

Test de Cast Connect

Procédure d'installation du fichier APK 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. Depuis la fenêtre de votre terminal, accédez au dossier de premier niveau contenant les exemples 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 situé 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. Vous devriez maintenant voir une application appelée Caster des vidéos 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. Cette action devrait maintenant lancer l'application Android TV sur votre Android Receiver et vous permettre de contrôler la lecture à l'aide de la 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 de l'expéditeur Web.