mediasoupのインストールと基本的な実装

mediasoupとは

  • nodejsのSFUサーバのライブラリ。ライブラリなので基本的にメディア(映像、音声)の受信、配信のみを行います。
  • クライアントはwebRTCを想定しています。

SFUとは

SFU(Selective Forwarding Unit)とは配信者に代わり映像、音声を視聴者に配信する仕組み。配信の代行的なことを行うサーバですかね。

とりあえず環境情報ともろもろ

  • OS
    debian 8.8

  • node
    version 6.10

  • npm
    3.10.0



調査期間 : 2017/5/20 〜 2017/6/2 調査期間中にいろいろ仕様とか変わっているかもしれませんので、、ご了承下さい。

mediasoupのインストー

npmにてインストールすることができるが、mediasoupの実装がC++なのでコンパイルできる環境を用意

apt-get install gcc g++ make build-essential

pythonも必要だか、バージョンが2.x系じゃないといけないみたいです。なので2.x系のやつが使える環境にしておきます。

package.json

...
"dependencies": {
    ....
    "mediasoup": "1.2.0"
}
....

npm でインストー

npm install

mediasoupの実装

大体の流れとして下記のリスト。

  1. roomの作成
  2. roomからPeerの取得
  3. PeerからPeerConnectionの作成

—- シグナリング処理 —-
4. SDPのOfferを作成し、localDescriptionにセット、クライアントにSDPを送信
5. クライアントからAnswerが返ってきてremoteDescriptionにセット

0. mediasoupの準備

const mediasoup = require("mediasoup");

クライアントと接続するときに使用するクラスの読み込み

const RTCPeerConnection = mediasoup.webrtc.RTCPeerConnection;
const RTCSessionDescription = mediasoup.webrtc.RTCSessionDescription;

mediasoupのサーバ設定

const mediaServer = mediasoup.Server({
    ...
});

※ 設定内容参照 : https://mediasoup.org/api/#Server-dictionaries

1. roomの作成

クライアントが接続するroomを作成。そのroomにいるユーザが配信した場合は同一のroomに接続している全ユーザに配信されます。 room作成

const roomOptions = {
    mediaCodecs: [
        {
            kind: 'audio',
            name: 'audio/opus',
            clockRate: 48000,
            payloadType: 111
        },
        {
            kind: 'video',
            name: 'video/vp8',
            clockRate: 90000,
            payloadType: 100
        }
    ]
};
mediaServer.createRoom(roomOptions)
.then(function(room) {
    // 引数のroomが作成したroomになる
});

※ roomOptionsは作成するroomのオプション、コーデックとかを設定
参照:
https://mediasoup.org/api/#RtpDictionaries-RtpCodecParameters https://mediasoup.org/api/#server-createRoom

2. roomからPeerの作成

クライアントとメディアストリームの配信、受信を行います。
Peerの作成

peer = room.Peer("peerName");

peerName: room内のPeerの名前になります。ひとつのroom内に同じ名前のPeerを作成することはできないため、注意が必要(別のroomならOK)。

3. PeerからPeerConnectionの作成

Peerからコネクションを作成します。webRTCのPeerConnectionみたいな感じです。
だけどちょっと違うようです。
コネクションの作成

peerConnection = new RTCPeerConnection({
  peer: peer
});

引数の設定はここを参照: https://mediasoup.org/api/#webrtc-RTCPeerConnection-dictionaries
usePlanBはSDPの規格になるため、これでシグナリングが成功しないときもあるかも、
chromefirefoxで違いがあるため要注意(2017/5/30 現在)


—- シグナリング処理 —-

シグナリングの方法はwebRTCでは決まっていない。そのため、どんな実装でもいいのだが、今回はwebSocketにて行います。
実装も簡単、一番楽ですし、情報も多い。

4. SDPのOfferを作成し、localDescriptionにセット、クライアントにSDPを送信

webRTCのシグナリングで使用するSDPの作成を行う。mediasoupからofferを送らないとシグナリングができないようです。
なので、クライアントがofferを送ってきて、setRemoteDescriptionでセットするとエラーになってしまいました…

offerの作成

peerConnection.createOffer({
        offerToReceiveAudio: 1,
        offerToReceiveVideo: 1
})
.then(function(desc) {
    // 作成したSDPをローカルの情報として保存
    peerConnection.setCapabilities(desc);
    return peerConnection.setLocalDescription(desc);
})
.then(function() {
    // webSocket経由でクライアントにSDPの情報を送信
    const message = JSON.stringify(peerConnection.localDescription.serialize());
    return ws.send(message);
})

5. クライアントからAnswerが返ってきてremoteDescriptionにセット

offerをクライアントに送信し、無事にanswerが返ってきたらその情報をリモートの情報としてConnectionにセットする

remote = new RTCSessionDescription(description);
peerConnection.setRemoteDescription(remote);

これで無事にmediasoupとクライアントでコネクションが確立できて、通信ができるようになります(なるはず)。