SlideShare a Scribd company logo
Amazon Kinesis Video
Streams WebRTC 使ってみた
WebRTC Meetup Tokyo #23
がねこまさし @massie_g
自己紹介
• がねこまさし / @massie_g
• インフォコム(株)の技術調査チームに所属
• WebRTC Meetup Tokyo スタッフ
• 今日の元ネタ
• Amazon Kinesis Video Streams WebRTC を動かしてみた
• Qiita https://qiita.com/massie_g/items/b6d3513d06a28ba89677
2
Amazon Kinesis Video Stream (KVS)とは
• https://aws.amazon.com/jp/kinesis/video-streams/
• 分析、機械学習 (ML)、再生、およびその他の処理のために
• 接続されたデバイスから AWS へ動画を簡単かつ安全にストリーミン
グできるようになります
• Kinesis Video Streams は、数百万ものデバイスからの動画のスト
リーミングデータを取り込むために…
• ライブやオンデマンド視聴用の動画を再生したり
• Amazon Rekognition Video との統合… コンピュータビジョンと動画
分析を活用するアプリケーションを迅速に構築することができます
動画の収集、分析、(配信)
Amazon KVS WebRTCとは
• https://aws.amazon.com/jp/kinesis/video-streams/
• またKinesis Video Streams がサポートするオープンソースプロジェ
クトの WebRTC は、
• リアルタイムのメディアストリーミング、ウェブブラウザ間のインタ
ラクション、モバイルアプリケーション、シンプルな API によるコネ
クテッドデバイスを可能にします
• 用途としては、ビデオチャットやピアツーピアのメディアストリーミ
ングが一般的です。
→通常のKVSと併用して使う想定
Amazon KVS ユーズケースより
KVS WebRTC
KVS WebRTCがサポートするもの(1)
サーバー機能
• シグナリング
• P2P通信を始める前に、必要な情報を交換するステップ
• Offer/Answer SDP の交換、ICE candidateの交換
• WebSocket利用
• マネージドSTUN/TURN
• P2P通信でNATや越え、制限がある環境で通信を行うための仕組み
• (が、自社の社内NWとインターネット側でまだうまく使えてない…)
• 参考:WebRTCハンズオン 概要編(Qiita)
• https://qiita.com/massie_g/items/916694413353a3293f73
• サーバー側でメディアを受信、保管、変換する機能は無し
• → 従来のKVSの機能を使うのが前提
KVS WebRTCがサポートするもの(2)
クライアント機能
• クライアント用SDK
• ブラウザ用(JavaScript用) … シグナリング
• https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-js
• P2P通信そのものは、ブラウザの持つ機能を利用
• 組み込み用(C言語用) … シグナリング+(S)RTP通信
• https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-c
• スマートデバイス用(iOS, Android)… シグナリング+??
• https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-ios
• https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-
android
KVS WebRTCの通信形態
• シグナリングチャネル(ルーム)ごとのシグナリング
• 1つのMasterが参加
• 1つ以上複数のViewerが参加可能(現在、最大10まで)
• P2P通信
• メディアの通信
• データの通信(DataChannel)
• 片方向、双方向
KVS WebRTCの通信形態: 1対n
JavaScript用SDKのサンプル/Demo
• ソースコード
• https://github.com/mganeko/kvs_webrtc_example
• デモ: Master ← 複数Viewer
• Master側… master_multiviewer.html
• Viewer側 … viewer.html
コード例
• SDK読み込み
• https://sdk.amazonaws.com/js/aws-sdk-2.595.0.min.js
• https://unpkg.com/amazon-kinesis-video-streams-webrtc/dist/kvs-
webrtc.min.js
• シグナリングチャネルを準備
• AWS.KinesisVideoインスタンスを生成
• シグナリングチャネル用のエンドポイントを取得
• STUN/TURNサーバー(iceServers)の情報を取得
• KVSWebRTC.SignalingClient インスタンスを生成
• イベントハンドラを指定
コード例:シグナリングチャネルを準備
• AWS.KinesisVideoインスタ
ンスを生成
• シグナリングチャネル用のエ
ンドポイントを取得
• STUN/TURNサーバー
(iceServers)の情報を取得
• KVSWebRTC.SignalingClient
インスタンスを生成
• イベントハンドラを指定
const kinesisVideoClient = new
AWS.KinesisVideo({
region,
accessKeyId,
secretAccessKey,
});
コード例:シグナリングチャネルを準備
• AWS.KinesisVideoインスタ
ンスを生成
• シグナリングチャネル用の
エンドポイントを取得
• STUN/TURNサーバー
(iceServers)の情報を取得
• KVSWebRTC.SignalingClie
nt インスタンスを生成
• イベントハンドラを指定
const getSignalingChannelEndpointResponse =
await kinesisVideoClient
.getSignalingChannelEndpoint({
ChannelARN: channelARN,
SingleMasterChannelEndpointConfiguration: {
Protocols: ['WSS', 'HTTPS’],
Role: KVSWebRTC.Role.MASTER, // or VIEWER
},
}).promise();
const endpointsByProtocol =
getSignalingChannelEndpointResponse
.ResourceEndpointList.reduce(
(endpoints, endpoint) => {
endpoints[endpoint.Protocol] =
endpoint.ResourceEndpoint;
return endpoints;
}, {});
コード例
• AWS.KinesisVideoインスタ
ンスを生成
• シグナリングチャネル用の
エンドポイントを取得
• STUN/TURNサーバー
(iceServers)の情報を取得
• KVSWebRTC.SignalingClie
nt インスタンスを生成
• イベントハンドラを指定
const kinesisVideoSignalingChannelsClient
= new AWS.KinesisVideoSignalingChannels({
region, accessKeyId, secretAccessKey,
endpoint: endpointsByProtocol.HTTPS,
});
const getIceServerConfigResponse =
await kinesisVideoSignalingChannelsClient
.getIceServerConfig({
ChannelARN: channelARN,
}).promise();
const iceServers = [
{urls:
`stun:stun.kinesisvideo.${region}
.amazonaws.com:443`}
];
getIceServerConfigResponse.IceServerList
.forEach(
iceServer =>
iceServers.push({
urls: iceServer.Uris,
username: iceServer.Username,
credential: iceServer.Password,
})
);
コード例:シグナリングチャネルを準備
• AWS.KinesisVideoインスタン
スを生成
• シグナリングチャネル用のエン
ドポイントを取得
• STUN/TURNサーバー
(iceServers)の情報を取得
• KVSWebRTC.SignalingClient
インスタンスを生成
• イベントハンドラを指定
const signalingClient =
new KVSWebRTC.SignalingClient({
channelARN,
channelEndpoint: endpointsByProtocol.WSS,
clientId,
role: KVSWebRTC.Role.MASTER, // or VIEWER
region,
credentials: {
accessKeyId,
secretAccessKey,
},
});
コード例:シグナリングチャネルを準備
• AWS.KinesisVideoインスタ
ンスを生成
• シグナリングチャネル用の
エンドポイントを取得
• STUN/TURNサーバー
(iceServers)の情報を取得
• KVSWebRTC.SignalingClie
nt インスタンスを生成
• イベントハンドラを指定
signalingClient.on('open', async () => {
});
signalingClient.on('sdpAnswer', async answer => {
}); // VIEWER用
signalingClient.on('sdpOffer’,
async (offer, remoteClientId) => {
}
); // MASTER用
signalingClient.on('iceCandidate’,
(candidate, remoteClientId) => {
peerConnection.addIceCandidate(candidate);
}
);
signalingClient.on('close', () => {
});
コード例:Viewer側
• Offerを送り、Answerを受け取る
const offer = await peerConnection.createOffer({
offerToReceiveAudio: true,
offerToReceiveVideo: true,
});
await peerConnection.setLocalDescription(offer);
signalingClient.sendSdpOffer(
peerConnection.localDescription
);
// イベントハンドラ
signalingClient.on('sdpAnswer’,
async answer => {
await peerConnection.setRemoteDescription(answer);
}
);
コード例: Master側
• Offerを受け取り、Answerを返す
// イベントハンドラ
signalingClient.on('sdpOffer', async (offer, remoteClientId) => {
// … remoteClientId に対応する peerConnectionを準備する …
await peerConnection.setRemoteDescription(offer);
await peerConnection.setLocalDescription(
await peerConnection.createAnswer({
offerToReceiveAudio: true,
offerToReceiveVideo: true,
}),
);
signalingClient.sendSdpAnswer(peerConnection.localDescription,
remoteClientId
);
});
コード例: ICE Candidate(共通)
• PeerConnectionがICE Candidateを生成したとき
• ICE Candidateをシグナリングチャネルで受け取った時
// PeerConnectionがICE Candidateを生成したとき
peer.addEventListener('icecandidate', ({ candidate }) => {
if (candidate) {
signalingClient.sendIceCandidate(candidate, remoteClientId);
} else {
// No more ICE candidates will be generated
}
});
// 相手からICE Candidateを受け取った時
signalingClient.on('iceCandidate', (candidate, remoteClientId) => {
peer.addIceCandidate(candidate);
});
シグナリングの注意点
• Offerは、必ずMasterに届く
• ViewerからOfferに送る際に、相手を指定する必要はない
• Answerは、相手(clientId)を指定してViewerに送る
• Viewerは複数いる可能性があるので、clientIdで区別する
• ICE candidateを送るとき
• Viewer  Offer の場合は、相手を指定しなくて良い
• Offer  Viewerの場合には、相手(clientId)を指定
• それ以外のアプリケーションメッセージは送れない
• 切断通知には使えない
シグナリングチャネルの作成
• WebRTCのアプリで良くある「ルーム」や「チャネル」に相当
• 同じ「シグナリングチャネル」に参加しているクライアント同士でシ
グナリング→P2P通信が可能
• シグナリングチャネルを作成する4つの方法
• AWSコンソールから作成
• AWSのコマンドラインツール(CLI)から作成
• AWSのSDKからAPIを利用して作成
• REST APIを利用して作成
その前に、IAMの準備
• IAM(Identity and Access Managemenent)でユーザを作成
• AmazonKinesisVideoStreamsFullAccess の権限を付与
• アクセスに必要な情報を記録しておく
• アクセスキー
• アクセスシークレットキー
IAMでユーザー作成 (1)
IAMでユーザー作成(2)
IAMでユーザー作成(3)
IAMでユーザー作成(4)
AWSコンソールでシグナリングチャネルの作成
AWSコンソールでシグナリングチャネルの作成
AWSコンソールでシグナリングチャネルの作成
CLIツールでシグナリングチャネルの作成
• CLIツールをインストール
• アクセスキー/アクセスシークレットーキーを指定
• 設定ファイル or 環境変数
• macOSで設定ファイルの場合 ~/.aws/credentials
[default]
aws_access_key_id=xxxxxx
aws_secret_access_key=xxxxxxxxx/xxxxxxx
• us-west-2リージョンに “channel02”を作る場合
$ aws2 --region us-west-2 kinesisvideo create-signaling-channel
--channel-name channel02 --channel-type SINGLE_MASTER
{ "ChannelARN":
"arn:aws:kinesisvideo:us-west-2:xxxxxxxxxx:channel/channel02/xxxxxxxxx”
}
• ※ARNを記録しておく
SDKでシグナリングチャネルの作成(JS)
const kinesisVideoClient = new AWS.KinesisVideo({
region, accessKeyId, secretAccessKey });
const kinesisvideo = new AWS.KinesisVideo();
const channel = 'channel03’;
const params = {
ChannelName: channel,
ChannelType: 'SINGLE_MASTER’
};
kinesisvideo.createSignalingChannel(params, function (err, data) {
if (err) console.log(err, err.stack); // エラー
else console.log(data); // 成功、ARNがJSONで返ってくる
});
DEMO
REST API でシグナリングチャネルの作成
• リージョン:us-west-2, チャネル名:chanel04 の場合
$ curl
-X POST https://kinesisvideo.us-west-2.amazonaws.com/createSignalingChannel
-H "Content-Type: application/json"
-d '{"ChannelName": "channel04", "ChannelType": "SINGLE_MASTER"} '
-H "Authorization: AWS AWSAccessKeyId:Signature"
※ここの文字列の生成方法が、
よくわかってません
KVS WebRTCの価格
• こちらのユースケースから
• https://aws.amazon.com/jp/kinesis/video-streams/pricing/
• 料金の例 2: WebRTC と KVSを使用するスマホ用ライブストリーミングア
プリケーション
• ライブメディアストリーミング用に KVS の WebRTC 機能を使用
• ユーザーが 100 人、それぞれ独自のシグナリングチャネル
• 50 件のライブストリーミングセッションを経由
• 1 か月あたり合計 2,000 分間のライブストリーミング、TURN 20% (400分)
• アクティブなシグナリングチャネル = 100 x (0.03 USD/月) = 3.0 USD
• シグナリングメッセージ = 0.34 USD
• TURN (分) = 100 ユーザー x 400 TURN ストリーミング時間 (分)
• x (0.12 USD/1,000 TURN ストリーミング時間 (分)) = 4.8 USD
• 合計 = 8.14 USD
• 転送 1Mbps と仮定
• 40000 TURNストリーミング時間/月 → 300GB/月
• 転送料金 27 USD/月 (299GB分、us-west-2の場合)
KVS WebRTCの価格
• 料金の例 3: ビデオストリームと WebRTC の両方を使用するスマートホームセ
キュリティカメラ
• ホームセキュリティシステムのプロバイダーには 1,000 人のユーザー
• 各ユーザーの家には 1 台のカメラ、動きを検出するとストリーミング
• ユーザーはコンパニオンアプリで 1 か月あたりに 100 回カメラに接続
• WebRTC によって、ライブビデオストリームの視聴や双方向のオーディオセッション
• セッションの所要時間は 2 分間で、メディアストリームの 40% は TURN
• WebRTC: 各カメラはそれぞれ独自のシグナリングチャネル
• 合計で 1 か月あたり 1,000 件のアクティブなシグナリングチャネル
• 各セッションが配信するシグナリングメッセージは 30 件で
• 合計 3,000,000 件になります
• カメラはそれぞれ TURN 経由の 80 分間のライブストリーミング、
• 1 か月に 80,000 TURN ストリーミング時間 (分)
• 合計 = 46.35 USD
• 転送 1Mbps と仮定
• 80000 TURNストリーミング時間/月 → 600GB/月
• 転送料金 54 USD/月 (599GB分、us-west-2の場合)
KVS WebRTCの感想/まとめ
• KVS WebRTCは、KVSの使い方を広げるもの
• KVS WebRTC 単独では、魅力が少ないかも
• マネージドSTUN/TURNは魅力
• TURNのセッションのパスワード発行もやってくれる
• 通信料は安くはない … 300GB/月 → 27USD
• Vultr.com のIaaS … 1TB/月→ 5USD
• シグナリングの縛りは強い
• シグナリングチャネルにつながるまでの時間も数秒かかる
• 用途
• 今のところ、ビデオチャットのようなコミュニケーション向けではない印象
• 他のサービスの方が使い勝手が良さそう(個人の感想)
• IoTデバイスを使った、動画の収集+リアルタイムモニターのケースがマッチ
THANK YOU!
• ご質問があれば

More Related Content

PDF
AWSのログ管理ベストプラクティス
PDF
Serverless時代のJavaについて
PDF
Dockerからcontainerdへの移行
PDF
Kinesis + Elasticsearchでつくるさいきょうのログ分析基盤
PDF
Grafana LokiではじめるKubernetesロギングハンズオン(NTT Tech Conference #4 ハンズオン資料)
PDF
20180425 AWS Black Belt Online Seminar Amazon Relational Database Service (Am...
PDF
KafkaとAWS Kinesisの比較
PDF
20200212 AWS Black Belt Online Seminar AWS Systems Manager
AWSのログ管理ベストプラクティス
Serverless時代のJavaについて
Dockerからcontainerdへの移行
Kinesis + Elasticsearchでつくるさいきょうのログ分析基盤
Grafana LokiではじめるKubernetesロギングハンズオン(NTT Tech Conference #4 ハンズオン資料)
20180425 AWS Black Belt Online Seminar Amazon Relational Database Service (Am...
KafkaとAWS Kinesisの比較
20200212 AWS Black Belt Online Seminar AWS Systems Manager

What's hot (20)

PPTX
20220409 AWS BLEA 開発にあたって検討したこと
PDF
20200303 AWS Black Belt Online Seminar AWS Cloud Development Kit (CDK)
PDF
20191016 AWS Black Belt Online Seminar Amazon Route 53 Resolver
PDF
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
PPTX
[20220126] JAWS-UG 2022初頭までに葬ったAWSアンチパターン大紹介
PDF
The Usage and Patterns of MagicOnion
PPTX
Dockerからcontainerdへの移行
PPTX
Prometheus入門から運用まで徹底解説
PDF
AWS Black Belt Online Seminar 2016 Amazon EC2 Container Service
PDF
20190326 AWS Black Belt Online Seminar Amazon CloudWatch
PDF
20200930 AWS Black Belt Online Seminar Amazon Kinesis Video Streams
PDF
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
PDF
超実践 Cloud Spanner 設計講座
PDF
Kubernetesによる機械学習基盤への挑戦
PDF
20190604 AWS Black Belt Online Seminar Amazon Simple Notification Service (SNS)
PDF
AWS BlackBelt AWS上でのDDoS対策
PPTX
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
PDF
20201028 AWS Black Belt Online Seminar Amazon CloudFront deep dive
PDF
20190129 AWS Black Belt Online Seminar AWS Identity and Access Management (AW...
20220409 AWS BLEA 開発にあたって検討したこと
20200303 AWS Black Belt Online Seminar AWS Cloud Development Kit (CDK)
20191016 AWS Black Belt Online Seminar Amazon Route 53 Resolver
AWSとオンプレミスを繋ぐときに知っておきたいルーティングの基礎知識(CCSI監修!)
[20220126] JAWS-UG 2022初頭までに葬ったAWSアンチパターン大紹介
The Usage and Patterns of MagicOnion
Dockerからcontainerdへの移行
Prometheus入門から運用まで徹底解説
AWS Black Belt Online Seminar 2016 Amazon EC2 Container Service
20190326 AWS Black Belt Online Seminar Amazon CloudWatch
20200930 AWS Black Belt Online Seminar Amazon Kinesis Video Streams
実運用して分かったRabbit MQの良いところ・気をつけること #jjug
超実践 Cloud Spanner 設計講座
Kubernetesによる機械学習基盤への挑戦
20190604 AWS Black Belt Online Seminar Amazon Simple Notification Service (SNS)
AWS BlackBelt AWS上でのDDoS対策
ネットストーカー御用達OSINTツールBlackBirdを触ってみた.pptx
20201028 AWS Black Belt Online Seminar Amazon CloudFront deep dive
20190129 AWS Black Belt Online Seminar AWS Identity and Access Management (AW...
Ad

Similar to Amazon Kinesis Video Streams WebRTC 使ってみた (20)

PDF
Aws summits2014 エンタープライズ向けawscdpネットワーク編
PDF
AWS Lake Formation で実現、マイクロサービスのサーバーレスな分散トレーシング
PDF
20120528 aws meister-reloaded-awssd-kforjava-public
PDF
AWS Lambda Updates
PPTX
AWS ではじめる Programmable Cloud
PDF
OpenStack API
PDF
k8sクラスタ構築
PDF
20170725 black belt_monitoring_on_aws
PPTX
AWSで認証機能のついたサイトを手軽に構築する(Cognito+CloudFront+API Gateway)
PPTX
Migration to aws as of 20170920
PDF
AWSとGCPを使用したインフラ環境
PDF
20191125 Container Security
PDF
AWS Black Belt Online Seminar Amazon EC2
PDF
Amazon EC2 Container Service Deep dive
PDF
はじめてのAWS CLI
PDF
CloudStack Overview(OSC2012Kansai@Kyoto)
PDF
AWS初心者向けWebinar AWS上にWebサーバーシステムを作ってみましょう ~まずは仮想サーバーから[演習つき]~
PDF
Running Java Apps with Amazon EC2, AWS Elastic Beanstalk or Serverless
PDF
Architecting on Alibaba Cloud - 超基礎編 -
PDF
AWS Black Belt Techシリーズ Amazon VPC
Aws summits2014 エンタープライズ向けawscdpネットワーク編
AWS Lake Formation で実現、マイクロサービスのサーバーレスな分散トレーシング
20120528 aws meister-reloaded-awssd-kforjava-public
AWS Lambda Updates
AWS ではじめる Programmable Cloud
OpenStack API
k8sクラスタ構築
20170725 black belt_monitoring_on_aws
AWSで認証機能のついたサイトを手軽に構築する(Cognito+CloudFront+API Gateway)
Migration to aws as of 20170920
AWSとGCPを使用したインフラ環境
20191125 Container Security
AWS Black Belt Online Seminar Amazon EC2
Amazon EC2 Container Service Deep dive
はじめてのAWS CLI
CloudStack Overview(OSC2012Kansai@Kyoto)
AWS初心者向けWebinar AWS上にWebサーバーシステムを作ってみましょう ~まずは仮想サーバーから[演習つき]~
Running Java Apps with Amazon EC2, AWS Elastic Beanstalk or Serverless
Architecting on Alibaba Cloud - 超基礎編 -
AWS Black Belt Techシリーズ Amazon VPC
Ad

More from mganeko (20)

PDF
Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
PPTX
Build Node.js-WASM/WASI Tiny compiler with Node.js
PPTX
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
PPTX
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
PPTX
Skywayのビデオチャットを録画しよう。そう、ブラウザでね
PPTX
WebRTC mediasoup on raspberrypi3
PPTX
WebRTC SFU Mediasoup Sample update
PPTX
ブラウザでWebRTC - iOSゲートウェイ作ってみた
PPTX
WebRTC SFU mediasoup sample
PDF
Inside of 聖徳玉子 by O2
PDF
Node.js with WebRTC DataChannel
PPTX
WebRTC Build MCU on browser
PPTX
PeerConnectionリレーとMediaRecorder
PPTX
ここがつらいよWebRTC - WebRTC開発の落とし穴
PPTX
Webrtc bootcamp handson
PPTX
WebRTC multitrack / multistream
PDF
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
PDF
WebRTC multistream
PPTX
Inside WebM
PPTX
MediaRecorder と WebM で、オレオレ Live Streaming
Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
Build Node.js-WASM/WASI Tiny compiler with Node.js
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
Skywayのビデオチャットを録画しよう。そう、ブラウザでね
WebRTC mediasoup on raspberrypi3
WebRTC SFU Mediasoup Sample update
ブラウザでWebRTC - iOSゲートウェイ作ってみた
WebRTC SFU mediasoup sample
Inside of 聖徳玉子 by O2
Node.js with WebRTC DataChannel
WebRTC Build MCU on browser
PeerConnectionリレーとMediaRecorder
ここがつらいよWebRTC - WebRTC開発の落とし穴
Webrtc bootcamp handson
WebRTC multitrack / multistream
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC multistream
Inside WebM
MediaRecorder と WebM で、オレオレ Live Streaming

Amazon Kinesis Video Streams WebRTC 使ってみた

  • 1. Amazon Kinesis Video Streams WebRTC 使ってみた WebRTC Meetup Tokyo #23 がねこまさし @massie_g
  • 2. 自己紹介 • がねこまさし / @massie_g • インフォコム(株)の技術調査チームに所属 • WebRTC Meetup Tokyo スタッフ • 今日の元ネタ • Amazon Kinesis Video Streams WebRTC を動かしてみた • Qiita https://qiita.com/massie_g/items/b6d3513d06a28ba89677 2
  • 3. Amazon Kinesis Video Stream (KVS)とは • https://aws.amazon.com/jp/kinesis/video-streams/ • 分析、機械学習 (ML)、再生、およびその他の処理のために • 接続されたデバイスから AWS へ動画を簡単かつ安全にストリーミン グできるようになります • Kinesis Video Streams は、数百万ものデバイスからの動画のスト リーミングデータを取り込むために… • ライブやオンデマンド視聴用の動画を再生したり • Amazon Rekognition Video との統合… コンピュータビジョンと動画 分析を活用するアプリケーションを迅速に構築することができます 動画の収集、分析、(配信)
  • 4. Amazon KVS WebRTCとは • https://aws.amazon.com/jp/kinesis/video-streams/ • またKinesis Video Streams がサポートするオープンソースプロジェ クトの WebRTC は、 • リアルタイムのメディアストリーミング、ウェブブラウザ間のインタ ラクション、モバイルアプリケーション、シンプルな API によるコネ クテッドデバイスを可能にします • 用途としては、ビデオチャットやピアツーピアのメディアストリーミ ングが一般的です。 →通常のKVSと併用して使う想定
  • 6. KVS WebRTCがサポートするもの(1) サーバー機能 • シグナリング • P2P通信を始める前に、必要な情報を交換するステップ • Offer/Answer SDP の交換、ICE candidateの交換 • WebSocket利用 • マネージドSTUN/TURN • P2P通信でNATや越え、制限がある環境で通信を行うための仕組み • (が、自社の社内NWとインターネット側でまだうまく使えてない…) • 参考:WebRTCハンズオン 概要編(Qiita) • https://qiita.com/massie_g/items/916694413353a3293f73 • サーバー側でメディアを受信、保管、変換する機能は無し • → 従来のKVSの機能を使うのが前提
  • 7. KVS WebRTCがサポートするもの(2) クライアント機能 • クライアント用SDK • ブラウザ用(JavaScript用) … シグナリング • https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-js • P2P通信そのものは、ブラウザの持つ機能を利用 • 組み込み用(C言語用) … シグナリング+(S)RTP通信 • https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-c • スマートデバイス用(iOS, Android)… シグナリング+?? • https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-ios • https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk- android
  • 8. KVS WebRTCの通信形態 • シグナリングチャネル(ルーム)ごとのシグナリング • 1つのMasterが参加 • 1つ以上複数のViewerが参加可能(現在、最大10まで) • P2P通信 • メディアの通信 • データの通信(DataChannel) • 片方向、双方向
  • 10. JavaScript用SDKのサンプル/Demo • ソースコード • https://github.com/mganeko/kvs_webrtc_example • デモ: Master ← 複数Viewer • Master側… master_multiviewer.html • Viewer側 … viewer.html
  • 11. コード例 • SDK読み込み • https://sdk.amazonaws.com/js/aws-sdk-2.595.0.min.js • https://unpkg.com/amazon-kinesis-video-streams-webrtc/dist/kvs- webrtc.min.js • シグナリングチャネルを準備 • AWS.KinesisVideoインスタンスを生成 • シグナリングチャネル用のエンドポイントを取得 • STUN/TURNサーバー(iceServers)の情報を取得 • KVSWebRTC.SignalingClient インスタンスを生成 • イベントハンドラを指定
  • 12. コード例:シグナリングチャネルを準備 • AWS.KinesisVideoインスタ ンスを生成 • シグナリングチャネル用のエ ンドポイントを取得 • STUN/TURNサーバー (iceServers)の情報を取得 • KVSWebRTC.SignalingClient インスタンスを生成 • イベントハンドラを指定 const kinesisVideoClient = new AWS.KinesisVideo({ region, accessKeyId, secretAccessKey, });
  • 13. コード例:シグナリングチャネルを準備 • AWS.KinesisVideoインスタ ンスを生成 • シグナリングチャネル用の エンドポイントを取得 • STUN/TURNサーバー (iceServers)の情報を取得 • KVSWebRTC.SignalingClie nt インスタンスを生成 • イベントハンドラを指定 const getSignalingChannelEndpointResponse = await kinesisVideoClient .getSignalingChannelEndpoint({ ChannelARN: channelARN, SingleMasterChannelEndpointConfiguration: { Protocols: ['WSS', 'HTTPS’], Role: KVSWebRTC.Role.MASTER, // or VIEWER }, }).promise(); const endpointsByProtocol = getSignalingChannelEndpointResponse .ResourceEndpointList.reduce( (endpoints, endpoint) => { endpoints[endpoint.Protocol] = endpoint.ResourceEndpoint; return endpoints; }, {});
  • 14. コード例 • AWS.KinesisVideoインスタ ンスを生成 • シグナリングチャネル用の エンドポイントを取得 • STUN/TURNサーバー (iceServers)の情報を取得 • KVSWebRTC.SignalingClie nt インスタンスを生成 • イベントハンドラを指定 const kinesisVideoSignalingChannelsClient = new AWS.KinesisVideoSignalingChannels({ region, accessKeyId, secretAccessKey, endpoint: endpointsByProtocol.HTTPS, }); const getIceServerConfigResponse = await kinesisVideoSignalingChannelsClient .getIceServerConfig({ ChannelARN: channelARN, }).promise(); const iceServers = [ {urls: `stun:stun.kinesisvideo.${region} .amazonaws.com:443`} ]; getIceServerConfigResponse.IceServerList .forEach( iceServer => iceServers.push({ urls: iceServer.Uris, username: iceServer.Username, credential: iceServer.Password, }) );
  • 15. コード例:シグナリングチャネルを準備 • AWS.KinesisVideoインスタン スを生成 • シグナリングチャネル用のエン ドポイントを取得 • STUN/TURNサーバー (iceServers)の情報を取得 • KVSWebRTC.SignalingClient インスタンスを生成 • イベントハンドラを指定 const signalingClient = new KVSWebRTC.SignalingClient({ channelARN, channelEndpoint: endpointsByProtocol.WSS, clientId, role: KVSWebRTC.Role.MASTER, // or VIEWER region, credentials: { accessKeyId, secretAccessKey, }, });
  • 16. コード例:シグナリングチャネルを準備 • AWS.KinesisVideoインスタ ンスを生成 • シグナリングチャネル用の エンドポイントを取得 • STUN/TURNサーバー (iceServers)の情報を取得 • KVSWebRTC.SignalingClie nt インスタンスを生成 • イベントハンドラを指定 signalingClient.on('open', async () => { }); signalingClient.on('sdpAnswer', async answer => { }); // VIEWER用 signalingClient.on('sdpOffer’, async (offer, remoteClientId) => { } ); // MASTER用 signalingClient.on('iceCandidate’, (candidate, remoteClientId) => { peerConnection.addIceCandidate(candidate); } ); signalingClient.on('close', () => { });
  • 17. コード例:Viewer側 • Offerを送り、Answerを受け取る const offer = await peerConnection.createOffer({ offerToReceiveAudio: true, offerToReceiveVideo: true, }); await peerConnection.setLocalDescription(offer); signalingClient.sendSdpOffer( peerConnection.localDescription ); // イベントハンドラ signalingClient.on('sdpAnswer’, async answer => { await peerConnection.setRemoteDescription(answer); } );
  • 18. コード例: Master側 • Offerを受け取り、Answerを返す // イベントハンドラ signalingClient.on('sdpOffer', async (offer, remoteClientId) => { // … remoteClientId に対応する peerConnectionを準備する … await peerConnection.setRemoteDescription(offer); await peerConnection.setLocalDescription( await peerConnection.createAnswer({ offerToReceiveAudio: true, offerToReceiveVideo: true, }), ); signalingClient.sendSdpAnswer(peerConnection.localDescription, remoteClientId ); });
  • 19. コード例: ICE Candidate(共通) • PeerConnectionがICE Candidateを生成したとき • ICE Candidateをシグナリングチャネルで受け取った時 // PeerConnectionがICE Candidateを生成したとき peer.addEventListener('icecandidate', ({ candidate }) => { if (candidate) { signalingClient.sendIceCandidate(candidate, remoteClientId); } else { // No more ICE candidates will be generated } }); // 相手からICE Candidateを受け取った時 signalingClient.on('iceCandidate', (candidate, remoteClientId) => { peer.addIceCandidate(candidate); });
  • 20. シグナリングの注意点 • Offerは、必ずMasterに届く • ViewerからOfferに送る際に、相手を指定する必要はない • Answerは、相手(clientId)を指定してViewerに送る • Viewerは複数いる可能性があるので、clientIdで区別する • ICE candidateを送るとき • Viewer  Offer の場合は、相手を指定しなくて良い • Offer  Viewerの場合には、相手(clientId)を指定 • それ以外のアプリケーションメッセージは送れない • 切断通知には使えない
  • 21. シグナリングチャネルの作成 • WebRTCのアプリで良くある「ルーム」や「チャネル」に相当 • 同じ「シグナリングチャネル」に参加しているクライアント同士でシ グナリング→P2P通信が可能 • シグナリングチャネルを作成する4つの方法 • AWSコンソールから作成 • AWSのコマンドラインツール(CLI)から作成 • AWSのSDKからAPIを利用して作成 • REST APIを利用して作成
  • 22. その前に、IAMの準備 • IAM(Identity and Access Managemenent)でユーザを作成 • AmazonKinesisVideoStreamsFullAccess の権限を付与 • アクセスに必要な情報を記録しておく • アクセスキー • アクセスシークレットキー
  • 30. CLIツールでシグナリングチャネルの作成 • CLIツールをインストール • アクセスキー/アクセスシークレットーキーを指定 • 設定ファイル or 環境変数 • macOSで設定ファイルの場合 ~/.aws/credentials [default] aws_access_key_id=xxxxxx aws_secret_access_key=xxxxxxxxx/xxxxxxx • us-west-2リージョンに “channel02”を作る場合 $ aws2 --region us-west-2 kinesisvideo create-signaling-channel --channel-name channel02 --channel-type SINGLE_MASTER { "ChannelARN": "arn:aws:kinesisvideo:us-west-2:xxxxxxxxxx:channel/channel02/xxxxxxxxx” } • ※ARNを記録しておく
  • 31. SDKでシグナリングチャネルの作成(JS) const kinesisVideoClient = new AWS.KinesisVideo({ region, accessKeyId, secretAccessKey }); const kinesisvideo = new AWS.KinesisVideo(); const channel = 'channel03’; const params = { ChannelName: channel, ChannelType: 'SINGLE_MASTER’ }; kinesisvideo.createSignalingChannel(params, function (err, data) { if (err) console.log(err, err.stack); // エラー else console.log(data); // 成功、ARNがJSONで返ってくる }); DEMO
  • 32. REST API でシグナリングチャネルの作成 • リージョン:us-west-2, チャネル名:chanel04 の場合 $ curl -X POST https://kinesisvideo.us-west-2.amazonaws.com/createSignalingChannel -H "Content-Type: application/json" -d '{"ChannelName": "channel04", "ChannelType": "SINGLE_MASTER"} ' -H "Authorization: AWS AWSAccessKeyId:Signature" ※ここの文字列の生成方法が、 よくわかってません
  • 33. KVS WebRTCの価格 • こちらのユースケースから • https://aws.amazon.com/jp/kinesis/video-streams/pricing/ • 料金の例 2: WebRTC と KVSを使用するスマホ用ライブストリーミングア プリケーション • ライブメディアストリーミング用に KVS の WebRTC 機能を使用 • ユーザーが 100 人、それぞれ独自のシグナリングチャネル • 50 件のライブストリーミングセッションを経由 • 1 か月あたり合計 2,000 分間のライブストリーミング、TURN 20% (400分) • アクティブなシグナリングチャネル = 100 x (0.03 USD/月) = 3.0 USD • シグナリングメッセージ = 0.34 USD • TURN (分) = 100 ユーザー x 400 TURN ストリーミング時間 (分) • x (0.12 USD/1,000 TURN ストリーミング時間 (分)) = 4.8 USD • 合計 = 8.14 USD • 転送 1Mbps と仮定 • 40000 TURNストリーミング時間/月 → 300GB/月 • 転送料金 27 USD/月 (299GB分、us-west-2の場合)
  • 34. KVS WebRTCの価格 • 料金の例 3: ビデオストリームと WebRTC の両方を使用するスマートホームセ キュリティカメラ • ホームセキュリティシステムのプロバイダーには 1,000 人のユーザー • 各ユーザーの家には 1 台のカメラ、動きを検出するとストリーミング • ユーザーはコンパニオンアプリで 1 か月あたりに 100 回カメラに接続 • WebRTC によって、ライブビデオストリームの視聴や双方向のオーディオセッション • セッションの所要時間は 2 分間で、メディアストリームの 40% は TURN • WebRTC: 各カメラはそれぞれ独自のシグナリングチャネル • 合計で 1 か月あたり 1,000 件のアクティブなシグナリングチャネル • 各セッションが配信するシグナリングメッセージは 30 件で • 合計 3,000,000 件になります • カメラはそれぞれ TURN 経由の 80 分間のライブストリーミング、 • 1 か月に 80,000 TURN ストリーミング時間 (分) • 合計 = 46.35 USD • 転送 1Mbps と仮定 • 80000 TURNストリーミング時間/月 → 600GB/月 • 転送料金 54 USD/月 (599GB分、us-west-2の場合)
  • 35. KVS WebRTCの感想/まとめ • KVS WebRTCは、KVSの使い方を広げるもの • KVS WebRTC 単独では、魅力が少ないかも • マネージドSTUN/TURNは魅力 • TURNのセッションのパスワード発行もやってくれる • 通信料は安くはない … 300GB/月 → 27USD • Vultr.com のIaaS … 1TB/月→ 5USD • シグナリングの縛りは強い • シグナリングチャネルにつながるまでの時間も数秒かかる • 用途 • 今のところ、ビデオチャットのようなコミュニケーション向けではない印象 • 他のサービスの方が使い勝手が良さそう(個人の感想) • IoTデバイスを使った、動画の収集+リアルタイムモニターのケースがマッチ