1. ก่อนเริ่มต้น
ลักษณะ CameraStream
เป็นของอุปกรณ์ที่สามารถสตรีมฟีดวิดีโอไปยังจออัจฉริยะ อุปกรณ์ Chromecast และสมาร์ทโฟนได้ ขณะนี้ระบบรองรับโปรโตคอล WebRTC ภายในลักษณะ CameraStream
แล้ว ซึ่งหมายความว่าคุณจะลดเวลาในการตอบสนองของการเริ่มต้นใช้งานและการสตรีมจากอุปกรณ์กล้องไปยังอุปกรณ์แสดงผล 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 ให้ทำตามขั้นตอนต่อไปนี้
- ดาวน์โหลดและติดตั้ง Firebase CLI โดยทำดังนี้
$ npm install -g firebase-tools
- ยืนยันว่า CLI ติดตั้งอย่างถูกต้องแล้ว ดังนี้
$ firebase --version
- ให้สิทธิ์ Firebase CLI ด้วยบัญชี Google
$ firebase login
สร้างและกำหนดค่าโปรเจ็กต์ Actions
- ไปที่คอนโซล Actions แล้วคลิกโปรเจ็กต์ใหม่
- ในช่องข้อความชื่อโปรเจ็กต์ ให้ป้อนชื่อโปรเจ็กต์ แล้วคลิกสร้างโปรเจ็กต์
- ในหน้าคุณต้องการสร้างการดำเนินการประเภทใด ให้คลิกสมาร์ทโฮม > เริ่มสร้าง โปรเจ็กต์จะเปิดขึ้นในคอนโซลการดำเนินการ
- คลิกพัฒนา > การเรียกใช้
- ในช่องข้อความชื่อที่แสดง ให้ป้อนชื่อสำหรับการดำเนินการ แล้วคลิกบันทึก ชื่อนี้จะปรากฏในแอป Google Home ภายหลังเมื่อมีอุปกรณ์สำหรับตั้งค่า สำหรับ Codelab นี้ เราป้อน
WebRTC Codelab
เป็นชื่อที่แสดง แต่คุณใช้ชื่ออื่นได้
- คลิกการดำเนินการ
- ในช่องข้อความ 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
- ไปที่ไดเรกทอรี
camerastream-start
จากนั้นตั้งค่า Firebase CLI ด้วยโปรเจ็กต์ Actions ดังนี้
$ cd camerastream-start $ firebase use PROJECT_ID
- ในไดเรกทอรี
camerastream-start
ให้ไปที่โฟลเดอร์functions
แล้วติดตั้งทรัพยากร Dependency ทั้งหมดที่จำเป็นดังนี้
$ cd functions $ npm install
- หากเห็นข้อความต่อไปนี้ ก็ไม่ต้องสนใจ คำเตือนนี้เกิดจากทรัพยากร Dependency เก่า ดูข้อมูลเพิ่มเติมได้ที่ปัญหาเกี่ยวกับ GitHub นี้
found 5 high severity vulnerabilities run `npm audit fix` to fix them, or `npm audit` for details
- เริ่มต้นโปรเจ็กต์ Firebase
$ firebase init
- เลือกฟังก์ชันและโฮสติ้ง การดำเนินการนี้จะเริ่มต้น 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
- กำหนดค่า 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
- กำหนดค่าโฮสติ้งด้วยไดเรกทอรี
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 สำหรับสมาร์ทโฮม ให้ทำตามขั้นตอนต่อไปนี้
- ในคอนโซล Firebase ให้คลิกสร้าง > ฐานข้อมูลเรียลไทม์ > สร้างฐานข้อมูล
- ในเมนูแบบเลื่อนลงตำแหน่งของ Realtime Database ให้เลือกตำแหน่งที่เหมาะสมในการโฮสต์ฐานข้อมูล
- เลือกเริ่มในโหมดทดสอบ แล้วคลิกเปิดใช้ เมื่อเปิดใช้ Realtime Database คุณจะต้องสามารถอ้างอิงได้จากแอปไคลเอ็นต์ CameraStream
- ในคอนโซล Firebase ให้เลือก การตั้งค่าโปรเจ็กต์ > การตั้งค่าโปรเจ็กต์ > เพิ่ม Firebase ไปยังเว็บแอปเพื่อเปิดเวิร์กโฟลว์การตั้งค่า
- หากเพิ่มแอปลงในโปรเจ็กต์ Firebase แล้ว ให้คลิกเพิ่มแอปเพื่อแสดงตัวเลือกแพลตฟอร์ม
- ป้อนชื่อเล่นของแอป เช่น
My web app
แล้วคลิกลงทะเบียนแอป - ในส่วนเพิ่ม Firebase SDK ให้เลือกใช้แท็ก <script>
- คัดลอกค่าจากออบเจ็กต์
firebasebaseConfig
แล้ววางลงในไฟล์camaerastream-start/public/webrtc_generator.js
const firebaseConfig = {
apiKey: "XXXXX",
authDomain: "XXXXX",
projectId: "XXXXX",
storageBucket: "XXXXX",
messagingSenderId: "XXXXX",
appId: "XXXXX",
measurementId: "XXXXX"
};
- คลิกดำเนินการต่อในคอนโซลเพื่อทำขั้นตอนให้เสร็จ คุณจะเห็นเว็บแอปที่สร้างขึ้นใหม่ในหน้าการตั้งค่าโปรเจ็กต์
4. สร้างกล้อง WebRTC
ตอนนี้คุณกำหนดค่า Action แล้ว บริการระบบคลาวด์ต้องจัดการ Intent ต่อไปนี้
- Intent
SYNC
ที่เกิดขึ้นเมื่อ Assistant ต้องการทราบอุปกรณ์ที่ผู้ใช้เชื่อมต่ออยู่ โดยจะส่งไปยังบริการของคุณเมื่อผู้ใช้ลิงก์บัญชี คุณควรตอบกลับด้วยเพย์โหลด JSON ของอุปกรณ์และความสามารถของอุปกรณ์ของผู้ใช้ - Intent
EXECUTE/QUERY
ที่เกิดขึ้นเมื่อ Assistant ต้องการควบคุมอุปกรณ์ในนามของผู้ใช้ คุณควรตอบกลับด้วยเพย์โหลด JSON พร้อมสถานะการดำเนินการของอุปกรณ์แต่ละเครื่องที่ขอ
ในส่วนนี้ คุณจะอัปเดตฟังก์ชันที่คุณทำให้ใช้งานได้ก่อนหน้านี้เพื่อจัดการ Intent เหล่านี้
อัปเดตการตอบกลับ SYNC
- ไปที่ไฟล์
functions/index.js
มีโค้ดสำหรับตอบกลับคำขอจาก Assistant - แก้ไข
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
ให้แก้ไข IntentEXECUTE
เพื่อแสดงผลปลายทาง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
เปิดใช้การลิงก์บัญชี
หากต้องการเปิดใช้การลิงก์บัญชีหลังจากติดตั้งใช้งานโปรเจ็กต์แล้ว ให้ทำตามขั้นตอนต่อไปนี้
- ในคอนโซล Actions ให้เลือกพัฒนา > การลิงก์บัญชี
- ในส่วนข้อมูลไคลเอ็นต์ OAuth ให้ป้อนข้อมูลต่อไปนี้ในกล่องข้อความที่สอดคล้องกัน
Client ID |
|
รหัสลับไคลเอ็นต์ |
|
URL การให้สิทธิ์ |
|
URL ของโทเค็น |
|
- คลิกบันทึก > ทดสอบ
5. ทดสอบกล้อง WebRTC เสมือน
- ไปที่ URL โฮสติ้งที่เห็นเมื่อทำให้โปรเจ็กต์ Firebase ใช้งานได้ คุณจะเห็นอินเทอร์เฟซต่อไปนี้ซึ่งเป็นแอปไคลเอ็นต์ CameraStream
- ในแผงความละเอียดวิดีโอในเครื่อง ให้เลือกวิดีโอที่ต้องการ
- ให้สิทธิ์แก่แอปไคลเอ็นต์ CameraStream เพื่อเข้าถึงเว็บแคมและไมโครโฟน ฟีดวิดีโอจากเว็บแคมของคุณจะปรากฏบนไคลเอ็นต์
ลิงก์ไปยังสมาร์ทโฮม CameraStream
การดำเนินการ
- ในแอป Google Home ให้แตะเพิ่ม > ใช้ได้กับ Google
- ค้นหาการดำเนินการที่คุณสร้างขึ้นแล้วเลือกการดำเนินการนั้น
- โปรดสังเกตรหัสที่เป็นตัวอักษรและตัวเลขคละกันความยาว 5 อักขระที่ไม่ซ้ำกัน เนื่องจากคุณจำเป็นต้องใช้ในภายหลัง
- แตะนำฉันกลับ มีการเพิ่มกล้อง WebRTC ไปยังโครงสร้างของคุณในแอป Google Home
เริ่มสตรีม WebRTC
- ในหน้าเว็บสำหรับแอปไคลเอ็นต์ CameraStream ให้ป้อนรหัสตัวอักษรและตัวเลขคละกันจากส่วนสุดท้ายในช่องข้อความค่าโทเค็นการลิงก์บัญชี แล้วคลิกส่ง
- หากต้องการเริ่มเซสชัน WebRTC จากอุปกรณ์ Smart Display ของ Google ให้ทำอย่างใดอย่างหนึ่งต่อไปนี้
- พูดว่า "Ok Google สตรีมกล้อง WebRTC"
- ในอุปกรณ์ Smart Display ของ Google ให้แตะระบบควบคุมอุปกรณ์ในบ้าน > กล้อง > กล้อง WebRTC
จากแอปไคลเอ็นต์ CameraStream ในสมาร์ทโฮมของ Google คุณจะเห็นว่าการสร้างและแลกเปลี่ยนข้อเสนอ SPD และ SDP ของข้อเสนอนั้นเสร็จสมบูรณ์แล้ว รูปภาพจากเว็บแคมของคุณจะสตรีมไปยังอุปกรณ์ Smart Display ของ Google ผ่าน WebRTC
6. ขอแสดงความยินดี
ยินดีด้วย คุณได้เรียนรู้วิธีสตรีมจากเว็บแคมไปยังอุปกรณ์แสดงผล Google Nest ด้วยโปรโตคอล WebRTC แล้ว