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

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

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

Устройства камеры передают потоковую передачу на устройство отображения Google Nest

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

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

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

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

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

2. Начните работу

Установите интерфейс командной строки Firebase

Интерфейс командной строки Firebase позволяет обслуживать ваши веб-приложения локально и развертывать их на хостинге Firebase.

Чтобы установить Firebase CLI, выполните следующие действия:

  1. В своем терминале загрузите и установите Firebase CLI:
$ npm install -g firebase-tools
  1. Убедитесь, что CLI установлен правильно:
$ 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 , содержащий полностью реализованный облачный сервис, который управляет камерой с помощью облачных функций для Firebase и базы данных реального времени.

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

// TODO: Implement full SYNC response.

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

  1. Перейдите в Firebase .
  2. Нажмите «Создать проект» и введите имя проекта.
  3. Установите флажок «Соглашение» и нажмите «Продолжить» . Если флажок «Соглашение» отсутствует, вы можете пропустить этот шаг.
    Создать проект Firebase
  4. После создания проекта Firebase найдите идентификатор проекта. Перейдите в раздел «Обзор проекта» и щелкните значок настроек > «Настройки проекта» .
    Открыть настройки проекта
  5. Ваш проект указан на вкладке «Общие» .
    Общие настройки проекта

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

  1. Перейдите в каталог camerastream-start , а затем настройте интерфейс командной строки Firebase для вашего проекта Actions:
$ cd camerastream-start
$ firebase use <firebase-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 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. Настройте 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-адреса участников и порты, используемые для транспортировки мультимедиа.

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

  1. В консоли Firebase нажмите «Создать» > «База данных реального времени» > «Создать базу данных» .

Страница базы данных реального времени в консоли 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 . Он содержит код для ответа на запросы Ассистента.
  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 , чтобы вернуть конечную точку signaling проекта Firebase в файле 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],
    },
  };
});

Обработка совместного использования ресурсов между источниками (CORS)

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

index.js

'use strict';
.....

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

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

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

Чтобы обработать завершение потока WebRTC, добавьте URL-адрес функции сигнализации Firebase в файл 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:

$ 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» .

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

6. Поздравления

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

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