画角制御機能付きのセキュリティカメラを作ってみた

2021-09-02
日常で楽しむクラウドテクノロジー

Author : 三平 悠磨

こんにちは、IoT スペシャリストソリューションアーキテクトの三平です。

昨年、この builders.flash で Raspberry Pi で簡単おうちセキュリティカメラを作ってみた  という記事を書きました (まだ読んだことがない方はぜひ読んでみてください)。昨年の記事では Raspberry Pi と USB カメラを利用して、顔検出時にクラウドに映像をアップロード、ユーザーに通知を送信して、録画した映像をオンデマンドで視聴できるというシステムを構成し、イベント録画機能付きの簡易な監視カメラを作ることができます。

しかし、昨年のシステムには、カメラの映像をいつでも視聴できるわけではないといった課題や、カメラの画角が固定されており広い範囲を監視するのが難しいといった課題があります。そこで、今年は画角制御機能付きで、いつでもリアルタイムに映像を視聴できるセキュリティカメラを作ることにチャレンジしてみたいと思います。

画角制御を実現するためには、カメラから映像を送ってユーザーが視聴するだけでなく、ユーザーからカメラに制御コマンドを送ってカメラを動かすという双方向の通信が必要になります。これは一見難しそうにも聞こえますが、AWS の提供するマネージドサービスを利用すれば、実は容易に実現することができます。

この記事のデモを無料でお試しいただけます »

毎月提供されるデベロッパー向けアップデート情報とともに、クレジットコードを受け取ることができます。 


1. システムの構成

今回構築するシステムは以下のような構成になっています。

まず、ハードウェアとして Raspberry Pi とカメラモジュール、そして画角制御のためのサーボモータを用意します。カメラ映像のストリーミングと画角制御のためのコマンド送信には WebRTC という技術を用います。そして、ブラウザ上でカメラからのリアルタイム映像を視聴しながら、WebRTC のデータチャネルを利用してカメラに対して画角制御のコマンドを送信します。

Amazon Kinesis Video Streams というサービスを用いると、カメラデバイスとアプリケーション間での WebRTC の通信を簡単に実現することができます。Kinesis Video Streams では WebRTC の通信を行うためのサーバー側のリソースをフルマネージドな形式で提供しているため、インフラ管理などを意識することなく、セキュアでスケーラブルな WebRTC のアプリケーションを構築することができます。また、組み込みデバイス向けの C 言語の SDK やウェブアプリ向けの JavaScript SDK、モバイルアプリ向けの iOS, Android の SDK を提供しております。今回はこれらの SDK を活用してアプリケーションを作っていきます。

Kinesis Video Streams について詳しく知りたいという方は、Black Belt オンラインセミナー をご視聴ください。


2. Raspberry Pi のセットアップ

今回のシステムでは以下のハードウェアを使用します。

  • Raspberry Pi (Raspberry Pi 3 Model B+ で動作確認しています)
  • Raspberry Pi カメラモジュール V2
  • SG-90 サーボモータ
  • ジャンパー線
  • microSD カード (8 GB 以上)
  • 電源アダプターおよび電源用 USB ケーブル

IoT のハードウェアを自作する際に 3D プリンターなどの機器を活用して部品を作成される場合もあるかと思います。しかし、多くのご家庭と同じように筆者の自宅には 3D プリンターがなかったため、今回はレゴブロックとセロハンテープのみでハードを組み立てました。

個人的にはちょっとした試作やホームユースであれば、レゴブロックは実用に耐えうる使い勝手の良いアイテムだと思います。

カメラモジュールをサーボモータに取り付けるアタッチメントはレゴブロック製です

それでは、Raspberry Pi の設定を行なっていきましょう。まず、こちらのドキュメント に従って Raspberry Pi OS with desktop をダウンロードし、microSD カードに書き込んでください。Raspberry Pi を起動、Wi-Fi などの設定を行いインターネットへ接続できたら、Raspberry Pi のターミナル (もしくは SSH によるリモート接続) を起動します。そして、以下のコマンドを実行して必要なライブラリをインストールします。

sudo apt update
sudo apt install -y cmake \
                    libssl-dev \
                    libcurl4-openssl-dev \
                    liblog4cplus-dev \
                    libgstreamer1.0-dev \
                    libgstreamer-plugins-base1.0-dev \
                    gstreamer1.0-plugins-base-apps \
                    gstreamer1.0-plugins-bad \
                    gstreamer1.0-plugins-good \
                    gstreamer1.0-plugins-ugly \
                    gstreamer1.0-tools

続いて、以下のコマンドを実行すると設定画面が表示されるので、下記手順に則ってカメラインターフェースを有効化しておきます。

sudo raspi-config
  1. 「3 Interface Options」を選択
  2. 「P1 Camera」を選択
  3. Would you like the camera interface to be enabled? に対して <Yes> を選択
  4. <OK>, <Finish>, <Yes> を順に選択して、設定を完了

ライブラリのインストールと設定が完了したら、一度 Raspberry Pi の電源を落とし、こちらのような配線で SG-90 サーボモータを Raspberry Pi に接続します。なお、Raspberry Pi 3 以外ではピン配置が異なる場合があるため、確認した上で接続してください。また、カメラモジュールを Raspberry Pi の CSI ポートに接続します。

  • GND (茶色) : GND ピン
  • 電源 (赤) : 5V PWR ピン
  • 制御 (黄色) : GPIO 18

クリックすると拡大します
本画像は Fritzing で作成しました

なお、サーボモータを利用する際は、サーボモータの電力を Raspberry Pi から直接取得する代わりに、別の電源から供給したり、サーボモータ制御用の別の基板を介して供給したりすることが一般的です。今回は、小型でトルクの小さいサーボモータを利用しており、構成を簡略化するために Raspberry Pi から電源を取っています。


3. Amazon Kinesis Video Streams WebRTC SDK C のセットアップ

さて、配線が完了したら、再度 Raspberry Pi を電源に接続し起動します。

続いて、Raspberry Pi に Amazon Kinesis Video Streams WebRTC SDK C をインストールしていきます。Kinesis Video Streams WebRTC SDK C は組み込みデバイス向けの C 言語の軽量な SDK で、カメラデバイスから Kinesis Video Streams with WebRTC を利用するための機能やサンプルアプリケーションを提供しており、WebRTC による動画のストリーミングなどを容易に試していただくことができます。

今回はこの WebRTC SDK C のサンプルアプリケーションをベースに、画角制御機能を付け加えたアプリケーションを Raspberry Pi で動かします。

まず、Raspberry Pi のターミナルで以下のコマンドを実行し、Kinesis Video Streams WebRTC SDK C をダウンロードし、バージョンを変更します。

cd 
git clone --recursive https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-c.git
cd amazon-kinesis-video-streams-webrtc-sdk-c
git checkout v1.5.0

続いて、WebRTC SDK C にデータチャンネルを利用した画角制御の機能を追加するために、パッチをダウンロードして適用します。

パッチをダウンロード »

上記の「パッチをダウンロード」のリンク先の URL をコピーして、以下のコマンドに貼り付けてを実行します。

wget "上記でコピーしたパッチのURL" -O patch.diff
git apply patch.diff

パッチを適用したら、SDK をビルドします。コマンドの実行完了まで 20〜30 分程度かかります。

mkdir build
cd build
cmake ..
make

4. WebRTC とは ?

さて、SDKのビルドを待っている間に、WebRTC について理解を深めておきましょう。

WebRTC とは、簡易な API を経由してブラウザとモバイルアプリケーションとの間でリアルタイム通信 (RTC) ができるようにするためのオープンなテクノロジー仕様です。身近な場では、例えばビデオ会議システムやボイスチャットなどで使われています。

WebRTC の仕様には、複数のプロトコル (ICE, TURN, STUN など) のセットが含まれており、ピアツーピアでの接続の確立やリアルタイムのメディアおよびデータストリーミング向けの、プロトコル仕様の確立を目的としています。また、WebRTC では End-to-end で通信が暗号化されており、セキュアにメディアのストリーミングを行うことができます。詳しくは、Kinesis Video Streams の FAQ をご参照ください。

Kinesis Video Streams では、この WebRTC の通信を確立してメディアストリーミングを行うために必要なサーバー側のリソースを、マネージド型エンドポイントとして提供しています。具体的には、アプリケーション同士が接続を行うためのシグナリング、ピアツーピアでの接続ができない場合にクラウド経由でメディアリレーを行うための TURN、アプリケーションが NAT やファイアウォールの背後にあるときにパブリック IP アドレスの検出を行うための STUN の 3 つのエンドポイントです。

Kinesis Video Streams の他にも AWS ではビデオユースケース向けのサービスを複数提供しており、ユースケースに応じて適切なサービスをご利用いただくことができます。詳しくは こちらの記事 をご参照ください。また、Kinesis Video Streams with WebRTC についてさらに詳しく知りたい方は、こちらのドキュメント をご参照ください。

4-1. WebRTC SDK C でのデータチャネルの利用

ここで、上記で当てたパッチについて、Kinesis Video Streams WebRTC SDK C でのデータチャネルの扱い方とあわせて紹介いたします。

先ほどダウンロードした WebRTC SDK C には、WebRTC の標準規格に則った各種プロトコルの実装や、GStreamer と連携するサンプルアプリケーションなどが含まれております。サンプルアプリケーションは samples フォルダ の中に実装があり、これらをカスタマイズすることで、デバイスのカメラやマイクからメディアを取得したり、データチャンネルを用いたメッセージの送受信を行ったりすることができるようになります。

今回利用する kvsWebRTCClientMasterGstreamerSample のサンプルには、Viewer (ブラウザやモバイルアプリ) で作成したデータチャネルから届いたメッセージを受け取るための コールバック関数 が用意されています。上記のパッチでは、このコールバック関数の中で、届いたメッセージの内容に応じて接続されたサーボモータを制御するような実装を行なっています。サーボモータの制御には WiringPi という Raspberry Pi の GPIO を制御するためのライブラリを利用しています (利用しているバージョンは 2.50 です)。

VOID onDataChannelMessage(UINT64 customData, PRtcDataChannel pDataChannel, BOOL isBinary, PBYTE pMessage, UINT32 pMessageLen)
{
    UNUSED_PARAM(customData);
    UNUSED_PARAM(pDataChannel);
    if (isBinary) {
        DLOGI("DataChannel Binary Message");
    } else {
        DLOGI("DataChannel String Message: %.*s\n", pMessageLen, pMessage);
        // Control servo by data channel message
        if (pMessageLen == 1) {
            if (pMessage[0] == 'L') {
                DLOGI("Turn left");
                pwmWrite(SERVO_PIN, 95);
            } else if (pMessage[0] == 'R') {
                DLOGI("Turn right");
                pwmWrite(SERVO_PIN, 45);
            } else if (pMessage[0] == 'C') {
                DLOGI("Turn center");
                pwmWrite(SERVO_PIN, 70);
            }
        }
    }
}

今回のサンプルでは水平方向に 3 方向だけのシンプルな制御を実装していますが、この仕組みを応用することで PTZ (パンチルトズーム) 制御のような、高度な画角制御を実現することも可能です。

また、カメラ側からもデータチャネルにメッセージを送ることができますので、例えばカメラで音声や人の検出のイベントなどが発生した際に、イベント発生を視聴者へ通知するといったことも考えられます。データチャネルを利用するための関数については、こちらのドキュメント をご参照ください。


5. IAM ポリシーと IAM ロールの作成

本アプリケーションではデバイス側での認証に AWS IoT の Credentials Provider という仕組みを用います。通常、Kinesis Video Streams などの AWS サービスを呼び出す場合、SigV4 形式 の認証情報を利用してサービスを呼び出します。しかし、IoT のユースケースでは、デバイスに対してこの認証情報をどのように発行し受け渡すかという課題がしばしば生じます。

Credentials Provider を用いると、AWS IoT Core で管理された X.509 のクライアント証明書を用いて、Kinesis Video Streams with WebRTC に対してアクセスするための一時認証情報を取得できます。これによって、認証情報の発行や管理の仕組みを作ることなく、Raspberry Pi にクライアント証明書を埋め込んでおくだけで、Kinesis Video Streams へアクセスできるようになります。先程のパッチの中で、AWS IoT の Credentials Provider を利用するためのコードも追加されています。

// Use IoT Credential Provider instead of static credentials
CHK_STATUS(createLwsIotCredentialProvider(
    pIoTCredentialsEndpoint,  // IoT credentials endpoint
    "/home/pi/amazon-kinesis-video-streams-webrtc-sdk-c/build/certificate.pem.crt",  // path to iot certificate
    "/home/pi/amazon-kinesis-video-streams-webrtc-sdk-c/build/private.pem.key", // path to iot private key
    "/home/pi/amazon-kinesis-video-streams-webrtc-sdk-c/build/AmazonRootCA1.pem", // path to CA cert
    "RasPiKVSWebRTCRoleAlias", // IoT role alias
    channelName, // iot thing name, recommended to be same as your channel name
    &pSampleConfiguration->pCredentialProvider));

まず、Credentials Provider で利用される IAM ポリシーおよび IAM ロールを作成していきます。AWS CLI を利用できる PC や AWS CloudShell を用いて、以下のコマンドを実行していきます。なお、AWS のマネジメントコンソールからポリシーやロールを作成しても差し支えありませんが、本記事では手順の簡略化のために AWS CLI を用います。

5-1. IAM ポリシーの作成

以下のコマンドを実行して IAM ポリシーを作成します。

aws iam create-policy \
    --policy-name RasPiKVSWebRTCPolicy \
    --policy-document "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"kinesisvideo:DescribeSignalingChannel\",\"kinesisvideo:CreateSignalingChannel\",\"kinesisvideo:GetSignalingChannelEndpoint\",\"kinesisvideo:GetIceServerConfig\",\"kinesisvideo:ConnectAsMaster\"],\"Resource\":\"arn:aws:kinesisvideo:*:*:channel/\${credentials-iot:ThingName}/*\"}]}"

以下のような結果が表示されるので、この Arn の値を控えておきます。

{
    "Policy": {
        "PolicyName": "RasPiKVSWebRTCPolicy",
        "PolicyId": "...",
        "Arn": "arn:aws:iam::123456789012:policy/RasPiKVSWebRTCPolicy",
        ...
        "CreateDate": "2021-07-12T05:52:40+00:00",
        "UpdateDate": "2021-07-12T05:52:40+00:00"
    }
}

5-2. IAM ロールの作成

続いて、以下のコマンドを実行して IAM ロールを作成します。

aws iam create-role \
    --role-name RasPiKVSWebRTCRole \
    --assume-role-policy-document "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"credentials.iot.amazonaws.com\"},\"Action\":\"sts:AssumeRole\"}]}"

以下のような結果が表示されるので、この Arn の値も控えておきます (AWS IoT の設定のセクションで利用します)。

{
    "Role": {
        "Path": "/",
        "RoleName": "RasPiKVSWebRTCRole",
        "RoleId": "...",
        "Arn": "arn:aws:iam::123456789012:role/RasPiKVSWebRTCRole",
        "CreateDate": "2021-07-12T05:59:13+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Sid": "",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "credentials.iot.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}

5-3. ポリシーのアタッチ

最後に、以下のコマンドを実行して IAM ロールに IAM ポリシーをアタッチします。コマンドの中の --policy-arn には 5-1. で控えた値をペーストします。

aws iam attach-role-policy \
    --role-name RasPiKVSWebRTCRole \
    --policy-arn "5-1.で控えたポリシーの Arn の値 (例: arn:aws:iam::123456789012:policy/RasPiKVSWebRTCPolicy)"

6. AWS IoT の設定

続いて、作成した IAM ロールを Credentials Provider から呼び出すための AWS IoT の設定を行なっていきます。IAM の時と同じように、AWS CLI が利用できる環境で、以下のコマンドを順に実行していきます。

6-1. ロールエイリアスの作成

以下のコマンドを実行してロールエイリアスを作成します。コマンドの中の --role-arn には 5-2. で控えた値をペーストします。

aws iot create-role-alias \
    --role-alias RasPiKVSWebRTCRoleAlias \
    --role-arn "5-2.で控えたロールの Arn の値 (例: arn:aws:iam::123456789012:role/RasPiKVSWebRTCRole)"

6-2. IoT ポリシーの作成

続いて、IoT ポリシーを作成します。以下のコマンドのうち、リージョン:アカウントID の部分をお使いのものに置き換えて(例: ap-northeast-1:123456789012)、実行します。

aws iot create-policy \
    --policy-name RasPiKVSWebRTCPolicy \
    --policy-document "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"iot:AssumeRoleWithCertificate\",\"Resource\":\"arn:aws:iot:リージョン:アカウントID:rolealias\/RasPiKVSWebRTCRoleAlias\"}]}"

6-3. モノの作成

以下のコマンドを実行して IoT の Thing を作成します。

aws iot create-thing --thing-name raspi-channel

6-4. 証明書と鍵の作成

次に、証明書と鍵を発行します。以下のコマンドを実行すると、コマンドを実行したフォルダに certificate.pem.crt, private.pem.key, public.pem.key という 3 つのファイルが作成されます。このファイルは後で Raspberry Pi に転送して利用するので、分かりやすい場所で実行してください (AWS CloudShell を利用した場合は、コマンド実行後に Actions > Download File からファイルをダウンロードしておきましょう)。

aws iot create-keys-and-certificate \
    --set-as-active \
    --certificate-pem-outfile "certificate.pem.crt" \
    --public-key-outfile "public.pem.key" \
    --private-key-outfile "private.pem.key"

以下のような結果が出力されるので、certificateArn の値を控えておきます。

{
    "certificateArn": "arn:aws:iot:ap-northeast-1:123456789012:cert/...",
    "certificateId": "...",
    ...
}

6-5. ポリシーのアタッチ

以下のコマンドを実行して IoT ポリシーを証明書にアタッチします。コマンドの中の --target には 6-4. で控えた値をペーストします。

aws iot attach-policy \
    --policy-name "RasPiKVSWebRTCPolicy" \
    --target "6-4.で控えた certificateArn の値 (例: arn:aws:iot:ap-northeast-1:123456789012:cert/...)"

6-6. モノのアタッチ

また、以下のコマンドを実行して証明書をモノにアタッチします。こちらも、コマンドの中の --principal には 6-4. で控えた値をペーストします。

aws iot attach-thing-principal \
    --thing-name raspi-channel \
    --principal "6-4.で控えた certificateArn の値 (例: arn:aws:iot:ap-northeast-1:123456789012:cert/...)"

6-7. Credentials Provider のエンドポイントの確認

最後に、以下のコマンドを実行して、Credentials Provider のエンドポイントを確認しておきます。

aws iot describe-endpoint --endpoint-type iot:CredentialProvider

以下のような結果が得られますので、この endpointAddress の値を控えておきます。

{
    "endpointAddress": "cxxxxxxxxxxxxx.credentials.iot.ap-northeast-1.amazonaws.com"
}

長くなりましたが、以上で IAM および AWS IoT の設定が完了しました。


7. サンプルアプリケーションの起動

さて、そろそろ SDK のビルドも完了した頃でしょうか。いよいよ、Kinesis Video Stream WebRTC SDK C のアプリケーションを起動していきます。

まず、先ほどダウンロードしたファイルのうち、 certificate.pem.crt, private.pem.key の 2 ファイルを Raspberry Pi の /home/pi/amazon-kinesis-video-streams-webrtc-sdk-c/build/ ディレクトリに、SCP などで転送します(ファイル名は certificate.pem.crt, private.pem.key のままにしてください)。

さて、ここからは Raspberry Pi のターミナルに切り替えて操作を行います。以下のコマンドを実行し、AWS IoT のルート CA 証明書をダウンロードしておきます。

wget https://www.amazontrust.com/repository/AmazonRootCA1.pem -O ~/amazon-kinesis-video-streams-webrtc-sdk-c/build/AmazonRootCA1.pem

続いて、以下のコマンドで root ユーザーへ切り替え (GPIO の制御のために必要です)、環境変数を設定します。環境変数の値は、それぞれ 6-7. で控えた値と利用するリージョンに置き換えてください。

sudo su -
export AWS_IOT_CREDENTIALS_ENDPOINT="6-7.で控えた Credentials Provider の endpointAddress の値 (例: cxxxxxxxxxxxxx.credentials.iot.ap-northeast-1.amazonaws.com)"
export AWS_DEFAULT_REGION="利用するリージョン (例: ap-northeast-1)"

同じターミナルで以下のコマンドを実行して、アプリケーションを起動します。

cd /home/pi/amazon-kinesis-video-streams-webrtc-sdk-c/build
./kvsWebrtcClientMasterGstSample raspi-channel

以下のようなログが表示されれば、アプリケーションは無事起動し、接続を待ち受けている状態です。

[KVS GStreamer Master] Using trickleICE by default
[2021/07/12 06:17:12:3202] N: lws_tls_client_create_vhost_context: doing cert filepath /home/pi/amazon-kinesis-video-streams-webrtc-sdk-c/build/certificate.pem.crt
[2021/07/12 06:17:12:3210] N: Loaded client cert /home/pi/amazon-kinesis-video-streams-webrtc-sdk-c/build/certificate.pem.crt
[2021/07/12 06:17:12:3211] N: lws_tls_client_create_vhost_context: doing private key filepath
[2021/07/12 06:17:12:3215] N: Loaded client cert private key /home/pi/amazon-kinesis-video-streams-webrtc-sdk-c/build/private.pem.key
[KVS GStreamer Master] Created signaling channel raspi-channel
[KVS Gstreamer Master] Finished initializing GStreamer
[KVS Gstreamer Master] Streaming video only
[KVS GStreamer Master] streaming type video-only
[KVS GStreamer Master] KVS WebRTC initialization completed successfully
...
[KVS GStreamer Master] Signaling client created successfully
[KVS GStreamer Master] Signaling client connection to socket established
[KVS Gstreamer Master] Beginning streaming...check the stream over channel raspi-channel

なお、このプロセスを常時起動しておくことで、いつでもカメラの映像を視聴しにいくことができるようになります。


8. ブラウザから視聴と制御を行う

いよいよ、ブラウザ (Chrome や Firefox) から Raspberry Pi へ WebRTC の通信を行なっていきます。ブラウザ向けには Kinesis Video Streams WebRTC SDK for JavaScript という SDK を提供しており、WebRTC の接続を確立するためのシグナリングクライアントやサンプルページが含まれています。今回は、Kinesis Video Streams WebRTC SDK JavaScript のサンプルページ を利用して、映像の視聴と画角の制御を行います。

まず、アプリケーションを実行する際に、AWS のクレデンシャルが必要になります。AWS CLI を利用できる PC などを用いて以下のコマンドを実行し、一時的なクレデンシャルを取得します。

aws sts get-session-token

以下のような結果が得られます。

{
    "Credentials": {
        "AccessKeyId": "...",
        "SecretAccessKey": "...",
        "SessionToken": "...",
        "Expiration": "2021-08-15T01:23:45Z"
    }

ブラウザで サンプルページ を開き、以下のようにフォームに入力していきます。

  • Region : お使いのリージョン (東京リージョンならば ap-northeast-1)
  • Access Key ID, Secret Access Key, Session Token : 上記で取得した一時的なクレデンシャルを入力
  • Channel Name : raspi-channel と入力

 

クリックすると拡大します

続いて、チェックボックスを以下のように設定していきます。

  • Tracks : Send Audio と Open DataChannel にチェックを入れる
  • Video Resolution : 1280x720 (デフォルト)
  • NAT Traversal : STUN/TURN かつ Use trickle ICE (デフォルト)

最後に Start Viewer をクリックします。

クリックすると拡大します

以下のような画面に切り替わり、Raspberry Pi のカメラモジュールからの映像が表示されます。カメラモジュールの前に手をかざしたりして、映像がほぼリアルタイムで視聴できていることを確認しましょう。

続いて、データチャネル経由でカメラに制御コマンドを送信します。画面中央左側のテキストボックスにメッセージを入力して Send DataChannel Message をクリックすると、データチャネルにメッセージを送信できます。

今回作成したアプリケーションでは、以下の3種類のコマンドに対応しています。

  • L : カメラを左側に向ける
  • C : カメラを中央に向ける
  • R : カメラを右側に向ける

実際にコマンドを送信してみると、以下のようにカメラが動いて画角が変わるのを確認できます。

ブラウザから視聴した画面

Raspberry Pi を真上から撮影した様子

なお、今回のアプリケーションでは簡単のために3種類のコマンドに絞って制御を行うようにしましたが、WebRTC のデータチャネルのペイロードとしては、さらに長い文字列やバイナリなどを扱うことができます。この仕組みを応用することで、細かい画角制御やカメラ設定の変更などを実現することもできますので、是非試してみてください。


9. コストの見積もり

本システムを運用した際に発生するコストについて試算してみたいと思います。なお、コストは 2021 年 7 月現在の東京リージョンの料金に基づいて試算しております。最新の料金については各サービスの料金ページ (Amazon Kinesis Video Streams, AWS IoT Core) をご参照ください。

前提として、Raspberry Pi のサンプルアプリケーションは常時起動させておき、1 日 5 回、1 回あたり 60 秒間ブラウザから映像を視聴します。映像のビットレートは 0.5 Mbps で、接続 1 回あたりのシグナリングメッセージ数を 30 件、TURN 経由で接続される割合を 30% と仮定します。データチャネル上でやりとりされるメッセージのデータ量は映像と比べて非常に小さいため、今回の計算では無視します。

1 ヶ月あたりのシグナリングメッセージ数 30 件/回 × 5 回/日 × 30 日/月 = 4,500 件/月
1 ヶ月あたりの TURN Streaming の時間 1 分/回 × 5 回/日 × 30 日/月 × 30% = 45 分/月
1 ヶ月あたりの TURN 経由で転送されるデータ量 0.5 Mbps ÷ 8 bit/byte × 60 秒/回 × 5 回/日 × 30 日/月 × 30% = 168.75 MB/月

この場合の Kinesis Video Streams の料金は以下のようになります。

アクティブなシグナリングチャネル 0.04500 USD × 1 チャネル = 0.04500 USD/月
シグナリングメッセージ 3.37500 USD × 4,500 件/月 ÷ 1,000,000 件 = 0.0151875 USD/月
TURN Streaming の時間 0.18000 USD × 45 分/月 ÷ 1,000 分 = 0.0081 USD/月
合計 0.04500 USD/月 + 0.0151875 USD/月 + 0.0081 USD/月 = 0.0682875 USD/月

TURN 経由で転送されるデータには AWS の標準のデータ転送料金が発生しますが、こちらは 1 GB/月 までは無料であり、今回の 168.75 MBの転送には費用はかかりません。また、IoT Core の Credentials Provider に関しても追加費用はありません。結果として、0.0682875 USD/月、月あたり10 円未満で運用することができます。

なお、TURN 経由で接続される割合や接続あたりのシグナリングメッセージ数は、ネットワーク環境やデバイス設定によって異なる場合がありますので、より正確な見積もりのためには、実際の環境で検証した際の CloudWatch メトリクスやコストを確認するようにしてください。


まとめ

本記事では、Amazon Kinesis Video Streams with WebRTC を利用して画角制御機能付きのセキュリティカメラを作成する方法をご紹介しました。

最近では遠隔から視聴可能なセキュリティカメラが安価に販売されており、こういった仕組みをわざわざ構築しなくとも十分便利に利用できると思います。しかし、今回あえてセキュリティカメラのアプリケーションを構築してみたことで、その裏側で利用されている技術について理解が深まり、より良く活用していけるようになったのではないでしょうか ?

スマートホームだけでなく、スマートシティや自動運転、遠隔制御やスマート工場など、IoT におけるカメラやビデオの活用は今後も広がっていくと思われます。この記事をきっかけに、これらのユースケースや技術についての理解を深め、より身近に感じていただけると嬉しいです。


builders.flash メールメンバーへ登録することで
AWS のベストプラクティスを毎月無料でお試しいただけます

筆者紹介

三平 悠磨 (みひら ゆうま)
アマゾン ウェブ サービス ジャパン合同会社
IoT スペシャリスト ソリューションアーキテクト

ソフトウェアエンジニアとして会話 AI やロボット開発を経験しました。AWS では IoT スペシャリストソリューションアーキテクトとして、お客様の IoT 関連案件を支援しています。趣味はバンドと作曲で、プログラミングやテクノロジーを駆使して音楽をもっと楽しくしたいと思っています。 

さらに最新記事・デベロッパー向けイベントを検索

下記の項目で絞り込む
1

AWS を無料でお試しいただけます

AWS 無料利用枠の詳細はこちら ≫
5 ステップでアカウント作成できます
無料サインアップ ≫
ご不明な点がおありですか?
日本担当チームへ相談する