Реализация 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

Создание и настройка проекта Actions

  1. Перейдите в консоль «Действия» и нажмите «Новый проект».
  2. В текстовом поле «Имя проекта» введите имя проекта и нажмите «Создать проект» .

Диалоговое окно «Новый проект» в консоли «Действия»

  1. На вопрос «Какое действие вы хотите построить?» нажмите Умный дом > Начать строительство . Проект откроется в консоли действий.

Вкладка «Обзор» в консоли «Действия».

  1. Нажмите «Разработка» > «Вызов» .
  2. В текстовом поле «Отображаемое имя» введите имя действия и нажмите «Сохранить» . Это имя появится в приложении Google Home позже, когда появится устройство, которое нужно настроить. Для этой лаборатории кода мы указали WebRTC Codelab в качестве отображаемого имени, но вы можете использовать другое имя.

Панель «Вызов» в консоли «Действия»

  1. Нажмите Действия .
  2. В текстовом поле URL-адрес выполнения введите URL-заполнитель, например https://example.com .

Запустите клиентское приложение 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. Перейдите в каталог camerastream-start , а затем настройте интерфейс командной строки Firebase для вашего проекта 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 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. Настройте облачные функции с использованием файлов по умолчанию и убедитесь, что вы не перезаписываете существующие файлы 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
        },
      }],
    },
  };
});

Обработка намерения 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';

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.

Дополнительные сведения о 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. В разделе «Информация о клиенте OAuth» введите следующую информацию в соответствующие текстовые поля:

ID клиента

ABC123

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

DEF456

URL-адрес авторизации

https://us-central1-{project-id}.cloudfunctions.net/fakeauth

URL-адрес токена

https://us-central1-{project-id}.cloudfunctions.net/faketoken

Страница привязки учетной записи в консоли действий.

  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.

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