Реализация CameraStream с помощью WebRTC

1. Прежде чем начать

Компонент CameraStream предназначен для устройств, способных передавать видеопоток на умные дисплеи, устройства Chromecast и смартфоны. Теперь в компоненте CameraStream поддерживается протокол WebRTC, что позволяет значительно сократить задержку запуска и потоковой передачи с камеры на дисплей Google Nest.

Камеры передают видеопоток на дисплей Google Nest.

Предварительные требования

Что вы узнаете

  • Как развернуть облачный сервис для умного дома.
  • Как подключить ваш сервис к Google Ассистенту.
  • Как осуществлять потоковую передачу на дисплей Google Nest с использованием протокола WebRTC.

Что вам понадобится

  • Веб-браузер, например, Google Chrome .
  • Устройство на базе iOS или Android с установленным приложением Google Home .
  • Node.js версии 10.16 или выше.
  • Тарифный план Blaze (с оплатой по факту использования) для Firebase .
  • Встроенная или внешняя веб-камера, поддерживающая разрешение Full HD.
  • Устройство отображения Google Nest.

2. Начните

Установите Firebase CLI.

Firebase CLI позволяет запускать веб-приложения локально и развертывать их на Firebase Hosting.

Для установки Firebase CLI выполните следующие действия:

  1. В терминале загрузите и установите Firebase CLI:
$ npm install -g firebase-tools
  1. Убедитесь, что интерфейс командной строки установлен правильно:
$ firebase --version
  1. Авторизуйте Firebase CLI с помощью своей учетной записи Google:
$ firebase login

Создать проект

  1. Перейдите в консоль разработчика Google Home .
  2. Нажмите «Создать проект» , введите название проекта и нажмите «Создать проект» .

Название проекта

Запустите клиентское приложение CameraStream.

Исходный код для этой практической работы включает в себя WebRTC-клиент, который устанавливает, согласовывает и управляет сеансом WebRTC между веб-камерой и устройством умного дома Google.

Для запуска клиентского приложения CameraStream WebRTC выполните одно из следующих действий:

  • Нажмите на следующую кнопку, чтобы загрузить исходный код на свой компьютер для разработки:

  • Клонируйте этот репозиторий GitHub:
    $ git clone https://github.com/google-home/smarthome-camerastream-webrtc.git
    

Код содержит следующие директории:

  • Каталог camerastream-start содержит стартовый код, на основе которого выполняется сборка.
  • Каталог camerastream-done содержит код решения для завершенной лабораторной работы.

Каталог camerastream-start содержит следующие подкаталоги:

  • Подкаталог public содержит пользовательский интерфейс для удобного управления и мониторинга состояния вашего фотоустройства.
  • Подкаталог functions содержит полностью реализованный облачный сервис, управляющий камерой с помощью Cloud Functions for Firebase и Realtime Database.

В начальном коде содержатся комментарии TODO , указывающие, где необходимо добавить или изменить код, как, например, в следующем примере:

// TODO: Implement full SYNC response.

Добавьте Firebase в свой проект в консоли разработчика Google Home.

Способ 1: Через консоль Firebase

  1. Перейдите на сайт Firebase .
  2. Нажмите «Создать проект Firebase» .
    Создать проект Firebase
  3. На экране «Создать проект» нажмите «Добавить проект Firebase в Google Cloud» .
    Добавить Firebase в проект Google Cloud
  4. На экране «Начало работы» выберите проект Google Cloud, который вы только что создали в консоли разработчика Google Home, а затем нажмите «Продолжить» .
    Выберите проект Google Cloud

Метод 2: Через интерфейс командной строки Firebase

firebase projects:addfirebase

Выберите проект Google Home Developer Console, который вы только что создали, чтобы добавить Firebase.

После добавления Firebase в ваш проект в консоли разработчика Google Home, он отобразится в консоли Firebase. Идентификатор проекта Firebase будет совпадать с идентификатором вашего проекта в консоли разработчика Google Home.

Добавлен облачный проект.

Подключитесь к Firebase

  1. Перейдите в каталог camerastream-start и настройте Firebase CLI для вашего проекта Actions:
$ cd camerastream-start
$ firebase use <project-id>
  1. В каталоге camerastream-start перейдите в папку functions и установите все необходимые зависимости:
$ cd functions
$ npm install
  1. Если вы видите следующее сообщение, проигнорируйте его. Это предупреждение связано со старыми зависимостями. Для получения дополнительной информации см. эту проблему на GitHub .
found 5 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details
  1. Инициализация проекта Firebase:
$ firebase init
  1. Выберите «Функции и хостинг» . Это инициализирует необходимые API и возможности для вашего проекта.
? 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. Настройте Cloud Functions, используя файлы по умолчанию, и убедитесь, что вы не перезаписываете существующие файлы index.js и package.json в примере проекта:
? 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. Настройте хостинг, указав в коде проекта директорию public , и используйте существующий файл 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. Обмен сообщениями протокола описания сеанса (SDP)

Обмен сообщениями SDP является важным шагом в установлении потока WebRTC. SDP — это текстовый протокол, описывающий характеристики мультимедийной сессии. Он используется в WebRTC для согласования параметров однорангового соединения, таких как используемые кодеки, IP-адреса участников и порты, используемые для передачи мультимедиа.

Чтобы использовать базу данных Realtime Database в качестве хоста для обмена сообщениями SDP между вашей веб-камерой и клиентским приложением CameraStream для умного дома, выполните следующие действия:

  1. В консоли Firebase нажмите Build > Realtime Database > Create database .

Страница «База данных реального времени» в консоли Firebase.

  1. В раскрывающемся меню «Расположение базы данных в реальном времени» выберите подходящее местоположение для размещения вашей базы данных.

В диалоговом окне «Настройка базы данных» в выпадающем меню «Расположение базы данных в реальном времени» выберите соответствующий пункт.

  1. Выберите «Запустить» в тестовом режиме , а затем нажмите «Включить» . При включенной базе данных реального времени вам потребуется возможность ссылаться на нее из клиентского приложения CameraStream.
  1. В консоли Firebase выберите 513f2be95dcd7896.png Настройки проекта > Настройки проекта > e584a9026e2b407f.png Добавьте Firebase в свое веб-приложение , чтобы запустить процесс настройки.
  2. Если вы уже добавили приложение в свой проект Firebase, нажмите «Добавить приложение» , чтобы отобразить параметры платформы.
  3. Введите псевдоним для приложения, например, My web app , а затем нажмите «Зарегистрировать приложение» .
  4. В разделе «Добавить Firebase SDK» выберите «Использовать тег <script>» .
  5. Скопируйте значения из объекта firebasebaseConfig и вставьте их в файл camaerastream-start/public/webrtc_generator.js .
const firebaseConfig = {
  apiKey: "XXXXX",
  authDomain: "XXXXX",
  projectId: "XXXXX",
  storageBucket: "XXXXX",
  messagingSenderId: "XXXXX",
  appId: "XXXXX",
  measurementId: "XXXXX"
};
  1. Нажмите «Продолжить в консоль» , чтобы завершить процесс. Вы увидите созданное веб-приложение на странице настроек проекта .

4. Создайте камеру WebRTC.

Теперь, когда вы настроили действие, ваш облачный сервис должен обрабатывать следующие интенты:

  • Интент SYNC , который возникает, когда Ассистент запрашивает информацию о подключенных пользователем устройствах. Эта информация отправляется в ваш сервис, когда пользователь связывает учетную запись. В ответ вы должны предоставить JSON-данные, содержащие информацию об устройствах пользователя и их возможностях.
  • Интент EXECUTE/QUERY , который возникает, когда Ассистент хочет управлять устройством от имени пользователя. В ответ следует отправить JSON-данные со статусом выполнения для каждого запрошенного устройства.

В этом разделе вы обновляете функции, которые ранее были развернуты для обработки этих намерений.

Обновите ответ SYNC

  1. Перейдите к файлу functions/index.js . Он содержит код для обработки запросов от Assistant.
  2. Отредактируйте интент 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. В коде не определен USER_ID . Добавьте следующий код под const _ = require('underscore'); `:
// Hardcoded user ID
const USER_ID = '123';

Обработайте намерение EXECUTE

Интент EXECUTE обрабатывает команды для обновления состояния устройства. В ответ возвращается статус каждой команды — например, SUCCESS , ERROR или PENDING — и новое состояние устройства.

Для обработки интента EXECUTE отредактируйте интент EXECUTE , указав в файле functions/index.js адрес конечной точки signaling проекта 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],
    },
  };
});

Обработка междоменного обмена ресурсами (CORS)

Для обработки CORS, возникающего при использовании метода POST для отправки SDP, добавьте URL-адрес Firebase Hosting в массив allowlist в файле functions/index.js :

index.js

'use strict';
.....

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

Для получения дополнительной информации о CORS см. раздел «Совместное использование ресурсов между источниками (CORS)» .

Обработка завершения потока

Для обработки завершения потока WebRTC добавьте URL-адрес функции Firebase 'signaling' в файл 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();

Развернуть в Firebase

Для развертывания в Firebase выполните обновление облачного сервиса с помощью Firebase CLI:

$ firebase deploy

Эта команда развертывает веб-приложение и несколько облачных функций для Firebase :

...

✔ Deploy complete!

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

Настройте свой проект в консоли разработчика.

  1. Перейдите в консоль разработчика .
  2. Нажмите «Создать проект» , введите название проекта и нажмите «Создать проект» .

Название проекта

Выберите интеграцию «облако-облако».

На главной странице проекта в консоли разработчика выберите пункт «Добавить интеграцию между облаками» в разделе «Интеграция между облаками» .

Добавьте интеграцию между облачными сервисами.

  1. Введите название интеграции и выберите «Камера» в разделе «Тип устройства» . Это название отобразится в приложении Google Home позже, когда появится устройство для настройки. Для этого практического занятия мы ввели WebRTC Codelab в качестве отображаемого названия, но вы можете использовать другое название.

Добавить отображаемое имя

  1. В разделе «Брендинг приложения» загрузите файл png для значка приложения размером 144 x 144 пикселя и назовите его соответствующим образом. .png .

Добавить значок приложения

Включить привязку учетных записей

Чтобы включить привязку учетных записей после развертывания проекта, выполните следующие действия:

  1. Перейдите в консоль разработчика и откройте проект.
  2. В разделе «Облако-облако» нажмите «Разработка» > «Редактировать» рядом с интеграцией.
  3. На странице «Настройка и конфигурация» найдите раздел « Связывание учетных записей» и введите следующую информацию в соответствующие текстовые поля:

Идентификатор клиента

ABC123

Секрет клиента

DEF456

URL авторизации

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

URL токена

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

Обновите URL-адреса для привязки учетных записей.

  1. Нажмите «Сохранить» > «Тест» .

5. Проверьте работу виртуальной камеры WebRTC.

  1. Перейдите по URL-адресу хостинга, который вы видели при развертывании проекта Firebase. Вы увидите следующий интерфейс, представляющий собой клиентское приложение CameraStream:

Интерфейс клиентского приложения CameraStream

  1. В панели «Разрешение локального видео» выберите нужное видео.
  2. Предоставьте клиентскому приложению CameraStream разрешение на доступ к вашей веб-камере и микрофону. Видеопоток с вашей веб-камеры отобразится на экране клиента.
  1. В приложении Google Home нажмите «Добавить» > «Работает с Google» .

Страница «Настройка устройства» в приложении Google Home.

  1. Найдите созданное вами действие и выберите его.

Действие «Умный дом» в приложении Google Home

  1. Обратите внимание на уникальный пятисимвольный буквенно-цифровой код, он понадобится вам позже.

Уникальный пятизначный буквенно-цифровой код

  1. Нажмите « Вернуться назад» . WebRTC-камера будет добавлена ​​к вашему зданию в приложении Google Home.

Запустить поток WebRTC

  1. На веб-странице клиентского приложения CameraStream введите буквенно-цифровой код из последнего раздела в текстовое поле «Значение токена привязки учетной записи» , а затем нажмите «Отправить» .

Текстовое поле «Значение токена привязки учетной записи»

  1. Чтобы запустить сеанс WebRTC с вашего смарт-дисплея Google, выполните одно из следующих действий:
  • Скажите: «Привет, Google, трансли видео с WebRTC-камеры».
  • На вашем смарт-дисплее Google перейдите в меню «Управление домом» > «Камера» > «Камера WebRTC» .

В клиентском приложении Google Smart Home CameraStream вы видите, что Offer SPD и Answer SDP успешно сгенерированы и обменены. Изображение с вашей веб-камеры передается на ваше устройство Google Smart Display с помощью WebRTC.

6. Поздравляем!

Поздравляем! Вы научились транслировать изображение с веб-камеры на дисплей Google Nest с использованием протокола WebRTC.

Узнать больше