Implementowanie funkcji CameraStream za pomocą WebRTC

1. Zanim zaczniesz

Właściwość CameraStream należy do urządzeń z możliwością strumieniowego przesyłania filmów na inteligentne wyświetlacze, urządzenia Chromecast i smartfony. Protokół WebRTC jest teraz obsługiwany w atrybucie CameraStream, co oznacza, że możesz znacznie skrócić czas uruchamiania i opóźnienia strumieniowego przesyłania danych z urządzenia z kamerą na wyświetlacz Google Nest.

Urządzenia z kamerą przesyłające strumieniowo treści na wyświetlacze 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 treści 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.
  • Abonament Blaze (opłaty według wykorzystania) w 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 udostępnianie aplikacji internetowych lokalnie i wdrażanie ich w Hostingu Firebase.

Aby zainstalować wiersz poleceń Firebase:

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

Utwórz projekt

  1. Otwórz konsolę programistów Google Home.
  2. Kliknij Utwórz projekt, wpisz nazwę projektu i kliknij Utwórz projekt.

Nazwa projektu

Uruchamianie aplikacji klienckiej CameraStream

Kod źródłowy tego ćwiczenia zawiera klienta WebRTC, który nawiązuje, negocjuje i zarządza sesją WebRTC między kamerą internetową a urządzeniem wyświetlającym Google Home.

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

  • Aby pobrać kod źródłowy na komputer programisty, 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 podstawie którego kompilujesz aplikację.
  • Katalog camerastream-done, który zawiera kod rozwiązania dla ukończonego ćwiczenia z programowania.

Katalog camerastream-start zawiera te katalogi podrzędne:

  • Podkatalog public, który zawiera interfejs użytkownika umożliwiający łatwe sterowanie kamerą i monitorowanie jej stanu.
  • Podkatalog functions, który zawiera w pełni zaimplementowaną usługę w chmurze zarządzającą 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, np.

// TODO: Implement full SYNC response.

Tworzenie projektu Firebase

  1. Otwórz Firebase.
  2. Kliknij Utwórz projekt i wpisz nazwę projektu.
  3. Zaznacz pole wyboru akceptacji i kliknij Dalej. Jeśli nie ma pola wyboru dotyczącego umowy, możesz pominąć ten krok.
    Utwórz projekt Firebase
  4. Po utworzeniu projektu Firebase odszukaj jego identyfikator. Kliknij Przegląd projektu, a potem ikonę ustawień > Ustawienia projektu.
    Otwieranie ustawień projektu
  5. Twój projekt jest widoczny na karcie Ogólne.
    Ogólne ustawienia projektu

Łączenie Analytics z Firebase

  1. Otwórz katalog camerastream-start i skonfiguruj wiersz poleceń Firebase w projekcie Actions:
$ cd camerastream-start
$ firebase use <firebase-project-id>
  1. W katalogu camerastream-start otwórz folder functions i 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 wątku 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. Spowoduje to zainicjowanie niezbędnych interfejsów API i funkcji 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 Cloud Functions za pomocą plików domyślnych i upewnij się, że nie nadpiszesz istniejących plików index.jspackage.json w próbnym 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. Wiadomości protokołu SDP (Session Description Protocol)

Wymiana wiadomości SDP jest ważnym krokiem w ustanowieniu strumienia WebRTC. SDP to protokół tekstowy opisujący cechy sesji multimedialnej. Jest on używany w WebRTC do negocjowania parametrów połączenia typu 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 w czasie rzeczywistym jako hosta do wymiany wiadomości SDP między kamerą internetową a aplikacją klienta CameraStream w inteligentnym domu, wykonaj te czynności:

  1. W konsoli Firebase kliknij Kompiluj > Firebase Realtime Database > 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 chcesz hostować bazę danych.

Menu lokalizacji Bazy danych czasu rzeczywistego w oknie Konfigurowanie bazy danych

  1. Kliknij kolejno Rozpocznij w trybie testowymWłącz. Aby korzystać z Bazy danych czasu rzeczywistego, musisz mieć możliwość odwołania się do niej z aplikacji klienta CameraStream.
  1. Aby rozpocząć proces konfiguracji, w konsoli Firebase kliknij 513f2be95dcd7896.png Ustawienia projektu > Ustawienia projektu > e584a9026e2b407f.pngDodaj Firebase do aplikacji internetowej.
  2. Jeśli aplikacja została już dodana do projektu Firebase, kliknij Dodaj aplikację, aby wyświetlić opcje platformy.
  3. Wpisz pseudonim aplikacji, np. My web app, a następnie 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 Dalej w konsoli. Nowo utworzona aplikacja internetowa jest widoczna na stronie Ustawienia projektu.

4. Tworzenie kamery WebRTC

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

  • SYNCintencja, która występuje, gdy Asystent chce wiedzieć, jakie urządzenia są połączone z użytkownikiem; Jest on wysyłany do Twojej usługi, gdy użytkownik połączy konto. W odpowiedzi należy podać ładunek JSON z danymi o urządzeniach użytkownika i ich możliwościach.
  • Intencje EXECUTE/QUERY, które występują, gdy Asystent chce kontrolować urządzenie w imieniu użytkownika. W odpowiedzi należy podać treść w formacie JSON z informacjami o stanie wykonania na każdym z wybranych urządzeń.

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

Zaktualizuj odpowiedź SYNC

  1. Przejdź do pliku functions/index.js. Zawiera kod, który odpowiada na żądania Asystenta.
  2. Aby zwrócić metadane i możliwości urządzenia, zmodyfikuj intencję SYNC:

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łaściwość USER_ID nie jest zdefiniowana w kodzie. W sekcji const _ = require('underscore'); dodaj te informacje:
// Hardcoded user ID
const USER_ID = '123';

Obsługa zamiaru EXECUTE

Intencją EXECUTE zarządza poleceniami 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, aby zwracała 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 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://<firebase-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).

Zakończ transmisję

Aby obsłużyć zakończenie strumienia WebRTC, dodaj do pliku public/webrtc_generator.js adres URL funkcji „signaling” 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();

Wdrażanie w Firebase

Aby wdrożyć usługę w Firebase, użyj zaktualizowanego narzędzia do przetwarzania w chmurze w wierszu 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

Konfigurowanie projektu w Konsoli programisty

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

Nazwa projektu

Wybierz integrację chmur

W sekcji Cloud-to-cloud (Między chmurami) na stronie Project Home (Strona projektu) w Konsoli programisty kliknij Add cloud-to-cloud integration (Dodaj integrację między chmurami).

Dodawanie integracji między chmurami

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

Dodawanie wyświetlanej nazwy

  1. W sekcji Marka aplikacji prześlij plik png ikony aplikacji o rozmiarze 144 × 144 pikseli i nazwie .png.

Dodawanie ikony aplikacji

Włączanie połączenia kont

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

  1. Otwórz Konsolę dewelopera i otwórz projekt.
  2. W sekcji Z chmury do chmury obok integracji kliknij Opracuj > Edytuj.
  3. Na stronie Ustawienia i konfiguracja odszukaj 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

Adres URL tokena

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

Aktualizacja adresów URL służących do łączenia kont

  1. Kliknij Zapisz > Test.

5. Testowanie wirtualnej kamery WebRTC

  1. Otwórz adres URL hostingu, który został wyświetlony podczas wdrażania projektu Firebase. Zobaczysz ten interfejs aplikacji klienta CameraStream:

Interfejs aplikacji klienta CameraStream

  1. W panelu Lokalna rozdzielczość wideo wybierz odpowiedni film.
  2. Przyznaj aplikacji klienta CameraStream uprawnienia do dostępu do kamery internetowej i mikrofonu. Na kliencie pojawia się obraz z Twojej kamery internetowej.
  1. W aplikacji Google Home kliknij Dodaj > Współpracuje z Google.

Strona Konfigurowanie urządzenia w aplikacji Google Home

  1. Wyszukaj utworzone przez siebie działanie i je wybierz.

Akcja inteligentnego domu w aplikacji Google Home

  1. Zapamiętaj ten 5-znakowy kod alfanumeryczny, bo będzie Ci potrzebny później.

Unikalny, 5-cyfrowy kod alfanumeryczny

  1. Kliknij Wróć do poprzedniego menu. Kamera WebRTC jest dodawana do Twojej struktury w aplikacji Google Home.

Rozpoczęcie strumienia WebRTC

  1. Na stronie internetowej aplikacji klienta CameraStream wpisz kod alfanumeryczny z ostatniej sekcji w polu tekstowym Wartość tokenu do łą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, strumieniuj kamerę WebRTC”.
  • Na inteligentnym ekranie Google kliknij Sterowanie domem > Kamera > Kamera WebRTC.

W aplikacji klienta CameraStream w inteligentnym domu Google widać, że parametry Offer SPD i Answer SDP zostały wygenerowane i wymienne. Obraz z Twojej kamery internetowej jest przesyłany na urządzenie Google Smart Display za pomocą WebRTC.

6. Gratulacje

Gratulacje! Dowiedz się, jak prowadzić transmisję z kamery internetowej na ekran Google Nest za pomocą protokołu WebRTC.

Więcej informacji