1. Trước khi bắt đầu
Đặc điểm CameraStream thuộc về những thiết bị có khả năng phát trực tuyến nguồn cấp dữ liệu video đến màn hình thông minh, thiết bị Chromecast và điện thoại thông minh. Giao thức WebRTC hiện được hỗ trợ trong đặc điểm CameraStream. Điều này có nghĩa là bạn có thể giảm đáng kể độ trễ khi khởi động và phát trực tuyến từ thiết bị camera đến thiết bị màn hình Google Nest.

Điều kiện tiên quyết
Kiến thức bạn sẽ học được
- Cách triển khai dịch vụ đám mây nhà thông minh.
- Cách kết nối dịch vụ của bạn với Trợ lý Google.
- Cách truyền phát trực tiếp đến màn hình Google Nest bằng giao thức WebRTC.
Bạn cần có
- Một trình duyệt web, chẳng hạn như Google Chrome.
- Thiết bị iOS hoặc Android có ứng dụng Google Home.
- Node.js phiên bản 10.16 trở lên.
- Gói linh hoạt (trả tiền theo mức dùng) cho Firebase.
- Một thiết bị webcam tích hợp hoặc bên ngoài có thể hỗ trợ độ phân giải Full HD.
- Thiết bị màn hình Nest của Google.
2. Bắt đầu
Cài đặt Giao diện dòng lệnh (CLI) của Firebase
Giao diện dòng lệnh (CLI) của Firebase cho phép bạn phân phát các ứng dụng web cục bộ và triển khai chúng lên Lưu trữ Firebase.
Để cài đặt Giao diện dòng lệnh (CLI) của Firebase, hãy làm theo các bước sau:
- Trong thiết bị đầu cuối, hãy tải xuống và cài đặt Giao diện dòng lệnh (CLI) của Firebase:
$ npm install -g firebase-tools
- Xác minh rằng bạn đã cài đặt CLI đúng cách:
$ firebase --version
- Uỷ quyền cho Giao diện dòng lệnh (CLI) của Firebase bằng Tài khoản Google của bạn:
$ firebase login
Tạo dự án
- Chuyển đến Google Home Developer Console.
- Nhấp vào Tạo dự án, nhập tên cho dự án rồi nhấp vào Tạo dự án.

Chạy ứng dụng CameraStream
Mã nguồn của lớp học lập trình này bao gồm một ứng dụng WebRTC thiết lập, thương lượng và quản lý phiên WebRTC giữa webcam và thiết bị màn hình nhà thông minh của Google.
Để chạy ứng dụng CameraStream WebRTC, hãy làm một trong những việc sau:
- Nhấp vào nút sau đây để tải mã nguồn xuống máy phát triển của bạn:
- Sao chép kho lưu trữ này trên GitHub:
$ git clone https://github.com/google-home/smarthome-camerastream-webrtc.git
Mã này có các thư mục sau:
- Thư mục
camerastream-startchứa mã khởi đầu mà bạn sẽ dùng để tạo. - Thư mục
camerastream-donechứa mã giải pháp cho lớp học lập trình đã hoàn thành.
Thư mục camerastream-start chứa các thư mục con sau:
- Thư mục con
publicchứa giao diện người dùng để dễ dàng kiểm soát và theo dõi trạng thái của thiết bị camera. - Thư mục con
functionschứa một dịch vụ đám mây được triển khai đầy đủ, quản lý camera bằng Cloud Functions cho Firebase và Cơ sở dữ liệu theo thời gian thực.
Mã khởi đầu chứa các nhận xét TODO cho biết vị trí bạn cần thêm hoặc thay đổi mã, chẳng hạn như ví dụ sau:
// TODO: Implement full SYNC response.
Thêm Firebase vào dự án Google Home Developer Console
Cách 1: Thông qua bảng điều khiển của Firebase
- Truy cập vào Firebase.
- Nhấp vào Tạo dự án Firebase.

- Trên màn hình Tạo dự án, hãy nhấp vào Thêm Firebase vào dự án trên Google Cloud.

- Trên màn hình Bắt đầu, hãy chọn dự án trên đám mây của Google mà bạn vừa tạo trong Google Home Developer Console rồi nhấp vào Tiếp tục.

Cách 2: Thông qua Giao diện dòng lệnh (CLI) của Firebase
firebase projects:addfirebase
Chọn dự án Google Home Developer Console mà bạn vừa tạo để thêm Firebase.
Khi bạn thêm Firebase vào dự án trên Google Home Developer Console, dự án đó sẽ xuất hiện trong Bảng điều khiển Firebase. Mã dự án của dự án Firebase sẽ khớp với mã dự án của bạn trên Google Home Developer Console.

Kết nối với Firebase
- Chuyển đến thư mục
camerastream-start, sau đó thiết lập Firebase CLI bằng dự án Actions của bạn:
$ cd camerastream-start $ firebase use <project-id>
- Trong thư mục
camerastream-start, hãy chuyển đến thư mụcfunctionsrồi cài đặt tất cả các phần phụ thuộc cần thiết:
$ cd functions $ npm install
- Nếu bạn thấy thông báo sau, hãy bỏ qua. Cảnh báo này là do các phần phụ thuộc cũ. Để biết thêm thông tin, hãy xem vấn đề này trên GitHub.
found 5 high severity vulnerabilities run `npm audit fix` to fix them, or `npm audit` for details
- Khởi động một dự án Firebase:
$ firebase init
- Chọn Functions (Hàm) và Hosting (Lưu trữ). Thao tác này sẽ khởi chạy các API và tính năng cần thiết cho dự án của bạn.
? 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
- Định cấu hình Cloud Functions bằng các tệp mặc định và đảm bảo rằng bạn không ghi đè các tệp
index.jsvàpackage.jsonhiện có trong mẫu dự án:
? 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
- Định cấu hình Hosting bằng thư mục
publictrong mã dự án và sử dụng tệpindex.htmlhiện có:
? 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. Trao đổi thông báo theo Giao thức mô tả phiên (SDP)
Việc trao đổi thông báo SDP là một bước quan trọng trong việc thiết lập luồng WebRTC. SDP là một giao thức dựa trên văn bản, mô tả các đặc điểm của một phiên đa phương tiện. ICE được dùng trong WebRTC để thương lượng các thông số của một kết nối ngang hàng, chẳng hạn như codec được dùng, địa chỉ IP của những người tham gia và các cổng được dùng để truyền tải nội dung nghe nhìn.
Để sử dụng Cơ sở dữ liệu theo thời gian thực làm máy chủ lưu trữ để trao đổi thông báo SDP giữa webcam và ứng dụng CameraStream cho nhà thông minh, hãy làm theo các bước sau:
- Trong bảng điều khiển của Firebase, hãy nhấp vào Tạo > Cơ sở dữ liệu theo thời gian thực > Tạo cơ sở dữ liệu.

- Trong trình đơn thả xuống Vị trí của Cơ sở dữ liệu theo thời gian thực, hãy chọn một vị trí phù hợp để lưu trữ cơ sở dữ liệu của bạn.

- Chọn Bắt đầu ở chế độ kiểm thử rồi nhấp vào Bật. Khi bật Cơ sở dữ liệu theo thời gian thực, bạn cần có khả năng tham chiếu cơ sở dữ liệu này từ ứng dụng CameraStream.
- Trong bảng điều khiển của Firebase, hãy chọn
Cài đặt dự án > Cài đặt dự án >
Thêm Firebase vào ứng dụng web của bạn để khởi chạy quy trình thiết lập. - Nếu bạn đã thêm một ứng dụng vào dự án Firebase, hãy nhấp vào Thêm ứng dụng để hiển thị các lựa chọn về nền tảng.
- Nhập một biệt hiệu cho ứng dụng, chẳng hạn như
My web app, rồi nhấp vào Đăng ký ứng dụng. - Trong mục Thêm Firebase SDK, hãy chọn Sử dụng thẻ <script>.
- Sao chép các giá trị từ đối tượng
firebasebaseConfigrồi dán vào tệpcamaerastream-start/public/webrtc_generator.js.
const firebaseConfig = {
apiKey: "XXXXX",
authDomain: "XXXXX",
projectId: "XXXXX",
storageBucket: "XXXXX",
messagingSenderId: "XXXXX",
appId: "XXXXX",
measurementId: "XXXXX"
};
- Nhấp vào Tiếp tục đến bảng điều khiển để hoàn tất quy trình. Bạn sẽ thấy ứng dụng web mới tạo trên trang Cài đặt dự án.
4. Tạo camera WebRTC
Giờ đây, sau khi bạn định cấu hình Thao tác, dịch vụ đám mây của bạn cần xử lý các ý định sau:
- Một ý định
SYNCxảy ra khi Trợ lý muốn biết người dùng đã kết nối những thiết bị nào. Thông tin này được gửi đến dịch vụ của bạn khi người dùng liên kết một tài khoản. Bạn nên phản hồi bằng một tải trọng JSON gồm các thiết bị của người dùng và khả năng của các thiết bị đó. - Một ý định
EXECUTE/QUERYxảy ra khi Trợ lý muốn thay mặt người dùng điều khiển một thiết bị. Bạn nên phản hồi bằng một tải trọng JSON có trạng thái thực thi của từng thiết bị được yêu cầu.
Trong phần này, bạn sẽ cập nhật các hàm mà bạn đã triển khai trước đó để xử lý những ý định này.
Cập nhật câu trả lời SYNC
- Chuyển đến tệp
functions/index.js. Nó chứa mã để phản hồi các yêu cầu từ Trợ lý. - Chỉnh sửa ý định
SYNCđể trả về siêu dữ liệu và các chức năng của thiết bị:
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_IDchưa được xác định trong mã. Thêm nội dung sau vàoconst _ = require('underscore');:
// Hardcoded user ID
const USER_ID = '123';
Xử lý ý định EXECUTE
Ý định EXECUTE xử lý các lệnh cập nhật trạng thái thiết bị. Phản hồi sẽ trả về trạng thái của từng lệnh (ví dụ: SUCCESS, ERROR hoặc PENDING) và trạng thái mới của thiết bị.
Để xử lý ý định EXECUTE, hãy chỉnh sửa ý định EXECUTE để trả về điểm cuối signaling của dự án Firebase trong tệp 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],
},
};
});
Xử lý giao thức Chia sẻ tài nguyên trên nhiều nguồn gốc (CORS)
Để xử lý CORS do sử dụng phương thức POST để gửi SDP, hãy thêm URL của Lưu trữ Firebase vào mảng allowlist trong tệp functions/index.js:
index.js
'use strict';
.....
var allowList = ['https://www.gstatic.com','https://<project-id>.web.app']; //TODO Add Firebase hosting URL.
Để biết thêm thông tin về CORS, hãy xem phần Chia sẻ tài nguyên trên nhiều nguồn gốc (CORS).
Xử lý việc kết thúc luồng
Để xử lý việc chấm dứt luồng WebRTC, hãy thêm URL hàm "truyền tín hiệu" của Firebase vào tệp 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();
Triển khai lên Firebase
Để triển khai lên Firebase, hãy triển khai yêu cầu thực hiện trên đám mây đã cập nhật bằng Giao diện dòng lệnh (CLI) của Firebase:
$ firebase deploy
Lệnh này triển khai một ứng dụng web và một số Cloud Functions cho Firebase:
... ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/<project-id>/overview Hosting URL: https://<project-id>.web.app
Định cấu hình dự án Developer Console
- Chuyển đến Developer Console.
- Nhấp vào Tạo dự án, nhập tên cho dự án rồi nhấp vào Tạo dự án.

Chọn chế độ Tích hợp từ đám mây sang đám mây
Trên Trang chủ dự án trong Developer Console, hãy chọn Thêm tính năng tích hợp đám mây với đám mây trong mục Đám mây với đám mây.

- Nhập tên tích hợp rồi chọn Camera trong mục Loại thiết bị. Tên này sẽ xuất hiện trong ứng dụng Google Home sau này khi có thiết bị cần thiết lập. Trong lớp học lập trình này, chúng ta đã nhập WebRTC Codelab làm tên hiển thị, nhưng bạn có thể sử dụng một tên khác.

- Trong mục Thương hiệu của ứng dụng, hãy tải một tệp
pngcó kích thước 144 x 144 px lên cho biểu tượng ứng dụng và đặt tên là..png

Bật tính năng liên kết tài khoản
Để bật tính năng liên kết tài khoản sau khi triển khai dự án, hãy làm theo các bước sau:
- Chuyển đến Developer Console rồi mở dự án.
- Trong phần Đám mây với đám mây, hãy nhấp vào Phát triển > Chỉnh sửa bên cạnh chế độ tích hợp.
- Trên trang Thiết lập và cấu hình, hãy tìm mục Liên kết tài khoản rồi nhập thông tin sau vào các hộp văn bản tương ứng:
ID khách hàng |
|
Mật khẩu ứng dụng khách |
|
URL Uỷ quyền |
|
URL mã thông báo |
|

- Nhấp vào Lưu > Kiểm thử.
5. Kiểm thử camera WebRTC ảo
- Chuyển đến URL lưu trữ mà bạn thấy khi triển khai dự án Firebase. Bạn sẽ thấy giao diện sau đây, đây là ứng dụng CameraStream:

- Trong bảng Độ phân giải video cục bộ, hãy chọn video bạn muốn.
- Cấp quyền cho ứng dụng CameraStream truy cập vào webcam và micrô của bạn. Nguồn cấp dữ liệu video từ webcam sẽ xuất hiện trên ứng dụng.
Liên kết với Thao tác CameraStream nhà thông minh
- Trong ứng dụng Google Home, hãy nhấn vào Thêm > Hoạt động với Google.

- Tìm Hành động mà bạn đã tạo rồi chọn hành động đó.

- Ghi lại mã gồm 5 ký tự chữ và số duy nhất vì bạn sẽ cần mã này sau.

- Nhấn vào Đưa tôi trở lại. Camera WebRTC sẽ được thêm vào cấu trúc của bạn trong ứng dụng Google Home.
Bắt đầu một luồng WebRTC
- Trên trang web của ứng dụng CameraStream, hãy nhập mã chữ và số trong phần cuối cùng vào hộp văn bản Giá trị mã thông báo liên kết tài khoản rồi nhấp vào Gửi.

- Để bắt đầu một phiên WebRTC trên thiết bị màn hình thông minh của Google, hãy làm một trong những việc sau:
- Nói "Ok Google, truyền phát Camera WebRTC."
- Trên thiết bị Màn hình thông minh của Google, hãy nhấn vào Điều khiển nhà > Camera > Camera WebRTC.
Trong ứng dụng CameraStream của nhà thông minh Google, bạn sẽ thấy rằng SPD đề xuất và SDP phản hồi đã được tạo và trao đổi thành công. Hình ảnh từ webcam sẽ được truyền trực tuyến đến thiết bị Màn hình thông minh của Google bằng WebRTC.
6. Xin chúc mừng
Xin chúc mừng! Bạn đã tìm hiểu cách truyền trực tuyến từ webcam đến thiết bị màn hình Google Nest bằng giao thức WebRTC.