Amazon Kinesis Video StreamsのWebRTC対応まとめ + 1対1の低遅延なビデオ通話を試してみる


# はじめに

この記事は DMMグループ Advent Calendar 2019 15日目の記事です

今年DMM.comに新卒入社した @k0bya4 です
現在はWebRTCを利用したライブ配信サービスで主にサーバサイドの開発をしています

今回は、先日発表されたAmazon Kinesis Video StreamsのWebRTCサポートについて個人的に試してみたことについてまとめます


# Amazon Kinesis Video Streams
### サービスの概要
[Amazon Kinesis Video Streams](https://aws.amazon.com/jp/kinesis/video-streams/)

> Amazon Kinesis Video Streams を使用すると、分析、機械学習 (ML)、再生、およびその他の処理のために、接続されたデバイスから AWS へ動画を簡単かつ安全にストリーミングできるようになります。Kinesis Video Streams は、数百万ものデバイスからの動画のストリーミングデータを取り込むために必要なすべてのインフラストラクチャを、自動的にプロビジョニングして、伸縮自在にスケールします。また、ストリーム内の動画データの耐久性に優れた保存、暗号化、インデックス作成を行い、使い勝手のよい API を介したデータへのアクセスも可能にします。Kinesis Video Streams を使用すると、ライブやオンデマンド視聴用の動画を再生したり、Amazon Rekognition Video との統合、および Apache MxNet、TensorFlow、OpenCV といった ML フレームワーク向けライブラリとの統合により、コンピュータビジョンと動画分析を活用するアプリケーションを迅速に構築することができます。

Amazon Kinesis Video Streamsを利用したことはなかったのですが、動画のストリーム、保存、分析向けのユースケースで活用できるストリーミングデータを取り込むためのマネージドサービスということらしいです

### WebRTCのサポート

先日、Kinesis Video StreamでWebRTCによる双方向メディアストリームがサポートされることが発表されました
[Amazon Kinesis Video Streams adds support for real-time two-way media streaming with WebRTC](https://aws.amazon.com/jp/about-aws/whats-new/2019/12/amazon-kinesis-video-streams-adds-support-for-real-time-two-way-media-streaming-with-webrtc/)

### どこまでがマネージドなのか
通常P2PのWebRTCを利用する際には接続状況のやり取りを行うシグナリングサーバーやNAT超えを実現するSTUN/TURNサーバを運用する必要があります
![webrtc-signaling-stun-turn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228724/6fcdfdf5-498a-bc49-9143-491288d70677.png)

Kinesis Video Streamでは、これらがAWSのマネージドサービスとして提供され各種SDKから利用可能になります
比較すると下図のようなイメージになるかと思います
![webrtc-kinesis-video.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228724/9748862f-d794-a0d9-7980-a65fcbb66d0e.png)

# ブラウザでサンプル実装を動作させる
### SDKのサンプル実装を動かす
JavaScript向けのSDKにブラウザで動作するサンプル実装が含まれているので、こちらを動作させてみます
[Amazon Kinesis Video Streams WebRTC SDK for JavaScript](https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-js)

### AWSコンソールでチャネル作成
シグナリングチャネル名を入力してシグナリングチャネルを作成します
![スクリーンショット 2019-12-15 4.00.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228724/abebbc64-a712-b8e8-e5c9-7b473bc51596.png)
AWSコンソール側で必要な準備はこれだけです

### 配信/視聴の開始

JavaScript SDKのリポジトリをクローンします

```
    git clone https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-js.git
```

yarnやnpmでサンプル実装を起動させます

```
    cd amazon-kinesis-video-streams-webrtc-sdk-js/examples
    yarn install
    yarn run develop
```

`localhost:3001` にアクセスしてAWSのCredentialやSTUN/TURNの利用など設定項目を埋めていきます
<img width="1143" alt="スクリーンショット 2019-12-15 4.21.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228724/51f169f4-7e93-1a5e-05f0-c066dc262c90.png">

Channel Nameには先ほど作成したチャネル名を入力します
今回は下記のような設定でテストします

- 音声と映像を配信
- DataChannel使用
- 解像度は1280 x 720
- 動画コーデックはVP8
- STUN/TURNを利用
- tricke ICEを利用

### 動作状況の確認
MasterとViewerそれぞれ立ち上げることで1対1のビデオ通話を行うことができます
（映像は黒塗りしてます）
Master/Viewerともに

- 画面左 : カメラデバイスからのMediaStreamをVideoタグで再生
- 画面右 : Kinesis Video Streamsを経由して受信した映像

が再生されています
東京リージョンを使用し、都内から接続したテスト結果になります 
<img width="941" alt="スクリーンショット 2019-12-15 4.04.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228724/d3316830-5e7e-9bbf-5533-749281a9c3d7.png">
![スクリーンショット 2019-12-15 4.04.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228724/8bfc650f-870c-3a0c-730e-3d5becfe6cd0.png)

サンプル実装ではDataChannelを利用して簡易的なチャットが実現されています
DataChannelを利用するとファイル送信などもできるのでいろいろ実装できそうですね

![スクリーンショット 2019-12-15 4.07.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228724/f51eacd3-6b87-228c-09d2-2c3b031f3129.png)

気になる遅延は **0.13秒ほど** でした 🎉
かなり低遅延な映像配信が実現できてますね

[追記]
Netlifyにサンプルをデプロイしてスマホからの接続も確認してみました
遅延も同じ程度で配信できました〜

<img width="439" alt="スクリーンショット 2019-12-15 14.31.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/228724/3fd2a54d-7d2d-d23b-dc24-dc1d7d92d4f2.png">

# 気になったこと
### 料金
WebRTC利用時の料金や制限などの情報は現時点 (2019/12/15) で英語版のドキュメントには掲載されています
[Amazon Kinesis Video Streams pricing](https://aws.amazon.com/kinesis/video-streams/pricing)

- シグナリングチャンネル作成
    - 0.045USD
- シグナリングメッセージ ( 100万回あたり )
    - 3.375USD
- TURN経由のストリーミング ( 1000分あたり )
    - 0.18USD
        
＋ データ転送料金

### 制限
現時点での制限は下記のようになっています
[Amazon Kinesis Video Streams with WebRTC Service Quotas](https://docs.aws.amazon.com/kinesisvideostreams-webrtc-dg/latest/devguide/kvswebrtc-limits.html)

- シグナリングチャンネルの作成
    - リージョンごとに10000（緩和リクエスト可能）
- 視聴者の接続数
    - 1チャンネル10接続まで（緩和リクエスト可能）
        - リクエストでどの程度緩和可能か気になりますね

### AWSの類似サービスとの違い
AWS Elemental MediaLiveとの棲み分けがどのようになっているか気になったのですが、FAQに下記のような記載がありました
[Amazon Kinesis Video Streams のよくある質問](https://aws.amazon.com/jp/kinesis/video-streams/faqs/)

> Q: Kinesis Video Streams と AWS Elemental MediaLive の違いは何ですか?
AWS Elemental MediaLive は、ブロードキャストグレードのライブ動画エンコードサービスです。テレビ放送やインターネット接続のマルチスクリーンデバイス (インターネット接続対応の TV、タブレット、スマートフォン、セットトップボックス) での配信用に、高品質な動画ストリームを作成できます。このサービスは独立して、または AWS メディアサービスの一部として機能します。
Amazon Kinesis Video Streams を使用すると、リアルタイムとバッチ処理用の機械学習 (ML)、動画再生、分析、およびその他の処理のために、接続されたデバイスから AWS へ動画を簡単かつ安全にストリーミングできます。マシンビジョンに基づいたアプリケーションを構築して、スマートホーム、スマートシティー、産業用オートメーション、セキュリティモニタリングなどに組み込むことができます。

Elemental Medialiveはより多数への動画配信に特化したサービスで、Kinesis Video Streamsは動画配信が主目的ではなく取り込んだストリームをモニタリング・映像配信等にも使用することができるという感じなのかなと思いました
現状WebRTCでのP2Pなやり取りができるAWSのマネージドサービスはKinesis Video Streamsだけですが、この先Elemental Medialiveで対多数の配信向けのSFUのようなサービスがサポートされたりするのでしょうかね

# おわりに
Amazon Kinesis Video StreamsでサポートされたWebRTCでのビデオ通話のサンプル実装を試してみました

現状の制限も踏まえて対少人数のライブ配信や1対1のビデオ通話機能の実装などに活用できそうです
シグナリングサーバやSTUN/TURNサーバの運用時には、ポートの開放やSSL化、TCP関連のパラメータのチューニングなど考慮すべき点が多いので、マネージドサービスで気軽に低遅延な音声と映像の配信が取り入れられるのはかなり便利ですね
料金もインターネットへのデータ転送料金がちょっと怖いですが、Kinesis Video Streams自体の利用料金は高くないので個人開発などでも試してみたいですね

今回の検証にはDMMのエンジニア向けのサポート制度のひとつで、月100ドルまでAWS・GCPを利用できる実弾演習場制度を使いました！
個人的な学習にもサービスを気軽に動かしながら学べるので良いです

[DMM Tech Empowerment -エンジニア・デザイナーのためのサポート制度パッケージを公開！-](https://inside.dmm.com/entry/2019/01/15/dmm-tech-empowerment)
> 月100ドルまで自由に使って学習可能なAWS・GCP実弾演習場

それでは、DMMグループアドベントカレンダー16日目 @umerin さんの更新をお楽しみに！