Implementowanie funkcji CameraStream za pomocą WebRTC

1. Zanim zaczniesz

Cechę CameraStream mają urządzenia, które mogą przesyłać strumieniowo obraz na inteligentne wyświetlacze, urządzenia Chromecast i smartfony. Protokół WebRTC jest teraz obsługiwany w ramach cechy CameraStream, co oznacza, że możesz znacznie skrócić czas uruchamiania i opóźnienie transmisji strumieniowej z kamery na wyświetlacz Google Nest.

Kamery przesyłające obraz na ekran Google Nest

Wymagania wstępne

Czego się nauczysz

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

Czego potrzebujesz

  • przeglądarka internetowa, np. Google Chrome;
  • Urządzenie z iOS lub Androidem z aplikacją Google Home.
  • Node.js w wersji 10.16 lub nowszej.
  • plan Blaze (płatność według wykorzystania) dla Firebase.
  • Wbudowana lub zewnętrzna kamera internetowa obsługująca rozdzielczość Full HD.
  • ekran Google Nest;

2. Rozpocznij

Instalowanie wiersza poleceń Firebase

Wiersz 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 wiersz poleceń Firebase:
$ npm install -g firebase-tools
  1. Sprawdź, czy interfejs CLI został prawidłowo zainstalowany:
$ firebase --version
  1. Autoryzuj wiersz poleceń Firebase za pomocą konta Google:
$ firebase login

Utwórz projekt

  1. Otwórz Konsolę programisty Google Home.
  2. Kliknij Utwórz projekt, wpisz nazwę projektu i kliknij Utwórz projekt.

Nadawanie nazwy projektu

Uruchamianie aplikacji klienckiej CameraStream

Kod źródłowy tego laboratorium obejmuje klienta WebRTC, który nawiązuje, negocjuje i zarządza sesją WebRTC między kamerą internetową a inteligentnym wyświetlaczem Google Home.

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

  • Aby pobrać kod źródłowy na komputer używany do programowania, kliknij ten przycisk:

  • Sklonuj 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 startowy, na którym będziesz pracować.
  • Katalog camerastream-done, który zawiera kod rozwiązania dla ukończonych ćwiczeń z programowania.

Katalog camerastream-start zawiera te podkatalogi:

  • Podkatalog public, który zawiera interfejs użytkownika do łatwego sterowania stanem kamery i jego monitorowania.
  • Podkatalog functions, który zawiera w pełni wdrożoną usługę w chmurze zarządzającą kamerą za pomocą Cloud Functions dla Firebase i Bazy danych czasu rzeczywistego.

Kod startowy zawiera TODO komentarze wskazujące, gdzie należy dodać lub zmienić kod, np. w tym przykładzie:

// TODO: Implement full SYNC response.

Dodawanie Firebase do projektu w konsoli programisty Google Home

Metoda 1. W konsoli Firebase

  1. Otwórz Firebase.
  2. Kliknij Utwórz projekt w Firebase.
    Utwórz projekt Firebase
  3. Na ekranie Utwórz projekt kliknij Dodaj Firebase do projektu Google Cloud.
    Dodawanie Firebase do projektu Google Cloud
  4. Na ekranie Rozpocznij wybierz projekt w chmurze Google, który został utworzony w konsoli Google Home Developer, a następnie kliknij Dalej.
    Wybierz projekt Google Cloud

Metoda 2. Za pomocą wiersza poleceń Firebase

firebase projects:addfirebase

Aby dodać Firebase, wybierz utworzony przed chwilą projekt w konsoli dewelopera Google Home.

Gdy dodasz Firebase do projektu w Konsoli dewelopera Google Home, pojawi się on w konsoli Firebase. Identyfikator projektu w Firebase będzie zgodny z identyfikatorem projektu w Konsoli dewelopera Google Home.

Dodano projekt w chmurze

Łączenie Analytics z Firebase

  1. Przejdź do katalogu camerastream-start, a następnie skonfiguruj wiersz poleceń Firebase w projekcie Akcji:
$ cd camerastream-start
$ firebase use <project-id>
  1. W katalogu camerastream-start otwórz folder functions, a następnie zainstaluj wszystkie niezbędne zależności:
$ cd functions
$ npm install
  1. Jeśli zobaczysz ten komunikat, zignoruj go. To ostrzeżenie jest spowodowane starszymi zależnościami. Więcej informacji znajdziesz w tym artykule na GitHubie.
found 5 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details
  1. Zainicjuj projekt w Firebase:
$ firebase init
  1. Wybierz FunkcjeHosting. Spowoduje to zainicjowanie niezbędnych interfejsów API i funkcji w projekcie.
? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter
 to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to
 proceed)
>( ) Data Connect: Set up a Firebase Data Connect service
 ( ) Firestore: Configure security rules and indexes files for Firestore
 ( ) Genkit: Setup a new Genkit project with Firebase
 (*) Functions: Configure a Cloud Functions directory and its files
 ( ) App Hosting: Configure an apphosting.yaml file for App Hosting
 (*) Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
 ( ) Storage: Configure a security rules file for Cloud Storage
 ( ) Emulators: Set up local emulators for Firebase products
 ( ) Remote Config: Configure a template file for Remote Config
 ( ) Extensions: Set up an empty Extensions manifest
 (*) Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision
default instance
 ( ) Data Connect: Set up a Firebase Data Connect service
 ( ) Firestore: Configure security rules and indexes files for Firestore
  1. Skonfiguruj Cloud Functions za pomocą domyślnych plików i upewnij się, że nie zastąpisz istniejących plików index.jspackage.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. Wymiana wiadomości protokołu SDP (Session Description Protocol)

Wymiana wiadomości SDP jest ważnym krokiem w procesie tworzenia strumienia WebRTC. SDP to protokół tekstowy, który opisuje charakterystykę sesji multimedialnej. Jest on używany w WebRTC 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ą CameraStream w inteligentnym domu, wykonaj te czynności:

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

strona Bazy danych czasu rzeczywistego w konsoli Firebase;

  1. W menu Lokalizacja Bazy danych czasu rzeczywistego wybierz odpowiednią lokalizację, w której będzie hostowana Twoja baza danych.

Menu Baza danych czasu rzeczywistego w oknie Konfigurowanie bazy danych

  1. Kliknij Uruchom w trybie testowym, a potem Włącz. Gdy Baza danych czasu rzeczywistego jest włączona, musisz mieć możliwość odwoływania się do niej z aplikacji klienckiej CameraStream.
  1. W konsoli Firebase kliknij 513f2be95dcd7896.png Ustawienia projektu > Ustawienia projektu > e584a9026e2b407f.pngDodaj Firebase do aplikacji internetowej, aby uruchomić proces konfiguracji.
  2. Jeśli aplikacja została już dodana do projektu w Firebase, 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 kliknij 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 utworzona aplikacja internetowa będzie widoczna na stronie Ustawienia projektu.

4. Tworzenie kamery WebRTC

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

  • SYNC zamiar, który występuje, gdy Asystent chce się dowiedzieć, jakie urządzenia są połączone z użytkownikiem; Jest on wysyłany do Twojej usługi, gdy użytkownik połączy konto. Odpowiedz ładunkiem JSON z informacjami o urządzeniach użytkownika i ich możliwościach.
  • EXECUTE/QUERY, która występuje, gdy Asystent chce sterować urządzeniem w imieniu użytkownika. Powinna zwrócić ładunek JSON ze stanem wykonania każdego żądanego urządzenia.

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

Aktualizowanie odpowiedzi SYNC

  1. Przejdź do pliku functions/index.js. Zawiera kod do odpowiadania na żądania Asystenta.
  2. Edytuj SYNC intencję, aby zwracać 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
      },
    }],
  },
};
});
  1. W kodzie nie zdefiniowano elementu USER_ID. W sekcji const _ = require('underscore'); dodaj te informacje:
// Hardcoded user ID
const USER_ID = '123';

Obsługa intencji EXECUTE

EXECUTEIntencja obsługuje polecenia aktualizowania stanu urządzenia. Odpowiedź zawiera stan każdego polecenia, np. SUCCESS, ERROR lub PENDING, oraz nowy stan urządzenia.

Aby obsłużyć intencję EXECUTE, zmień intencję EXECUTE, aby zwracała punkt końcowy signaling projektu w 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 współdzielenia zasobów pomiędzy serwerami z różnych domen (CORS)

Aby obsłużyć CORS z powodu użycia metody POST do wysyłania SDP, dodaj adres URL Hostingu Firebase do tablicy allowlist w pliku functions/index.js:

index.js

'use strict';
.....

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

Więcej informacji o CORS znajdziesz w artykule Współdzielenie zasobów pomiędzy serwerami z różnych domen (CORS).

Obsługa zakończenia strumienia

Aby obsługiwać zakończenie strumienia WebRTC, dodaj adres URL funkcji „sygnalizacja” Firebase do pliku public/webrtc_generator.js:

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

Wdrażanie w Firebase

Aby wdrożyć usługę w Firebase, wdróż zaktualizowaną usługę realizacji w chmurze za pomocą wiersza poleceń Firebase:

$ firebase deploy

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

...

✔ Deploy complete!

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

Konfigurowanie projektu w Konsoli programisty

  1. Otwórz Konsolę programisty.
  2. Kliknij Utwórz projekt, wpisz nazwę projektu i kliknij Utwórz projekt.

Nadawanie nazwy projektu

Wybierz integrację typu chmura-chmura

Na stronie Strona główna projektu w Konsoli Play w sekcji Cloud-to-cloud kliknij Add cloud-to-cloud integration (Dodaj integrację cloud-to-cloud).

Dodawanie integracji między chmurami

  1. Wpisz nazwę integracji i w sekcji Typ urządzenia wybierz Kamera. Ta nazwa pojawi się później w aplikacji Google Home, gdy będzie można skonfigurować urządzenie. W tym ćwiczeniu z programowania jako wyświetlaną nazwę wpisaliśmy WebRTC Codelab, ale możesz użyć innej nazwy.

Dodawanie wyświetlanej nazwy

  1. W sekcji Branding aplikacji prześlij plik png z ikoną aplikacji o rozmiarach 144 x 144 piksele i nazwie .png.

Dodawanie ikony aplikacji

Włączanie połączenia konta

Aby włączyć połączenie kont po wdrożeniu projektu:

  1. Otwórz Konsolę programisty i otwórz projekt.
  2. W sekcji Cloud-to-Cloud (Chmura do chmury) kliknij Programowanie > Edytuj obok integracji.
  3. Na stronie Konfiguracja znajdź sekcję Łączenie kont i w odpowiednich polach tekstowych wpisz te informacje:

Identyfikator klienta

ABC123

Tajny klucz klienta

DEF456

Adres URL autoryzacji

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

URL tokena

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

Aktualizowanie adresów URL połączenia kont

  1. Kliknij Zapisz > Testuj.

5. Testowanie wirtualnej kamery WebRTC

  1. Otwórz adres URL hostingu, który pojawił się podczas wdrażania projektu w Firebase. Pojawi się interfejs aplikacji klienckiej CameraStream:

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. Obraz z kamery internetowej pojawi się na urządzeniu klienta.
  1. W aplikacji Google Home kliknij Dodaj > Współpracuje z Google.

Strona Skonfiguruj urządzenie w aplikacji Google Home

  1. Wyszukaj utworzone działanie i wybierz je.

Działanie inteligentnego domu w aplikacji Google Home

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

Unikalny, 5-znakowy kod alfanumeryczny

  1. Kliknij Wróć. Kamera WebRTC zostanie dodana do Twojej struktury w aplikacji Google Home.

Rozpoczynanie strumienia WebRTC

  1. Na stronie aplikacji klienckiej CameraStream wpisz kod alfanumeryczny z ostatniej sekcji w polu tekstowym Wartość tokena łączenia kont, a następnie kliknij Prześlij.

Pole tekstowe Wartość tokena łączenia kont

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

W aplikacji klienckiej CameraStream Google Home zobaczysz, że oferta SDP i odpowiedź SDP zostały wygenerowane i wymienione. Obraz z kamery internetowej jest przesyłany strumieniowo do inteligentnego wyświetlacza Google za pomocą WebRTC.

6. Gratulacje

Gratulacje! Dowiedzieliśmy się, jak przesyłać strumieniowo obraz z kamery internetowej na ekran Google Nest za pomocą protokołu WebRTC.

Więcej informacji