1. Présentation
Dans cet atelier de programmation, vous allez apprendre à créer une application Récepteur Web personnalisé pour lire du contenu sur des appareils compatibles 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 se servir de leur appareil mobile ou du navigateur Chrome de leur ordinateur comme télécommande pour contrôler la lecture des contenus multimédias sur leur téléviseur.
Le SDK Google Cast permet à votre application de contrôler des appareils compatibles Google Cast (un téléviseur ou un système audio, par exemple). Le SDK Cast fournit 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. En savoir plus
Qu'allons-nous créer ?
À la fin de cet atelier de programmation, vous disposerez d'une application HTML5 qui servira de récepteur personnalisé, capable d'afficher du contenu vidéo sur les appareils compatibles Cast.
Points abordés
- Configurer le développement du récepteur
- Principes de base d'un récepteur compatible Cast basé sur le framework d'application Cast
- Comment recevoir une vidéo castée
- Intégrer Debug Logger
- Comment optimiser votre récepteur pour les écrans connectés.
Prérequis
- La dernière version du navigateur Google Chrome
- Service d'hébergement HTTPS tel que Firebase Hosting ou ngrok.
- Un appareil Google Cast, comme un Chromecast ou un Android TV, configuré pour accéder à Internet
- Un téléviseur ou un moniteur doté d'une entrée HDMI
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 ?
Comment évalueriez-vous votre expérience en matière de création d'applications Web ?
Comment évalueriez-vous votre expérience en tant que téléspectateur ?
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. Déployer le récepteur en local
Pour que vous puissiez utiliser votre récepteur Web avec un appareil Cast, celui-ci doit être hébergé à un emplacement auquel votre appareil Cast peut accéder. Si vous disposez déjà d'un serveur compatible avec HTTPS, ignorez les instructions ci-dessous et notez l'URL, car vous en aurez besoin dans la section suivante.
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-start
et démarrez votre serveur.
Notez l'URL de votre récepteur hébergé. Vous l'utiliserez dans la section suivante.
4. Enregistrer une application dans la console développeur Cast
Vous devez enregistrer votre application pour pouvoir exécuter un récepteur personnalisé, tel qu'il est intégré dans cet atelier de programmation, sur des appareils Chromecast. Une fois votre application enregistrée, vous recevrez un ID application dont l'application émettrice doit se servir pour effectuer des appels d'API, par exemple pour lancer une application réceptrice.
Cliquez sur "Add new application" (Ajouter une nouvelle application).
Sélectionnez "Récepteur personnalisé". c'est ce que nous sommes en train de créer.
Saisissez les informations sur votre nouveau récepteur (assurez-vous d'utiliser l'URL avec laquelle vous avez obtenu
dans la dernière section. Notez l'ID application attribué à votre nouveau récepteur.
Vous devez également enregistrer votre appareil Google Cast afin qu'il puisse accéder à l'application réceptrice avant de le publier. Une fois votre application réceptrice publiée, elle est disponible pour tous les appareils Google Cast. Pour les besoins de cet atelier de programmation, il est recommandé d'utiliser une application réceptrice non publiée.
Cliquez sur "Add new Device" (Ajouter un appareil).
Saisissez le numéro de série indiqué au dos de votre appareil Cast et donnez-lui un nom descriptif. Vous pouvez également trouver le numéro de série en castant votre écran dans Chrome lorsque vous accédez à la console développeur du SDK Google Cast.
Vous devrez patienter entre 5 et 15 minutes avant que le récepteur et l'appareil soient prêts à être testés. Après 5 à 15 minutes, vous devez redémarrer votre appareil Cast.
5. Exécuter l'application exemple
En attendant que notre nouvelle application réceptrice soit prête à être testée, voyons à quoi ressemble un exemple d'application réceptrice terminée. Le récepteur que nous allons créer sera capable de lire des contenus multimédias à l'aide du streaming à débit adaptatif. Nous utiliserons pour cela un exemple de contenu encodé pour la diffusion adaptative dynamique sur HTTP (DASH).
Dans votre navigateur, ouvrez l'outil Command and Control (CaC).
- L'outil CaC doit s'afficher.
- Utilisez la valeur par défaut "CC1AD845" l'exemple d'ID de récepteur, puis cliquez sur "Définir l'ID de l'application" .
- Cliquez sur l'icône Cast en haut à gauche, puis sélectionnez votre appareil Google Cast.
- Accédez à l'onglet "Load Media" (Charger le contenu multimédia). en haut.
- Cliquez sur le bouton "Charger par contenu" pour lire un échantillon vidéo.
- La lecture de la vidéo commence sur votre appareil Google Cast pour montrer à quoi ressemble le fonctionnement de base du récepteur avec le récepteur par défaut.
6. Préparer le projet de départ
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é:
- Sélectionnez le répertoire
app-start
à partir de l'exemple de code téléchargé. - Ouvrez
js/receiver.js
etindex.html
.
Notez que tout au long de cet atelier de programmation, http-server
devrait appliquer les modifications que vous apportez. Si ce n'est pas le cas, essayez de fermer et de redémarrer http-server
.
Conception de l'application
L'application réceptrice initialise la session Cast et reste en veille jusqu'à l'arrivée d'une requête LOAD (en d'autres termes, la commande de lecture d'un contenu multimédia) de l'expéditeur.
L'application comprend une vue principale, définie dans index.html
, et un fichier JavaScript appelé js/receiver.js
qui contient toute la logique permettant au récepteur de fonctionner.
index.html
Ce fichier HTML contiendra l'interface utilisateur de notre application réceptrice. Pour l'instant, il est vide. Nous allons l'ajouter tout au long de l'atelier de programmation.
receiver.js
Ce script gérera toute la logique de notre application réceptrice. Pour le moment, il s'agit simplement d'un fichier vide. Dans la section suivante, nous allons le transformer en un récepteur Cast entièrement fonctionnel, avec quelques lignes de code.
7. Récepteur Cast de base
Un récepteur Cast de base initialise la session Cast au démarrage. Cette étape est nécessaire pour indiquer à toutes les applications émettrices connectées que le destinataire a bien été affiché. De plus, le nouveau SDK est préconfiguré pour gérer les contenus multimédias en streaming à débit adaptatif (à l'aide de DASH, HLS et Smooth Streaming), ainsi que les fichiers MP4 ordinaires prêts à l'emploi. Essayons ceci.
Initialisation
Ajoutez le code suivant à index.html
dans l'en-tête:
<head>
...
<script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
</head>
Ajoutez le code suivant à index.html
<body>
avant le <footer>
qui charge receiver.js,
afin de fournir au SDK du récepteur l'espace nécessaire pour afficher l'UI du récepteur par défaut qui est envoyée avec le script que vous venez d'ajouter.
<cast-media-player></cast-media-player>
Nous devons maintenant initialiser le SDK dans js/receiver.js
, comme suit:
- Acquisition d'une référence à
CastReceiverContext
, votre point d'entrée principal vers l'ensemble du SDK Récepteur - Stockage d'une référence à
PlayerManager
, l'objet qui gère la lecture et vous fournit tous les hooks dont vous avez besoin pour connecter votre propre logique personnalisée - initialiser le SDK en appelant
start()
surCastReceiverContext
;
Ajoutez le code suivant à js/receiver.js
.
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
context.start();
8. Caster du contenu "de base" contenu vidéo
Pour les besoins de cet atelier de programmation, utilisez l'outil CaC pour tester votre tout nouveau récepteur.
Dans votre navigateur Web, accédez à l'outil Command and Control (CaC).
Veillez à remplacer votre propre ID d'application, tel qu'enregistré précédemment, dans le champ, puis cliquez sur "Set App ID" (Définir l'ID d'application). Vous indiquez ainsi à l'outil d'utiliser votre récepteur au démarrage de la session Cast.
Caster un contenu multimédia
En règle générale, pour lire du contenu multimédia sur un appareil Cast, vous devez:
- L'émetteur crée un objet
JSON
MediaInfo
à partir du SDK Cast qui modélise un élément multimédia. - L'émetteur se connecte à l'appareil Cast pour lancer l'application réceptrice.
- Le récepteur charge l'objet
MediaInfo
via une requêteLOAD
pour lire le contenu. - Le récepteur surveille et suit l'état du contenu multimédia.
- L'émetteur envoie des commandes de lecture au récepteur pour contrôler la lecture en fonction des interactions de l'utilisateur avec l'application émettrice.
Lors de cette première tentative de base, nous allons renseigner MediaInfo
avec une URL d'élément jouable (stockée dans MediaInfo.contentUrl
).
Un expéditeur réel utilise un identifiant multimédia spécifique à l'application dans MediaInfo.contentId
. Le récepteur utilise contentId
comme identifiant pour effectuer les appels d'API backend appropriés afin de résoudre l'URL réelle de l'élément et de la définir sur MediaInfo.contentUrl.
. Il gère également des tâches telles que l'acquisition de licences DRM ou l'injection d'informations sur les coupures publicitaires.
Nous allons étendre votre récepteur pour qu'il effectue une opération similaire dans la section suivante. Pour l'instant, cliquez sur l'icône Cast et sélectionnez votre appareil pour ouvrir le récepteur.
Accédez à l'onglet "Load Media" (Charger le contenu multimédia). puis cliquez sur "Charger par contenu" . Votre récepteur doit lancer la lecture de l'échantillon de contenu.
Prêt à l'emploi, le SDK Récepteur gère les éléments suivants:
- Initialiser la session Cast
- Gérer les requêtes
LOAD
entrantes des expéditeurs contenant des éléments lisibles - Fournissez une interface utilisateur de base pour le joueur, prête à être affichée sur grand écran.
N'hésitez pas à explorer l'outil CaC et son code avant de passer à la section suivante, où nous allons étendre notre récepteur pour qu'il communique avec un exemple d'API simple permettant de traiter les requêtes LOAD
entrantes des expéditeurs.
9. Intégrer à une API externe
Conformément à la façon dont la plupart des développeurs interagissent avec leurs récepteurs Cast dans des applications réelles, nous allons modifier notre récepteur pour qu'il gère les requêtes LOAD
qui font référence au contenu multimédia prévu à l'aide de sa clé API, au lieu d'envoyer une URL d'élément lisible.
En général, cela se produit pour les raisons suivantes:
- L'expéditeur ne connaît peut-être pas l'URL du contenu.
- L'application Cast est conçue pour gérer l'authentification, d'autres logiques métier ou les appels d'API directement sur le récepteur.
Cette fonctionnalité est principalement implémentée dans la méthode setMessageInterceptor()
PlayerManager
. Cela vous permet d'intercepter les messages entrants par type et de les modifier avant qu'ils n'atteignent le gestionnaire de messages interne du SDK. Dans cette section, nous allons traiter les requêtes LOAD
pour lesquelles nous allons effectuer les opérations suivantes:
- Lisez la requête
LOAD
entrante et soncontentId
personnalisé. - Effectuez un appel
GET
à notre API pour rechercher l'élément pouvant être diffusé en streaming à l'aide de soncontentId
. - Remplacez la requête
LOAD
par l'URL du flux. - Modifiez l'objet
MediaInformation
pour définir les paramètres du type de flux. - Transmettez la requête au SDK pour lecture ou refusez la commande si nous ne parvenons pas à rechercher le contenu multimédia demandé.
L'exemple d'API fourni présente les hooks du SDK permettant de personnaliser les tâches courantes du récepteur, tout en s'appuyant sur une expérience principalement prête à l'emploi.
Exemple d'API
Dans votre navigateur, accédez à https://storage.googleapis.com/cpe-sample-media/content.json et consultez notre catalogue d'exemples de vidéos. Le contenu inclut les URL des images poster au format png, ainsi que les flux DASH et HLS. Les flux DASH et HLS pointent vers des sources audio et vidéo démuxées stockées dans des conteneurs mp4 fragmentés.
{
"bbb": {
"author": "The Blender Project",
"description": "Grumpy Bunny is grumpy",
"poster": "https://[...]/[...]/BigBuckBunny/images/screenshot1.png",
"stream": {
"dash": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.mpd",
"hls": "https://[...]/[...]/BigBuckBunny/BigBuckBunny_master.m3u8",
"title": "Big Buck Bunny"
},
"fbb_ad": {
"author": "Google Inc.",
"description": "Introducing Chromecast. The easiest way to enjoy [...]",
"poster": "https://[...]/[...]/ForBiggerBlazes/images/screenshot8.png",
"stream": {
"dash": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.mpd",
"hls": "https://[...]/[...]/ForBiggerBlazes/ForBiggerBlazes.m3u8",
"title": "For Bigger Blazes"
},
[...]
}
À l'étape suivante, nous allons mapper la clé de chaque entrée (par exemple, bbb, fbb_ad
) à l'URL du flux une fois que le récepteur a été appelé avec une requête LOAD
.
Intercepter la requête LOAD
Au cours de cette étape, nous allons créer un intercepteur de chargement avec une fonction qui envoie une requête XHR
au fichier JSON
hébergé. Une fois le fichier JSON
obtenu, nous analyserons le contenu et définirons les métadonnées. Dans les sections suivantes, nous allons personnaliser les paramètres MediaInformation
pour spécifier le type de contenu.
Ajoutez le code suivant à votre fichier js/receiver.js
, juste avant l'appel de context.start()
.
function makeRequest (method, url) {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(JSON.parse(xhr.response));
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
xhr.send();
});
}
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
return new Promise((resolve, reject) => {
// Fetch content repository by requested contentId
makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json').then(function (data) {
let item = data[request.media.contentId];
if(!item) {
// Content could not be found in repository
reject();
} else {
// Add metadata
let metadata = new
cast.framework.messages.GenericMediaMetadata();
metadata.title = item.title;
metadata.subtitle = item.author;
request.media.metadata = metadata;
// Resolve request
resolve(request);
}
});
});
});
La section suivante explique comment configurer la propriété media
de la requête de chargement pour le contenu DASH.
Utiliser le contenu DASH de l'exemple d'API
Maintenant que nous avons préparé l'intercepteur de chargement, nous allons spécifier le type de contenu pour le récepteur. Ces informations fournissent au récepteur l'URL de la playlist principale et le type MIME du flux. Ajoutez le code suivant au fichier js/receiver.js dans le Promise()
de l'intercepteur LOAD
:
...
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
return new Promise((resolve, reject) => {
...
} else {
// Adjusting request to make requested content playable
request.media.contentUrl = item.stream.dash;
request.media.contentType = 'application/dash+xml';
...
}
});
});
});
Une fois cette étape terminée, vous pouvez passer à la phase de test pour essayer de charger le contenu DASH. Si vous préférez tester le chargement avec du contenu HLS, passez à l'étape suivante.
Utiliser le contenu HLS de l'exemple d'API
L'exemple d'API inclut du contenu HLS et DASH. En plus de définir contentType
comme nous l'avons fait à l'étape précédente, la requête de chargement nécessite des propriétés supplémentaires pour utiliser les URL HLS de l'exemple d'API. Lorsque le récepteur est configuré pour lire des flux HLS, le type de conteneur attendu par défaut est le flux de transport (TS). Par conséquent, le récepteur tentera d'ouvrir les exemples de flux MP4 au format TS si seule la propriété contentUrl
est modifiée. Dans la requête de chargement, l'objet MediaInformation
doit être modifié avec des propriétés supplémentaires afin que le destinataire sache que le contenu est de type MP4 et non TS. Ajoutez le code suivant à votre fichier js/receiver.js dans l'intercepteur de chargement pour modifier les propriétés contentUrl
et contentType
. Ajoutez également les propriétés HlsSegmentFormat
et HlsVideoSegmentFormat
.
...
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
return new Promise((resolve, reject) => {
...
} else {
// Adjusting request to make requested content playable
request.media.contentUrl = item.stream.hls;
request.media.contentType = 'application/x-mpegurl';
request.media.hlsSegmentFormat = cast.framework.messages.HlsSegmentFormat.FMP4;
request.media.hlsVideoSegmentFormat = cast.framework.messages.HlsVideoSegmentFormat.FMP4;
...
}
});
});
});
Tester
Ouvrez à nouveau l'outil Command and Control (CaC) et définissez votre ID d'application sur l'ID d'application de votre récepteur. Sélectionnez votre appareil à l'aide de l'icône Cast.
Accédez à l'onglet "Load Media" (Charger le contenu multimédia). . Cette fois, supprimez le texte de la section "URL de contenu". à côté du champ "Charger par contenu" qui obligera notre application à envoyer une requête LOAD
contenant uniquement la référence contentId
à notre média.
En supposant que tout fonctionne correctement avec les modifications que vous avez apportées au récepteur, l'intercepteur doit transformer l'objet MediaInfo
en un élément que le SDK peut lire à l'écran.
Cliquez sur le bouton "Charger par contenu" pour vérifier si votre contenu multimédia est lu correctement. N'hésitez pas à remplacer l'identifiant Content ID par un autre dans le fichier content.json.
10. Optimiser pour les écrans connectés
Les écrans connectés sont des appareils dotés d'une fonctionnalité tactile qui permet aux applications réceptrices de prendre en charge les commandes tactiles.
Cette section explique comment optimiser votre application réceptrice lorsqu'elle est lancée sur des écrans connectés et comment personnaliser les commandes du lecteur.
Accéder aux commandes d'interface utilisateur
L'objet Commandes d'interface utilisateur pour les écrans connectés est accessible à l'aide de cast.framework.ui.Controls.GetInstance()
. Ajoutez le code suivant à votre fichier js/receiver.js
au-dessus de context.start()
:
...
// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
context.start();
Si vous n'utilisez pas <cast-media-player> vous devez définir touchScreenOptimizedApp
dans CastReceiverOptions
. Dans cet atelier de programmation, nous utilisons <cast-media-player> .
context.start({ touchScreenOptimizedApp: true });
Des boutons de commande par défaut sont attribués à chaque emplacement en fonction de MetadataType
et de MediaStatus.supportedMediaCommands
.
Commandes vidéo
Pour MetadataType.MOVIE
, MetadataType.TV_SHOW
et MetadataType.GENERIC
, l'objet Commandes d'interface utilisateur pour les écrans connectés s'affiche comme dans l'exemple ci-dessous.
--playback-logo-image
MediaMetadata.subtitle
MediaMetadata.title
MediaStatus.currentTime
MediaInformation.duration
ControlsSlot.SLOT_SECONDARY_1
:ControlsButton.QUEUE_PREV
ControlsSlot.SLOT_PRIMARY_1
:ControlsButton.SEEK_BACKWARD_30
PLAY/PAUSE
ControlsSlot.SLOT_PRIMARY_2
:ControlsButton.SEEK_FORWARD_30
ControlsSlot.SLOT_SECONDARY_2
:ControlsButton.QUEUE_NEXT
Commandes audio
Pour MetadataType.MUSIC_TRACK
, l'objet Commandes d'interface utilisateur pour les écrans connectés s'affiche comme suit:
--playback-logo-image
MusicTrackMediaMetadata.albumName
MusicTrackMediaMetadata.title
MusicTrackMediaMetadata.albumArtist
MusicTrackMediaMetadata.images[0]
MediaStatus.currentTime
MediaInformation.duration
ControlsSlot.SLOT_SECONDARY_1
:ControlsButton.NO_BUTTON
ControlsSlot.SLOT_PRIMARY_1
:ControlsButton.QUEUE_PREV
PLAY/PAUSE
ControlsSlot.SLOT_PRIMARY_2
:ControlsButton.QUEUE_NEXT
ControlsSlot.SLOT_SECONDARY_2
:ControlsButton.NO_BUTTON
Mettre à jour les commandes multimédias compatibles
L'objet Commandes d'interface utilisateur détermine également si une ControlsButton
est affichée ou non en fonction de MediaStatus.supportedMediaCommands
.
Lorsque la valeur de supportedMediaCommands
est égale à ALL_BASIC_MEDIA
, la disposition des commandes par défaut se présente comme suit:
Lorsque la valeur de supportedMediaCommands
est égale à ALL_BASIC_MEDIA | QUEUE_PREV | QUEUE_NEXT
, la disposition des commandes par défaut se présente comme suit:
Lorsque la valeur de supportedMediaCommands est égale à PAUSE | QUEUE_PREV | QUEUE_NEXT
, la disposition des commandes par défaut se présente comme suit:
Lorsque des pistes de texte sont disponibles, le bouton des sous-titres est toujours affiché sur SLOT_1
.
Pour modifier de manière dynamique la valeur de supportedMediaCommands
après avoir démarré un contexte de récepteur, vous pouvez appeler PlayerManager.setSupportedMediaCommands
afin de remplacer la valeur. Vous pouvez également ajouter une commande en utilisant addSupportedMediaCommands
ou supprimer une commande existante en utilisant removeSupportedMediaCommands
.
Personnaliser les boutons de commande
Vous pouvez personnaliser les commandes à l'aide de PlayerDataBinder
. Ajoutez le code suivant à votre fichier js/receiver.js
sous touchControls pour définir le premier emplacement de vos commandes:
...
// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);
playerDataBinder.addEventListener(
cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
(e) => {
if (!e.value) return;
// Clear default buttons and re-assign
touchControls.clearDefaultSlotAssignments();
touchControls.assignButton(
cast.framework.ui.ControlsSlot.SLOT_PRIMARY_1,
cast.framework.ui.ControlsButton.SEEK_BACKWARD_30
);
});
context.start();
11. Implémenter la navigation multimédia sur les écrans connectés
Media Browse est une fonctionnalité CAF Receiver qui permet aux utilisateurs d'explorer des contenus supplémentaires sur les appareils tactiles. Pour implémenter cela, vous allez utiliser PlayerDataBinder
afin de définir l'interface utilisateur BrowseContent
. Vous pouvez ensuite y insérer BrowseItems
en fonction du contenu que vous souhaitez afficher.
BrowseContent
Vous trouverez ci-dessous un exemple de l'interface utilisateur BrowseContent
et de ses propriétés:
BrowseContent.title
BrowseContent.items
Format
Utilisez le targetAspectRatio property
afin de sélectionner le meilleur format pour vos composants Image. Trois formats sont compatibles avec le SDK récepteur CAF: SQUARE_1_TO_1
, PORTRAIT_2_TO_3
et LANDSCAPE_16_TO_9
.
BrowseItem
Utilisez BrowseItem
pour afficher le titre, le sous-titre, la durée et l'image de chaque élément:
BrowseItem.image
BrowseItem.duration
BrowseItem.title
BrowseItem.subtitle
Définir les données Media Browse
Vous pouvez fournir une liste de contenus multimédias pour la navigation en appelant setBrowseContent
. Ajoutez le code suivant à votre fichier js/receiver.js
sous playerDataBinder
et dans votre écouteur d'événements MEDIA_CHANGED
pour définir les éléments de navigation avec le titre "À suivre".
// Optimizing for smart displays
const touchControls = cast.framework.ui.Controls.getInstance();
const playerData = new cast.framework.ui.PlayerData();
const playerDataBinder = new cast.framework.ui.PlayerDataBinder(playerData);
...
let browseItems = getBrowseItems();
function getBrowseItems() {
let browseItems = [];
makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
.then(function (data) {
for (let key in data) {
let item = new cast.framework.ui.BrowseItem();
item.entity = key;
item.title = data[key].title;
item.subtitle = data[key].description;
item.image = new cast.framework.messages.Image(data[key].poster);
item.imageType = cast.framework.ui.BrowseImageType.MOVIE;
browseItems.push(item);
}
});
return browseItems;
}
let browseContent = new cast.framework.ui.BrowseContent();
browseContent.title = 'Up Next';
browseContent.items = browseItems;
browseContent.targetAspectRatio = cast.framework.ui.BrowseImageAspectRatio.LANDSCAPE_16_TO_9;
playerDataBinder.addEventListener(
cast.framework.ui.PlayerDataEventType.MEDIA_CHANGED,
(e) => {
if (!e.value) return;
....
// Media browse
touchControls.setBrowseContent(browseContent);
});
Le fait de cliquer sur un élément de la navigation multimédia déclenche l'intercepteur LOAD
. Ajoutez le code suivant à votre intercepteur LOAD
pour mapper request.media.contentId
avec request.media.entity
à partir de l'élément Media Browse:
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
...
// Map contentId to entity
if (request.media && request.media.entity) {
request.media.contentId = request.media.entity;
}
return new Promise((resolve, reject) => {
...
});
});
Vous pouvez également définir l'objet BrowseContent
sur null
pour supprimer l'interface utilisateur Media Browse.
12. Déboguer les applications réceptrices
Le SDK Récepteur Cast offre aux développeurs une autre option pour déboguer facilement les applications réceptrices à l'aide de l'API CastDebugLogger et d'un outil Command and Control (CaC) associé pour capturer les journaux.
Initialisation
Pour intégrer l'API, ajoutez le script source CastDebugLogger
dans votre fichier index.html. La source doit être déclarée dans la section <head>. après la déclaration du SDK Récepteur Cast.
<head>
...
<script src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
<!-- Cast Debug Logger -->
<script src="//www.gstatic.com/cast/sdk/libs/devtools/debug_layer/caf_receiver_logger.js"></script>
</head>
Dans js/receiver.js
, en haut du fichier et sous playerManager
, ajoutez le code suivant pour récupérer l'instance CastDebugLogger
et activer l'enregistreur:
const context = cast.framework.CastReceiverContext.getInstance();
const playerManager = context.getPlayerManager();
// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
const LOG_TAG = 'MyAPP.LOG';
// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
if (!castDebugLogger.debugOverlayElement_) {
castDebugLogger.setEnabled(true);
}
});
Lorsque l'enregistreur de débogage est activé, une superposition affichant DEBUG MODE
s'affiche sur le récepteur.
Événements du lecteur de journal
CastDebugLogger
vous permet de consigner facilement les événements du lecteur déclenchés par le SDK Récepteur CAF et d'utiliser différents niveaux d'enregistreur pour consigner les données des événements. La configuration loggerLevelByEvents
utilise cast.framework.events.EventType
et cast.framework.events.category
pour spécifier les événements à enregistrer.
Ajoutez le code suivant sous la déclaration castDebugLogger
pour consigner le déclenchement d'un événement CORE
du lecteur ou la diffusion d'une modification mediaStatus
:
// Debug Logger
const castDebugLogger = cast.debug.CastDebugLogger.getInstance();
// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
context.addEventListener(cast.framework.system.EventType.READY, () => {
if (!castDebugLogger.debugOverlayElement_) {
castDebugLogger.setEnabled(true);
}
});
// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}
Messages de journal et balises personnalisées
L'API CastDebugLogger vous permet de créer des messages de journal qui apparaissent avec différentes couleurs sur la superposition de débogage du récepteur. Les méthodes de journalisation suivantes sont disponibles, classées de la priorité la plus haute à la plus basse:
castDebugLogger.error(custom_tag, message);
castDebugLogger.warn(custom_tag, message);
castDebugLogger.info(custom_tag, message);
castDebugLogger.debug(custom_tag, message);
Pour chaque méthode d'enregistrement, le premier paramètre est une balise personnalisée. Il peut s'agir de n'importe quelle chaîne d'identification que vous trouvez pertinente. Le CastDebugLogger
utilise des tags pour filtrer les journaux. L'utilisation des balises est expliquée en détail ci-dessous. Le deuxième paramètre est le message de journal.
Pour les afficher en action, ajoutez-les à votre intercepteur LOAD
.
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD,
request => {
castDebugLogger.info(LOG_TAG, 'Intercepting LOAD request');
// Map contentId to entity
if (request.media && request.media.entity) {
request.media.contentId = request.media.entity;
}
return new Promise((resolve, reject) => {
// Fetch content repository by requested contentId
makeRequest('GET', 'https://storage.googleapis.com/cpe-sample-media/content.json')
.then(function (data) {
let item = data[request.media.contentId];
if(!item) {
// Content could not be found in repository
castDebugLogger.error(LOG_TAG, 'Content not found');
reject();
} else {
// Adjusting request to make requested content playable
request.media.contentUrl = item.stream.dash;
request.media.contentType = 'application/dash+xml';
castDebugLogger.warn(LOG_TAG, 'Playable URL:', request.media.contentUrl);
// Add metadata
let metadata = new cast.framework.messages.MovieMediaMetadata();
metadata.metadataType = cast.framework.messages.MetadataType.MOVIE;
metadata.title = item.title;
metadata.subtitle = item.author;
request.media.metadata = metadata;
// Resolve request
resolve(request);
}
});
});
});
Vous pouvez contrôler les messages qui s'affichent sur le calque de débogage en définissant le niveau de journalisation dans loggerLevelByTags
pour chaque balise personnalisée. Par exemple, si vous activez une balise personnalisée avec le niveau de journalisation cast.framework.LoggerLevel.DEBUG
, tous les messages ajoutés avec une erreur, un avertissement, des informations et des messages de débogage s'afficheront. Si vous activez une balise personnalisée de niveau WARNING
, seuls les messages de journal d'erreur et d'avertissement s'affichent.
La configuration loggerLevelByTags
est facultative. Si aucune balise personnalisée n'est configurée pour son niveau d'enregistreur, tous les messages de journal s'affichent sur le calque de débogage.
Ajoutez le code suivant sous l'enregistreur d'événements CORE
:
// Set verbosity level for Core events.
castDebugLogger.loggerLevelByEvents = {
'cast.framework.events.category.CORE': cast.framework.LoggerLevel.INFO,
'cast.framework.events.EventType.MEDIA_STATUS': cast.framework.LoggerLevel.DEBUG
}
// Set verbosity level for custom tags.
castDebugLogger.loggerLevelByTags = {
[LOG_TAG]: cast.framework.LoggerLevel.DEBUG,
};
Déboguer la superposition
L'enregistreur de débogage Cast fournit un superposition de débogage sur le récepteur pour afficher vos messages de journal personnalisés sur l'appareil Cast. Utilisez showDebugLogs
pour activer/désactiver le calque de débogage et clearDebugLogs
pour effacer les messages de journal sur la superposition.
Ajoutez le code suivant pour prévisualiser le calque de débogage sur votre récepteur.
context.addEventListener(cast.framework.system.EventType.READY, () => {
if (!castDebugLogger.debugOverlayElement_) {
// Enable debug logger and show a 'DEBUG MODE' overlay at top left corner.
castDebugLogger.setEnabled(true);
// Show debug overlay
castDebugLogger.showDebugLogs(true);
// Clear log messages on debug overlay
castDebugLogger.clearDebugLogs();
}
});
13. Félicitations
Vous savez maintenant créer une application réceptrice personnalisée à l'aide du SDK Cast Web Receiver.
Pour en savoir plus, consultez le guide du développeur Web Receiver.