USBカメラで映像が見えた。その次が長かった
2021年11月、Raspberry Pi 3 Model B+にUSB Webカメラをつなぎ、Amazon Kinesis Video Streams(以下、KVS)へ映像を送るハンズオンを試しました。当時のメモには、Producer SDKのビルドに20〜30分ほどかかったこと、kvs_gstreamer_sampleを実行してKVSコンソールで映像を確認できたことが残っています。
ここまでなら「KVSへ映像を送れた」で終われます。
その後、ローカルネットワーク内でしか映像を提供しない既存IPカメラ製品を、エッジGWを介してKVSへ接続するPoCを構築しました。公開記事では入力をRTSP/H.264へ一般化していますが、USBカメラのサンプルとは違い、カメラ認証、RTPの受信、GStreamerのパイプライン、AWS認証、KVSへの取り込み、再生まで、確認すべき区間が一気に増えます。
実際に大変だったのは、クラウドへ映像を出すことそのものより、カメラ、エッジGW、AWSのどの区間まで正常なのかを切り分けることでした。
この記事では、このPoCで増えた境界を公開可能な形へ一般化し、既存IPカメラのRTSP映像をKVSへ送るとき、何をどの順番で確認するかを整理します。
この記事に登場するカメラ名、IPアドレス、ストリーム名、認証情報、ネットワーク構成は説明用です。実務で使った値や顧客構成は掲載していません。
読者と前提
- 対象読者:IPカメラの映像をAWSへ送る小規模な検証を始める人
- 前提知識:Linuxの基本コマンド、IPアドレスとポートの基礎
- 経験時点:USBカメラのハンズオンは2021年11月、既存IPカメラのPoCも2021年に実施
- 2026年時点の補足:GStreamerの
kvssink、CloudWatchメトリクス、AWS IoTの証明書を使う認証方式はAWS公式資料で現行仕様を確認しました - 扱う範囲:H.264のRTSP映像を、Linux上のGStreamerからKVSへ送るまでの切り分け
- 扱わない範囲:商用サービスの可用性設計、録画保存期間の設計、料金比較、WebRTCによる双方向通信
USBカメラの送信は、機材、実行コマンド、KVSコンソールでの確認結果が当時のメモに残っています。既存IPカメラのPoCは、RTSPを受けるエッジGWとKVSまでの構成図は残っていますが、公開できる実行ログは残っていません。そのため、本文では筆者が実施した範囲と、2026年時点のAWS公式資料から組み直した確認手順を分けて書きます。現行Producer SDKで同じPoCを再実行した記事ではありません。
当時、USBカメラで映像を確認したコマンドは次の形でした。ストリーム名はハンズオン用の値だったため、ここでは置き換えています。
cd ~/amazon-kinesis-video-streams-producer-sdk-cpp/build
./kvs_gstreamer_sample <stream-name>
先に分けるべき3区間
映像が見えないときは、システム全体を一度に疑わず、次の3区間に分けます。
| 区間 | 確認したいこと | 代表的な確認手段 |
|---|---|---|
| 1. カメラからエッジ端末 | RTSPで映像を受信できるか | VLC、gst-launch-1.0、カメラのログ |
| 2. エッジ端末の映像処理 | RTP/H.264をKVSへ渡せる形にできるか | GStreamer、gst-inspect-1.0、デバッグログ |
| 3. エッジ端末からKVS | 認証され、フレームがAWSへ届くか | KVSコンソール、CloudWatchメトリクス |
次の図では、カメラ、エッジ端末、KVSを物理的な配置と責任範囲で分けています。矢印は製品固有の構成ではなく、映像が通る方向を示す模式図です。
この分け方の利点は、「カメラが生きている」と「クラウドで再生できる」を同じ正常判定にしないことです。Pingが通っても、RTSP認証に失敗しているかもしれません。RTSPをローカル再生できても、KVSへの認証や送信で止まることがあります。
区間1:まずRTSPをローカルで終端する
KVSへ接続する前に、エッジ端末だけでRTSP映像を確認します。ここで映らなければ、AWS側を調べても原因には届きません。
説明用の構成は次のとおりです。
| 項目 | 例 |
|---|---|
| カメラ | H.264対応の一般的なIPカメラ |
| カメラIP |
192.0.2.10(文書用アドレス) |
| RTSPポート | 554 |
| エッジ端末 | Linux搭載SBCまたはPC |
| AWSリージョン | 利用環境で選択したリージョン |
認証情報をシェル履歴へ残さないため、実運用のURLをそのままコマンドへ書くのは避けます。検証例を示す場合も、次のようにプレースホルダーにします。
gst-launch-1.0 rtspsrc location="rtsp://<camera-host>/<stream-path>" \
! rtph264depay \
! h264parse \
! fakesink
この段階では、映像を表示することだけが目的ではありません。少なくとも次を確認します。
- 名前解決またはIP到達性
- RTSPポートへのTCP接続
- RTSP認証の成否
- 選択したストリームがH.264か
- RTPパケットを継続して受信できるか
- 数分間動かしたときに切断や再接続が起きないか
カメラによっては、メインストリームとサブストリームで解像度やコーデックが違います。「URLは正しいのに想定したH.264ではなかった」ということもあるため、管理画面の表示だけでなく、受信側が認識したメディア情報も確認します。
区間2:GStreamerの中で映像をKVS向けに整える
AWSの公式資料では、KVS Producer SDKの機能をGStreamerのsink要素として使うkvssinkが提供されています。RTSPカメラでは、概念的に次の要素をつなぎます。
rtspsrc
rtph264depay
h264parse
kvssink
各要素の役割と確認境界を図にすると、次のようになります。
まずkvssinkがGStreamerから見えているかを確認します。
gst-inspect-1.0 kvssink
No such element or plugin 'kvssink'となる場合は、カメラやAWS認証より先に、Producer SDKのビルド結果とGST_PLUGIN_PATHを確認します。
export GST_PLUGIN_PATH="<producer-sdk-build-directory>"
gst-inspect-1.0 kvssink
RTSPからKVSへ送るパイプラインの形は、AWS公式資料に例があります。実際にはカメラが出すH.264の形式やGStreamerのバージョンに応じて調整が必要です。
gst-launch-1.0 rtspsrc location="rtsp://<camera-host>/<stream-path>" short-header=TRUE \
! rtph264depay \
! h264parse \
! kvssink stream-name="example-camera-01" storage-size=128 \
aws-region="<aws-region>"
これはAWS公式例を基にした構成の骨格であり、当時の製品固有コマンドを再掲したものではありません。カメラの出力形式やGStreamerのバージョンによって追加のcaps指定等が必要です。長いコマンドを完成形としてコピーせず、fakesinkやローカル再生まで通るか、kvssink単体が認識されるか、と境界ごとに確認します。
区間3:KVSへ届いたことをフレームで確認する
KVSコンソールで再生できない場合、画面だけを何度も更新するより、CloudWatchメトリクスで取り込み状況を確認します。
AWS公式資料では、データがKVSへ届いているかを見る指標として、次のメトリクスが案内されています。
PutMedia.IncomingBytesPutMedia.IncomingFragmentsPutMedia.IncomingFrames
これらが増えていなければ、少なくとも「KVSが継続して映像を受け取っている」とは判断できません。逆に、フレームが届いているのに再生できない場合は、受信以前ではなく、フラグメント、タイムスタンプ、再生側などへ調査範囲を進められます。
当時の記録を読み返して気づいたのは、「映像が見えた」という結果だけでは、後から正常条件を再現しにくいことでした。現在なら、次を同じ時間軸で残します。
- エッジ端末のGStreamerログ
- KVSのストリーム名とリージョン
- CloudWatchの取り込みメトリクス
- カメラ側の接続または再接続ログ
- 検証開始・終了時刻
ストリーム名や時刻は公開用に置き換えられますが、区間を突き合わせるための相関情報は検証時に必要です。
検証用認証を製品へ持ち込まない
2021年のハンズオンでは、AWS CLIで取得した一時認証情報を環境変数へ設定する手順を試しました。短時間の動作確認としては理解しやすい方法です。しかし、アクセスキーを端末へ固定保存する設計は、カメラを複数台展開する製品には向きません。
2026年時点のAWS公式資料では、AWS IoTのX.509証明書でデバイスを識別し、Credentials Providerから一時的で権限を限定した認証情報を取得してKVSへ送る構成が説明されています。これにより、長期利用するアクセスキーIDとシークレットアクセスキーをデバイスへ保存せずに済みます。
設計時には、少なくとも次を分けて考えます。
- ハンズオンを通すための認証
- 1台の検証機を安全に動かす認証
- 複数台を登録、失効、交換できる製品運用の認証
「送信できた」ことと「端末を安全に運用できる」ことは別の完了条件です。
「映らない」を調べる順番
私なら現在は、次の順で確認します。
長い確認項目を区間ごとの判断フローにすると、失敗した場所で調査を止めやすくなります。
- カメラの管理画面に入れるか
- RTSPポートへ到達できるか
- RTSPをエッジ端末で受信できるか
- H.264のRTPを取り出せるか
-
h264parseまでエラーなく通るか -
kvssinkをGStreamerが認識しているか - AWS認証と対象ストリームへの権限があるか
-
PutMedia.IncomingFramesなどが増えているか - KVS側で再生できるか
- 回線断後に自動復旧するか
この順なら、「AWSだから難しい」「カメラが不安定だ」と早い段階で決めつけずに済みます。
次の表は、当時すべての故障を実測した一覧ではありません。PoCで区間を分けて調べた経験と、現在の公式資料から組み直した初動の対応表です。
| 観測 | まず疑う区間 |
|---|---|
| Pingは通るがRTSPを開けない | カメラ設定、ポート、認証、ネットワーク |
ローカル再生できるがkvssinkがない |
Producer SDKのビルド、プラグインパス |
kvssinkは動くが取り込みメトリクスが増えない |
AWS認証、権限、リージョン、ストリーム指定 |
| 取り込みフレームは増えるが再生できない | タイムスタンプ、フラグメント、再生側 |
| 最初は映るが回線断後に戻らない | 再接続、状態管理、監視、プロセス制御 |
2021年の結果と現在の確認手順を混ぜない
この記事で実体験として扱ったのは、USBカメラからKVSへの送信と、ローカル配信だけの既存IPカメラをエッジGW経由でKVSへつないだところまでです。回線断試験、CloudWatch Alarm、AWS IoT証明書の運用、独自ビュワーは実施済みの成果ではありません。
一方、kvssinkの構成、KVSのCloudWatchメトリクス、AWS IoT Credentials Providerによる認証は、2026年時点の公式資料で確認しました。古いPoCを現行環境の成功例として見せず、今なら何を観測するかを切り分け手順として残す。これがこの記事の範囲です。
参考資料
- Example: Kinesis Video Streams producer SDK GStreamer Plugin - kvssink
- Stream video to your Kinesis video stream
- Controlling access to Kinesis Video Streams resources using AWS IoT
- Monitor Amazon Kinesis Video Streams metrics with CloudWatch
- 『AWS上のシステム設計』:クラウド側だけでなく、エッジ、認証、監視を含めて責任範囲を整理する観点の参考にしました


