ใช้งาน CameraStream กับ WebRTC

เกี่ยวกับ Codelab นี้
schedule23 นาที
subjectอัปเดตล่าสุดเมื่อ 8 เมษายน 2568
account_circleเขียนโดย Keyur Kanabar

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

สร้างโปรเจ็กต์

  1. ไปที่ Google Home Developer Console
  2. คลิกสร้างโปรเจ็กต์ ป้อนชื่อโปรเจ็กต์ แล้วคลิกสร้างโปรเจ็กต์

ตั้งชื่อโปรเจ็กต์

เรียกใช้แอปไคลเอ็นต์ CameraStream

แหล่งที่มาของโค้ดแล็บนี้ประกอบด้วยไคลเอ็นต์ WebRTC ที่สร้าง เจรจา และจัดการเซสชัน WebRTC ระหว่างเว็บแคมกับอุปกรณ์จอแสดงผลสมาร์ทโฮมของ Google

หากต้องการเรียกใช้แอปไคลเอ็นต์ WebRTC ของ CameraStream ให้ทําอย่างใดอย่างหนึ่งต่อไปนี้

  • คลิกปุ่มต่อไปนี้เพื่อดาวน์โหลดซอร์สโค้ดลงในเครื่องสำหรับพัฒนาซอฟต์แวร์

  • โคลนที่เก็บ 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 ไปยังโปรเจ็กต์ Google Home Developer Console

วิธีที่ 1: ผ่านคอนโซล Firebase

  1. ไปที่ Firebase
  2. คลิกสร้างโปรเจ็กต์ Firebase
    สร้างโปรเจ็กต์ Firebase
  3. ในหน้าจอสร้างโปรเจ็กต์ ให้คลิกเพิ่ม Firebase ไปยังโปรเจ็กต์ Google Cloud
    เพิ่ม Firebase ไปยังโปรเจ็กต์ Google Cloud
  4. ในหน้าจอเริ่มต้นใช้งาน ให้เลือกโปรเจ็กต์ Google Cloud ที่คุณเพิ่งสร้างในคอนโซลนักพัฒนาแอป Google Home แล้วคลิกต่อไป
    เลือกโปรเจ็กต์ Google Cloud

วิธีที่ 2: ผ่าน Firebase Click

เมื่อเพิ่มโปรเจ็กต์ Firebase ใหม่ลงในโปรเจ็กต์ Google Home Developer Console โปรเจ็กต์ดังกล่าวจะปรากฏในคอนโซล Firebase รหัสโปรเจ็กต์ของโปรเจ็กต์ Firebase จะสอดคล้องกับรหัสโปรเจ็กต์ในคอนโซลนักพัฒนาแอป Google Home

เพิ่มโปรเจ็กต์ที่อยู่ในระบบคลาวด์แล้ว

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

  1. ไปที่ไดเรกทอรี camerastream-start แล้วตั้งค่า Firebase CLI กับโปรเจ็กต์ Actions โดยทำดังนี้
$ cd camerastream-start
$ firebase use <project-id>
  1. ในไดเรกทอรี camerastream-start ให้ไปที่โฟลเดอร์ functions แล้วติดตั้ง Dependency ที่จําเป็นทั้งหมด ดังนี้
$ 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 features do you want to set up for this directory? Press Space to select features, then Enter
 to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to
 proceed)
>( ) Data Connect: Set up a Firebase Data Connect service
 ( ) Firestore: Configure security rules and indexes files for Firestore
 ( ) Genkit: Setup a new Genkit project with Firebase
 (*) Functions: Configure a Cloud Functions directory and its files
 ( ) App Hosting: Configure an apphosting.yaml file for App Hosting
 (*) Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
 ( ) Storage: Configure a security rules file for Cloud Storage
 ( ) Emulators: Set up local emulators for Firebase products
 ( ) Remote Config: Configure a template file for Remote Config
 ( ) Extensions: Set up an empty Extensions manifest
 (*) Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision
default instance
 ( ) Data Connect: Set up a Firebase Data Connect service
 ( ) Firestore: Configure security rules and indexes files for Firestore
  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 เพื่อเจรจาต่อรองพารามิเตอร์ของการเชื่อมต่อแบบ Peer-to-Peer เช่น ตัวแปลงรหัสที่ใช้ ที่อยู่ 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

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

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

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

อัปเดตคําตอบ 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
      },
    }],
  },
};
});
  1. ไม่ได้กำหนด USER_ID ในโค้ด เพิ่มข้อมูลต่อไปนี้ในส่วน const _ = require('underscore');
// Hardcoded user ID
const USER_ID = '123';

จัดการ 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';
.....

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

ดูข้อมูลเพิ่มเติมเกี่ยวกับ CORS ได้ที่กลไกการแชร์ทรัพยากรข้ามโดเมน (CORS)

จัดการการสิ้นสุดสตรีม

หากต้องการจัดการการสิ้นสุดสตรีม WebRTC ให้เพิ่ม URL ของฟังก์ชัน "signaling" ของ 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 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. ไปที่คอนโซลนักพัฒนาแอป
  2. คลิกสร้างโปรเจ็กต์ ป้อนชื่อโปรเจ็กต์ แล้วคลิกสร้างโปรเจ็กต์

ตั้งชื่อโปรเจ็กต์

เลือกการผสานรวมระบบคลาวด์กับระบบคลาวด์

ในหน้าแรกของโปรเจ็กต์ในคอนโซลของนักพัฒนาซอฟต์แวร์ ให้เลือกเพิ่มการผสานรวมระบบคลาวด์กับระบบคลาวด์ในส่วนระบบคลาวด์กับระบบคลาวด์

เพิ่มการผสานรวมระบบคลาวด์สู่ระบบคลาวด์

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

เพิ่มชื่อที่แสดง

  1. ในส่วนการสร้างแบรนด์แอป ให้อัปโหลดไฟล์ png สำหรับไอคอนแอปขนาด 144 x 144 พิกเซล และตั้งชื่อว่า .png

เพิ่มไอคอนแอป

เปิดใช้การลิงก์บัญชี

หากต้องการเปิดใช้การลิงก์บัญชีหลังจากติดตั้งใช้งานโปรเจ็กต์แล้ว ให้ทําตามขั้นตอนต่อไปนี้

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

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

  1. แตะกลับไปยังหน้าก่อนหน้า ระบบจะเพิ่มกล้อง WebRTC ลงในโครงสร้างในแอป Google Home

เริ่มสตรีม WebRTC

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

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

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

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

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

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

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