1. Antes de comenzar
El atributo CameraStream
pertenece a los dispositivos con la capacidad de transmitir feeds de video a pantallas inteligentes, dispositivos Chromecast y smartphones. El protocolo WebRTC ahora es compatible con el atributo CameraStream
, lo que significa que puedes reducir en gran medida la latencia de inicio y transmisión de un dispositivo de cámara a un dispositivo de pantalla Google Nest.
Requisitos previos
Qué aprenderás
- Cómo implementar un servicio en la nube para casa inteligente
- Cómo conectar tu servicio a Asistente de Google
- Cómo transmitir contenido a un dispositivo de pantalla Google Nest con el protocolo WebRTC
Requisitos
- Un navegador web, como Google Chrome
- Un dispositivo iOS o Android con la app de Google Home
- Node.js versión 10.16 o posterior
- Plan Blaze (pago por uso) para Firebase
- Un dispositivo de cámara web integrado o externo que admita resolución Full HD
- Un dispositivo de pantalla Google Nest
2. Comenzar
Instala Firebase CLI
Firebase CLI te permite publicar tus apps web a nivel local y, luego, implementarlas en Firebase Hosting.
Para instalar Firebase CLI, sigue estos pasos:
- En la terminal, descarga e instala Firebase CLI:
$ npm install -g firebase-tools
- Verifica que la CLI se haya instalado correctamente:
$ firebase --version
- Autoriza Firebase CLI con tu Cuenta de Google:
$ firebase login
Crea un proyecto
- Ve a la Developer Console de Google Home.
- Haz clic en Create Project, ingresa un nombre para el proyecto y haz clic en Create Project.
Ejecuta la app cliente de CameraStream
El código fuente de este codelab incluye un cliente WebRTC que establece, negocia y administra la sesión de WebRTC entre la cámara web y el dispositivo de pantalla de la casa inteligente de Google.
Para ejecutar la app cliente de WebRTC de CameraStream, haz una de las siguientes acciones:
- Haz clic en el siguiente botón para descargar el código fuente en tu máquina de desarrollo:
- Clona este repositorio de GitHub:
$ git clone https://github.com/google-home/smarthome-camerastream-webrtc.git
El código contiene los siguientes directorios:
- El directorio
camerastream-start
, que contiene el código de partida en el que compilas - El directorio
camerastream-done
, que contiene el código de la solución del codelab finalizado
El directorio camerastream-start
contiene los siguientes subdirectorios:
- El subdirectorio
public
, que contiene una IU de frontend para controlar y supervisar fácilmente el estado del dispositivo de la cámara - El subdirectorio
functions
, que contiene un servicio de nube completamente implementado que administra la cámara con Cloud Functions para Firebase y Realtime Database
El código de partida contiene comentarios TODO
que indican dónde debes agregar o cambiar código, como en el siguiente ejemplo:
// TODO: Implement full SYNC response.
Crea un proyecto de Firebase
- Ve a Firebase.
- Haz clic en Crear un proyecto y, luego, ingresa el nombre del proyecto.
- Marca la casilla de verificación del acuerdo y haz clic en Continuar. Si no hay una casilla de verificación de acuerdo, puedes omitir este paso.
- Una vez que crees tu proyecto de Firebase, busca el ID del proyecto. Ve a Descripción general del proyecto y haz clic en el ícono de configuración > Configuración del proyecto.
- Tu proyecto aparecerá en la pestaña General.
Cómo conectarse a Firebase
- Navega al directorio
camerastream-start
y configura Firebase CLI con tu proyecto de Acciones:
$ cd camerastream-start $ firebase use <firebase-project-id>
- En el directorio
camerastream-start
, navega a la carpetafunctions
y, luego, instala todas las dependencias necesarias:
$ cd functions $ npm install
- Si ves el siguiente mensaje, ignóralo. Esta advertencia se debe a dependencias más antiguas. Para obtener más información, consulta este problema de GitHub.
found 5 high severity vulnerabilities run `npm audit fix` to fix them, or `npm audit` for details
- Inicializa un proyecto de Firebase:
$ firebase init
- Selecciona Functions y Hosting. De este modo, se inicializarán las APIs y las funciones necesarias para tu proyecto.
? 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
- Configura Cloud Functions con los archivos predeterminados y asegúrate de no reemplazar los archivos
index.js
ypackage.json
existentes en el ejemplo del proyecto:
? 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
- Configura Hosting con el directorio
public
en el código del proyecto y usa el archivoindex.html
existente:
? 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. Intercambia mensajes del protocolo de descripción de sesión (SDP)
El intercambio de mensajes SDP es un paso importante en el establecimiento de una transmisión de WebRTC. El SDP es un protocolo basado en texto que describe las características de una sesión multimedia. Se usa en WebRTC para negociar los parámetros de una conexión punto a punto, como los códecs utilizados, las direcciones IP de los participantes y los puertos utilizados para el transporte de contenido multimedia.
Para usar Realtime Database como host para intercambiar mensajes SDP entre tu cámara web y la app cliente CameraStream de la casa inteligente, sigue estos pasos:
- En Firebase console, haz clic en Compilación > Base de datos en tiempo real > Crear base de datos.
- En el menú desplegable Ubicación de Realtime Database, selecciona una ubicación adecuada desde la que alojar tu base de datos.
- Selecciona Comenzar en modo de prueba y, luego, haz clic en Habilitar. Con Realtime Database habilitada, debes poder hacer referencia a ella desde la app cliente de CameraStream.
- En Firebase console, selecciona Configuración del proyecto > Configuración del proyecto > Agrega Firebase a tu app web para iniciar el flujo de trabajo de configuración.
- Si ya agregaste una app a tu proyecto de Firebase, haz clic en Agregar app para que se muestren las opciones de plataforma.
- Ingresa un sobrenombre para la app, como
My web app
, y haz clic en Registrar app. - En la sección Agregar el SDK de Firebase, selecciona Usar la etiqueta <script>.
- Copia los valores del objeto
firebasebaseConfig
y, luego, pégalos en el archivocamaerastream-start/public/webrtc_generator.js
.
const firebaseConfig = {
apiKey: "XXXXX",
authDomain: "XXXXX",
projectId: "XXXXX",
storageBucket: "XXXXX",
messagingSenderId: "XXXXX",
appId: "XXXXX",
measurementId: "XXXXX"
};
- Haz clic en Ir a la consola para completar el proceso. Verás la app web recién creada en la página Configuración del proyecto.
4. Cómo crear una cámara WebRTC
Ahora que configuraste tu Acción, tu servicio en la nube debe controlar los siguientes intents:
- Un intent
SYNC
que se produce cuando Asistente desea saber qué dispositivos conectó el usuario. Este se envía a tu servicio cuando el usuario vincula una cuenta. Deberías responder con una carga útil JSON de los dispositivos del usuario y sus capacidades. - Un intent
EXECUTE/QUERY
que se produce cuando el Asistente desea controlar un dispositivo en nombre de un usuario. Deberías responder con una carga útil JSON con el estado de ejecución de cada dispositivo solicitado.
En esta sección, actualizarás las funciones que implementaste antes para controlar estos intents.
Actualiza la respuesta de SYNC
- Navega al archivo
functions/index.js
. Contiene el código para responder las solicitudes del Asistente. - Edita el intent
SYNC
para mostrar los metadatos y las capacidades del dispositivo:
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
},
}],
},
};
});
USER_ID
no se define en el código. Agrega lo siguiente aconst _ = require('underscore');
:
// Hardcoded user ID
const USER_ID = '123';
Cómo controlar el intent EXECUTE
El intent EXECUTE
controla los comandos para actualizar el estado del dispositivo. La respuesta muestra el estado de cada comando (por ejemplo, SUCCESS
, ERROR
o PENDING
) y el estado del dispositivo nuevo.
Para controlar un intent EXECUTE
, edita el intent EXECUTE
para que devuelva el extremo signaling
del proyecto de Firebase en el archivo 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],
},
};
});
Controla el uso compartido de recursos entre dominios (CORS)
Para controlar el CORS debido al uso del método POST
para enviar el SDP, agrega la URL de Firebase Hosting al array allowlist
en el archivo functions/index.js
:
index.js
'use strict';
.....
var allowList = ['https://www.gstatic.com','https://<firebase-project-id>.web.app']; //TODO Add Firebase hosting URL.
Para obtener más información sobre CORS, consulta Uso compartido de recursos entre dominios (CORS).
Controla la finalización de la transmisión
Para controlar la finalización de la transmisión de WebRTC, agrega la URL de la función de "indicadores" de Firebase al archivo 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();
Cómo implementar en Firebase
Para implementar en Firebase, implementa la entrega en la nube actualizada con Firebase CLI:
$ firebase deploy
Este comando implementa una app web y varias Cloud Functions para Firebase:
... ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/<project-id>/overview Hosting URL: https://<project-id>.web.app
Configura tu proyecto de Play Console
- Ve a Developer Console.
- Haz clic en Create Project, ingresa un nombre para el proyecto y haz clic en Create Project.
Selecciona la integración de nube a nube.
En Página principal del proyecto en la Consola de Play, selecciona Agregar integración de nube a nube en Nube a nube.
- Ingresa un nombre de integración y selecciona Cámara en Tipo de dispositivo. Este nombre aparecerá en la app de Google Home más adelante, cuando haya un dispositivo para configurar. Para este codelab, ingresamos Codelab de WebRTC como nombre visible, pero puedes usar otro nombre.
- En Desarrollo de la marca de la app, sube un archivo
png
para el ícono de la app, con un tamaño de 144 × 144 px y el nombre
..png
Habilita la vinculación de cuentas
Para habilitar la vinculación de cuentas después de que se implemente tu proyecto, sigue estos pasos:
- Ve a Developers Console y abre el proyecto.
- En la sección De nube a nube, haz clic en Desarrollo > Editar junto a la integración.
- En la página Configuración, busca la sección Vinculación de cuentas y, luego, ingresa la siguiente información en los cuadros de texto correspondientes:
ID de cliente |
|
Secreto del cliente |
|
URL de autorización |
|
URL del token |
|
- Haz clic en Guardar > Probar.
5. Prueba la cámara virtual de WebRTC
- Navega a la URL de Hosting que viste cuando implementaste tu proyecto de Firebase. Verás la siguiente interfaz, que es la app cliente de CameraStream:
- En el panel Local Video Resolution, selecciona el video que quieras.
- Otorga permiso a la app cliente de CameraStream para que acceda a tu cámara web y micrófono. Aparecerá un feed de video de tu cámara web en el cliente.
Vincula la acción CameraStream
de la casa inteligente
- En la app de Google Home, presiona Agregar > Funciona con Google.
- Busca la acción que creaste y selecciónala.
- Anota el código alfanumérico único de cinco caracteres, ya que lo necesitarás más adelante.
- Presiona Volver atrás. La cámara WebRTC se agregará a tu estructura en la app de Google Home.
Cómo iniciar una transmisión de WebRTC
- En la página web de la app cliente de CameraStream, ingresa el código alfanumérico de la última sección en el cuadro de texto Account linking token value y, luego, haz clic en Submit.
- Para iniciar una sesión de WebRTC desde tu dispositivo de pantalla inteligente de Google, haz lo siguiente:
- Di "Hey Google, transmite la cámara WebRTC".
- En tu dispositivo de pantalla inteligente de Google, presiona Control de la casa > Cámara > Cámara WebRTC.
En la app cliente de CameraStream de la casa inteligente de Google, verás que se generaron y se intercambiaron correctamente el SPD de oferta y el SDP de respuesta. La imagen de la cámara web se transmite a tu dispositivo de pantalla inteligente de Google con WebRTC.
6. Felicitaciones
¡Felicitaciones! Aprendiste a transmitir desde tu cámara web a un dispositivo de pantalla Google Nest con el protocolo WebRTC.