こちらの資料は古いので WebRTC Simulcast コトハジメ をどうぞ。
WebRTC の Simulcast という仕組みは、複数の品質で映像を配信する仕組みのことです。
P2P で必要かどうかというと、必要ではありません。Simulcast はクライアント・サーバモデル、さらに SFU モデルでの利用を前提としています。
配信者は複数の品質でサーバに配信します。例えば 300kbps と 500kbps と 800kbps という感じです。3 種類の画質で変換するので、もちろんその分配信側には負担がかかります。
では、この Simulcast のメリットですが、視聴側にあります。視聴側の回線が細かったりする場合サーバは品質の低い 300kbps の配信します。 それとは別に安定して視聴できている人には 800kbps で配信します。
WebRTC SFU は映像を転送するだけしかできないため、このような「配信側への負担」を強いる仕組み採用するしかありません。
Simulcast の図が付いた説明を書いた記事があるので、こちらを御覧ください。
WebRTC を利用した配信の現実 – V – Medium
Simulcast ですが、Chrome と Firefox では取っているアプローチが異なります。
- Chrome は Google 独自の仕様
- Firefox は IETF や W3C 沿った仕様
そのため、もし Simulcast に対応する場合はブラウザ間の差異を吸収する必要があります。
ただ、Firefox は正しい方向に進んでいます。これは忘れないでください。
ここはうろ覚えを文章にしているため、信頼性はありません
Chrome は Firefox 、つまり正式な Simulcast の実装からははみ出ています。
SDP に独自の拡張を入れることで動作するようになります。これはクライアント側で SDP の書き換えをする必要があります。
a=x-google-flag:conference
a=ssrc-group:SIM 1 2 3
a=ssrc:1
a=ssrc:2
a=ssrc:3
a=ssrc-group:FID 1 4
a=ssrc:1
a=ssrc:4
a=ssrc-group:FID 2 5
a=ssrc:2
a=ssrc:5
a=ssrc-group:FID 3 6
a=ssrc:3
a=ssrc:6
さらに、Chrome 側は正式実装には興味はほとんどないようです。実装自体も対応する雰囲気も見せていません。 理由として、彼らは VP9/SVC に力を入れていることが上げられます。これについては、ぐぐってください。
a=rid と a=simulcast を利用します。
a=rid はエンコードの仕様を指定できます。つまり品質を指定する仕組みです。
a=simulcast はそれらの rid をまとめる仕組みです。
a=rid:0 send max-width=1280;max-height=720;max-fps=15
a=rid:1 send max-width=1280;max-height=720;max-fps=30
a=rid:2 recv max-width=1280;max-height=720;max-fps=30
a=rid:5 send max-width=640;max-height=360;max-fps=15
a=rid:6 send max-width=320;max-height=180;max-fps=15
a=simulcast: send rid=0;1;5;6 recv rid=2
自分はこの種類を配信する、受信はこれをくれという感じですね。これは全員が Simulcast で配信している前提の例です。
Simulcast はクライアント・サーバモデルでさらに SFU を利用した場合で、さらにサーバ側が視聴側の帯域推定を行える場合のみ有効なモデルです。
かなり限定的なモデルのため、各ブラウザはあまり積極的ではなかったのですが、ここにきて Firefox が頑張っています。
少し気にしておいてもいいかもしれません。
Simulcast な SDP を生成するためのサンプルです。コードが汚いのは気にしないでください。
var pc = new RTCPeerConnection({});
var sender;
var parameters;
navigator.mediaDevices.enumerateDevices()
.then(function (devices) {
return navigator.mediaDevices.getUserMedia({audio: false, video: true})
})
.then(function (stream) {
console.log(stream);
pc.addTrack(stream.getVideoTracks()[0], stream);
sender = pc.getSenders()[0];
console.log(sender);
parameters = sender.getParameters();
console.log(parameters);
sender.setParameters({encodings: [{ rid: "spam", active: true, priority: "high", maxBitrate: 40000 },
{ rid: "egg", active: true, priority: "medium", maxBitrate: 10000 }]})
pc.createOffer()
.then(function (offer) {
console.log(offer.sdp);
})
})
.catch(function (error) {
});
v=0
o=mozilla...THIS_IS_SDPARTA-57.0.1 4439473149147144035 0 IN IP4 0.0.0.0
s=-
t=0 0
a=fingerprint:sha-256 2C:74:50:1B:47:76:57:E0:C1:D8:D3:F1:76:52:1E:E8:C9:24:37:22:96:34:7A:07:03:9F:36:29:7F:A2:B4:AF
a=group:BUNDLE sdparta_0
a=ice-options:trickle
a=msid-semantic:WMS *
m=video 9 UDP/TLS/RTP/SAVPF 120 121 126 97
c=IN IP4 0.0.0.0
a=sendrecv
a=extmap:1 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
a=extmap:3/sendonly urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=fmtp:126 profile-level-id=42e01f;level-asymmetry-allowed=1;packetization-mode=1
a=fmtp:97 profile-level-id=42e01f;level-asymmetry-allowed=1
a=fmtp:120 max-fs=12288;max-fr=60
a=fmtp:121 max-fs=12288;max-fr=60
a=ice-pwd:53e694529986500711443aa9fac84011
a=ice-ufrag:7939d9ba
a=mid:sdparta_0
a=msid:{5ba51dcf-0879-cc4d-8ca5-dc64e611bf2a} {1b1f5d70-ede8-9f4a-8e1c-81036454189e}
a=rid:spam send
a=rid:egg send
a=rtcp-fb:120 nack
a=rtcp-fb:120 nack pli
a=rtcp-fb:120 ccm fir
a=rtcp-fb:120 goog-remb
a=rtcp-fb:121 nack
a=rtcp-fb:121 nack pli
a=rtcp-fb:121 ccm fir
a=rtcp-fb:121 goog-remb
a=rtcp-fb:126 nack
a=rtcp-fb:126 nack pli
a=rtcp-fb:126 ccm fir
a=rtcp-fb:126 goog-remb
a=rtcp-fb:97 nack
a=rtcp-fb:97 nack pli
a=rtcp-fb:97 ccm fir
a=rtcp-fb:97 goog-remb
a=rtcp-mux
a=rtpmap:120 VP8/90000
a=rtpmap:121 VP9/90000
a=rtpmap:126 H264/90000
a=rtpmap:97 H264/90000
a=setup:actpass
a=simulcast: send rid=spam;egg
a=ssrc:4039161908 cname:{6098ff0c-bca1-e740-a72a-e3db492212ec}
a=ssrc:4029456389 cname:{6098ff0c-bca1-e740-a72a-e3db492212ec}
- https://www.w3.org/2011/04/webrtc/wiki/images/6/6c/WebRTC_RTCSender-Receiver,_TPAC_2014.pdf https://datatracker.ietf.org/meeting/100/materials/slides-100-mmusic-simulcast-and-rid/
- https://bugzilla.mozilla.org/show_bug.cgi?id=1230184
- https://bugzilla.mozilla.org/show_bug.cgi?id=1398820
- https://hg.mozilla.org/mozilla-central/rev/59cefb0904c4
- https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-10
- https://tools.ietf.org/html/draft-ietf-mmusic-rid-12