はじめに
- この資料は、WebRTC入門者の会(2016.11.01)用の資料です。
- 資料の全体はこちらのINDEXを参照してください。
自己紹介
- 名前: なかゆうすけ(@Tukimikage)
- 仕事:
- SkyWayのDevrel
- HTML5 Experts.jpの運営
- コミュニティ:
今日のスライドの目的
- WebRTCサービスを開発する際に必要となる、各種デバッグ技術をお伝えします
前提条件
- Webブラウザでの利用を前提とします
- WebRTCハンズオン の知識が最低限必要となりますので、まだ読んでいない方は先にご一読ください。
- MediaChannelのみしか扱いません
- デバッグ方法やそのためのノウハウをご紹介するだけなので、事象解決には別の努力がきっと必要です
目次
- よくあるトラブルユースケース
- その他知っておくと便利なトピックする
よくあるトラブルユースケース
- うまくつながらない時がある
「つながらない」場合の切り分け王道パターン
- 切り分け1:ネットワーク的に接続されているか
- 切り分け2:音声、映像ストリームが流れているか
切り分け1
- ネットワーク的に接続されているかどうかを確認する
- Chromeの場合
- アドレスバーで
chrome://webrtc-internals
- 一つだけ 太字 の Conn-xxxx-x-x という項目がある(有効なTransport/輸送路)
- 存在しなければネットワーク的に接続されているか
- ある場合でもタイムスタンプが更新されていない場合はその時点で利用されていない
- アドレスバーで
- Chromeの場合
- サンプル
- 表示されている項目と意味(重要なものだけ抜粋)
項目 | 意味 |
---|---|
timestamp | タイムスタンプ 現在利用しているTransportかどうかはこのタイムスタンプが更新されているかどうかで判断 |
googxxxxAddress | ローカル・リモートそれぞれのIPアドレスとポート番号 |
xxxxCandidateId | ローカル・リモートそれぞれで採択されたCandidate情報のID※1(通信するためのIPアドレス、ポート番号等の候補情報) このIDでサイト内を検索すると詳細が確認できる |
googxxxxCandidateType | ローカル・リモートそれぞれのCandidateタイプrelay : TURN経由の接続それ以外 : TURNを使用せずにダイレクト接続 |
- ※1 採択されたCandidate情報
- これはFirefoxの方が見やすい
- アドレスバーで
about:webrtc
- アドレスバーで
- これはFirefoxの方が見やすい
切り分け2
- 音声、映像ストリームが流れているかを確認する
- Chromeの場合
- アドレスバーで
chrome://webrtc-internals
- AudioTrackとVideoTrack情報を確認する
-
ssrc_xxxxxxx_send
: 送信側でAudioとVideoで2つ(Track単位) -
ssrc_xxxxxxx_recv
: 受信側で同じく2つ
-
- 送受信バイト数がカウントアップしていればストリームは流れている
- AudioTrackとVideoTrack情報を確認する
- アドレスバーで
- Chromeの場合
- サンプル
- 表示されている項目と意味(重要なものだけ抜粋)
項目 | 意味 |
---|---|
msid | MediaStreamIDでAudioTrackとVideoTrackを束ねた1つのStreamを指す JavaScriptから識別することができる |
timestamp | タイムスタンプ 有効なTrackかどうかはこのタイムスタンプが更新されているかどうかで判断 |
bytesSent | 送受信バイト数 |
mediaType | audio/video |
packetsLost | パケットがロストした場合に表示される |
ssrc | Synchronisation Sourceという。ここではRTP(リアルタイムプロトコル)で利用する識別子 |
transportId | 先程見た Conn-xxxx-x-x に該当このTrackがどのTransport(輸送路)を利用しているかわかる |
googCodecName | 仕様しているコーデック Audioであれば、 Opus が主流Videoであれば、 VP8 やH264 が主流 |
googTrackId | TrackIDでJavaScriptから識別することもができる |
- 参考:Transport、MediaStream、Trackの関係
よくあるトラブルユースケース
- カメラの映像やマイクの音声が取得できない
ブラウザのデバイス認識状態を確認
-
プルダウンで選択しブラウザをリロードすることで有効になる
-
PCに利用できるマイク、カメラが接続されていない場合、
navigator.mediaDevices.getUserMedia
のAPIでエラーが返ってくるので注意 -
Chromeは一度デバイス選択するとその状態が記録されるので、うっかりアクセスをブロックすると、以後ブロックを明示的に解除するまで利用できないので注意
- ブラウザで認識しているのに映像が出ない、音が聞こえない場合に考えられること
- Video
-
navigator.mediaDevices.getUserMedia
で指定するキャプチャサイズ(width
とheight
)の映像をWebカメラから取得できない
-
- Audio
- PC側のマスターボリュームが
0
になっているなど
- PC側のマスターボリュームが
- Video
よくあるトラブルユースケース
- PCやブラウザの動作が重い、途中で映像が止まる、音が途切れる
P2P接続によるマシン負荷が高い
- P2Pによるビデオチャットを複数本同時に行こない(フルメッシュ接続)多人数ビデオチャットを実現する場合、マシンへの負荷が増大する
P2P接続によるマシン負荷が高い
- 対策1
-
navigator.mediaDevices.getUserMedia
で指定するキャプチャサイズを小さくする - 画面共有等はフレームレートを下げる(Firefoxでは効かない)
-
function startVideo() {
navigator.mediaDevices.getUserMedia({
video: {
width: {
min: 320,
max: 1280
},height: {
min: 240,
max: 720
},frameRate: {
min: 1,
max: 10
}
},
audio: true})
.then(function (stream) { // success
playVideo(localVideo,stream);
localStream = stream;
}).catch(function (error) { // error
console.error('mediaDevice.getUserMedia() error:', error);
return;
});
}
ネットワークの品質(速度等)が良くない
- WebRTCにはネットワーク帯域を推定し動的に転送レートを変動させるが、限度がある
- 【注意】プロバイダが提供する速度測定サイトの結果はWebRTCではあまりあてにならない
- 速度測定サイトはプロバイダが提供するサーバとの転送速度を測るものだから
- WebRTCではEnd-to-Endでの速度を測定する必要がある
参考:WebRTCはどのくらいの通信帯域を利用するのか
-
送信する映像のサイズ、フレームレート数によってい左右される
-
測定条件
- カメラ前の画面の動きはほぼ無い
- ローカルで計測(ネットワーク遅延は無視)
- ブラウザは Chrome M54
- コーデック:VP8
-
測定結果
設定 | ビットレート |
---|---|
640x480/30fps |
1.5Mbps前後 |
320x240/30fps |
600kbps前後 |
320x240/10fps |
400kbps前後 |
1920x1080/30fps |
2Mbps前後 |
- WebRTCによるアプリケーションを実業務で開発導入する場合は、ネットワーク設計まで含めて考慮憂する必要がある
P2P接続によるマシン負荷が高い
- 対策2
- WebRTCプラットフォームサービスが提供するMCUやSFUを利用する
- MCUやSFUを自分で建てて運用する(上級)
MCU(Multipoint Control Unit)
- メディアサーバを用意して映像音声をミキシングすることで、人数が増えた場合でも、送受信するメディアの数が変わらない
- トランスコード、オーバーレイ、録画、録音、何でもできるが、サーバ側の処理で画面レイアウトが決まってしまう等、クライアント側での自由度がない
- 代表例:Skype
SFU(Selective Forwarding Unit)
-
送信側のMediaをサーバで受信者数分スプリットして配信することで、送信側の負荷(エンコード負荷)を押さえることができる
-
受信者の処理能力にバラツキがある場合には、RTCPを利用し品質をコントロールする機能が、SFU側に必要となる
- Simulcast+SVCという技術を組み合わせて解決する方法もある(この場合は、受信側の対応が必須)
-
代表例:Google Hangout
その他知っておくと便利なトピックする
- ICEによる自動再接続
ICEとは?
- ICE(Interactive Connectivity Establishment)はNAT超えするためのユーティリティ
- WebRTCではICEを利用してP2P通信を確立する
- ICEの手順
- 1.通信候補の収集
- IceCandaidateという情報をブラウザが収集する
- 2.通信候補の交換
- シグナリングサーバを介して相手と交換
- 3.通信候補の整理
- P2PなのかRelayなのか(つまりTURN経由)等を考慮して優先度が高い順に候補を並べる
- TrickleICEという手法の場合は省略される
- 4.通信の試行
- 一般的にUDPホールパンチングと呼ばれる手法を利用して通信を試みる
- 新しく候補が見つかることもある
- 5.通信手段を確定
- 通信に成功した候補の中からどのルートを使うかを確定する(制御権を持つPeerが決める)
- 1.通信候補の収集
- ICEの手順
実は繋がったら終わりではない
- ICEは通信状態をモニタリングしており、一時的な通信断については自動で復旧する
- 例:前回ハンズオンで開発したアプリの場合
// ICEのステータスが変更になったときの処理
peer.oniceconnectionstatechange = function() {
console.log('ICE connection Status has changed to ' + peer.iceConnectionState);
switch (peer.iceConnectionState) {
case 'closed':
case 'failed':
// ICEのステートが切断状態または異常状態になったら切断処理を実行する
if (peerConnection) {
hangUp();
}
break;
case 'dissconnected':
break;
}
};
- ICEステータスの変化(コンソール抜粋)
- 数秒程度の通信断であれば復旧できる可能性あり
ICE connection Status has changed to connected ←接続候補をチェック中
ICE connection Status has changed to completed ←全ての候補のチェックが完了
ICE connection Status has changed to disconnected ←故意に通信を切断
ICE connection Status has changed to connected ←通信断を解除
ICE connection Status has changed to completed ←再び接続
ICE connection Status has changed to disconnected ←故意に通信を切断
ICE connection Status has changed to failed ←そのまま放置すると修復不可状態に
sending close message
ICE connection Status has changed to closed ←ICEのプロセスが全て終了
その他知っておくと便利なトピックする
- どのようなシーンでTURNサーバは有効なのか?
TURNサーバはどのように利用されるのか?
-
TURNサーバとは?
- P2Pによる通信ができない場合にリレーするためのサーバ
-
Q. こうやってプログラムすれば全ての通信がTURN経由になると思いますか?
let pc_config = {"iceServers":[
{"urls":"stun:stun.xxxx.xxx:3478"},
{"urls": "turn:turn.xxxx.xxx:3478?transport=tcp",
"username:": "username",
"credential": "password"
}]
};
let peer = new RTCPeerConnection(pc_config);
- A. NO
まとめ
- よくあるトラブルユースケース
- うまくつながらない時がある
- カメラの映像やマイクの音声が取得できない
- PCやブラウザの動作が重い、途中で映像が止まる、音が途切れる
- その他知っておくと便利なトピックする
- ICEによる自動再接続
- どんなシーンでTURNサーバは有効なのか?