Implementowanie funkcji CameraStream za pomocą WebRTC

1. Zanim zaczniesz

Cecha CameraStream dotyczy urządzeń z możliwością strumieniowania plikó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 skrócić czas oczekiwania na uruchomienie i strumieniowanie transmisji z kamery na ekran urządzenia Google Nest.

Urządzenia z kamerami przesyłającymi dane na wyświetlacz 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.
  • Jak przesyłać strumieniowo treści na ekran Google Nest przy użyciu protokołu WebRTC.

Czego potrzebujesz

  • Przeglądarka, 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.
  • Kamera internetowa (wbudowana lub zewnętrzna), która obsługuje rozdzielczość Full HD.
  • ekran Google Nest;

2. Rozpocznij

Instalowanie interfejsu wiersza poleceń Firebase

Interfejs wiersza poleceń Firebase pozwala udostępniać aplikacje internetowe lokalnie i wdrażać je w Hostingu Firebase.

Aby zainstalować interfejs wiersza poleceń Firebase:

  1. W terminalu pobierz i zainstaluj interfejs wiersza poleceń Firebase:
$ npm install -g firebase-tools
  1. Sprawdź, czy interfejs wiersza poleceń został prawidłowo zainstalowany:
$ firebase --version
  1. Autoryzuj interfejs wiersza poleceń Firebase na swoim 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 nowego projektu w Konsoli Actions

  1. Na stronie Jakie działanie chcesz utworzyć? kliknij Inteligentny dom > Zacznij tworzyć. 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ę akcji i kliknij Zapisz. Ta nazwa pojawi się w aplikacji Google Home później, gdy będziesz mieć urządzenie do skonfigurowania. Na potrzeby tego ćwiczenia w programie jako wyświetlaną nazwę wpisz WebRTC Codelab, ale możesz użyć innej.

Panel wywołań w konsoli Actions

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

Uruchamianie aplikacji klienckiej CameraStream

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

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

  • Aby pobrać kod źródłowy na komputer, na którym pracujesz, kliknij ten przycisk:

  • 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 podstawie którego skompilujesz.
  • Katalog camerastream-done, który zawiera kod rozwiązania ukończonego ćwiczenia w Codelabs.

Katalog camerastream-start zawiera te podkatalogi:

  • Podkatalog public, który zawiera interfejs użytkownika do łatwego kontrolowania i monitorowania stanu kamery.
  • Podkatalog functions zawierający 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 komentarze TODO wskazujące, gdzie należy dodać lub zmienić kod. Przykład:

// TODO: Implement full SYNC response.

Łączenie Analytics z Firebase

  1. Przejdź do katalogu camerastream-start, a następnie skonfiguruj interfejs wiersza poleceń Firebase za pomocą projektu 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 zobaczysz poniższy komunikat, zignoruj go. To ostrzeżenie jest spowodowane 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 Functions (Funkcje) i Hosting. Spowoduje to zainicjowanie interfejsów API i funkcji niezbędnych 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 Cloud Functions za pomocą plików domyślnych 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, używając katalogu public w kodzie projektu i używając 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 komunikatów SDP to ważny krok w procesie tworzenia strumienia WebRTC. SDP to protokół tekstowy, który opisuje właściwości sesji multimedialnej. Jest 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 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 będzie hostowana baza danych.

Menu lokalizacji Bazy danych czasu rzeczywistego w oknie Skonfiguruj bazę danych

  1. Wybierz Rozpocznij w trybie testowym, a następnie kliknij Włącz. Przy włączonej Bazie 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 rozpocząć proces konfiguracji.
  2. Jeśli masz już aplikację dodaną do projektu Firebase, kliknij Dodaj aplikację, aby wyświetlić opcje platformy.
  3. Wpisz nazwę aplikacji, na przykład 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 i 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ć ten proces, kliknij Przejdź do konsoli. Nowo utworzoną aplikację internetową zobaczysz na stronie Ustawienia projektu.

4. Utwórz kamerę WebRTC

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

  • Intencja SYNC występująca, gdy Asystent chce się dowiedzieć, z jakimi urządzeniami użytkownik połączył dane. Jest ona wysyłana do usługi, gdy użytkownik połączy konto. W odpowiedzi musisz przesłać ładunek JSON zawierający urządzenia 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 musisz przesłać ładunek JSON zawierający stan wykonania każdego żądanego urządzenia.

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 on kod służący do odpowiadania na prośby Asystenta.
  2. Zmodyfikuj 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 służące do aktualizowania stanu urządzenia. Odpowiedź zwróci stan każdego polecenia, na przykład SUCCESS, ERROR lub PENDING, oraz nowy stan urządzenia.

  • Aby obsługiwać intencję EXECUTE, zmodyfikuj intencję EXECUTE tak, aby w pliku functions/index.js zwracała punkt końcowy signaling projektu Firebase:

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 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';

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 o CORS znajdziesz w artykule na temat współdzielenia zasobów między serwerami z różnych domen (CORS).

Obsługa zakończenia transmisji

  • Aby obsługiwać zamykanie strumienia WebRTC, dodaj „sygnalizowanie” Firebase adres URL funkcji 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();

Wdróż w Firebase

  • Aby przeprowadzić wdrożenie w Firebase, wdróż zaktualizowaną realizację w chmurze za pomocą interfejsu 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

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 te informacje w odpowiednich polach tekstowych:

Client-ID

ABC123

Tajny klucz klienta

DEF456

Adres 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 > Testuj.

5. Testowanie wirtualnej kamery WebRTC

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

Interfejs aplikacji klienckiej CameraStream

  1. W panelu Rozdzielczość filmu lokalnego wybierz odpowiedni film.
  2. Przyznaj aplikacji klienckiej CameraStream uprawnienia dostępu do kamery internetowej i mikrofonu. Na ekranie pojawi się obraz z 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 ją wybierz.

Działanie inteligentnego domu w aplikacji Google Home

  1. Zwróć uwagę na niepowtarzalny 5-znakowy kod alfanumeryczny, ponieważ będzie on potrzebny później.

Niepowtarzalny, pięciocyfrowy kod alfanumeryczny.

  1. Kliknij Przywróć. Kamera WebRTC jest dodana do Twojego domu w aplikacji Google Home.

Uruchamianie strumienia WebRTC

  1. Na stronie aplikacji klienckiej CameraStream wpisz kod alfanumeryczny z ostatniej sekcji w polu tekstowym Wartość tokena łączenia kont i 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, prześlij strumieniowo kamerę WebRTC”.
  • Na inteligentnym ekranie Google kliknij Sterowanie domem > Aparat > Kamera WebRTC.

W aplikacji klienckiej CameraStream Google Smart Home zobaczysz, że pola Offer SPD i Answer SDP zostały wygenerowane i wymienione. Obraz z kamery internetowej jest przesyłany strumieniowo na inteligentny ekran Google przy użyciu WebRTC.

6. Gratulacje

Gratulacje! Wiesz już, jak przesyłać strumieniowo obraz z kamery internetowej na ekran Google Nest przy użyciu protokołu WebRTC.

Więcej informacji