Implementowanie funkcji CameraStream za pomocą WebRTC

1. Zanim zaczniesz

Cecha CameraStream należy do urządzeń z możliwością strumieniowania kanałów wideo na inteligentne ekrany, urządzenia Chromecast i smartfony. Protokół WebRTC jest teraz obsługiwany w ramach cechy CameraStream, co oznacza, że możesz znacznie zmniejszyć opóźnienia uruchamiania i strumieniowania z kamery na ekran Google Nest.

Strumieniowe przesyłanie danych z kamer na ekran Google Nest

Wymagania wstępne

Czego się nauczysz

  • Jak wdrożyć usługę w chmurze do inteligentnego domu.
  • Jak połączyć usługę z Asystentem Google.
  • Jak przesyłać strumieniowo treści na ekran Google Nest za pomocą protokołu WebRTC.

Czego potrzebujesz

  • Przeglądarka, na przykład Google Chrome.
  • urządzenie z iOS lub Androidem i aplikacją Google Home;
  • Node.js w wersji 10.16 lub nowszej.
  • Abonament Blaze (płatność według wykorzystania) na potrzeby Firebase.
  • Urządzenie z wbudowaną lub zewnętrzną kamerą internetową, które może obsługiwać rozdzielczość Full HD.
  • Wyświetlacz Google Nest.

2. Rozpocznij

Instalowanie interfejsu wiersza poleceń Firebase

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

Aby zainstalować interfejs wiersza 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ń został zainstalowany prawidłowo:
$ firebase --version
  1. Autoryzuj interfejs wiersza poleceń Firebase na koncie Google:
$ firebase login

Tworzenie i konfigurowanie projektu w Actions

  1. Otwórz Konsolę Actions, a potem kliknij 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 Jakie działanie chcesz utworzyć? kliknij Inteligentny dom > Rozpocznij tworzenie. Projekt otworzy się w Konsoli Actions.

Karta Przegląd w Konsoli Actions

  1. Kliknij Programowanie > Wywołanie.
  2. W polu tekstowym Wyświetlana nazwa wpisz nazwę działania i kliknij Zapisz. Ta nazwa pojawi się w aplikacji Google Home później, gdy będzie można skonfigurować urządzenie. Na potrzeby tych ćwiczeń w Codelabs podaliśmy nazwę WebRTC Codelab jako wyświetlaną nazwę, ale możesz użyć innej nazwy.

Panel Wywołanie w konsoli Actions

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

Uruchamianie aplikacji klienckiej CameraStream

Kod źródłowy tych ćwiczeń w Codelabs zawiera klienta WebRTC, który inicjuje i negocjuje sesję WebRTC między kamerą internetową a inteligentnym ekranem domowym Google.

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

  • Kliknij przycisk, aby pobrać kod źródłowy na swój komputer programistyczny:

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

Kod zawiera następujące katalogi:

  • Katalog camerastream-start zawierający kod startowy, na którym utworzysz kompilację.
  • Katalog camerastream-done, który zawiera kod rozwiązania z zakończonych ćwiczeń z programowania.

Katalog camerastream-start zawiera te podkatalogi:

  • Podkatalog public zawierający interfejs użytkownika, który ułatwia kontrolowanie i monitorowanie stanu kamery.
  • Podkatalog functions zawierający w pełni wdrożoną usługę w chmurze, która zarządza kamerą za pomocą Cloud Functions dla Firebase i Bazy danych czasu rzeczywistego.

Kod startowy zawiera komentarze TODO, które wskazują, gdzie należy dodać lub zmienić kod, jak w tym przykładzie:

// TODO: Implement full SYNC response.

Łączenie Analytics z Firebase

  1. Przejdź do katalogu camerastream-start, a następnie skonfiguruj interfejs wiersza poleceń Firebase w projekcie Actions:
$ cd camerastream-start
$ firebase use PROJECT_ID
  1. W katalogu camerastream-start przejdź do folderu functions, a następnie zainstaluj wszystkie wymagane zależności:
$ cd functions
$ npm install
  1. Jeśli zobaczysz ten komunikat, zignoruj go. To ostrzeżenie jest związane ze starszymi zależnościami. Więcej informacji znajdziesz w tym problemie na GitHubie.
found 5 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details
  1. Zainicjuj projekt Firebase:
$ firebase init
  1. Wybierz Funkcje i Hosting. Inicjuje to interfejsy API i funkcje niezbędne w projekcie.
? 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 pliki domyślne i upewnij się, że 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 przy użyciu 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 Opis Protocol)

Wymiana komunikatów SDP to ważny krok w procesie ustanowienia strumienia WebRTC. SDP to protokół tekstowy, który opisuje cechy sesji multimedialnej. Jest używany w WebRTC do negocjowania parametrów połączeń peer-to-peer, takich jak używane kodeki, adresy IP uczestników i porty używane do transportu multimediów.

Aby używać Bazy danych czasu rzeczywistego jako hosta do wymiany wiadomości SDP między kamerą internetową a aplikacją kliencką CameraStream w inteligentnym 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 czasu rzeczywistego wybierz odpowiednią lokalizację, z której chcesz hostować bazę danych.

Menu Lokalizacja bazy danych czasu rzeczywistego w oknie dialogowym Skonfiguruj bazę danych

  1. Wybierz Uruchom w trybie testowym, a następnie kliknij Włącz. Po włączeniu Bazy danych czasu rzeczywistego musisz mieć możliwość odwoływania się do niej w aplikacji klienckiej CameraStream.
  1. W konsoli Firebase wybierz 513f2be95dcd7896.png Ustawienia projektu > Ustawienia projektu > e584a9026e2b407f.pngDodaj Firebase do swojej aplikacji internetowej, aby rozpocząć proces konfiguracji.
  2. Jeśli aplikacja została już dodana do projektu Firebase, kliknij Dodaj aplikację, aby wyświetlić opcje platformy.
  3. Wpisz nazwę 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. Aby zakończyć proces, kliknij Przejdź do konsoli. Nowo utworzoną aplikację internetową zobaczysz na stronie Ustawienia projektu.

4. Utwórz kamerę WebRTC

Po skonfigurowaniu akcji usługa w chmurze musi obsługiwać te intencje:

  • Intencja SYNC, która występuje, gdy Asystent chce się dowiedzieć, z jakimi urządzeniami połączony jest użytkownik. Jest ona wysyłana do Twojej usługi, gdy użytkownik połączy konto. W odpowiedzi musisz przesłać ładunek JSON dotyczący urządzeń użytkownika i ich możliwości.
  • Intencja EXECUTE/QUERY, która występuje, gdy Asystent chce sterować urządzeniem w imieniu użytkownika. W odpowiedzi należy przesłać ładunek JSON zawierający informacje o stanie wykonania każdego żądanego urządzenia.

W tej sekcji zaktualizujesz funkcje wdrożone wcześniej na potrzeby tych intencji.

Zaktualizuj odpowiedź SYNC

  1. Przejdź do pliku functions/index.js. Zawiera kod odpowiadający na prośby od Asystenta.
  2. Edytuj intencję SYNC, aby zwracać metadane i funkcje 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 do aktualizowania stanu urządzenia. Odpowiedź zwraca stan każdego polecenia (na przykład SUCCESS, ERROR lub PENDING) oraz nowy stan urządzenia.

  • Aby obsłużyć intencję EXECUTE, zmodyfikuj intencję EXECUTE, która zwraca punkt końcowy 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 między domenami (CORS)

  • Aby obsługiwać CORS ze względu na użycie metody POST do wysyłania SDP, dodaj adres 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 na temat współdzielenia zasobów między serwerami (CORS).

Zakończ proces anulowania strumienia

  • Aby obsługiwać zakończenie strumienia WebRTC, dodaj do pliku public/webrtc_generator.js adres URL funkcji sygnalizacji 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ć w Firebase, wdróż zaktualizowaną realizację usług 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ć łączenie kont po wdrożeniu projektu, wykonaj te czynności:

  1. W Konsoli Actions kliknij Programowanie > Łączenie kont.
  2. W sekcji Informacje o kliencie OAuth wpisz następujące informacje w odpowiednich polach tekstowych:

Client-ID

ABC123

Tajny klucz klienta

DEF456

Adres URL autoryzacji

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

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 adres URL Hostingu widoczny podczas wdrażania projektu Firebase. Oto interfejs, który jest aplikacją kliencką CameraStream:

Interfejs aplikacji klienckiej CameraStream

  1. W panelu Lokalna rozdzielczość filmu wybierz odpowiedni film.
  2. Przyznaj aplikacji klienckiej CameraStream uprawnienia dostępu do kamery internetowej i mikrofonu. Na ekranie klienta pojawi się obraz z Twojej kamery internetowej.
  1. W aplikacji Google Home kliknij Dodaj > Obsługiwane przez Google.

Strona Skonfiguruj urządzenie w aplikacji Google Home

  1. Wyszukaj utworzoną przez siebie akcję i wybierz ją.

Działanie inteligentnego domu w aplikacji Google Home

  1. Zapisz ten niepowtarzalny 5-znakowy kod alfanumeryczny, ponieważ będzie Ci potrzebny później.

Niepowtarzalny, pięciocyfrowy kod alfanumeryczny

  1. Kliknij Wróć. Kamera WebRTC zostanie dodana do Twojego budynku w aplikacji Google Home.

Uruchamianie strumienia WebRTC

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

Pole tekstowe wartości tokena łączenia kont

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

W aplikacji klienckiej CameraStream Google inteligentnego domu udało się wygenerować i wymienić SPD oferty i odpowiedzi na żądanie. Obraz z kamery internetowej jest przesyłany strumieniowo na Twój inteligentny ekran Google przez WebRTC.

6. Gratulacje

Gratulacje! Wiesz już, jak przesyłać obraz z kamery internetowej na ekran Google Nest za pomocą protokołu WebRTC.

Więcej