Implementowanie kamery przy użyciu WebRTC

1. Zanim zaczniesz

Atrybut CameraStream należy do urządzeń z możliwością odtwarzania kanałów wideo na inteligentnych ekranach, urządzeniach Chromecast i smartfonach. Protokół WebRTC jest teraz obsługiwany w ramach cechy CameraStream, co oznacza, że można znacznie skrócić czas uruchamiania i strumieniowego przesyłania danych z aparatu na urządzenie Google Nest.

Urządzenia z kamerą przesyłane strumieniowo na ekran wyświetlacza Google Nest

Wymagania wstępne

Czego się nauczysz

  • Jak wdrożyć usługę inteligentnego domu w chmurze.
  • Jak połączyć usługę z Asystentem Google
  • Przesyłanie strumieniowe na urządzenie wyświetlające Google Nest za pomocą protokołu WebRTC

Czego potrzebujesz

  • Przeglądarkę, na przykład Google Chrome.
  • urządzenie z iOS lub Androidem z aplikacją Google Home,
  • Node.js w wersji 10.16 lub nowszej.
  • Abonament Blaze (płatność według wykorzystania) w Firebase.
  • Wbudowane lub zewnętrzne urządzenie z kamerą internetową, które może obsługiwać rozdzielczość HD.
  • Ekran Google Nest.

2. Rozpocznij

Instalowanie wiersza poleceń Firebase

Interfejs wiersza poleceń Firebase umożliwia lokalne udostępnianie aplikacji internetowych i wdrażanie ich w Hostingu Firebase.

Aby zainstalować wiersz poleceń Firebase, wykonaj te czynności:

  1. W terminalu pobierz i zainstaluj interfejs wiersza poleceń Firebase:
$ npm install -g firebase-tools
  1. Sprawdź, czy interfejs wiersza poleceń jest poprawnie zainstalowany:
$ firebase --version
  1. Autoryzuj wiersz poleceń Firebase za pomocą konta Google:
$ firebase login

Tworzenie i konfigurowanie projektu w Actions

  1. Otwórz konsolę Actions i kliknij New project (Nowy projekt).
  2. W polu tekstowym Nazwa projektu wpisz nazwę projektu i kliknij Utwórz projekt.

Okno Nowy projekt w konsoli Actions

  1. Na stronie Jakiego działania chcesz utworzyć? kliknij Inteligentny dom > Rozpocznij tworzenie. Projekt zostanie otwarty w konsoli Actions.

Karta Przegląd w konsoli Actions

  1. Kliknij Develop > Wywołanie.
  2. W polu tekstowym Nazwa wyświetlana wpisz nazwę działania, a następnie kliknij Zapisz. Ta nazwa pojawi się w aplikacji Google Home, gdy będzie można skonfigurować urządzenie. Na potrzeby tego ćwiczenia jako nazwę wyświetlaną wpisaliśmy WebRTC Codelab, ale możesz użyć innej.

Panel Wywołania w konsoli Actions

  1. Kliknij Czynności.
  2. W polu tekstowym URL realizacji wpisz zastępczy adres URL, np. https://example.com.

Uruchamianie aplikacji klienckiej CameraStream

Kod źródłowy tego ćwiczenia z programowania obejmuje klienta WebRTC, który ustanawia i negocjuje sesję WebRTC oraz zarządza nią między kamerą internetową a inteligentnym inteligentnym ekranem Google.

Aby uruchomić aplikację kliencką WebRTC Streaming WebRTC, wykonaj jedną z tych czynności:

  • Kliknij ten przycisk, aby pobrać kod źródłowy do swojego komputera programisty:

  • Skopiuj to repozytorium GitHub:
$ git clone https://github.com/google-home/smarthome-camerastream-webrtc.git

Kod zawiera te katalogi:

  • Katalog camerastream-start, który zawiera kod początkowy, na którym tworzysz kompilację.
  • Katalog camerastream-done, który zawiera kod rozwiązania gotowego ćwiczenia z programowania.

Katalog camerastream-start zawiera te podkatalogi:

  • Podkatalog public zawierający interfejs frontendu umożliwiający łatwe sterowanie i monitorowanie stanu urządzenia kamery.
  • Podkatalog functions zawierający w pełni zaimplementowaną usługę chmurową, która zarządza kamerą z funkcjami Cloud Functions dla Firebase i Bazy danych czasu rzeczywistego.

Kod początkowy zawiera komentarze (TODO) wskazujące, gdzie trzeba dodać lub zmienić kod, na przykład taki:

// TODO: Implement full SYNC response.

Łączenie Analytics z Firebase

  1. Przejdź do katalogu camerastream-start, a potem skonfiguruj wiersz poleceń Firebase w projekcie Actions:
$ cd camerastream-start
$ firebase use PROJECT_ID
  1. W katalogu camerastream-start przejdź do folderu functions i zainstaluj wszystkie niezbędne zależności:
$ cd functions
$ npm install
  1. Jeśli widzisz ten komunikat, zignoruj go. To ostrzeżenie jest spowodowane starszymi zależnościami. Więcej informacji znajdziesz w artykule Ten problem na GitHubie.
found 5 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details
  1. Inicjowanie projektu Firebase:
$ firebase init
  1. Wybierz Funkcje i Hosting. Inicjuje niezbędne interfejsy API i funkcje dla Twojego projektu.
? 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. Skonfiguruj w Cloud Functions domyślne pliki i sprawdź, czy nie zastąpisz istniejących plików index.js i package.json w przykładowym projekcie:
? 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. Skonfiguruj Hosting za pomocą katalogu public w kodzie projektu i użyj istniejącego pliku 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. Komunikaty SDP (Exchange Session Description Protocol)

Wymiana wiadomości SDP jest ważnym krokiem podczas tworzenia strumienia WebRTC. SDP to protokół tekstowy opisujący cechy sesji multimedialnej. Służy on do negocjowania parametrów połączenia peer-to-peer, takich jak używane kodeki, adresy IP uczestników i porty używane do przesyłania multimediów.

Aby używać Bazy danych czasu rzeczywistego jako hosta do wymiany wiadomości SDP między kamerą internetową a aplikacją kliencką inteligentnego domu, wykonaj te czynności:

  1. W konsoli Firebase kliknij Kompilacja > Baza danych czasu rzeczywistego > Utwórz bazę danych.

Strona Baza danych czasu rzeczywistego w konsoli Firebase

  1. W menu Lokalizacja bazy danych w czasie rzeczywistym wybierz odpowiednią lokalizację, z której chcesz przechowywać bazę danych.

Menu rozwijane Baza danych czasu rzeczywistego w oknie Skonfiguruj bazę danych

  1. Kliknij kolejno Uruchom w trybie testowym i Włącz. Po włączeniu Bazy danych czasu rzeczywistego musisz mieć możliwość odwoływania się do niej z aplikacji klienckiej CameraStream.
  1. W konsoli Firebase wybierz 513f2be95dcd7896.png Ustawienia projektu > Ustawienia projektu > e584a9026e2b407f.pngDodaj Firebase do swojej aplikacji internetowej, aby uruchomić proces konfiguracji.
  2. Jeśli w projekcie Firebase masz już dodaną aplikację, kliknij Dodaj aplikację, aby wyświetlić opcje platformy.
  3. Wpisz pseudonim aplikacji, np. My web app, a potem kliknij Zarejestruj aplikację.
  4. W sekcji Dodaj pakiet SDK Firebase wybierz Użyj tagu <script>.
  5. Skopiuj wartości z obiektu firebasebaseConfig, a następnie wklej je do pliku camaerastream-start/public/webrtc_generator.js.
const firebaseConfig = {
  apiKey: "XXXXX",
  authDomain: "XXXXX",
  projectId: "XXXXX",
  storageBucket: "XXXXX",
  messagingSenderId: "XXXXX",
  appId: "XXXXX",
  measurementId: "XXXXX"
};
  1. Kliknij Przejdź do konsoli, aby zakończyć proces. Nowo utworzoną aplikację internetową zobaczysz na stronie Ustawienia projektu.

4. Tworzenie kamery WebRTC

Po skonfigurowaniu działania, usługa w chmurze musi obsługiwać te intencje:

  • Intencja SYNC, która występuje, gdy Asystent chce wiedzieć, z jakimi urządzeniami połączył się użytkownik. Ta opcja jest wysyłana do usługi, gdy użytkownik połączy konto. W odpowiedzi podaj ładunek JSON z informacjami o urządzeniach użytkownika i ich możliwościach.
  • Intencja EXECUTE/QUERY, która występuje, gdy Asystent chce sterować urządzeniem w imieniu użytkownika. Otrzymasz odpowiedź z ładunkiem JSON zawierającym stan wykonania każdego żądanego urządzenia.

W tej sekcji zaktualizujesz funkcje, które wcześniej zostały wdrożone w celu obsługi tych intencji.

Zaktualizuj odpowiedź SYNC

  1. Przejdź do pliku functions/index.js. Zawiera kod służący do odpowiadania na prośby Asystenta.
  2. Edytuj intencję SYNC, aby zwrócić metadane i możliwości urządzenia:

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

Obsługa intencji EXECUTE

Intencja EXECUTE obsługuje polecenia aktualizowania stanu urządzenia. Odpowiedź zwraca stan każdego polecenia, na przykład SUCCESS, ERROR lub PENDING, a także nowy stan urządzenia.

  • Aby obsłużyć intencję EXECUTE, zmień intencję EXECUTE w celu zwrócenia punktu końcowego signaling projektu Firebase w pliku functions/index.js:

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

Obsługa udostępniania zasobów z innych domen (CORS)

  • Aby obsługiwać CORS ze względu na użycie metody POST do wysyłania SDP, dodaj URL Hostingu Firebase do tablicy allowlist w pliku functions/index.js:

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.

Więcej informacji na temat CORS znajdziesz w artykule CORS.

Zakończenie transmisji

  • Aby obsługiwać zamykanie strumienia WebRTC, dodaj do pliku public/webrtc_generator.js adres URL funkcji „sygnału” Firebase:

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

Wdróż w Firebase

  • Aby wdrożyć Firebase w Firebase, wdróż zaktualizowaną realizację w chmurze za pomocą interfejsu wiersza poleceń Firebase:
$ firebase deploy

To polecenie wdraża aplikację internetową i kilka funkcji Cloud Functions dla Firebase:

...

✔ Deploy complete!

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

Włącz łączenie kont

Aby włączyć wdrożenie konta po wdrożeniu projektu, wykonaj te czynności:

  1. W konsoli Actions wybierz Programowanie > Łączenie kont.
  2. W sekcji Informacje o kliencie OAuth wpisz te informacje w odpowiednich polach tekstowych:

Client-ID

ABC123

Tajny klucz klienta

DEF456

URL autoryzacji

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

Adres URL tokena

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

Strona łączenia kont w Konsoli Actions

  1. Kliknij Zapisz > Test.

5. Testowanie wirtualnej kamery WebRTC

  1. Otwórz URL Hostingu wyświetlany podczas wdrażania projektu Firebase. Zobaczysz ten interfejs, który jest aplikacją kliencką Aparatu:

Interfejs aplikacji klienckiej CameraStream

  1. W panelu Lokalna rozdzielczość wideo wybierz odpowiedni film.
  2. Przyznaj aplikacji klienckiej CameraStream dostęp do kamery internetowej i mikrofonu. Kanał wideo z kamery internetowej wyświetli się klientowi.
  1. W aplikacji Google Home kliknij Dodaj > Współpracuje z Google.

Strona Skonfiguruj urządzenie w aplikacji Google Home

  1. Wyszukaj utworzone działanie, a potem je wybierz.

Działanie inteligentnego domu w aplikacji Google Home

  1. Zanotuj unikalny pięcioznakowy kod alfanumeryczny, ponieważ będzie potrzebny później.

Unikalny pięciocyfrowy kod alfanumeryczny

  1. Kliknij Przenieś. Kamera WebRTC zostanie dodana do struktury w aplikacji Google Home.

Rozpoczynanie strumienia WebRTC

  1. Na stronie internetowej aplikacji klienckiej CameraStream wpisz kod alfanumeryczny z ostatniej sekcji w polu tekstowym Wartość tokena połączenia konta i kliknij Prześlij.

Pole tekstowe wartości tokena połączenia konta

  1. Aby rozpocząć sesję WebRTC na inteligentnym ekranie Google, wykonaj jedną z tych czynności:
  • Powiedz „OK Google, odtwarzam kamerę WebRTC”.
  • Na inteligentnym ekranie Google kliknij Sterowanie domem > Aparat > Aparat WebRTC.

W aplikacji klienckiej inteligentnego kamery Google Home widzisz, że karta SPD i odpowiedź SDP Oferta została wygenerowana i wymieniona. Obraz z kamery internetowej jest przesyłany strumieniowo na Twoje inteligentne urządzenie Google z WebRTC.

6. Gratulacje

Gratulacje! Nauczyłeś się, jak przesyłać obraz z kamery internetowej na urządzenie wyświetlające Google Nest za pomocą protokołu WebRTC.

Więcej informacji