AWS Kinesis Video StreamsでビデオストリーミングWebRTCを実施

こんにちは　フリーランスの永田です。

今年も仕事をしながら、技術を探求して、ARのライブラリー、ビデオ編集のライブラリー、背面前面同時撮影できるカメラのライブラリーなどを作成しました。　[こちらに技術を公開しています](https://github.com/daisukenagata)

今回はSwift愛好会の2019年のアドベントカレンダーに参加させていただきました。

AWS Kinesis Video StreamsでビデオストリーミングWebRTCを実施します。

こちらの順序で展開させていただきます。

```

環境

サンプルソース

やり方

つまづきポイント

挙動

```


### 環境　

`macOS Catalina 10.16.2`

`Xcode Version 11.2.1 (11B500)　`

[AWS マネジメントコンソールに入れること(AWSに登録済み)](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=2ahUKEwjZo6Lwu7fmAhXPwYsBHZLQDRgQFjAAegQIBxAC&url=https%3A%2F%2Faws.amazon.com%2Fjp%2Fconsole%2F&usg=AOvVaw1yVeaToVi2rj68q1N4C5sx)

[AWS Kinesis Video Streamsでシグナリングチャンネルの作成](https://aws.amazon.com/jp/kinesis/video-streams/)


### サンプルソース
このリンク先のアプリとAWS Kinesis Video Streamsを連携させてWebRTCを実現します。
https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-ios



### やり方

[サンプルソース](https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-ios)のReadMeを確認願います。

[Amazon Cognitoのユーザープール、IDプールの管理設定が必要になります。](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=2ahUKEwi3uZGcvbfmAhWvBKYKHbvvBa0QFjAAegQIARAB&url=https%3A%2F%2Faws.amazon.com%2Fjp%2Fcognito%2F&usg=AOvVaw2Ht2JKsa_DdN0DqKSiuvbz)



[Amazon Cognitoの作成方法、サンプルの確認手順はこのリンクに書いています。](https://docs.aws.amazon.com/ja_jp/kinesisvideostreams-webrtc-dg/latest/devguide/kvswebrtc-sdk-ios.html)


`AWSKinesisVideoWebRTCDemoApp.xcworkspace`をbuild&Run

buildが通らない場合、[サンプルソース](https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-ios)にbuildを通すコマンド操作を確認。


- - -

記載箇所にAmazon Cognitoで設定した項目を記載します。


Constants.swift

```
import Foundation
import AWSCognitoIdentityProvider
// 記入
let CognitoIdentityUserPoolRegion = AWSRegionType.APNortheast1
// 記入
let CognitoIdentityUserPoolId = "Amazon Cognitoのプール ID"
// 記入
let CognitoIdentityUserPoolAppClientId = "Amazon Cognitoのアプリクライアント ID"
// 記入
let CognitoIdentityUserPoolAppClientSecret = "Amazon Cognitoのアプリクライアントのシークレット"

let AWSCognitoUserPoolsSignInProviderKey = "UserPool"
// 記入
let CognitoIdentityPoolID = "ap-northeast-1:~~~~~~~~~~~~~ ID プールの管理から作成するID プールID"
// 記入
let AWSKinesisVideoEndpoint = "https://kinesisvideo.ap-northeast-1.amazonaws.com"
let AWSKinesisVideoKey = "kinesisvideo"

let VideoProtocols =  ["WSS", "HTTPS"]

let ConnectAsMaster = "connect-as-master"
let ConnectAsViewer = "connect-as-viewer"

let MasterRole = "MASTER"
let ViewerRole = "VIEWER"

let ClientID = "ConsumerViewer"

```

awsconfiguration.json

```
{
    "Version": "1.0",
    "CredentialsProvider": {
        "CognitoIdentity": {
            "Default": {
　　　　　　　　　　// 記入
                "PoolId": "ap-northeast-1:~~~~~~~~~~~~~ ID プールの管理から作成するID プールID",
　　　　　　　　　　// 記入
                "Region": "ap-northeast-1"
            }
        }
    },
    "IdentityManager": {
        "Default": {}
    },
    "CognitoUserPool": {
        "Default": {
　　　　　　　// 記入
            "AppClientSecret": "Amazon Cognitoのアプリクライアントのシークレット",
　　　　　　　// 記入
            "AppClientId": "Amazon Cognitoのアプリクライアント ID",
　　　　　　　// 記入
            "PoolId": "Amazon Cognitoのプール ID",
　　　　　　　// 記入
            "Region": "ap-northeast-1"
        }
    }
}
```

- - -

- アプリ画面のサインアップ画面でユーザー登録
<img width="375" alt="IMG_0C39895C7541-1.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131469/5fc1e779-17a4-b706-a4b1-11795f0c3507.jpeg">


- 検証コードと新しいパスワードを登録

パスワードを再設定の際、Amazon Cognitoでメール、SMSからパスワードの再設定コードを受け取る必要があります。



<img width="244" alt="スクリーンショット 2019-12-15 20.12.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131469/a36f6359-67a6-ae14-f12a-1959c10a8db4.png">
<img width="1606" alt="スクリーンショット 2019-12-15 20.12.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131469/5219d125-5c80-ddc5-b7db-1d3006bc624d.png">

- サインインしてConnect画面に遷移

`Kinesis Video Streamsのシグナリングチャンネルのチャンネル名`
`Amazon Cognitoのアプリクライアントのシークレット`
`リージョン名`
を記入して、青い色Button(どちらでも良い)を押下で成功するとConnectedになり、RTC専用のカメラプレビュー画面に遷移します。AWSのライブラリーではカメラもライブラリー内で使用されていて、UIViewを渡す処理になっていますので、カメラの種類をカスタマイズは難しいようです。

モバイルで表示しているプログラムです。ライブラリーのRTCMTLVideoViewはUIViewになります。
<img width="434" alt="スクリーンショット 2019-12-16 12.06.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131469/e2a1bfda-cb25-3acb-8b84-1411375011ab.png">


```
    override func viewDidLoad() {
        super.viewDidLoad()
        
        #if arch(arm64)
        // Using metal (arm64 only)
        let localRenderer = RTCMTLVideoView(frame: localVideoView?.frame ?? CGRect.zero)
        let remoteRenderer = RTCMTLVideoView(frame: view.frame)
        localRenderer.videoContentMode = .scaleAspectFill
        remoteRenderer.videoContentMode = .scaleAspectFill
        #else
        // Using OpenGLES for the rest
        let localRenderer = RTCEAGLVideoView(frame: localVideoView?.frame ?? CGRect.zero)
        let remoteRenderer = RTCEAGLVideoView(frame: view.frame)
        #endif
        
        webRTCClient.startCaptureLocalVideo(renderer: localRenderer)
        webRTCClient.renderRemoteVideo(to: remoteRenderer)
        
        if let localVideoView = self.localVideoView {
            embedView(localRenderer, into: localVideoView)
        }
        embedView(remoteRenderer, into: view)
        view.sendSubviewToBack(remoteRenderer)
    }
```

## つまづきポイント

ユーザーは管理画面から作成ではなく、アプリのサインアップから作成してください。
管理画面から作成すると、パスワードの再設定をしていない状態になってしまい、別途コマンド操作でパスワードの再設定が必要になりますがAWS CLIから操作する場合に、シークレットキーを外す対応が必要です。
今回のサンプルの手順ではAWS CLIから対応するより、アプリのAPIから対応した方が良さそうです。
https://qiita.com/noobar/items/6615501b035e47792227



issuesを投げたところ、デバッグでレスポンスの確認をしてくださいとの事で、確認しましたら、パスワードの再設定的なログがでたので、アプリ側から操作してパスワードを再設定したところ、アプリ認証が通りました。
https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-ios/issues/1

<img width="1216" alt="スクリーンショット 2019-12-15 20.05.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131469/450fe95e-6fe7-2fc3-3ad8-4caa7652e9cb.png">


## 挙動
`モバイル`

シグナリングチャンネルのConnect画面

<img width="375" alt="IMG_1641292D2A90-1.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131469/606fe4d6-add3-6c7e-fea9-819e7e14bbaf.jpeg">

プレビュー画面

<img width="375" alt="IMG_36423BE3E0A2-1.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131469/8af12b8a-787f-46ec-59bc-68e5f5c49449.jpeg">

`AWS Kinesis Video Streams シグナリングチャンネル画面`
Chromeなどで開いて下さい。　
CloudWatch メトリクスなどで使用解析もできるので、価格プランなども検討できると思います。
<img width="638" alt="スクリーンショット 2019-12-15 20.23.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131469/7c67fbda-06f0-ac1b-2c62-14a437bfce66.png">

`複数端末での挙動`

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">複数端末でのAWSRTCの配信技術 <a href="https://t.co/1lIaz3U3WC">pic.twitter.com/1lIaz3U3WC</a></p>&mdash; DaisukeNagata (@dbank0208) <a href="https://twitter.com/dbank0208/status/1205275167372410880?ref_src=twsrc%5Etfw">December 12, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


アプリケーションを動作させる上で、合計工数は4時間ぐらいで確認できました。

リアルタイム配信が身近なものになったと思いますが、カメラ機能などカスタマイズ性を向上させるのはRTC側を自作する必要があり、Safariだとメディア再生ビューワーが開かなかったので、自作してSafariを開かせる必要が出てきそうです。


##### [関連資料 JSのWeb画面でビデオストリーミングWebRTCを利用する場合](https://dbank0208.com/wp/2019/12/08/amazon-kinesis-video-streams-%e3%81%a8-webrtc/)


今後も精進して、技術力を高めて、ゆくゆくは技術で還元していきます。

以上、貴重なお時間お読み下さいまして、誠にありがとうございます。