CameraStream mit WebRTC implementieren

1. Hinweis

Der Trait „CameraStream“ gehört zu Geräten, die Videofeeds auf Smart Displays, Chromecast-Geräte und Smartphones streamen können. Das WebRTC-Protokoll wird jetzt unter dem Trait CameraStream unterstützt. Das bedeutet, dass Sie die Start- und Streaming-Latenz von einer Kamera zu einem Google Nest-Displaygerät erheblich reduzieren können.

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

Vorbereitung

Lerninhalte

  • Hier erfahren Sie, wie Sie einen Cloud-Dienst für das Smart Home bereitstellen.
  • So verbinden Sie Ihren Dienst mit Google Assistant.
  • Hier erfahren Sie, wie Sie mit dem WebRTC-Protokoll auf ein Google Nest-Displaygerät streamen.

Voraussetzungen

  • Ein Webbrowser, z. B. 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. Erste Schritte

Firebase CLI installieren

Mit Firebase CLI können Sie Ihre Web-Apps lokal bereitstellen und in Firebase Hosting bereitstellen.

So installieren Sie die Firebase CLI:

  1. Laden Sie in Ihrem Terminal die Firebase CLI 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

Actions-Projekt erstellen und konfigurieren

  1. Rufen Sie die Actions Console auf und klicken Sie dann auf Neues Projekt.
  2. Geben Sie im Textfeld Projektname einen Namen für das Projekt ein und klicken Sie dann auf Projekt erstellen.

Das Dialogfeld „Neues Projekt“ in der Actions Console

  1. Klicken Sie auf der Seite Welche Art von Aktion möchten Sie erstellen? auf Smart Home > Beginnen Sie mit der Entwicklung. Das Projekt wird in der Actions Console geöffnet.

Der Tab „Übersicht“ in der Actions Console

  1. Klicken Sie auf Develop > Aufruf.
  2. Geben Sie im Textfeld Anzeigename einen Namen für die Aktion ein und klicken Sie dann auf Speichern. Dieser Name erscheint später in der Google Home App, wenn ein Gerät eingerichtet werden muss. In diesem Codelab haben wir WebRTC Codelab als Anzeigenamen eingegeben. Sie können aber einen anderen Namen verwenden.

Der Aufrufbereich in der Actions Console

  1. Klicken Sie auf Aktionen.
  2. Geben Sie in das Textfeld Fulfillment URL (Auftragsausführungs-URL) eine Platzhalter-URL ein, z. B. https://example.com.

CameraStream-Client-App ausführen

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

Führen Sie einen der folgenden Schritte aus, um die CameraStream WebRTC-Client-App auszuführen:

  • Klicken Sie auf die folgende Schaltfläche, um den Quellcode auf Ihren 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 den Build ausführen.
  • 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, das eine Front-End-Benutzeroberfläche zur einfachen Steuerung und Überwachung des Kamerageräts enthält.
  • 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. Beispiel:

// TODO: Implement full SYNC response.

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 PROJECT_ID
  1. Wechseln Sie im Verzeichnis camerastream-start zum Ordner functions und installieren Sie dann alle erforderlichen Abhängigkeiten:
$ cd functions
$ npm install
  1. Wenn Sie die folgende Meldung sehen, ignorieren Sie sie. 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. Initialisieren Sie ein Firebase-Projekt:
$ firebase init
  1. Wählen Sie Functions 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, dass Sie die vorhandenen Dateien index.js und package.json im Projektbeispiel nicht ü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 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 (Exchange Session Description Protocol)

Der Austausch von SDP-Nachrichten ist ein wichtiger Schritt beim Einrichten eines WebRTC-Streams. SDP ist ein textbasiertes Protokoll, das die Merkmale einer Multimedia-Sitzung beschreibt. Er wird in WebRTC verwendet, um die Parameter einer Peer-to-Peer-Verbindung auszuhandeln, z. B. die verwendeten Codecs, die IP-Adressen der Teilnehmer und die Ports, die für die Medienübertragung verwendet werden.

So verwenden Sie Realtime Database als Host für den Austausch von SDP-Nachrichten zwischen Ihrer Webcam und der CameraStream-Client-App für Smart Homes:

  1. Klicken Sie in der Firebase Console auf Erstellen > Echtzeitdatenbank > Datenbank erstellen.

Die Seite „Echtzeitdatenbank“ in der Firebase Console

  1. Wählen Sie im Drop-down-Menü Speicherort der Echtzeitdatenbank den entsprechenden Speicherort für Ihre Datenbank aus.

Das Drop-down-Menü des Realtime Database-Standorts im Dialogfeld „Datenbank einrichten“

  1. Wählen Sie Im Testmodus starten aus und klicken Sie dann auf Aktivieren. Wenn Realtime Database aktiviert ist, müssen Sie in der CameraStream-Client-App darauf verweisen können.
  1. Wählen Sie in der Firebase Console 513f2be95dcd7896.png Projekteinstellungen > Projekteinstellungen > e584a9026e2b407f.pngFügen Sie Ihrer Web-App Firebase hinzu, um den Einrichtungsworkflow 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 Abschnitt Firebase SDK hinzufügen die Option <script> verwenden -Tag.
  5. Kopieren Sie die Werte aus dem Objekt firebasebaseConfig und fügen Sie sie dann 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. Sie sehen die neu erstellte Webanwendung auf der Seite Projekteinstellungen.

4. WebRTC-Kamera erstellen

Nachdem Sie die 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. Sie wird an Ihren Dienst gesendet, wenn der Nutzer ein Konto verknüpft. Sie sollten mit einer JSON-Nutzlast der Geräte des Nutzers und ihrer Funktionen 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 Verarbeiten dieser Intents bereitgestellt haben.

Antwort SYNC aktualisieren

  1. Rufen Sie die Datei functions/index.js auf. Sie enthält den Code zum Antworten auf Anfragen von Assistant.
  2. Bearbeiten Sie den 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
        },
      }],
    },
  };
});

Intent EXECUTE verarbeiten

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

  • Zum Verarbeiten eines EXECUTE-Intents bearbeiten Sie den EXECUTE-Intent, um den signaling-Endpunkt des Firebase-Projekts in der Datei functions/index.js zurückzugeben:

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],
    },
  };

Umgang mit Cross-Origin Resource Sharing (CORS)

  • Damit CORS aufgrund der Verwendung der Methode POST zum Senden des SDP verarbeitet wird, fügen Sie die Firebase Hosting-URL dem allowlist-Array in der Datei functions/index.js hinzu:

index.js

'use strict';

const functions = require('firebase-functions');
const {smarthome} = require('actions-on-google');
const {google} = require('googleapis');
const util = require('util');
const admin = require('firebase-admin');

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

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

Ablauf der Beendigung von Streams

  • Fügen Sie die Firebase-Signalisierung hinzu, um die Beendigung von WebRTC-Streams zu verarbeiten Funktions-URL zur Datei public/webrtc_generator.js 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

  • Stellen Sie zum Bereitstellen in Firebase die aktualisierte Cloud-Auftragsausführung mit der Firebase CLI bereit:
$ 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

Kontoverknüpfung aktivieren

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

  1. Wählen Sie in der Actions Console die Option Develop > aus. Kontoverknüpfung:
  2. Geben Sie im Abschnitt OAuth-Clientinformationen die folgenden Informationen in die entsprechenden Textfelder ein:

Client-ID

ABC123

Clientschlüssel

DEF456

Autorisierungs-URL

https://us-central1-{project-id}.cloudfunctions.net/fakeauth

Token-URL

https://us-central1-{project-id}.cloudfunctions.net/faketoken

Die Seite zur Kontoverknüpfung in der Actions Console

  1. Klicken Sie auf Speichern > Testen.

5. Virtuelle WebRTC-Kamera testen

  1. Rufen Sie die Hosting-URL auf, die Sie bei der Bereitstellung Ihres Firebase-Projekts gesehen haben. Sie sehen die folgende Benutzeroberfläche, also die CameraStream-Client-App:

Schnittstelle der CameraStream-Client-App

  1. Wähle im Bereich Lokale Videoauflösung das gewünschte Video aus.
  2. Erteile der CameraStream-Client-App die Berechtigung, auf deine Webcam und dein Mikrofon zuzugreifen. Auf dem Client wird ein Videofeed von Ihrer Webcam angezeigt.
  1. Tippen Sie in der Google Home App auf Hinzufügen > Kompatibel mit Google.

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

  1. Suchen Sie nach der von Ihnen erstellten Aktion 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.

Der eindeutige fünfstellige alphanumerische Code

  1. Tippen Sie auf Zurückkehren. 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 Wert des Kontoverknüpfungstokens ein und klicke dann auf Senden.

Textfeld für den Wert des Kontoverknüpfungstokens

  1. Führen Sie einen der folgenden Schritte aus, um auf Ihrem Smart Display von Google eine WebRTC-Sitzung zu starten:
  • Sagen Sie „Hey Google, streame WebRTC-Kamera“.
  • Tippen Sie auf Ihrem Smart Display von Google auf Smart-Home-Steuerung > Kamera > WebRTC-Kamera

In der CameraStream-Client-App für Smart-Home-Geräte von Google sehen Sie, dass das Angebots-SPD und das Antwort-SDP erfolgreich generiert und ausgetauscht wurden. Das Bild von Ihrer Webcam wird mit WebRTC auf Ihr Smart Display von Google gestreamt.

6. Glückwunsch

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

Weitere Informationen