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

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

  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

  1. ไปที่ Firebase
  2. คลิกสร้างโปรเจ็กต์ แล้วป้อนชื่อโปรเจ็กต์
  3. เลือกช่องทำเครื่องหมายข้อตกลง แล้วคลิกต่อไป หากไม่มีช่องทำเครื่องหมายข้อตกลง คุณข้ามขั้นตอนนี้ได้
    สร้างโปรเจ็กต์ Firebase
  4. เมื่อสร้างโปรเจ็กต์ Firebase แล้ว ให้ค้นหารหัสโปรเจ็กต์ ไปที่ภาพรวมโปรเจ็กต์ แล้วคลิกไอคอนการตั้งค่า > การตั้งค่าโปรเจ็กต์
    เปิดการตั้งค่าโปรเจ็กต์
  5. โปรเจ็กต์จะแสดงอยู่ในแท็บทั่วไป
    การตั้งค่าทั่วไปของโปรเจ็กต์

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

  1. ไปที่ไดเรกทอรี camerastream-start แล้วตั้งค่า Firebase CLI กับโปรเจ็กต์ Actions โดยทำดังนี้
$ cd camerastream-start
$ firebase use <firebase-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 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. แลกเปลี่ยนข้อความโปรโตคอลคำอธิบายเซสชัน (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://<firebase-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 แล้ว

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