הטמעת CameraStream עם WebRTC

1. לפני שמתחילים

התכונה CameraStream שייכת למכשירים עם יכולת לשדר פידים של וידאו למסכים חכמים, למכשירי Chromecast ולסמארטפונים. פרוטוקול WebRTC נתמך עכשיו במסגרת ה-trait CameraStream, כך שאפשר לקצר משמעותית את זמן האחזור של ההפעלה והסטרימינג ממכשיר מצלמה למכשיר מסך של Google Nest.

מכשירים שמשדרים בסטרימינג למסך של Google Nest

דרישות מוקדמות

מה תלמדו

  • איך לפרוס שירות ענן לבית חכם
  • איך לחבר את השירות אל Google Assistant
  • איך לשדר בסטרימינג למכשיר Google Nest עם פרוטוקול WebRTC.

מה הדרישות כדי להצטרף לתוכנית?

  • דפדפן אינטרנט, כמו Google Chrome.
  • מכשיר iOS או Android עם אפליקציית Google Home.
  • Node.js מגרסה 10.16 ואילך.
  • Blaze (תשלום לפי שימוש) ב-Firebase.
  • התקן מצלמת אינטרנט מובנה או חיצוני שיכול לתמוך ברזולוציית HD מלאה.
  • מסך Google Nest.

2. תחילת העבודה

התקנת ה-CLI של Firebase

CLI של Firebase מאפשר להציג את אפליקציות האינטרנט באופן מקומי ולפרוס אותן באירוח ב-Firebase.

כך מתקינים את ה-CLI של Firebase:

  1. בטרמינל, מורידים ומתקינים את ה-CLI של Firebase:
$ npm install -g firebase-tools
  1. מוודאים שה-CLI מותקן בצורה נכונה:
$ firebase --version
  1. מאשרים את Firebase CLI באמצעות חשבון Google:
$ firebase login

יצירה והגדרה של פרויקט Actions

  1. נכנסים למסוף הפעולות ולוחצים על פרויקט חדש.
  2. בתיבת הטקסט Project name, נותנים שם לפרויקט ולוחצים על Create project.

תיבת הדו-שיח 'פרויקט חדש' במסוף הפעולות

  1. בדף איזה סוג של פעולה ברצונך ליצור? לוחצים על בית חכם > התחלת הבנייה. הפרויקט ייפתח במסוף Actions.

הכרטיסייה Overview (סקירה כללית) במסוף Actions

  1. לוחצים על פיתוח > הפעלה.
  2. בתיבת הטקסט Display name, נותנים שם לפעולה ולוחצים על Save. השם הזה יופיע באפליקציית Google Home מאוחר יותר כשיש מכשיר להגדרה. עבור ה-Codelab הזה, הזנו את WebRTC Codelab כשם המוצג, אבל אפשר להשתמש בשם אחר.

חלונית ההפעלה במסוף Actions

  1. לוחצים על פעולות.
  2. בתיבת הטקסט כתובת URL למילוי הזמנות, מזינים כתובת URL של placeholder, כמו https://example.com.

הפעלת אפליקציית הלקוח CameraStream

קוד המקור של ה-codelab הזה כולל לקוח WebRTC שיוצר, מנהל משא ומתן ומנהל את הסשן של WebRTC בין מצלמת האינטרנט לבין מכשיר התצוגה של Google לבית החכם.

כדי להפעיל את אפליקציית הלקוח של CameraStream WebRTC, צריך לבצע אחת מהפעולות הבאות:

  • יש ללחוץ על הלחצן הבא כדי להוריד את קוד המקור למחשב הפיתוח:

  • שכפול המאגר הזה ב-GitHub:
$ git clone https://github.com/google-home/smarthome-camerastream-webrtc.git

הקוד מכיל את הספריות הבאות:

  • הספרייה camerastream-start, שמכילה את הקוד לתחילת הדרך שעליה בונים.
  • הספרייה camerastream-done, שמכילה את קוד הפתרון של ה-codelab הסופי.

הספרייה camerastream-start מכילה את ספריות המשנה הבאות:

  • ספריית המשנה public, שמכילה ממשק משתמש חזיתי שמאפשר לך לשלוט בקלות במצב המצלמה שלך ולעקוב אחריו.
  • ספריית המשנה functions, שמכילה שירות ענן שהוטמע באופן מלא שמנהל את המצלמה באמצעות Cloud Functions for Firebase ומסד נתונים בזמן אמת.

הקוד לתחילת פעולה מכיל TODO תגובות שמציינות איפה צריך להוסיף או לשנות קוד, כמו הדוגמה הבאה:

// TODO: Implement full SYNC response.

התחברות אל Firebase

  1. עוברים לספרייה camerastream-start ומגדירים את ה-CLI של Firebase בפרויקט הפעולות:
$ 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. בוחרים באפשרות Functions (פונקציות) ו-Hosting (אירוח). הפעולה הזו תפעיל את התכונות וממשקי ה-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. הודעות של Exchange Action Description Protocol (SDP)

חילופי הודעות SDP היא שלב חשוב ביצירת זרם WebRTC. SDP הוא פרוטוקול מבוסס-טקסט שמתאר את המאפיינים של סשן מולטימדיה. היא משמשת ב-WebRTC כדי לנהל משא ומתן על הפרמטרים של חיבור עמית-לעמית, כמו הקודק שנעשה בו שימוש, כתובות ה-IP של המשתתפים והיציאות המשמשות להעברת מדיה.

כדי להשתמש במסד נתונים בזמן אמת כמארח כדי להעביר הודעות SDP בין מצלמת האינטרנט לבין אפליקציית הלקוח CameraStream בבית החכם, יש לבצע את השלבים הבאים:

  1. במסוף Firebase, לוחצים על Build > Realtime Database > Create מסד נתונים (יצירת מסד נתונים).

הדף 'מסד נתונים בזמן אמת' במסוף Firebase

  1. בתפריט הנפתח מיקום של מסד נתונים בזמן אמת, בוחרים את המיקום המתאים שממנו תארח את מסד הנתונים.

התפריט הנפתח של המיקום של מסד הנתונים בזמן אמת בתיבת הדו-שיח 'הגדר מסד נתונים'

  1. בוחרים באפשרות הפעלה במצב בדיקה ולאחר מכן לוחצים על הפעלה. כאשר 'מסד נתונים בזמן אמת' מופעל, צריכה להיות לכם יכולת להפנות אליו מאפליקציית הלקוח CameraStream.
  1. במסוף Firebase, בוחרים בסמל 513f2be95dcd7896.png הגדרות הפרויקט > הגדרות הפרויקט > e584a9026e2b407f.pngהוספת Firebase לאפליקציית האינטרנט כדי להפעיל את תהליך ההגדרה.
  2. אם כבר הוספתם אפליקציה לפרויקט Firebase, לוחצים על הוספת אפליקציה כדי להציג את אפשרויות הפלטפורמה.
  3. מזינים כינוי לאפליקציה, למשל My web app, ולוחצים על Register 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. לוחצים על Continue to console כדי להשלים את התהליך. אפליקציית האינטרנט החדשה תופיע בדף Project settings.

4. יצירה של מצלמת WebRTC

אחרי שהגדרתם את הפעולה, שירות הענן שלכם צריך לטפל באובייקטים הבאים:

  • אובייקט Intent מסוג SYNC שמתרחש כש-Assistant רוצה לדעת אילו מכשירים המשתמש חיבר. המזהה נשלח לשירות שלכם כשהמשתמש מקשר חשבון. עליך להגיב באמצעות מטען ייעודי (payload) של JSON של מכשירי המשתמש והיכולות שלהם.
  • Intent של EXECUTE/QUERY שמתרחש כש-Assistant רוצה לשלוט במכשיר בשמו של משתמש. עליך להגיב באמצעות מטען ייעודי (payload) של JSON עם סטטוס הביצוע של כל מכשיר מבוקש.

בקטע הזה מעדכנים את הפונקציות שפרסתם בעבר כדי לטפל באובייקטים האלה של Intent.

עדכון התשובה של SYNC

  1. עוברים לקובץ functions/index.js. היא מכילה את הקוד שצריך להגיב לבקשות מ-Assistant.
  2. עורכים את Intent 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
        },
      }],
    },
  };
});

טיפול ב-Intent EXECUTE

אובייקט ה-Intent EXECUTE מטפל בפקודות לעדכון מצב המכשיר. התגובה מחזירה את הסטטוס של כל פקודה — לדוגמה, SUCCESS, ERROR או PENDING – ואת המצב החדש של המכשיר.

  • כדי לטפל ב-Intent מסוג EXECUTE, יש לערוך את ה-Intent 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, צריך לפרוס את מילוי הבקשה המעודכן בענן באמצעות ה-CLI של Firebase:
$ firebase deploy

הפקודה הזו פורסת אפליקציית אינטרנט וכמה Cloud Functions for Firebase:

...

✔ Deploy complete!

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

הפעלת קישור חשבונות

כדי להפעיל את קישור החשבונות אחרי פריסת הפרויקט, מבצעים את השלבים הבאים:

  1. במסוף הפעולות, בוחרים באפשרות פיתוח > קישור חשבונות.
  2. בקטע מידע על לקוח OAuth, מזינים את המידע הבא בתיבות הטקסט המתאימות:

Client ID

ABC123

סוד לקוח

DEF456

כתובת URL להרשאה

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

כתובת ה-URL של האסימון

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

הדף לקישור החשבונות ב-Actions Console

  1. לוחצים על שמירה > בדיקה.

5. בדיקה של מצלמת WebRTC הווירטואלית

  1. עוברים אל כתובת ה-URL לאירוח שהוצגה כשפרסתם את פרויקט Firebase. אתם רואים את הממשק הבא, שהוא אפליקציית הלקוח CameraStream:

ממשק אפליקציית הלקוח CameraStream

  1. בחלונית Local Video Resolution (רזולוציית וידאו מקומית), בוחרים את הסרטון הרצוי.
  2. מעניקים הרשאה לאפליקציית הלקוח CameraStream כדי לגשת למצלמת האינטרנט ולמיקרופון. פיד וידאו ממצלמת האינטרנט שלך מופיע אצל הלקוח.
  1. באפליקציית Google Home, מקישים על הוספה > מכשירים שפועלים עם Google.

הדף &#39;הגדרת מכשיר&#39; באפליקציית Google Home

  1. מחפשים את הפעולה שיצרתם ובוחרים אותה.

הפעולות בבית החכם באפליקציית Google Home

  1. שימו לב לקוד האלפאנומרי הייחודי בן 5 התווים, כי תצטרכו אותו מאוחר יותר.

קוד ייחודי בן חמש ספרות עם אותיות וספרות

  1. מקישים על חזרה למסך הקודם. מצלמת WebRTC נוספת למבנה שלך באפליקציית Google Home.

התחלת סטרימינג של WebRTC

  1. בדף האינטרנט של אפליקציית הלקוח CameraStream, מזינים את הקוד האלפאנומרי שבקטע האחרון בתיבת הטקסט ערך של אסימון קישור לחשבון ואז לוחצים על שליחה.

תיבת הטקסט של הערך של אסימון הקישור לחשבון

  1. כדי להתחיל סשן WebRTC במכשיר המסך החכם של Google, צריך לבצע אחת מהפעולות הבאות:
  • אומרים "Ok Google, Stream WebRTC Camera"
  • במסך החכם של Google, מקישים על בית חכם > מצלמה > מצלמת WebRTC.

באפליקציית הלקוח של CameraStream לבית החכם של Google, אפשר לראות שה-SPD וה-Answer של ה-SPD נוצרו בהצלחה והוחלפו בהצלחה. התמונה ממצלמת האינטרנט נשלחת בסטרימינג למכשיר המסך החכם של Google עם WebRTC.

6. מזל טוב

כל הכבוד! למדת איך לשדר ממצלמת אינטרנט למכשיר Google Nest במסך עם פרוטוקול WebRTC.

מידע נוסף