CameraStream mit WebRTC implementieren

1. Hinweis

Das Attribut CameraStream bezieht sich auf Geräte, die Videofeeds auf Smart-Displays, Chromecast-Geräte und Smartphones streamen können. Das WebRTC-Protokoll wird jetzt im Attribut CameraStream unterstützt. Das bedeutet, dass du die Start- und Streaminglatenz von einem Kameragerät zu einem Google Nest-Displaygerät deutlich reduzieren kannst.

Kamerageräte, die auf ein Google Nest-Display-Gerät streamen

Vorbereitung

Lerninhalte

  • Informationen zum Bereitstellen eines Smart-Home-Cloud-Dienstes
  • So verknüpfen Sie Ihren Dienst mit Google Assistant.
  • So streamen Sie mit dem WebRTC-Protokoll auf ein Google Nest-Displaygerät.

Voraussetzungen

  • Einen Webbrowser wie Google Chrome
  • Ein iOS- oder Android-Gerät mit der Google Home App
  • Node.js Version 10.16 oder höher
  • Blaze-Tarif (Pay-as-you-go) für Firebase
  • Eine integrierte oder externe Webcam, die eine Full-HD-Auflösung unterstützt.
  • Ein Google Nest-Display

2. Jetzt starten

Firebase CLI installieren

Mit der Firebase CLI können Sie Ihre Webanwendungen lokal bereitstellen und in Firebase Hosting bereitstellen.

So installieren Sie die Firebase CLI:

  1. Laden Sie die Firebase CLI in Ihr Terminal herunter und installieren Sie sie:
$ npm install -g firebase-tools
  1. Prüfen Sie, ob die Befehlszeile korrekt installiert ist:
$ firebase --version
  1. Autorisieren Sie die Firebase CLI mit Ihrem Google-Konto:
$ firebase login

Projekt erstellen

  1. Rufen Sie die Google Home Developer Console auf.
  2. Klicken Sie auf Projekt erstellen, geben Sie einen Namen für das Projekt ein und klicken Sie auf Projekt erstellen.

Projekt benennen

Client-App „CameraStream“ ausführen

Der Quellcode für dieses Codelab enthält einen WebRTC-Client, der die WebRTC-Sitzung zwischen der Webcam und dem Google Smart-Home-Displaygerät herstellt, verhandelt und verwaltet.

So führen Sie die WebRTC-Client-App „CameraStream“ aus:

  • Klicke auf die folgende Schaltfläche, um den Quellcode auf deinen Entwicklungscomputer herunterzuladen:

  • Klonen Sie dieses GitHub-Repository:
    $ git clone https://github.com/google-home/smarthome-camerastream-webrtc.git
    

Der Code enthält die folgenden Verzeichnisse:

  • Das Verzeichnis camerastream-start, das den Startcode enthält, auf dem Sie aufbauen.
  • Das Verzeichnis camerastream-done, das den Lösungscode für das fertige Codelab enthält.

Das Verzeichnis camerastream-start enthält die folgenden Unterverzeichnisse:

  • Das Unterverzeichnis public enthält eine Benutzeroberfläche, mit der Sie den Status Ihres Kamerageräts ganz einfach steuern und überwachen können.
  • Das Unterverzeichnis functions, das einen vollständig implementierten Cloud-Dienst enthält, der die Kamera mit Cloud Functions for Firebase und Realtime Database verwaltet.

Der Startcode enthält TODO-Kommentare, die angeben, wo Sie Code hinzufügen oder ändern müssen. Hier ein Beispiel:

// TODO: Implement full SYNC response.

Firebase-Projekt erstellen

  1. Rufen Sie Firebase auf.
  2. Klicken Sie auf Projekt erstellen und geben Sie den Projektnamen ein.
  3. Klicken Sie auf das Kästchen für die Zustimmung und dann auf Weiter. Wenn kein Kästchen für die Vereinbarung vorhanden ist, können Sie diesen Schritt überspringen.
    Firebase-Projekt erstellen
  4. Suchen Sie nach der Projekt-ID Ihres Firebase-Projekts. Rufen Sie die Projektübersicht auf und klicken Sie auf das Symbol „Einstellungen“ > Projekteinstellungen.
    Projekteinstellungen öffnen
  5. Ihr Projekt wird auf dem Tab Allgemein aufgeführt.
    Allgemeine Projekteinstellungen

Mit Firebase verknüpfen

  1. Rufen Sie das Verzeichnis camerastream-start auf und richten Sie die Firebase CLI mit Ihrem Actions-Projekt ein:
$ cd camerastream-start
$ firebase use <firebase-project-id>
  1. Rufen Sie im Verzeichnis camerastream-start den Ordner functions auf und installieren Sie dann alle erforderlichen Abhängigkeiten:
$ cd functions
$ npm install
  1. Ignorieren Sie die folgende Meldung. Diese Warnung ist auf ältere Abhängigkeiten zurückzuführen. Weitere Informationen finden Sie in diesem GitHub-Problem.
found 5 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details
  1. Firebase-Projekt initialisieren:
$ firebase init
  1. Wählen Sie Functions (Funktionen) und Hosting aus. Dadurch werden die erforderlichen APIs und Funktionen für Ihr Projekt initialisiert.
? 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. Konfigurieren Sie Cloud Functions mit den Standarddateien und achten Sie darauf, die vorhandenen index.js- und package.json-Dateien im Projektbeispiel nicht zu überschreiben:
? 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. Konfigurieren Sie das Hosting mit dem Verzeichnis public im Projektcode und verwenden Sie die vorhandene Datei index.html:
? 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. SDP-Nachrichten (Session Description Protocol) austauschen

Der Austausch von SDP-Nachrichten ist ein wichtiger Schritt bei der Einrichtung eines WebRTC-Streams. SDP ist ein textbasiertes Protokoll, das die Merkmale einer Multimedia-Sitzung beschreibt. In WebRTC wird es verwendet, um die Parameter einer Peer-to-Peer-Verbindung auszuhandeln, z. B. die verwendeten Codecs, die IP-Adressen der Teilnehmer und die für den Medientransport verwendeten Ports.

So verwenden Sie die Realtime Database als Host, um SDP-Nachrichten zwischen Ihrer Webcam und der Smart-Home-Client-App „CameraStream“ auszutauschen:

  1. Klicken Sie in der Firebase Console auf Entwickeln > Realtime Database > Datenbank erstellen.

Die Seite „Realtime Database“ in der Firebase Console

  1. Wählen Sie im Drop-down-Menü Realtime Database location (Speicherort der Realtime Database) einen geeigneten Standort für das Hosting Ihrer Datenbank aus.

Im Dialogfeld „Datenbank einrichten“ im Drop-down-Menü „Realtime Database-Standort“

  1. Wählen Sie Im Testmodus starten aus und klicken Sie dann auf Aktivieren. Wenn Realtime Database aktiviert ist, müssen Sie darauf über die CameraStream-Client-App verweisen können.
  1. Wählen Sie in der Firebase Console 513f2be95dcd7896.png Projekteinstellungen > Projekteinstellungen > e584a9026e2b407f.pngFirebase zu Ihrer Webanwendung hinzufügen aus, um den Einrichtungsablauf zu starten.
  2. Wenn Sie Ihrem Firebase-Projekt bereits eine App hinzugefügt haben, klicken Sie auf App hinzufügen, um die Plattformoptionen aufzurufen.
  3. Geben Sie einen Alias für die App ein, z. B. My web app, und klicken Sie dann auf App registrieren.
  4. Wählen Sie im Bereich Firebase-SDK hinzufügen die Option <script>-Tag verwenden aus.
  5. Kopieren Sie die Werte aus dem firebasebaseConfig-Objekt und fügen Sie sie in die Datei camaerastream-start/public/webrtc_generator.js ein.
const firebaseConfig = {
  apiKey: "XXXXX",
  authDomain: "XXXXX",
  projectId: "XXXXX",
  storageBucket: "XXXXX",
  messagingSenderId: "XXXXX",
  appId: "XXXXX",
  measurementId: "XXXXX"
};
  1. Klicken Sie auf Weiter zur Konsole, um den Vorgang abzuschließen. Die neu erstellte Webanwendung wird auf der Seite Projekteinstellungen angezeigt.

4. WebRTC-Kamera erstellen

Nachdem Sie Ihre Aktion konfiguriert haben, muss Ihr Cloud-Dienst die folgenden Intents verarbeiten:

  • Ein SYNC-Intent, der auftritt, wenn Assistant wissen möchte, welche Geräte der Nutzer verbunden hat. Dieser wird an deinen Dienst gesendet, wenn der Nutzer ein Konto verknüpft. Sie sollten mit einer JSON-Nutzlast der Geräte und ihrer Funktionen des Nutzers antworten.
  • Ein EXECUTE/QUERY-Intent, der auftritt, wenn Assistant ein Gerät im Namen eines Nutzers steuern möchte. Sie sollten mit einer JSON-Nutzlast mit dem Ausführungsstatus jedes angeforderten Geräts antworten.

In diesem Abschnitt aktualisieren Sie die Funktionen, die Sie zuvor zum Bearbeiten dieser Intents bereitgestellt haben.

SYNC-Antwort aktualisieren

  1. Rufen Sie die Datei functions/index.js auf. Sie enthält den Code, mit dem auf Anfragen von Assistant geantwortet wird.
  2. Bearbeiten Sie die SYNC-Intent, um die Metadaten und Funktionen des Geräts zurückzugeben:

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 ist im Code nicht definiert. Fügen Sie unter const _ = require('underscore'); Folgendes hinzu:
// Hardcoded user ID
const USER_ID = '123';

Intent EXECUTE verarbeiten

Der Intent EXECUTE verarbeitet Befehle zum Aktualisieren des Gerätestatus. Die Antwort gibt den Status jedes Befehls zurück, z. B. SUCCESS, ERROR oder PENDING, sowie den neuen Gerätestatus.

Wenn Sie eine EXECUTE-Intent bearbeiten möchten, geben Sie in der Datei functions/index.js den signaling-Endpunkt des Firebase-Projekts zurück: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],
    },
  };
});

Cross-Origin Resource Sharing (CORS) verarbeiten

Wenn du CORS aufgrund der Verwendung der POST-Methode zum Senden des SDP handhaben möchtest, füge die Firebase Hosting-URL dem allowlist-Array in der functions/index.js-Datei hinzu:

index.js

'use strict';
.....

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

Weitere Informationen zu CORS finden Sie unter Cross-Origin Resource Sharing (CORS).

Stream beenden

Wenn du die Beendigung von WebRTC-Streams verarbeiten möchtest, füge der Datei public/webrtc_generator.js die URL der Firebase-Funktion „signaling“ hinzu:

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();

In Firebase bereitstellen

Wenn Sie die Cloud-Auftragsausführung in Firebase bereitstellen möchten, verwenden Sie dazu die Firebase CLI:

$ firebase deploy

Mit diesem Befehl werden eine Webanwendung und mehrere Cloud Functions for Firebase bereitgestellt:

...

✔ Deploy complete!

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

Developer Console-Projekt konfigurieren

  1. Rufen Sie die Developer Console auf.
  2. Klicken Sie auf Projekt erstellen, geben Sie einen Namen für das Projekt ein und klicken Sie auf Projekt erstellen.

Projekt benennen

Cloud-zu-Cloud-Integration auswählen

Wählen Sie in der Developer Console auf der Projektstartseite unter Cloud-zu-Cloud die Option Cloud-zu-Cloud-Integration hinzufügen aus.

Cloud-zu-Cloud-Integration hinzufügen

  1. Geben Sie einen Integrationsnamen ein und wählen Sie unter Gerätetyp die Option Kamera aus. Dieser Name wird später in der Google Home App angezeigt, wenn ein Gerät eingerichtet werden muss. Für dieses Codelab haben wir WebRTC Codelab als Anzeigenamen eingegeben. Sie können aber auch einen anderen Namen verwenden.

Anzeigenamen hinzufügen

  1. Laden Sie unter App-Branding eine png-Datei für das App-Symbol mit einer Größe von 144 × 144 Pixeln und dem Namen .png hoch.

App-Symbol hinzufügen

Kontoverknüpfung aktivieren

So aktivieren Sie die Kontoverknüpfung nach der Bereitstellung Ihres Projekts:

  1. Rufen Sie die Developer Console auf und öffnen Sie das Projekt.
  2. Klicken Sie im Bereich Cloud-zu-Cloud neben der Integration auf Entwickeln > Bearbeiten.
  3. Suchen Sie auf der Seite Einrichtung und Konfiguration den Bereich Kontoverknüpfung und geben Sie die folgenden Informationen in die entsprechenden Textfelder ein:

Client-ID

ABC123

Clientschlüssel

DEF456

Autorisierungs-URL

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

Token-URL

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

URLs für die Kontoverknüpfung aktualisieren

  1. Klicken Sie auf Speichern > Testen.

5. Virtuelle WebRTC-Kamera testen

  1. Rufen Sie die Hosting-URL auf, die Sie beim Bereitstellen Ihres Firebase-Projekts gesehen haben. Die folgende Benutzeroberfläche ist die Client-App von CameraStream:

Benutzeroberfläche der CameraStream-Client-App

  1. Wählen Sie im Bereich Lokale Videoauflösung das gewünschte Video aus.
  2. Gewähren Sie der CameraStream-Client-App Zugriff auf Ihre Webcam und Ihr Mikrofon. Auf dem Client wird ein Videofeed von Ihrer Webcam angezeigt.
  1. Tippen Sie in der Google Home App auf Hinzufügen > Mit Google kompatibel.

Die Seite „Gerät einrichten“ in der Google Home App

  1. Suchen Sie nach der Aktion, die Sie erstellt haben, und wählen Sie sie aus.

Smart-Home-Aktion in der Google Home App

  1. Notieren Sie sich den eindeutigen fünfstelligen alphanumerischen Code, da Sie ihn später benötigen.

den eindeutigen fünfstelligen alphanumerischen Code

  1. Tippen Sie auf Zurück. Die WebRTC-Kamera wird Ihrem Gebäude in der Google Home App hinzugefügt.

WebRTC-Stream starten

  1. Gib auf der Webseite für die CameraStream-Client-App den alphanumerischen Code aus dem letzten Abschnitt in das Textfeld Tokenwert für die Kontoverknüpfung ein und klicke dann auf Senden.

Textfeld für den Tokenwert der Kontoverknüpfung

  1. So starten Sie eine WebRTC-Sitzung auf Ihrem Google-Smart-Display:
  • Sagen Sie „Hey Google, streame die WebRTC-Kamera“.
  • Tippen Sie auf Ihrem Google-Smart-Display auf Smart-Home-Steuerung > Kamera > WebRTC-Kamera.

In der Google Smart Home CameraStream-Client-App sehen Sie, dass die Offer SPD und die Answer SDP erfolgreich generiert und ausgetauscht wurden. Das Bild von Ihrer Webcam wird mit WebRTC auf Ihr Google-Smart-Display gestreamt.

6. Glückwunsch

Glückwunsch! Sie haben gelernt, wie Sie mit dem WebRTC-Protokoll von Ihrer Webcam auf ein Google Nest-Display streamen.

Weitere Informationen