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
สร้างโปรเจ็กต์
- ไปที่ Google Home Developer Console
- คลิกสร้างโปรเจ็กต์ ป้อนชื่อโปรเจ็กต์ แล้วคลิกสร้างโปรเจ็กต์
เรียกใช้แอปไคลเอ็นต์ 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
- ไปที่ Firebase
- คลิกสร้างโปรเจ็กต์ แล้วป้อนชื่อโปรเจ็กต์
- เลือกช่องทำเครื่องหมายข้อตกลง แล้วคลิกต่อไป หากไม่มีช่องทำเครื่องหมายข้อตกลง คุณข้ามขั้นตอนนี้ได้
- เมื่อสร้างโปรเจ็กต์ Firebase แล้ว ให้ค้นหารหัสโปรเจ็กต์ ไปที่ภาพรวมโปรเจ็กต์ แล้วคลิกไอคอนการตั้งค่า > การตั้งค่าโปรเจ็กต์
- โปรเจ็กต์จะแสดงอยู่ในแท็บทั่วไป
เชื่อมต่อกับ Firebase
- ไปที่ไดเรกทอรี
camerastream-start
แล้วตั้งค่า Firebase CLI กับโปรเจ็กต์ Actions โดยทำดังนี้
$ cd camerastream-start $ firebase use <firebase-project-id>
- ในไดเรกทอรี
camerastream-start
ให้ไปที่โฟลเดอร์functions
แล้วติดตั้ง Dependency ที่จําเป็นทั้งหมด ดังนี้
$ cd functions $ npm install
- หากเห็นข้อความต่อไปนี้ ให้เพิกเฉย คําเตือนนี้เกิดจากข้อกําหนดเบื้องต้นเวอร์ชันเก่า ดูข้อมูลเพิ่มเติมได้ที่ปัญหานี้ใน 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. แลกเปลี่ยนข้อความโปรโตคอลคำอธิบายเซสชัน (SDP)
การแลกเปลี่ยนข้อความ SDP เป็นขั้นตอนสำคัญในการสร้างสตรีม WebRTC SDP เป็นโปรโตคอลแบบข้อความที่อธิบายลักษณะของเซสชันมัลติมีเดีย ซึ่งใช้ใน WebRTC เพื่อเจรจาต่อรองพารามิเตอร์ของการเชื่อมต่อแบบ peer-to-peer เช่น ตัวแปลงรหัสที่ใช้ ที่อยู่ 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
เมื่อกำหนดค่าการดำเนินการแล้ว บริการระบบคลาวด์จะต้องจัดการ Intent ต่อไปนี้
- Intent
SYNC
ที่เกิดขึ้นเมื่อ Assistant ต้องการทราบว่าผู้ใช้เชื่อมต่ออุปกรณ์ใดอยู่ ระบบจะส่งข้อมูลนี้ไปยังบริการของคุณเมื่อผู้ใช้ลิงก์บัญชี คุณควรตอบกลับด้วยเพย์โหลด JSON ของอุปกรณ์ของผู้ใช้และความสามารถของอุปกรณ์ - Intent
EXECUTE/QUERY
ที่เกิดขึ้นเมื่อ Assistant ต้องการควบคุมอุปกรณ์ในนามของผู้ใช้ คุณควรตอบกลับด้วยเพย์โหลด JSON ที่มีสถานะการดำเนินการของอุปกรณ์แต่ละเครื่องที่ขอ
ในส่วนนี้ คุณจะอัปเดตฟังก์ชันที่ติดตั้งใช้งานก่อนหน้านี้เพื่อจัดการความตั้งใจเหล่านี้
อัปเดตคําตอบ SYNC
- ไปที่ไฟล์
functions/index.js
ซึ่งมีโค้ดสําหรับตอบคําขอจาก Assistant - แก้ไข 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
},
}],
},
};
});
- ไม่ได้กำหนด
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
กำหนดค่าโปรเจ็กต์คอนโซลนักพัฒนาซอฟต์แวร์
- ไปที่คอนโซลนักพัฒนาแอป
- คลิกสร้างโปรเจ็กต์ ป้อนชื่อโปรเจ็กต์ แล้วคลิกสร้างโปรเจ็กต์
เลือกการผสานรวมระบบคลาวด์กับระบบคลาวด์
ในหน้าแรกของโปรเจ็กต์ในคอนโซลของนักพัฒนาซอฟต์แวร์ ให้เลือกเพิ่มการผสานรวมระบบคลาวด์กับระบบคลาวด์ในส่วนระบบคลาวด์กับระบบคลาวด์
- ป้อนชื่อการผสานรวม แล้วเลือกกล้องในส่วนประเภทอุปกรณ์ ชื่อนี้จะปรากฏในแอป Google Home ในภายหลังเมื่อมีอุปกรณ์ที่ต้องตั้งค่า สําหรับ Codelab นี้ เราได้ป้อน WebRTC Codelab เป็นชื่อที่แสดง แต่คุณใช้ชื่ออื่นได้
- ในส่วนการสร้างแบรนด์แอป ให้อัปโหลดไฟล์
png
สำหรับไอคอนแอปขนาด 144 x 144 พิกเซล และตั้งชื่อว่า.png
เปิดใช้การลิงก์บัญชี
หากต้องการเปิดใช้การลิงก์บัญชีหลังจากติดตั้งใช้งานโปรเจ็กต์แล้ว ให้ทําตามขั้นตอนต่อไปนี้
- ไปที่ Developer Console แล้วเปิดโปรเจ็กต์
- ในส่วนระบบคลาวด์ต่อระบบคลาวด์ ให้คลิกพัฒนา > แก้ไขข้างการผสานรวม
- ในหน้าการตั้งค่าและการกําหนดค่า ให้ค้นหาส่วนการลิงก์บัญชี แล้วป้อนข้อมูลต่อไปนี้ในกล่องข้อความที่เกี่ยวข้อง
รหัสลูกค้า |
|
รหัสลับไคลเอ็นต์ |
|
URL สำหรับการอนุญาต |
|
URL โทเค็น |
|
- คลิกบันทึก > ทดสอบ
5. ทดสอบกล้องเสมือนของ WebRTC
- ไปที่ URL โฮสติ้งที่คุณเห็นเมื่อทำให้โปรเจ็กต์ Firebase ใช้งานได้ คุณจะเห็นอินเทอร์เฟซต่อไปนี้ ซึ่งเป็นแอปไคลเอ็นต์ CameraStream
- ในแผงความละเอียดของวิดีโอในเครื่อง ให้เลือกวิดีโอที่ต้องการ
- ให้สิทธิ์แอปไคลเอ็นต์ CameraStream เข้าถึงเว็บแคมและไมโครโฟน ฟีดวิดีโอจากเว็บแคมจะปรากฏในไคลเอ็นต์
ลิงก์กับบ้านอัจฉริยะ CameraStream
การดําเนินการ
- ในแอป Google Home ให้แตะเพิ่ม > ใช้ได้กับ Google
- ค้นหาการดำเนินการที่คุณสร้างขึ้น แล้วเลือกการดำเนินการนั้น
- จดรหัสที่เป็นตัวอักษรและตัวเลขคละกัน 5 ตัวที่ไม่ซ้ำกันไว้เนื่องจากคุณจะต้องใช้ในภายหลัง
- แตะกลับไปยังหน้าก่อนหน้า ระบบจะเพิ่มกล้อง WebRTC ลงในโครงสร้างในแอป Google Home
เริ่มสตรีม WebRTC
- ในหน้าเว็บสำหรับแอปไคลเอ็นต์ CameraStream ให้ป้อนรหัสที่เป็นตัวอักษรและตัวเลขจากส่วนสุดท้ายในกล่องข้อความค่าโทเค็นการลิงก์บัญชี แล้วคลิกส่ง
- หากต้องการเริ่มเซสชัน WebRTC จากอุปกรณ์จออัจฉริยะของ Google ให้ทําอย่างใดอย่างหนึ่งต่อไปนี้
- พูดว่า "Ok Google สตรีมกล้อง WebRTC"
- ในอุปกรณ์จออัจฉริยะของ Google ให้แตะการควบคุมอุปกรณ์สมาร์ทโฮม > กล้อง > กล้อง WebRTC
จากแอปไคลเอ็นต์ CameraStream สมาร์ทโฮมของ Google คุณจะเห็นการสร้างและแลกเปลี่ยน SPD ของข้อเสนอและ SDP ของคำตอบเรียบร้อยแล้ว ระบบจะสตรีมรูปภาพจากเว็บแคมไปยังอุปกรณ์จออัจฉริยะของ Google ด้วย WebRTC
6. ขอแสดงความยินดี
ยินดีด้วย คุณได้ดูวิธีสตรีมจากเว็บแคมไปยังอุปกรณ์จอแสดงผล Google Nest ด้วยโปรโตคอล WebRTC แล้ว