【初心者向け】Amazon Kinesis Video Streams WebRTC SDKのJSサンプルをEC2にデプロイする手順

## 1． この記事の内容
WebRTCを勉強中の初心者エンジニアです。
[前回](https://qiita.com/rie_uchida500/items/749dbe578c5ea5fac1c3)は、WebRTCの仕組みを調査しました。今後はハンズオンとして、Amazon Kinesis Video Streams WebRTC（以降、KVS WebRTC）でWebチャットアプリを作っていきます。
今回は、KVS WebRTC SDK（JavaScript）のサンプルをEC2にデプロイして動作確認したので、その手順をまとめます。

この記事で触れる内容は以下です。

* Amazon Kinesis Video Streams WebRTCの使い方
* EC2でWebサイトを公開する方法
* WebサイトのSSL化の方法

## 2．Amazon Kinesis Video Streams WebRTCとは
フルマネージドのシグナリングサーバー、STANサーバー、TURNサーバーを提供しています。
また、クライアント側のSDKも公開されています。ブラウザ向け（JavaScript）、組み込み用途（C言語）、iOS/Androidアプリ向けのSDKがあり、用途に合わせて利用できます。
詳細は[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/kinesisvideostreams-webrtc-dg/latest/devguide/what-is-kvswebrtc.html)をご覧ください。

## 3．構成イメージ
AWSリソースと、KVS WebRTC SDK（JavaScript）のサンプルを使って、下図のようなサービスを構築します。

![WebRTC0005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/22eb3395-ba15-fa1f-5b81-de0641aa4a87.png)

## 4．前提
AWSコンソールで作業します。AWSアカウントを作成していることを前提として進めます。
## 5．手順
![RTC0017.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/0112cf5a-b486-0e9a-cd8c-c69098210ddf.png)


### Webサイトの公開
###### 1.Amazon Elastic Compute Cloud（EC2）でWebサーバーを構築する
下記サイトの手順に従ってEC2を起動し、Apacheを入れてWebサーバーを構築します。

https://qiita.com/arashida/items/629aaed33401b8f2265c



###### 2.EC2にサンプルプログラムを配置する
Webサーバーに、クライアントのサンプルプログラムを配置します。

まずは、KVS JavaScript SDKのリポジトリをクローンします。
AWSコンソールからEC2に接続した状態で、下記コマンドを実行します。

```
sudo yum install git-all 
git clone https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-js 
```
サンプルのままでは、kvs-webrtc.jsが参照されずエラーになるのでindex.htmlを書き換えます。
下記コマンドで、index.htmlを開きます。

```
cd amazon-kinesis-video-streams-webrtc-sdk-js/examples
vim index.html 
```

開いたら、下図赤枠内のように書き換えて保存します。
![code.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/31d7ad68-2c36-fee8-e044-9f2d0e501cde.png)

次に、下記コマンドで、クローンしたフォルダ配下のサンプルプログラム（HTML、css、jsなど）を```/var/www/html/```配下に配置します。

```
cd amazon-kinesis-video-streams-webrtc-sdk-js/examples
sudo cp app.css favicon.ico loader.css createSignalingChannel.js index.html   master.js viewer.js app.js /var/www/html/
```

最後に、ブラウザからWebサイトにアクセスして確認します。
ブラウザにEC2の「パブリック IPv4 アドレス」を入力します。
下図のページが表示されれば、Webサイトの公開完了です。ページに入力する値は、次項の手順で取得します。
![page2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/740994b1-e781-c03a-e0ee-58651181abd0.png)


### KVS WebRTCの設定
KVS WebRTCのシグナリングサーバー・STUN/TURNサーバーを利用するには、以下２つが必要です。

* シグナリングチャネル
* AmazonKinesisVideoStreamsFullAccess権限のあるIAMユーザー

###### 1.KVSのシグナリングチャネルを取得する
AWSコンソールで「KVS」と検索して、KVSの画面を表示します。
画面左側のメニューから「シグナリングチャネル」を選択し「シグナリングチャネルを作成」を押下します。
画面右上のリージョンは「ap-northeast-1」にします。
![signal2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/5199a50f-4e38-7665-005f-8cabeba8b44d.png)

次の画面で、「シグナリングチャネル名」に任意の名前を入力して「シグナリングチャネルを作成」を押下します。
![signal3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/3366f224-f242-ae35-0c88-5cef115118c3.png)

###### 2.Identity and Access Managemenen（IAM）ユーザーを作成する
AWSコンソールで「IAM」を検索します。
IAMの画面左側のメニューの「ユーザー」を選択し、「ユーザーを追加」を押下します。
ユーザー詳細の設定で以下を入力して「次のステップ」を押下します。
ユーザー名：任意の名前
プログラムによるアクセス：チェック
![IAM2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/0318ec4f-1c7b-8312-1963-2b7d1533f44f.png)

アクセス許可の設定で、「既存のポリシーを直接アタッチ」を選択し、「AmazonKinesisVideoStreamsFullAccess」を選択して「次のステップ」を押下します。
![IAM3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/11bc8cc3-37a0-bf98-7062-4cdf1363d215.png)

タグの追加は何も指定せず、「次のステップ」を押下します。
確認画面で、「ユーザーの作成」を押下します。
最後に「.csvのダウンロード」を押下して、アクセスキーID、シークレットアクセスキーを保存しておきます。
![IAM4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/a3eb2cc8-3383-3e82-a71e-e9a5741601a1.png)

これで、KVS webRTCの利用準備が整いました。
が、まだ、ビデオチャットはできません。HTTPS通信でないと、ブラウザからカメラデバイスへアクセスできないからです。

### WebサイトのSSL化
構築したWebサイトをHTTPS通信で配信するように変更します。
Route53で取得したドメインを使ってAWS Certificate Manager（ACM）で証明書を取得し、証明書をElastic Load Balancing（ELB）に適用します。ELBとEC2を紐付けてインターネット-ELB間はHTTPS、ELB-EC2間はHTTPで通信します。（下図）
![onfla.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/abaec2ea-fcd5-0e29-aa5e-4381fc87684d.png)

###### 1.ドメインを取得する
以下のサイトの手順に従ってAWSコンソールでドメインを購入します。

https://dev.classmethod.jp/articles/route53-domain-2019/

###### 2.証明書を適応してSSL化する
以下のサイトの手順に従って、ELBに証明書を適応し、Webサーバーと紐付けます。
https://dev.classmethod.jp/articles/aws-web-server-https-for-beginner/

これで、ブラウザからカメラデバイスへアクセス可能となりました。

### 通信テスト
最後にPCを2台用意して、通信の確認をします。
###### 1.サンプルページのフォーム入力
下図に従って設定値を入力します。
![ページ３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/3513408b-1af7-eb4f-4931-c920bcef82e3.png)


1台目のPCで、「Start Master」を押下します。
2台目のPCで、「Start Viewer」を押下します。
下図のように両者の映像が表示されれば成功です。
![sample1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1073499/477c9056-7ee0-350f-53c1-70edd8db8926.png)


オフィスと自宅など、NATを超えた通信でも30分以上問題なく利用できました。

## 6．まとめ
Amazon Kinesis Video Streams WebRTCSDK（JavaScript）のサンプルをEC2で動かしてみたので、その手順をまとめました。
[次回](https://qiita.com/rie_uchida500/items/90811f8454edce648f89)は、C言語版の実装をしてみたいと思います。

## おまけ．サンプルコードの確認
動作確認ができたので、コードを覗いて処理の概要を確認します。

##### JSファイルの処理概要
サンプルのJSファイルは、それぞれ主に以下の処理を担当しているようです。

* APP.js・・・画面の更新などMaster、Viewerの共通処理。
* createSignalingChannel.js・・・シグナリングチャネルを利用するためのオブジェクトを作成する。
* Viewer.js・・・Viewer側の処理。シグナリングチャネルに接続する。RTCPeerConnectionを生成して、offer SDPを送信する。Masterのメディアを受信したら画面に表示する。

* Master.js・・・Master側の処理。シグナリングチャネルに接続する。
offer SDPを受け取ったらRTCPeerConnectionを生成してanswer SDPを送信する。Viewerのメディアを受信したら画面に表示する。


##### 主要なクラスやAPI
【KVSWebRTC.SignalingClient】
SDPの送受信や、ICEcandidateの送受信など、シグナリングの処理を行うクラス。

例．ICEcandidateの送信

```diff_javascript
signalingClient.sendIceCandidate(candidate);
```
例．ICEcandidate受信時の処理

```diff_javascript
signalingClient.on('iceCandidate', candidate => {
    peerConnection.addIceCandidate(candidate);
});
```

【RTCPeerConnection】
ピア間の接続の開始や、保守や監視などをするメソッドを提供するAPI。
例．相手のメディアを受信した際の処理

```diff_javascript
peerConnection.addEventListener('track', event => {
    console.log('[MASTER] Received remote track from client: ' + remoteClientId);
    if (remoteView.srcObject) {
        return;
    }
    remoteView.srcObject = event.streams[0];
});
```