ใช้งาน 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 CLI

Firebase CLI ช่วยให้คุณแสดงเว็บแอปในเครื่องและทำให้ใช้งานได้ในโฮสติ้งของ Firebase

หากต้องการติดตั้ง Firebase CLI ให้ทำตามขั้นตอนต่อไปนี้

  1. ดาวน์โหลดและติดตั้ง Firebase CLI โดยทำดังนี้
$ npm install -g firebase-tools
  1. ยืนยันว่า CLI ติดตั้งอย่างถูกต้องแล้ว ดังนี้
$ firebase --version
  1. ให้สิทธิ์ Firebase CLI ด้วยบัญชี Google
$ firebase login

สร้างและกำหนดค่าโปรเจ็กต์ Actions

  1. ไปที่คอนโซล Actions แล้วคลิกโปรเจ็กต์ใหม่
  2. ในช่องข้อความชื่อโปรเจ็กต์ ให้ป้อนชื่อโปรเจ็กต์ แล้วคลิกสร้างโปรเจ็กต์

กล่องโต้ตอบโปรเจ็กต์ใหม่ในคอนโซลการดำเนินการ

  1. ในหน้าคุณต้องการสร้างการดำเนินการประเภทใด ให้คลิกสมาร์ทโฮม > เริ่มสร้าง โปรเจ็กต์จะเปิดขึ้นในคอนโซลการดำเนินการ

แท็บภาพรวมในคอนโซลการดำเนินการ

  1. คลิกพัฒนา > การเรียกใช้
  2. ในช่องข้อความชื่อที่แสดง ให้ป้อนชื่อสำหรับการดำเนินการ แล้วคลิกบันทึก ชื่อนี้จะปรากฏในแอป Google Home ภายหลังเมื่อมีอุปกรณ์สำหรับตั้งค่า สำหรับ Codelab นี้ เราป้อน WebRTC Codelab เป็นชื่อที่แสดง แต่คุณใช้ชื่ออื่นได้

แผงคำขอในคอนโซลการดำเนินการ

  1. คลิกการดำเนินการ
  2. ในช่องข้อความ URL การดำเนินการ ให้ป้อน URL ตัวยึดตำแหน่ง เช่น 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 ซึ่งมี UI ฟรอนท์เอนด์เพื่อให้ควบคุมและตรวจสอบสถานะของอุปกรณ์กล้องได้อย่างง่ายดาย
  • ไดเรกทอรีย่อย functions ซึ่งมีบริการระบบคลาวด์ที่ใช้งานอย่างเต็มรูปแบบซึ่งจัดการกล้องด้วย Cloud Functions for Firebase และ Realtime Database

โค้ดเริ่มต้นมีความคิดเห็น TODO รายการที่บ่งชี้ว่าคุณต้องเพิ่มหรือเปลี่ยนโค้ดที่ใด ดังตัวอย่างต่อไปนี้:

// TODO: Implement full SYNC response.

เชื่อมต่อกับ Firebase

  1. ไปที่ไดเรกทอรี camerastream-start จากนั้นตั้งค่า Firebase CLI ด้วยโปรเจ็กต์ Actions ดังนี้
$ cd camerastream-start
$ firebase use PROJECT_ID
  1. ในไดเรกทอรี camerastream-start ให้ไปที่โฟลเดอร์ functions แล้วติดตั้งทรัพยากร Dependency ทั้งหมดที่จำเป็นดังนี้
$ cd functions
$ npm install
  1. หากเห็นข้อความต่อไปนี้ ก็ไม่ต้องสนใจ คำเตือนนี้เกิดจากทรัพยากร Dependency เก่า ดูข้อมูลเพิ่มเติมได้ที่ปัญหาเกี่ยวกับ 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. ข้อความโปรโตคอลคำอธิบายเซสชันของ Exchange (SDP)

การแลกเปลี่ยนข้อความ SDP เป็นขั้นตอนสำคัญในการสร้างสตรีม WebRTC SDP เป็นโปรโตคอลแบบข้อความที่อธิบายลักษณะของเซสชันมัลติมีเดีย โดยจะใช้ใน WebRTC เพื่อเจรจาเกี่ยวกับพารามิเตอร์ของการเชื่อมต่อแบบเพียร์ทูเพียร์ เช่น ตัวแปลงรหัสที่ใช้ ที่อยู่ IP ของผู้เข้าร่วม และพอร์ตที่ใช้สำหรับการส่งสื่อ

หากต้องการใช้ Realtime Database เป็นโฮสต์เพื่อแลกเปลี่ยนข้อความ SDP ระหว่างเว็บแคมกับแอปไคลเอ็นต์ CameraStream สำหรับสมาร์ทโฮม ให้ทำตามขั้นตอนต่อไปนี้

  1. ในคอนโซล Firebase ให้คลิกสร้าง > ฐานข้อมูลเรียลไทม์ > สร้างฐานข้อมูล

หน้าฐานข้อมูลเรียลไทม์ในคอนโซล Firebase

  1. ในเมนูแบบเลื่อนลงตำแหน่งของ Realtime Database ให้เลือกตำแหน่งที่เหมาะสมในการโฮสต์ฐานข้อมูล

เมนูแบบเลื่อนลงตำแหน่งของ Realtime Database ในกล่องโต้ตอบตั้งค่าฐานข้อมูล

  1. เลือกเริ่มในโหมดทดสอบ แล้วคลิกเปิดใช้ เมื่อเปิดใช้ Realtime Database คุณจะต้องสามารถอ้างอิงได้จากแอปไคลเอ็นต์ 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

ตอนนี้คุณกำหนดค่า Action แล้ว บริการระบบคลาวด์ต้องจัดการ Intent ต่อไปนี้

  • Intent SYNC ที่เกิดขึ้นเมื่อ Assistant ต้องการทราบอุปกรณ์ที่ผู้ใช้เชื่อมต่ออยู่ โดยจะส่งไปยังบริการของคุณเมื่อผู้ใช้ลิงก์บัญชี คุณควรตอบกลับด้วยเพย์โหลด JSON ของอุปกรณ์และความสามารถของอุปกรณ์ของผู้ใช้
  • Intent EXECUTE/QUERY ที่เกิดขึ้นเมื่อ Assistant ต้องการควบคุมอุปกรณ์ในนามของผู้ใช้ คุณควรตอบกลับด้วยเพย์โหลด JSON พร้อมสถานะการดำเนินการของอุปกรณ์แต่ละเครื่องที่ขอ

ในส่วนนี้ คุณจะอัปเดตฟังก์ชันที่คุณทำให้ใช้งานได้ก่อนหน้านี้เพื่อจัดการ Intent เหล่านี้

อัปเดตการตอบกลับ SYNC

  1. ไปที่ไฟล์ functions/index.js มีโค้ดสำหรับตอบกลับคำขอจาก Assistant
  2. แก้ไข SYNC Intent เพื่อแสดงผลข้อมูลเมตาและความสามารถของอุปกรณ์ดังนี้

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 ใช้งานได้ ให้ทำให้ Cloud Fulfillment ที่อัปเดตแล้วใช้งานได้ด้วย Firebase CLI
$ 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. ในคอนโซล Actions ให้เลือกพัฒนา > การลิงก์บัญชี
  2. ในส่วนข้อมูลไคลเอ็นต์ OAuth ให้ป้อนข้อมูลต่อไปนี้ในกล่องข้อความที่สอดคล้องกัน

Client 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. โปรดสังเกตรหัสที่เป็นตัวอักษรและตัวเลขคละกันความยาว 5 อักขระที่ไม่ซ้ำกัน เนื่องจากคุณจำเป็นต้องใช้ในภายหลัง

รหัสแบบไม่ซ้ำซึ่งเป็นตัวเลข 5 หลักที่เป็นตัวอักษรและตัวเลขคละกัน

  1. แตะนำฉันกลับ มีการเพิ่มกล้อง WebRTC ไปยังโครงสร้างของคุณในแอป Google Home

เริ่มสตรีม WebRTC

  1. ในหน้าเว็บสำหรับแอปไคลเอ็นต์ CameraStream ให้ป้อนรหัสตัวอักษรและตัวเลขคละกันจากส่วนสุดท้ายในช่องข้อความค่าโทเค็นการลิงก์บัญชี แล้วคลิกส่ง

กล่องข้อความค่าโทเค็นการลิงก์บัญชี

  1. หากต้องการเริ่มเซสชัน WebRTC จากอุปกรณ์ Smart Display ของ Google ให้ทำอย่างใดอย่างหนึ่งต่อไปนี้
  • พูดว่า "Ok Google สตรีมกล้อง WebRTC"
  • ในอุปกรณ์ Smart Display ของ Google ให้แตะระบบควบคุมอุปกรณ์ในบ้าน > กล้อง > กล้อง WebRTC

จากแอปไคลเอ็นต์ CameraStream ในสมาร์ทโฮมของ Google คุณจะเห็นว่าการสร้างและแลกเปลี่ยนข้อเสนอ SPD และ SDP ของข้อเสนอนั้นเสร็จสมบูรณ์แล้ว รูปภาพจากเว็บแคมของคุณจะสตรีมไปยังอุปกรณ์ Smart Display ของ Google ผ่าน WebRTC

6. ขอแสดงความยินดี

ยินดีด้วย คุณได้เรียนรู้วิธีสตรีมจากเว็บแคมไปยังอุปกรณ์แสดงผล Google Nest ด้วยโปรโตคอล WebRTC แล้ว

ดูข้อมูลเพิ่มเติม