ใช้งาน CameraStream ด้วย WebRTC

1. ข้อควรปฏิบัติก่อนที่จะเริ่มต้น

ลักษณะเฉพาะของ CameraStream คืออุปกรณ์ที่สามารถสตรีมวิดีโอฟีดไปยัง Smart Display, อุปกรณ์ Chromecast และสมาร์ทโฟน ตอนนี้โปรโตคอล WebRTC ได้รับการสนับสนุนภายในลักษณะเฉพาะของ 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. เริ่มต้นใช้งาน

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

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

  1. ในหน้าคุณต้องการสร้างการกระทําประเภทใด ให้คลิกบ้านอัจฉริยะ > เริ่มสร้างสิ่งปลูกสร้าง โปรเจ็กต์จะเปิดขึ้นในคอนโซล Actions

แท็บภาพรวมในคอนโซล Actions

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

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

  1. คลิกการดําเนินการ
  2. ในช่องข้อความ URL Fulfillment ให้ป้อน URL ตัวยึดตําแหน่ง เช่น https://example.com

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

ซอร์สโค้ดของ Codelab นี้จะมีไคลเอ็นต์ WebRTC ที่สร้าง เจรจาต่อรอง และจัดการเซสชัน WebRTC ระหว่างเว็บแคมและอุปกรณ์ Smart Home ของ 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

  1. ไปที่ไดเรกทอรี camerastream-start แล้วตั้งค่า Firebase CLI ด้วยโปรเจ็กต์การดําเนินการของคุณ
$ 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. กําหนดค่า 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 Session Description Protocol (SDP)

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

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

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

หน้า Realtime Database ในคอนโซล Firebase

  1. ในเมนูแบบเลื่อนลง ตําแหน่งฐานข้อมูลแบบเรียลไทม์ ให้เลือกตําแหน่งที่เหมาะสมที่จะใช้โฮสต์ฐานข้อมูลของคุณ

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

  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

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

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

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

อัปเดตคําตอบSYNC

  1. ไปยังไฟล์ functions/index.js มีโค้ดที่ใช้ตอบสนองต่อคําขอจาก Assistant
  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
        },
      }],
    },
  };
});

จัดการ Intent ของ EXECUTE

EXECUTE Intent จัดการคําสั่งเพื่ออัปเดตสถานะอุปกรณ์ การตอบสนองจะแสดงสถานะของคําสั่งแต่ละรายการ เช่น 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 ใช้งานได้ ให้ปรับใช้ 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

จากแอปไคลเอ็นต์ของ Google Home Camera CameraStream คุณจะเห็นว่า SPD และ Answer SD ของข้อเสนอพิเศษสามารถสร้างและแลกเปลี่ยนได้สําเร็จ รูปภาพจากเว็บแคมจะสตรีมไปยังอุปกรณ์ Smart Display ของ Google ด้วย WebRTC

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

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

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