[React] WebRTC x React でP2Pビデオ電話アプリを作ってみる #4 ~データ交換編~
概要
WebRTC と React を使ってビデオ電話アプリを作成する第4回です。今回は前回取得したデータを交換します。 今回は割と重かったりします。
今回のコード
今回のコードは長くなってしまったのでここに載せてあります。
変更したのはsrc/VideoConnect.js
とsrc/Video.css
です。src/index.js
も変更しているのでここに載せておきます。
src/index.js
import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; import VideoConnect from './VideoConnect'; // 変更点 ReactDOM.render( <React.StrictMode> <VideoConnect /> // 変更点 </React.StrictMode>, document.getElementById('root') ); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals();
コードの説明
大体の流れ
今回のコードは次のような流れで動いています。
[ページを開いた瞬間]
- localVideoRef, localVideoStreamに映像がセットする。
[CALLボタン押下後]
localPeerConnectionおよびremotePeerConnectionを作成。
それぞれにicecandidate、iceconnectionstatechangeを追加する。(remotePeerConnectionにはaddstreamも)
localPeerConnectionにlocalVideoStreamを設定。
localPeerConnectionからOfferを作成する。
remotePeerConnectionからAnswerを作成する。
という感じです。
RTCIceCandidate
そもそもICEとはなんですか?という話です。
ICE (Interactive Connectivity Establishment) は、ネットワークトポロジー (通常は音声および/またはビデオのチャット) に関係なく、2 つのピアを互いに接続するための WebRTC に (他の技術があまたある中で) 使用されるフレームワークです。 このプロトコルを使用すると、ネットワークアドレストランスレーター (NAT) を使用してそれぞれのローカルネットワーク上の他のデバイスとグローバル IP アドレスを共有していても、2 つのピアが相互に接続を見つけて確立することができます。
ICE - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN
とのことです。NATを超えてピアを接続するためのフレームワークってことみたいです。
このICEですが、5つの段階に分かれていて
通信できそうな候補を集める
集めた候補を交換する
受け取った候補と自分の候補を合わせる
ペアを用いて接続試行
接続成功した候補ペアからいいものを決定
という手順を踏みます。
ここでの候補がRTCIceCandidateです。
RTCPeerConnection
RTCPeerConnectionはローカルコンピューターとリモートピアをWebRTCで繋ぐためのインターフェースです。
RTCPeerConnection.addIceCandidate
リモートピアをリモートピアのICECandidateを追加するメソッドです。
Peer.addIceCandidate(newIceCandidate) .then(() => { console.log("connection success"); // 成功時の処理 }) .catch(() => { console.log("connection failure"); // 失敗時の処理 });
今回のコードではこのように使っています。
RTCPeerConnection.setLocalDescription / setRemoteDescription
PeerConnectionにローカル/リモートの情報を紐づけるメソッドです。
RTCPeerConnection.createOffer / createAnswer
WebRTCでの接続をするためにSDP offer / answerするための関数です。SDP(Session Description Protocol)とは、接続に必要なパラメータを記述する形式の一つです。
localPeerConnection.createOffer(offerOptions) .then(createdOffer) // 成功時の処理 .catch((error) => { console.log('createOffer Error', error); // 失敗時の処理 })
今回はこのようなコードになっています。
成功時にcreatedOfferが実行されるようになってます。createdOfferの中身は
localPeerConnection.setLocalDescription(description) remotePeerConnection.setRemoteDescription(description) remotePeerConnection.createAnswer() .then(createdAnswer)
というような感じで、ローカルピアとリモートピアそれぞれに各々のDescriptionを設定し、リモートピアがAnswerを作成します。 Answer作成時にcreatedAnswerが実行されます。createdAnswerの中身は
remotePeerConnection.setLocalDescription(description) localPeerConnection.setRemoteDescription(description)
というような感じで、それぞれのピアにもう片方のピアのDescriptionを設定します。
まとめ
- 同じブラウザ内でのデータ交換をした
- ICEすごい
参考文献
www.slideshare.net
次のページ→ [React] WebRTC x React でP2Pビデオ電話アプリを作ってみる #5 ~データ通信・交換編~ - やってみたらなんとかなる