Implémenter CameraStream avec WebRTC

1. Avant de commencer

La caractéristique CameraStream appartient aux appareils capables de diffuser des flux vidéo sur des écrans connectés, des appareils Chromecast et des smartphones. Le protocole WebRTC est désormais compatible avec la caractéristique CameraStream. Vous pouvez ainsi réduire considérablement la latence de démarrage et de streaming d'un appareil photo vers un appareil d'affichage Google Nest.

Appareils photo diffusant du contenu en streaming sur un écran Google Nest

Prérequis

Points abordés

  • Déployer un service cloud pour la maison connectée
  • Connecter votre service à l'Assistant Google
  • Diffuser du contenu en streaming sur un écran Google Nest avec le protocole WebRTC

Prérequis

  • Un navigateur Web tel que Google Chrome
  • Un appareil iOS ou Android avec l'application Google Home
  • Node.js version 10.16 ou ultérieure
  • Forfait Blaze (paiement à l'usage) pour Firebase
  • Une webcam intégrée ou externe compatible avec la résolution Full HD
  • Un écran Google Nest.

2. Commencer

Installer la CLI Firebase

La CLI Firebase vous permet de diffuser vos applications Web en local et de les déployer sur Firebase Hosting.

Pour installer la CLI Firebase, procédez comme suit:

  1. Dans votre terminal, téléchargez et installez la CLI Firebase:
$ npm install -g firebase-tools
  1. Vérifiez que la CLI a bien été installée:
$ firebase --version
  1. Autorisez la CLI Firebase avec votre compte Google:
$ firebase login

Créer un projet

  1. Accédez à la console pour les développeurs Google Home.
  2. Cliquez sur Créer un projet, saisissez un nom pour le projet, puis cliquez sur Créer un projet.

Nommer le projet

Exécuter l'application cliente CameraStream

Le code source de cet atelier de programmation inclut un client WebRTC qui établit, négocie et gère la session WebRTC entre la webcam et l'appareil d'affichage de la maison connectée Google.

Pour exécuter l'application cliente WebRTC CameraStream, procédez comme suit:

  • Cliquez sur le bouton suivant pour télécharger le code source sur votre ordinateur de développement:

  • Clonez le dépôt GitHub suivant:
    $ git clone https://github.com/google-home/smarthome-camerastream-webrtc.git
    

Le code contient les répertoires suivants:

  • Le répertoire camerastream-start, qui contient le code de démarrage sur lequel vous allez compiler.
  • Le répertoire camerastream-done, qui contient le code de la solution de l'atelier de programmation terminé.

Le répertoire camerastream-start contient les sous-répertoires suivants:

  • Le sous-répertoire public, qui contient une interface utilisateur frontale permettant de contrôler et de surveiller facilement l'état de votre appareil photo.
  • Le sous-répertoire functions, qui contient un service cloud entièrement implémenté qui gère la caméra avec Cloud Functions for Firebase et Realtime Database.

Le code de démarrage contient des commentaires TODO qui indiquent où vous devez ajouter ou modifier du code, comme dans l'exemple suivant:

// TODO: Implement full SYNC response.

Créer un projet Firebase

  1. Accédez à Firebase.
  2. Cliquez sur Créer un projet, puis saisissez le nom de votre projet.
  3. Cochez la case du contrat, puis cliquez sur Continuer. Si aucune case à cocher n'est disponible, vous pouvez ignorer cette étape.
    Créer un projet Firebase
  4. Une fois votre projet Firebase créé, recherchez son ID. Accédez à Vue d'ensemble du projet, puis cliquez sur l'icône des paramètres > Paramètres du projet.
    Ouvrir les paramètres du projet
  5. Votre projet est listé dans l'onglet Général.
    Paramètres généraux du projet

Se connecter à Firebase

  1. Accédez au répertoire camerastream-start, puis configurez la CLI Firebase avec votre projet Actions:
$ cd camerastream-start
$ firebase use <firebase-project-id>
  1. Dans le répertoire camerastream-start, accédez au dossier functions, puis installez toutes les dépendances nécessaires:
$ cd functions
$ npm install
  1. Si le message suivant s'affiche, ignorez-le. Cet avertissement est dû à des dépendances plus anciennes. Pour en savoir plus, consultez ce problème sur GitHub.
found 5 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details
  1. Initialisez un projet Firebase:
$ firebase init
  1. Sélectionnez Functions (Fonctions) et Hosting (Hébergement). Cette opération initialise les API et les fonctionnalités nécessaires pour votre projet.
? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. 
❯◯ Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance
 ◯ Firestore: Deploy rules and create indexes for Firestore
 ◉ Functions: Configure a Cloud Functions directory and its files
 ◉ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
 ◯ Hosting: Set up GitHub Action deploys
 ◯ Storage: Configure a security rules file for Cloud Storage
 ◯ Extensions: Set up an empty Extensions manifest
  1. Configurez Cloud Functions avec les fichiers par défaut et veillez à ne pas écraser les fichiers index.js et package.json existants dans l'exemple de projet:
? Would you like to initialize a new codebase, or overwrite an existing one?
Overwrite

? What language would you like to use to write Cloud Functions? 
JavaScript

? File functions/package.json already exists. Overwrite? 
No

? File functions/index.js already exists. Overwrite? 
No

? Do you want to install dependencies with npm now? 
Yes
  1. Configurez Hosting avec le répertoire public dans le code du projet et utilisez le fichier index.html existant:
? What do you want to use as your public directory? 
public

? Configure as a single-page app (rewrite all urls to /index.html)? 
Yes

? Set up automatic builds and deploys with GitHub?
No

? File public/index.html already exists. Overwrite?
 No

3. Échanger des messages SDP (Session Description Protocol)

L'échange de messages SDP est une étape importante de l'établissement d'un flux WebRTC. Le protocole SDP est un protocole basé sur du texte qui décrit les caractéristiques d'une session multimédia. Il est utilisé dans WebRTC pour négocier les paramètres d'une connexion peer-to-peer, tels que les codecs utilisés, les adresses IP des participants et les ports utilisés pour le transport multimédia.

Pour utiliser Realtime Database comme hôte pour échanger des messages SDP entre votre webcam et l'application cliente CameraStream de la maison connectée, procédez comme suit:

  1. Dans la console Firebase, cliquez sur Créer > Realtime Database > Créer une base de données.

Page &quot;Realtime Database&quot; (Base de données en temps réel) dans la console Firebase

  1. Dans le menu déroulant Emplacement de Realtime Database, sélectionnez un emplacement approprié pour héberger votre base de données.

Menu déroulant de l&#39;emplacement Realtime Database dans la boîte de dialogue &quot;Configurer la base de données&quot;

  1. Sélectionnez Start in test mode (Commencer en mode test), puis cliquez sur Enable (Activer). Lorsque Realtime Database est activé, vous devez pouvoir y faire référence à partir de l'application cliente CameraStream.
  1. Dans la console Firebase, sélectionnez 513f2be95dcd7896.png Project settings > Project settings > e584a9026e2b407f.pngAdd Firebase to your Web App (Paramètres du projet > Paramètres du projet > Ajouter Firebase à votre application Web) pour lancer le workflow de configuration.
  2. Si vous avez déjà ajouté une application à votre projet Firebase, cliquez sur Ajouter une application pour afficher les options de plate-forme.
  3. Saisissez un pseudo pour l'application, par exemple My web app, puis cliquez sur Enregistrer l'application.
  4. Dans la section Ajouter le SDK Firebase, sélectionnez Utiliser la balise <script>.
  5. Copiez les valeurs de l'objet firebasebaseConfig, puis collez-les dans le fichier camaerastream-start/public/webrtc_generator.js.
const firebaseConfig = {
  apiKey: "XXXXX",
  authDomain: "XXXXX",
  projectId: "XXXXX",
  storageBucket: "XXXXX",
  messagingSenderId: "XXXXX",
  appId: "XXXXX",
  measurementId: "XXXXX"
};
  1. Cliquez sur Accéder à la console pour terminer le processus. L'application Web que vous venez de créer s'affiche sur la page Paramètres du projet.

4. Créer une caméra WebRTC

Maintenant que vous avez configuré votre action, votre service cloud doit gérer les intents suivants:

  • Intent SYNC qui se produit lorsque l'Assistant souhaite connaître les appareils que l'utilisateur a connectés. Cet intent est envoyé à votre service lorsque l'utilisateur associe un compte. En réponse, vous devez fournir une charge utile JSON avec les appareils de l'utilisateur, ainsi que leurs fonctionnalités.
  • Intent EXECUTE/QUERY qui se produit lorsque l'Assistant souhaite contrôler un appareil pour le compte d'un utilisateur. En réponse, vous devez fournir une charge utile JSON avec le statut d'exécution de chaque appareil demandé.

Dans cette section, vous allez mettre à jour les fonctions que vous avez déployées précédemment pour gérer ces intents.

Mettre à jour la réponse SYNC

  1. Accédez au fichier functions/index.js. Il contient le code permettant de répondre aux requêtes de l'Assistant.
  2. Modifiez l'intent SYNC pour renvoyer les métadonnées et les fonctionnalités de l'appareil:

index.js

app.onSync((body) => {
return {
  requestId: body.requestId,
  payload: {
    agentUserId: USER_ID,
    devices: [{
      id: 'camera',
      type: 'action.devices.types.CAMERA',
      traits: [
        'action.devices.traits.OnOff',
        'action.devices.traits.CameraStream',
      ],
      name: {
        defaultNames: ['My WebRTC Camera'],
        name: 'Camera',
        nicknames: ['Camera'],
      },
      deviceInfo: {
        manufacturer: 'Acme Co',
        model: 'acme-camera',
        hwVersion: '1.0',
        swVersion: '1.0.1',
      },
      willReportState: false,
      attributes: {
        cameraStreamSupportedProtocols:['webrtc'],
        cameraStreamNeedAuthToken: true, 
        cameraStreamSupportsPreview: true
      },
    }],
  },
};
});
  1. USER_ID n'est pas défini dans le code. Ajoutez les éléments suivants sous const _ = require('underscore');:
// Hardcoded user ID
const USER_ID = '123';

Gérer l'intent EXECUTE

L'intent EXECUTE gère les commandes de mise à jour de l'état de l'appareil. La réponse renvoie le statut de chaque commande (SUCCESS, ERROR ou PENDING, par exemple) ainsi que le nouvel état de l'appareil.

Pour gérer un intent EXECUTE, modifiez-le afin qu'il renvoie le point de terminaison signaling du projet Firebase dans le fichier functions/index.js :EXECUTE

index.js

app.onExecute(async (body,headers) => {
  var array = headers.authorization.split(' ');
  var snapshot = await firebaseRef.ref('/userId/'+array[1]).once('value');
  var offerGenLocation = snapshot.val().type;
  const {requestId} = body;

  var result = {
    status: 'SUCCESS',
    states: {
      cameraStreamProtocol: 'webrtc',
      cameraStreamSignalingUrl:'https://us-central1-<project-id>.cloudfunctions.net/signaling?token='+array[1], // TODO: Add Firebase hosting URL
      cameraStreamIceServers: '',
      cameraStreamOffer:'',
      cameraStreamAuthToken:'',
    },
    ids: [ 
      'camera'
    ],
  };
  
  return {
    requestId: requestId,
    payload: {
      commands: [result],
    },
  };
});

Gérer le partage des ressources entre origines multiples (CORS)

Pour gérer le CORS en raison de l'utilisation de la méthode POST pour envoyer le SDP, ajoutez l'URL Firebase Hosting au tableau allowlist dans le fichier functions/index.js:

index.js

'use strict';
.....

var allowList = ['https://www.gstatic.com','https://<firebase-project-id>.web.app']; //TODO Add Firebase hosting URL.

Pour en savoir plus sur le CORS, consultez la page Partage des ressources entre origines multiples (CORS).

Gérer l'arrêt du flux

Pour gérer l'arrêt du flux WebRTC, ajoutez l'URL de la fonction de "signalisation" Firebase au fichier public/webrtc_generator.js:

webrtc_generator.js

terminateButton.onclick = function(){
  console.log('Terminating Stream!!')
  var signalingURL = 'https://us-central1-<project-id>.cloudfunctions.net/signaling'; //TODO Add Firebase hosting URL
   var http = new XMLHttpRequest();

Déployer sur Firebase

Pour déployer sur Firebase, déployez le traitement cloud mis à jour avec la CLI Firebase:

$ firebase deploy

Cette commande déploie une application Web et plusieurs fonctions Cloud Functions for Firebase:

...

✔ Deploy complete!

Project Console: https://console.firebase.google.com/project/<project-id>/overview
Hosting URL: https://<project-id>.web.app

Configurer votre projet dans la console du développeur

  1. Accédez à la console pour les développeurs.
  2. Cliquez sur Créer un projet, saisissez un nom pour le projet, puis cliquez sur Créer un projet.

Nommer le projet

Sélectionner l'intégration cloud à cloud

Sur la page Project Home (Accueil du projet) de la console du développeur, sélectionnez Add cloud-to-cloud integration (Ajouter une intégration cloud à cloud) sous Cloud-to-cloud (Cloud à cloud).

Ajouter une intégration cloud à cloud

  1. Saisissez un nom d'intégration, puis sélectionnez Caméra sous Type d'appareil. Ce nom s'affichera plus tard dans l'application Google Home lorsqu'un appareil devra être configuré. Pour cet atelier de programmation, nous avons saisi Atelier de programmation WebRTC comme nom à afficher, mais vous pouvez utiliser un autre nom.

Ajouter un nom à afficher

  1. Sous Identité visuelle de l'application, importez un fichier png pour l'icône de l'application, de taille 144 x 144 px et nommé .png.

Ajouter une icône d&#39;application

Activer l'association de comptes

Pour activer l'association de comptes après le déploiement de votre projet, procédez comme suit:

  1. Accédez à la console du développeur et ouvrez le projet.
  2. Dans la section Cloud à cloud, cliquez sur Développer > Modifier à côté de l'intégration.
  3. Sur la page Configuration et configuration, recherchez la section Association de comptes, puis saisissez les informations suivantes dans les champs de texte correspondants:

ID client

ABC123

Client secret (Code secret du client)

DEF456

Authorization URL (URL de l'autorisation)

https://us-central1-
.cloudfunctions.net/fakeauth

Token URL (URL du jeton)

https://us-central1-
.cloudfunctions.net/faketoken

Modifier les URL d&#39;association de comptes

  1. Cliquez sur Enregistrer > Tester.

5. Tester la caméra WebRTC virtuelle

  1. Accédez à l'URL d'hébergement qui s'affiche lorsque vous déployez votre projet Firebase. L'interface suivante s'affiche, qui est l'application cliente CameraStream:

Interface de l&#39;application cliente CameraStream

  1. Dans le panneau Résolution vidéo locale, sélectionnez la vidéo de votre choix.
  2. Autorisez l'application cliente CameraStream à accéder à votre webcam et à votre micro. Un flux vidéo de votre webcam s'affiche sur le client.
  1. Dans l'application Google Home, appuyez sur Ajouter > Fonctionne avec Google.

Page &quot;Configurer un appareil&quot; dans l&#39;application Google Home

  1. Recherchez l'action que vous avez créée, puis sélectionnez-la.

Action de maison connectée dans l&#39;application Google Home

  1. Notez le code alphanumérique unique à cinq caractères, car vous en aurez besoin plus tard.

Code alphanumérique unique à cinq chiffres

  1. Appuyez sur Revenir. La caméra WebRTC est ajoutée à votre structure dans l'application Google Home.

Lancer un flux WebRTC

  1. Sur la page Web de l'application cliente CameraStream, saisissez le code alphanumérique de la dernière section dans la zone de texte Valeur du jeton d'association de compte, puis cliquez sur Envoyer.

Zone de texte de la valeur du jeton d&#39;association de compte

  1. Pour démarrer une session WebRTC depuis votre écran connecté Google, procédez comme suit:
  • Dites "Hey Google, diffuse la caméra WebRTC".
  • Sur votre écran connecté Google, appuyez sur Contrôle de la maison > Caméra > Caméra WebRTC.

Dans l'application cliente CameraStream de la maison connectée Google, vous constatez que l'SPD d'offre et le SDP de réponse ont été générés et échangés avec succès. L'image de votre webcam est diffusée sur votre écran connecté Google avec WebRTC.

6. Félicitations

Félicitations ! Vous avez appris à diffuser du contenu depuis votre webcam vers un appareil à écran Google Nest à l'aide du protocole WebRTC.

En savoir plus