mediasoupでWebRTC SFUを実装する
mediasoupを使って、WebRTC SFUを実装する手順です。mediasoupのインストールについてはこちら。
mediasoup の機能
mediasoupの機能について簡単にまとめました。
mediasoupは次のような機能を持つNode.jsライブラリです。
- CPU(1コア)は1つのworkerを持つ
- workerは複数のrouterを持つことができる
- 同一routerに接続しているクライアント同士が双方向通信できる
このことから、router=部屋ともいえる - routerはクライアントごとに2つ(送信&受信)のtransportを持つ
- データの送信を"produce"といい、送信側のtransportをProducerTransportという
- データの受信を"consume"といい、受信側のtransportをConsumerTransportという
- 双方向通信する相手ごとにconsumerが必要
映像と音声なら、consumerは2つ必要
例えば、3人で映像・音声の双方向通信を行う場合、1人あたり 2x2 = 4consumer が必要となる(全体で 4x3 = 12consumer)- consumerはConsumerTransportに紐づく
- consumer生成時に受信したい相手のproducerを指定する
- 映像や音声を送信するためにproducerが必要
- 映像と音声ならproducerは2つ必要
- producerはProducerTransportに紐づく
- workerは最大で500以上のconsumerを持てる(CPUに依存)
- クライアントでもProducerTransport、ConsumerTransportを生成し、サーバ側と接続する
- クライアントでもproducer、consumerを生成し、サーバ側と接続する
参考
イメージ図
サーバ上の各機能の関係はこのようなイメージです。
送信元のproducerに他のクライアントのcomsumerを接続します。
サーバとクライアントのtransport、producer、consumerはこのようなイメージで接続します。
接続はSocketなどを使って、オプションやパラメータを受け渡す処理を自前で用意する必要があります。
各機能の生成API
サーバ
Type | API | パラメータ |
---|---|---|
Worker | mediasoup.createWorker() |
|
Router | worker.createRouter() |
mediaCodecs |
WebRtcTransport | router.createWebRtcTransport() |
WebRtcTransportOptions |
Producer | transport.produce() |
種別 クライアントから取得した rtpParameters |
Consumer | transport.consume() |
producerId クライアントの MediasoupClient.Device.rtpCapabilities |
クライアント
Type | API | パラメータ |
---|---|---|
(Producer)Transport | MediasoupClient.Device.createSendTransport() |
サーバから取得したTransportOptions |
(Consumer)Transport | MediasoupClient.Device.createRecvTransport() |
サーバから取得したTransportOptions |
Producer | transport.produce() |
クライアントのvideoやaudioトラック |
Consumer | (Consumer)Transport.consume() |
サーバから取得したrtpParameters |
利用の流れ
以下に、端末間で通信を行うための流れを記載します。ここではサーバとのやり取りにSocket.ioを利用しています。
青字は任意の送信メッセージです。
1. 接続~(Producer)Transport、Producer生成
メッセージ | 内容 |
---|---|
getRouterRtpCapabilities |
サーバから、MediasoupClient.Device.load() のパラメータを取得 |
createProducerTransport |
サーバ側のProducerTransport を生成し、非同期の戻り値としてサーバからTransportOptions を取得 |
2. (Producer)Transport・Producerの接続、Consumer登録
ProducerTransport.produce()
を実行後のイベント通知と処理の流れです。
メッセージ | 内容 |
---|---|
connectProducerTransport |
クライアントとサーバのProducerTransport を接続 |
produce |
オーディオまたはビデオを受信するようにProducerTransport に設定し、Producer を生成 |
createConsumerTransport |
サーバ側のConsumerTransport を生成し、非同期の戻り値としてサーバからTransportOptions を取得 |
getCurrentProducers |
現在接続中のProducer(クライアント)一覧を取得 |
newProducer |
新しくProducerが追加されたことを他のクライアントに通知 |
3. (Consumer)Transportの接続
メッセージ | 内容 |
---|---|
connectConsumerTransport |
クライアントとサーバのConsumerTransport を接続 |
4. Consume(受信)処理
メッセージ | 内容 |
---|---|
newConsumer |
任意のProducerから受信するConsumerを生成 |
resumeConsumer |
Consume(受信)処理を開始 |
remoteAdd Video
remoteAdd Audio
新規Producer追加時
新しくProducerが追加されたことを受け、受信処理を行います。
メッセージ | 内容 |
---|---|
newProducer |
新しく追加されたProducer(クライアント)を通知 |
終了処理
メッセージ | 内容 |
---|---|
producerClosed |
関連するProducerがなんらかの理由で閉じられたことを通知 |
Producerがなんらかの理由で閉じられた
Producerがなんらかの理由で閉じられた(クライアント)
ConsumerTransportがなんらかの理由で閉じられた
ProducerTransportがなんらかの理由で閉じられた
クライアントの切断
サンプル
紹介したシーケンスに沿ったサンプルソースをGitHubに公開しています。
mediasoup-simple