1. 始める前に
CameraStream
トレイトは、スマートディスプレイ、Chromecast デバイス、スマートフォンに動画フィードをストリーミングできるデバイスに使用します。WebRTC プロトコルが CameraStream
トレイト内でサポートされるようになりました。これにより、カメラデバイスから Google Nest ディスプレイ デバイスへの起動とストリーミングのレイテンシを大幅に短縮できます。
Prerequisites
- クラウドツークラウドの基礎を確認する。
学習内容
- スマートホーム クラウド サービスをデプロイする方法。
- サービスを Google アシスタントに接続する方法。
- WebRTC プロトコルを使用して Google Nest ディスプレイ デバイスにストリーミングする方法。
必要なもの
- ウェブブラウザ(Google Chrome など)
- Google Home アプリがインストールされた iOS または Android デバイス。
- Node.js バージョン 10.16 以降。
- Firebase の Blaze(従量課金制)プラン。
- フル HD 解像度に対応した内蔵または外部ウェブカメラ デバイス。
- Google Nest ディスプレイ デバイスです。
2. 始める
Firebase CLI をインストールする
Firebase CLI を使用すると、ウェブアプリをローカルで提供し、Firebase Hosting にデプロイできます。
Firebase CLI をインストールする手順は次のとおりです。
- ターミナルで、Firebase CLI をダウンロードしてインストールします。
$ npm install -g firebase-tools
- CLI が正しくインストールされたことを確認します。
$ firebase --version
- Google アカウントで Firebase CLI を承認します。
$ firebase login
Actions プロジェクトを作成して構成する
- Actions Console に移動して、[New project](新しいプロジェクト)をクリックします。
- [プロジェクト名] テキスト ボックスにプロジェクトの名前を入力し、[プロジェクトを作成] をクリックします。
- [What do you want to build?] ページで、[Smart home] > [Start Building] をクリックします。Actions Console でプロジェクトが開きます。
- [Develop](開発)> [Invocation](呼び出し)をクリックします。
- [表示名] テキスト ボックスにアクションの名前を入力し、[Save] をクリックします。この名前は、後でセットアップするデバイスがある場合に Google Home アプリに表示されます。この Codelab では表示名として「
WebRTC Codelab
」を使用しましたが、別の名前を使用することもできます。
- [操作] をクリックします。
- [Fulfillment URL] テキスト ボックスに、
https://example.com
などのプレースホルダ URL を入力します。
CameraStream クライアント アプリを実行する
この Codelab のソースコードには、ウェブカメラと Google スマートホーム ディスプレイ デバイス間の WebRTC セッションを確立、ネゴシエート、管理する WebRTC クライアントが含まれています。
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
ディレクトリに移動し、Actions プロジェクトで Firebase CLI を設定します。
$ cd camerastream-start $ firebase use 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
- [関数] と [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
ディレクトリを使用して Hosting を構成し、既存の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 Session Description Protocol(SDP)メッセージ
SDP メッセージの交換は、WebRTC ストリームを確立するうえで重要なステップです。SDP は、マルチメディア セッションの特性を記述するテキストベースのプロトコルです。WebRTC 内では、使用されるコーデック、参加者の IP アドレス、メディア転送に使用されるポートなど、ピアツーピア接続のパラメータのネゴシエートに使用されます。
Realtime Database をホストとして使用して、ウェブカメラとスマートホーム CameraStream クライアント アプリ間で SDP メッセージを交換するには、次の手順を行います。
- Firebase コンソールで、[Build] > [Realtime Database] > [Create database] の順にクリックします。
- [Realtime Database のロケーション] プルダウン メニューで、データベースをホストする適切なロケーションを選択します。
- [テストモードで開始する] を選択し、[有効にする] をクリックします。Realtime Database が有効になっている場合は、CameraStream クライアント アプリから Realtime Database を参照できる必要があります。
- 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 カメラを作成する
アクションを構成したので、次のインテントをクラウド サービスが処理する必要があります。
- ユーザーが接続済みのデバイスをアシスタントが把握しようとしたときに発生する
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
},
}],
},
};
});
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 を処理するには、Firebase Hosting の URL をfunctions/index.js
ファイルのallowlist
配列に追加します。
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 ストリームの終了を処理するには、Firebase の「シグナリング」関数の URL を
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
アカウントのリンクの有効化
プロジェクトのデプロイ後にアカウントのリンクを有効にする手順は次のとおりです。
- アクション コンソールで、[開発] > [アカウントのリンク] を選択します。
- [OAuth client information] セクションで、対応するテキスト ボックスに次の情報を入力します。
Client-ID |
|
クライアント シークレット |
|
認可 URL |
|
トークン URL |
|
- [保存] > [テスト] をクリックします。
5. 仮想 WebRTC カメラをテストする
- Firebase プロジェクトをデプロイしたときに見た Hosting の URL に移動します。次のインターフェース(CameraStream クライアント アプリ)が表示されます。
- [ローカルの動画の解像度] パネルで、目的の動画を選択します。
- ウェブカメラとマイクへのアクセスを CameraStream クライアント アプリに付与します。ウェブカメラの動画フィードがクライアントに表示されます。
スマートホーム CameraStream
アクションにリンクする
- Google Home アプリで、[追加] > [Google と連携させる] をタップします。
- 作成したアクションを検索し、選択します。
- 後で必要になるため、一意の 5 文字の英数字のコードに注意してください。
- [元に戻す] をタップします。WebRTC カメラは、Google Home アプリのストラクチャに追加されます。
WebRTC ストリームを開始する
- CameraStream クライアント アプリのウェブページで、[アカウントのリンクトークンの値] テキスト ボックスに最後のセクションにある英数字を入力し、[送信] をクリックします。
- Google スマートディスプレイ デバイスから WebRTC セッションを開始するには、次のいずれかを行います。
- 「OK Google, WebRTC カメラをストリーミングして」と言います。
- Google スマートディスプレイ デバイスで、[スマートホーム] > [カメラ] > [WebRTC カメラ] をタップします。
Google スマートホームの CameraStream クライアント アプリから、Offer SPD と Answer SDP が正常に生成されて交換されたことを確認できます。ウェブカメラの画像が WebRTC 対応の Google スマートディスプレイ デバイスにストリーミングされます。
6. 完了
これで完了です。WebRTC プロトコルを使用して、ウェブカメラから Google Nest ディスプレイ デバイスにストリーミングする方法を学びました。
その他の情報
- スマートホーム デバイスのトレイト
- Actions on Google: Node.js を使用したスマートホーム サンプル
- スマートホーム アクションのテストと共有