1. 시작하기 전에
CameraStream
트레잇은 스마트 디스플레이, Chromecast 기기, 스마트폰에 동영상 피드를 스트리밍할 수 있는 기기에 속합니다. 이제 WebRTC 프로토콜이 CameraStream
트레잇 내에서 지원되므로 카메라 기기에서 Google Nest 디스플레이 기기로의 시작 및 스트리밍 지연 시간을 크게 줄일 수 있습니다.
기본 요건
- 클라우드 간 입문서를 검토합니다.
학습할 내용
- 스마트 홈 클라우드 서비스를 배포하는 방법
- Google 어시스턴트에 서비스를 연결하는 방법
- WebRTC 프로토콜을 사용하여 Google Nest 디스플레이 기기로 스트리밍하는 방법
필요한 항목
- 웹브라우저(예: Chrome)
- Google Home 앱이 설치된 iOS 또는 Android 기기
- Node.js 버전 10.16 이상
- Firebase용 Blaze (사용한 만큼만 지불) 요금제
- 풀 HD 해상도를 지원할 수 있는 내장 또는 외장 웹캠 기기
- Google Nest 디스플레이 기기
2. 시작하기
Firebase CLI 설치
Firebase CLI를 사용하면 로컬에서 웹 앱을 제공하고 Firebase 호스팅에 배포할 수 있습니다.
Firebase CLI를 설치하려면 다음 단계를 따르세요.
- 터미널에서 Firebase CLI를 다운로드하여 설치합니다.
$ npm install -g firebase-tools
- CLI가 올바르게 설치되었는지 확인합니다.
$ firebase --version
- Google 계정으로 Firebase CLI를 승인합니다.
$ firebase login
프로젝트 만들기
- Google Home Developer Console로 이동합니다.
- 프로젝트 만들기를 클릭하고 프로젝트 이름을 입력한 후 프로젝트 만들기를 클릭합니다.
CameraStream 클라이언트 앱 실행
이 Codelab의 소스 코드에는 웹캠과 Google 스마트 홈 디스플레이 기기 간에 WebRTC 세션을 설정, 협상, 관리하는 WebRTC 클라이언트가 포함되어 있습니다.
CameraStream WebRTC 클라이언트 앱을 실행하려면 다음 중 하나를 실행합니다.
- 다음 버튼을 클릭하여 소스 코드를 개발 머신에 다운로드합니다.
- 이 GitHub 저장소를 클론합니다.
$ git clone https://github.com/google-home/smarthome-camerastream-webrtc.git
코드에는 다음 디렉터리가 포함됩니다.
- 빌드의 기반이 되는 시작 코드가 포함된
camerastream-start
디렉터리 - 완료된 Codelab의 솔루션 코드가 포함된
camerastream-done
디렉터리
camerastream-start
디렉터리에는 다음 하위 디렉터리가 포함됩니다.
public
하위 디렉터리: 카메라 기기의 상태를 쉽게 제어하고 모니터링할 수 있는 프런트엔드 UI가 포함되어 있습니다.functions
하위 디렉터리: Firebase용 Cloud Functions 및 실시간 데이터베이스로 카메라를 관리하는 완전히 구현된 클라우드 서비스가 포함되어 있습니다.
시작 코드에는 다음 예와 같이 코드를 추가하거나 변경해야 하는 위치를 나타내는 TODO
주석이 포함되어 있습니다.
// TODO: Implement full SYNC response.
Firebase 프로젝트 만들기
- Firebase로 이동합니다.
- 프로젝트 만들기를 클릭하고 프로젝트 이름을 입력합니다.
- 동의 체크박스를 선택하고 계속을 클릭합니다. 동의 체크박스가 없는 경우 이 단계를 건너뛰어도 됩니다.
- Firebase 프로젝트가 생성되면 프로젝트 ID를 찾습니다. 프로젝트 개요로 이동하여 설정 아이콘 > 프로젝트 설정을 클릭합니다.
- 프로젝트가 일반 탭에 표시됩니다.
Firebase에 연결
camerastream-start
디렉터리로 이동한 후 작업 프로젝트를 사용해 Firebase CLI를 설정합니다.
$ cd camerastream-start $ firebase use <firebase-project-id>
camerastream-start
디렉터리에서functions
폴더로 이동한 다음 필요한 모든 종속 항목을 설치합니다.
$ 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
- Functions 및 Hosting을 선택합니다. 이렇게 하면 프로젝트에 필요한 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에서 사용되는 코덱, 참여자의 IP 주소, 미디어 전송에 사용되는 포트와 같은 P2P 연결의 매개변수를 협상하는 데 사용됩니다.
실시간 데이터베이스를 호스트로 사용하여 웹캠과 스마트 홈 CameraStream 클라이언트 앱 간에 SDP 메시지를 교환하려면 다음 단계를 따르세요.
- Firebase Console에서 빌드 > 실시간 데이터베이스 > 데이터베이스 만들기를 클릭합니다.
- 실시간 데이터베이스 위치 드롭다운 메뉴에서 데이터베이스를 호스팅할 적절한 위치를 선택합니다.
- 테스트 모드로 시작을 선택한 다음 사용 설정을 클릭합니다. 실시간 데이터베이스를 사용 설정하면 CameraStream 클라이언트 앱에서 실시간 데이터베이스를 참조할 수 있어야 합니다.
- Firebase Console에서 프로젝트 설정 > 프로젝트 설정 > 웹 앱에 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"
};
- Console로 이동을 클릭하여 절차를 완료합니다. 프로젝트 설정 페이지에 새로 만든 웹 앱이 표시됩니다.
4. WebRTC 카메라 만들기
이제 작업을 구성했으므로 클라우드 서비스에서 다음 인텐트를 처리해야 합니다.
- 어시스턴트가 사용자가 연결한 기기를 알고자 할 때 발생하는
SYNC
인텐트입니다. 이 인텐트는 사용자가 계정을 연결하면 서비스로 전송됩니다. 사용자의 기기 및 기기 기능이 포함된 JSON 페이로드로 응답해야 합니다. - 어시스턴트가 사용자를 대신하여 기기를 제어하려고 할 때 발생하는
EXECUTE/QUERY
인텐트입니다. 요청된 각 기기의 실행 상태가 포함된 JSON 페이로드로 응답해야 합니다.
이 섹션에서는 이러한 인텐트를 처리하기 위해 이전에 배포한 함수를 업데이트합니다.
SYNC
응답 업데이트
functions/index.js
파일로 이동합니다. 여기에는 어시스턴트의 요청에 응답하는 코드가 포함되어 있습니다.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';
EXECUTE
인텐트 처리
EXECUTE
인텐트는 기기 상태를 업데이트하는 명령어를 처리합니다. 응답은 각 명령어의 상태(예: SUCCESS
, ERROR
또는 PENDING
)와 새 기기 상태를 반환합니다.
EXECUTE
인텐트를 처리하려면 functions/index.js
파일에서 Firebase 프로젝트의 signaling
엔드포인트를 반환하도록 EXECUTE
인텐트를 수정합니다.
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) 처리
POST
메서드를 사용하여 SDP를 전송할 때 발생하는 CORS를 처리하려면 functions/index.js
파일의 allowlist
배열에 Firebase 호스팅 URL을 추가합니다.
index.js
'use strict';
.....
var allowList = ['https://www.gstatic.com','https://<firebase-project-id>.web.app']; //TODO Add Firebase hosting URL.
CORS에 대한 자세한 내용은 교차 출처 리소스 공유 (CORS)를 참고하세요.
스트림 종료 처리
WebRTC 스트림 종료를 처리하려면 public/webrtc_generator.js
파일에 Firebase '신호' 함수 URL을 추가합니다.
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
이 명령어는 웹 앱과 여러 Firebase용 Cloud Functions를 배포합니다.
... ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/<project-id>/overview Hosting URL: https://<project-id>.web.app
개발자 콘솔 프로젝트 구성
- Developer Console로 이동합니다.
- 프로젝트 만들기를 클릭하고 프로젝트 이름을 입력한 후 프로젝트 만들기를 클릭합니다.
클라우드 간 통합 선택
Developer Console의 프로젝트 홈에서 클라우드 간의 클라우드 간 통합 추가를 선택합니다.
- 통합 이름을 입력하고 기기 유형에서 카메라를 선택합니다. 이 이름은 나중에 설정할 기기가 있을 때 Google Home 앱에 표시됩니다. 이 Codelab에서는 WebRTC Codelab을 표시 이름으로 입력했지만 다른 이름을 사용할 수도 있습니다.
- 앱 브랜딩에서 앱 아이콘의
png
파일을 업로드합니다. 크기는 144x144px이고 이름은
입니다..png
계정 연결 사용 설정
프로젝트가 배포된 후 계정 연결을 사용 설정하려면 다음 단계를 따르세요.
- Developer Console로 이동하여 프로젝트를 엽니다.
- 클라우드 간 섹션에서 통합 옆에 있는 개발 > 수정을 클릭합니다.
- 설정 및 구성 페이지에서 계정 연결 섹션을 찾아 해당 텍스트 상자에 다음 정보를 입력합니다.
클라이언트 ID |
|
클라이언트 비밀번호 |
|
인증 URL |
|
토큰 URL |
|
- 저장 > 테스트를 클릭합니다.
5. 가상 WebRTC 카메라 테스트
- Firebase 프로젝트를 배포할 때 표시된 호스팅 URL로 이동합니다. CameraStream 클라이언트 앱인 다음 인터페이스가 표시됩니다.
- 로컬 동영상 해상도 패널에서 원하는 동영상을 선택합니다.
- CameraStream 클라이언트 앱에 웹캠 및 마이크에 액세스할 수 있는 권한을 부여합니다. 웹캠의 동영상 피드가 클라이언트에 표시됩니다.
스마트 홈 CameraStream
작업 링크
- Google Home 앱에서 추가 > Works with Google을 탭합니다.
- 만든 작업을 검색한 다음 선택합니다.
- 나중에 필요하므로 고유한 영숫자 코드(5자리)를 기록해 둡니다.
- 뒤로 돌아가기를 탭합니다. WebRTC 카메라가 Google Home 앱의 구조에 추가됩니다.
WebRTC 스트림 시작
- CameraStream 클라이언트 앱의 웹페이지에서 마지막 섹션의 영숫자 코드를 계정 연결 토큰 값 텍스트 상자에 입력한 다음 제출을 클릭합니다.
- Google 스마트 디스플레이 기기에서 WebRTC 세션을 시작하려면 다음 중 하나를 실행합니다.
- "Hey Google, WebRTC 카메라 스트리밍해 줘"라고 말합니다.
- Google 스마트 디스플레이 기기에서 홈 컨트롤 > 카메라 > WebRTC 카메라를 탭합니다.
Google 스마트 홈 CameraStream 클라이언트 앱에서 Offer SPD 및 Answer SDP가 생성되고 교환된 것을 확인할 수 있습니다. 웹캠의 이미지가 WebRTC를 통해 Google 스마트 디스플레이 기기로 스트리밍됩니다.
6. 축하합니다
축하합니다. WebRTC 프로토콜을 사용하여 웹캠에서 Google Nest 디스플레이 기기로 스트리밍하는 방법을 알아봤습니다.
자세히 알아보기
- 스마트 홈 기기 트레잇
- Actions on Google: Node.js를 사용한 스마트 홈 샘플
- 스마트 홈 작업 테스트 및 공유하기