Amazon Kinesis Video Streams WebRTC

# Amazon Kinesis Video Streams WebRTC基本情報
## 用語定義
<dl>
<dt>Signaling channel</dt>
<dd>
WebRTCではシグナリングメッセージを交換することにより、ピアツーピア接続における検出、設定、制御、終了が可能になります。
シグナリングメッセージはメタデータであり、メディアコーデックやコーデックパラメータといったメディア情報や相互のアプリケーションをライブストリーミングで接続するためのネットワークパス情報が含まれます。
シグナリングチャネルは、複数のアプリケーション間をone-to-fewモデル（一つのマスタが複数のビューアと接続）で接続します。
マスタは、ConnectAsMaster APIを、ビューワはConnectAsViewer APIを使用し接続します。
</dd>

<dt>Peer</dt>
<dd>
Kinesis Video Streams with WebRTCを通じて、リアルタイムストリーミングを行うデバイスやアップりケーション（モバイル端末やWebアプリ、Webカメラなど）
</dd>

<dt>Master</dt>
<dd>
接続を開始し、シグナリングチャネルに接続されているピアで、シグナリングチャネルに接続されているビューアのいずれかとメディアを検出して交換する機能を備えています。
</dd>

<dt>Viewer</dt>
<dd>
シグナリングチャネルのマ​​スターとのみメディアを検出および交換する機能を備えたシグナリングチャネルに接続されているピア。視聴者は、特定のシグナリングチャネルを介して他の視聴者を発見したり、他の視聴者と対話したりすることはできません。シグナリングチャネルには、最大10人のビューアを接続できます。
</dd>
</dl>

<dt>Session Traversal Utilities for NAT (STUN)</dt>
<dd>
STUNは、NATの背後に実行しているクライアント（Peer）のパブリックIPアドレスを解決するために使用されるプロトコル。
クライアント（Peer）がインターネット上の STUN サーバーにリクエストを送信すると、サーバーは、クライアント（Peer）のパブリックアドレスと、ルーターの NAT 内部にアクセス可能かどうかを答えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/5d17fbe5-8444-9aa3-0d23-4bfb79d787aa.png)
</dd>

<dt>Traversal Using Relays around NAT (TURN)</dt>
<dd>
インターネットとの境界でNATによるアドレス変換が行われているネットワーク内の端末同士が通信できるよう、中継サーバがデータ伝送を取り次ぐためのプロトコル。
TURNサーバが中継する方法で、Symmetric NATをバイパスするために使われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/d739fbbd-9473-ea5f-aefb-6ed888472fdb.png)
</dd>

<dt>Session Description Protocol (SDP)</dt>
<dd>
解像度、フォーマット、コーデック、暗号化などのマルチメディアコンテンツを指定するための標準。これにより、両方のPeerは伝送されるデータを相互に理解する事ができます。
</dd>

<dt></dt>
<dd>
ネットワークトポロジーに関係なく、2 つのPeerを互いに接続するための WebRTC に使用されるフレームワーク
</dd>

## ICE,STUN,TURNの動作
2つのPeers（AとB）がWebRTCを用いてメディアストリーミングする例で説明します。

Bアプリに接続するために、`AアプリはSDP offer`を生成します。
SDP offerは、Aアプリが確立したいセッションの情報（例えば、使用するコーデックや、音声か映像なのかなど）が含まれます。
SDP offerには、`ICE candidates`リストも含みます。これは、BアプリがAに接続するために使用することができるIPとポートのリストです。

ICE candidatesリストを構築するために、Aアプリは一連の要求をSTUNサーバに行います。
STUNサーバは、要求を発信したパブリックIPとポートのペアを返します。Aアプリは、これらペアをICE candidatesリストを追加します。
一度、AアプリがICE candidatesを集め終わると、そのリストをSDPで返します。

次に、`Aアプリは、シグナリングチャネルを通じて、SDPをBアプリに送ります`。
ここで使われるプロトコルはWebRTCでは標準化されていません。HTTPSやWebSocketなどが使われます。

`BアプリはSDP answer`を生成します。
BアプリはAアプリが行った前述のステップと同様に（ICE candidatesを集めたり）します。
その後、Bアプリは`SDP answer`をAアプリに返します。

`AアプリとBアプリのSDP交換後、接続確認`を行います。
各アプリのICEアルゴリズムは、相手のSDPで受信したリストから候補のIP /ポートペアを取得し、`STUN要求`を送信します。
もし、`応答が返ってきたら、このIP/ポートのペアを有効なICE candidateと位置付けます`。

全IP/ポートペアの接続確認が終わると、アプリケーションはそのうちの１つを使って`接続のネゴシエーション`を始めます。

もし、いずれかのアプリケーションが接続チェックに合格するIP/ポートペアを見つけることができない場合、メディアリレーアドレスを取得するためにTURNサーバーにSTUN要求を行います。
リレーアドレスは、アプリケーションとの間で送受信されたパケットを転送してリレーアドレスを設定するパブリックIPアドレスおよびポートです。次に、このリレーアドレスが候補リストに追加され、シグナリングチャネルを介して交換されます。

## Kinesis Video Streams WebRTC SDKs
WebRTCクライアント向けSDKとして、組み込みC、Japascript(Webブラウザ）、Android、iOS版がダウンロード可能です。
- [WebRTC SDK in C for Embedded Devices](https://docs.aws.amazon.com/ja_jp/kinesisvideostreams-webrtc-dg/latest/devguide/kvswebrtc-sdk-c.html)
- [WebRTC SDK in JavaScript for Web Applications](https://docs.aws.amazon.com/ja_jp/kinesisvideostreams-webrtc-dg/latest/devguide/kvswebrtc-sdk-js.html)
- [WebRTC SDK for Android](https://docs.aws.amazon.com/ja_jp/kinesisvideostreams-webrtc-dg/latest/devguide/kvswebrtc-sdk-android.html)
- [WebRTC SDK for iOS](https://docs.aws.amazon.com/ja_jp/kinesisvideostreams-webrtc-dg/latest/devguide/kvswebrtc-sdk-ios.html)

# WebRTC SDK in C for Embedded Devicesインストールおよび利用方法
## ダウンロード&ビルド
下記コマンドにより、Kinesis Video Stream with WebRTC SDK in C for Embedded Devicesをダウンロードできます。
```
$ git clone --recursive https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-c.git
```

1 ビルドに必要なパッケージをインストール
```
sudo apt-get install pkg-config cmake libcap2 libcap-dev
```
2 AWSアカウントのAccess KeyとSecret Keyをダウンロード
3 下記コマンドをWebRTC C SDKをダウンロードしたディレクトリで実行しビルド。
```
mkdir -p amazon-kinesis-video-streams-webrtc-sdk-c/build;
cd amazon-kinesis-video-streams-webrtc-sdk-c/build; 
cmake ..
```
4 上記の手順で作成したビルドディレクトリに移動し、makeを実行してWebRTC C SDKとその提供されたサンプルをビルドします。

## サンプルを実行
提供サンプルのひとつ`kvsWebrtcClientMasterGstSample`を動かしてみます。これは、GStreamerパイプラインを通じて、H264エンコード出力するものです。

1 AWSアカウント認証情報の設定
```
export AWS_ACCESS_KEY_ID= <AWSアカウントのAccess Key>
export AWS_SECRET_ACCESS_KEY= <AWSアカウントのAccess Key>
export AWS_KVS_CACERT_PATH= <認証.pemファイルへのフルパス>
```

2 事前にAWSコンソールで作成したシグナリングチャネルをパラメータとして、kvsWebrtcClientMasterGstSampleを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/8c63014c-f4c6-b999-9e23-869ef5eafb1c.png)
今回は、`channel_for_test`という名前のシグナリングチャネルを作成したので、下記コマンドを実行します。
```
./kvsWebrtcClientMasterGstSample channel_for_test
```

3 シグナリングチャネルが生成され、接続されたMasterはストリーミングを開始します。
```
$ ./kvsWebrtcClientMasterGstSample channel_for_test
[KVS GStreamer Master] Using trickleICE by default
[KVS GStreamer Master] Created signaling channel channel_for_test
[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 channel_for_test
```

4 AWS WebコンソールのKinesis Video Streams - シグナリングチャネルで該当するシグナリングチャネルを選択し、メディア再生ビューワーで映像を確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/79b10d34-52ad-1244-b324-44c65260b140.png)

[KVS WebRTC Test Page](https://awslabs.github.io/amazon-kinesis-video-streams-webrtc-sdk-js/examples/index.html)からも確認ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/ddbf568b-24a5-4aaa-7f64-2571c207cd37.png)

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172313/d6ad10bc-75ba-8124-14d4-f144657c6473.png)](https://twitter.com/ghibi)