CameraStream mit WebRTC implementieren

1. Hinweis

Die Eigenschaft „CameraStream“ gehört zu Geräten, die Videofeeds auf Smart Displays, Chromecast-Geräte und Smartphones streamen können. Das WebRTC-Protokoll wird jetzt in der Trait CameraStream unterstützt. Dadurch lässt sich die Start- und Streaminglatenz von einer Kamera zu einem Google Nest-Display deutlich reduzieren.

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

Voraussetzungen

Lerninhalte

  • So stellen Sie einen Smart-Home-Cloud-Dienst bereit.
  • Informationen zum Verbinden Ihres Dienstes mit Google Assistant
  • Über das WebRTC-Protokoll auf ein Google Nest-Display 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.
  • Ein integriertes oder externes Webcam-Gerät, das Full HD-Auflösung unterstützt.
  • Ein Google Nest-Display.

2. Mehr erfahren

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 wurde:
$ 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 auf Neues Projekt.
  2. Geben Sie im Textfeld Projektname einen Namen für das Projekt ein und klicken Sie dann auf Projekt erstellen.

Dialogfeld „Neues Projekt“ in der Actions Console

  1. Klicken Sie auf der Seite Welche Art von Aktion möchtest du erstellen? auf Smart Home > Jetzt erstellen. Das Projekt wird in der Actions Console geöffnet.

Tab „Übersicht“ in der Actions Console

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

Der Bereich „Aufruf“ in der Actions Console

  1. Klicken Sie auf Aktionen.
  2. Geben Sie im Textfeld URL für die Auftragsausführung 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, mit dem die WebRTC-Sitzung zwischen der Webcam und dem Smart-Home-Display von Google eingerichtet, aushandelt und verwaltet wird.

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 aufbauen.
  • Das Verzeichnis camerastream-done, das den Lösungscode für das abgeschlossene Codelab enthält.

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

  • Das Unterverzeichnis public, das eine Front-End-UI zum einfachen Steuern und Überwachen des Status der Kamera 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, wie im folgenden 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. Gehen Sie im Verzeichnis camerastream-start zum Ordner functions und installieren Sie dann alle erforderlichen Abhängigkeiten:
$ cd functions
$ npm install
  1. Sie können die folgende Meldung ignorieren. 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 Funktionen und Hosting aus. Dadurch werden die für Ihr Projekt erforderlichen APIs und Features 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 die im Projektbeispiel vorhandenen Dateien index.js und package.json nicht überschrieben werden:
? 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 index.html-Datei:
? 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 bei der Einrichtung eines WebRTC-Streams. SDP ist ein textbasiertes Protokoll, das die Eigenschaften einer Multimedia-Sitzung beschreibt. Er wird in WebRTC verwendet, um die Parameter einer Peer-to-Peer-Verbindung auszuhandeln, wie die verwendeten Codecs, die IP-Adressen der Teilnehmer und die für die Medienübertragung verwendeten Ports.

Gehen Sie folgendermaßen vor, um Realtime Database als Host für den Austausch von SDP-Nachrichten zwischen Ihrer Webcam und der CameraStream-Client-App für Smart Home zu verwenden:

  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 einen geeigneten Speicherort für Ihre Datenbank aus.

Das Drop-down-Menü „Speicherort der Realtime Database“ im Dialogfeld „Datenbank einrichten“

  1. Wählen Sie Im Testmodus starten aus und klicken Sie dann auf Aktivieren. Wenn die Realtime Database aktiviert ist, müssen Sie in der CameraStream-Client-App darauf zugreifen können.
  1. Wählen Sie in der Firebase Console Logo: 513f2be95dcd7896.png Projekteinstellungen > Projekteinstellungen > e584a9026e2b407f.pngFirebase zu meiner Web-App hinzufügen aus, 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 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. Sie sehen die neu erstellte Web-App auf der Seite Projekteinstellungen.

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. Sie wird an Ihren Dienst gesendet, wenn der Nutzer ein Konto verknüpft. Sie sollten mit einer JSON-Nutzlast antworten, die die Geräte des Nutzers und deren Funktionen enthält.
  • 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 für die Verarbeitung dieser Intents bereitgestellt haben.

SYNC-Antwort 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 Intent SYNC, 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 Intent EXECUTE verarbeitet Befehle zum Aktualisieren des Gerätestatus. In der Antwort werden der Status jedes Befehls, z. B. SUCCESS, ERROR oder PENDING, und der neue Gerätestatus zurückgegeben.

  • Um einen EXECUTE-Intent zu verarbeiten, bearbeiten Sie den EXECUTE-Intent so, dass der Endpunkt signaling des Firebase-Projekts in der Datei functions/index.js zurückgegeben wird:

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 Sie CORS aufgrund der POST-Methode zum Senden des SDP verarbeiten möchten, fügen Sie die Firebase Hosting-URL dem allowlist-Array in der functions/index.js-Datei 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).

Umgang mit Stream-Beendigung

  • Fügen Sie der Datei public/webrtc_generator.js die URL der Firebase-Signalisierungsfunktion hinzu, um die Beendigung von WebRTC-Streams zu verarbeiten:

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

  • Für die Bereitstellung in Firebase stellen Sie 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, nachdem Ihr Projekt bereitgestellt wurde:

  1. Wählen Sie in der Actions Console die Option Entwickeln > Kontoverknüpfung aus.
  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 „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. Daraufhin wird die folgende Schnittstelle angezeigt, bei der es sich um die CameraStream-Client-App handelt:

Benutzeroberfläche 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. Ein Videofeed Ihrer Webcam wird im Client angezeigt.
  1. Tippen Sie in der Google Home App auf Hinzufügen > Mit Geräten von Google kompatibel.

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

  1. Suche nach der von dir erstellten Aktion und wähle sie aus.

Die 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ück. Die WebRTC-Kamera wird Ihrem Gebäude in der Google Home App hinzugefügt.

WebRTC-Stream starten

  1. Geben Sie 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 klicken Sie dann auf Senden.

Das Textfeld „Wert des Kontoverknüpfungstokens“

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

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

6. Glückwunsch

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

Mehr dazu