最近在调研基于WebRTC的Simulcast的方案,发现WebRTC 1.0的草案里面已经有了Simulcast的相关定义,并且举出了相关的例子。
EXAMPLE 15
var signalingChannel = new SignalingChannel();
var configuration = { "iceServers": [{ "urls": "stuns:stun.example.org" }] };
var pc;
// call start() to initiate
function start() {
pc = new RTCPeerConnection(configuration);
// let the "negotiationneeded" event trigger offer generation
pc.onnegotiationneeded = function () {
pc.createOffer().then(function (offer) {
return pc.setLocalDescription(offer);
})
.then(function () {
// send the offer to the other peer
signalingChannel.send(JSON.stringify({ "desc": pc.localDescription }));
})
.catch(logError);
};
// get a local stream, show it in a self-view and add it to be sent
navigator.mediaDevices.getUserMedia({ "audio": true, "video": true })
.then(function (stream) {
selfView.srcObject = stream;
pc.addTransceiver(stream.getAudioTracks()[0], {direction: "sendonly"});
pc.addTransceiver(stream.getVideoTracks()[0], {
direction: "sendonly",
sendEncodings: [
{
rid: "f",
},
{
rid: "h",
scaleDownResolutionBy: 2.0
},
{
rid: "q",
scaleDownResolutionBy: 4.0
}
]
});
})
.catch(logError);
}
signalingChannel.onmessage = function (evt) {
var message = JSON.parse(evt.data);
if (message.desc)
pc.setRemoteDescription(message.desc).catch(logError);
else
pc.addIceCandidate(message.candidate).catch(logError);
};
function logError(error) {
log(error.name + ": " + error.message);
}
既然标准里面已经有了Simulcast的相关定义,那么各个浏览器里面的WebRTC实现情况如何呢?通过一番搜索之后,发现目前能支持Simulcast的浏览器貌似只有Chrome和Firefox两款,而且只能使用VP8。
Chrome里面其实早就已经支持Simulcast,Google Hangouts里面就已经在使用。不过目前Chrome还不能使用WebRTC 1.0里面方法来启用,只能通过修改Local SDP的方式来开启,实现一个“SIM”的 ssrc group。SDP样式如下:
a=ssrc-group:SIM 2178216979 2295769805 636898760
a=ssrc-group:FID 2178216979 2643517961
a=ssrc-group:FID 2295769805 1534787773
a=ssrc-group:FID 636898760 1305495962
a=ssrc:2178216979 cname:localCname
a=ssrc:2178216979 msid:R6WoG3JzZEw8BVEBuy1XpTuUzzfSGIlr08Ro 541b12bc-754c-4c06-8367-481ec12e3192
a=ssrc:2295769805 cname:localCname
a=ssrc:2295769805 msid:R6WoG3JzZEw8BVEBuy1XpTuUzzfSGIlr08Ro 541b12bc-754c-4c06-8367-481ec12e3192
a=ssrc:636898760 cname:localCname
a=ssrc:636898760 msid:R6WoG3JzZEw8BVEBuy1XpTuUzzfSGIlr08Ro 541b12bc-754c-4c06-8367-481ec12e3192
a=ssrc:2643517961 cname:localCname
a=ssrc:2643517961 msid:R6WoG3JzZEw8BVEBuy1XpTuUzzfSGIlr08Ro 541b12bc-754c-4c06-8367-481ec12e3192
a=ssrc:1534787773 cname:localCname
a=ssrc:1534787773 msid:R6WoG3JzZEw8BVEBuy1XpTuUzzfSGIlr08Ro 541b12bc-754c-4c06-8367-481ec12e3192
a=ssrc:1305495962 cname:localCname
a=ssrc:1305495962 msid:R6WoG3JzZEw8BVEBuy1XpTuUzzfSGIlr08Ro 541b12bc-754c-4c06-8367-481ec12e3192
Firefox里面的实现看上去就是按照WebRTC 1.0定义的接口来实现的,启用方式与举例Example 15中类似,通过设置encodings参数。
if(sendVideo && simulcast && adapter.browserDetails.browser === "firefox") {
var sender = config.pc.getSenders()[0];
var parameters = sender.getParameters();
sender.setParameters({encodings: [
{ rid: "high", active: true, priority: "high", maxBitrate: 1000000 },
{ rid: "medium", active: true, priority: "medium", maxBitrate: 300000 },
{ rid: "low", active: true, priority: "low", maxBitrate: 100000 }
]});
}
SDP样式如下:
a=simulcast: send rid=high;medium;low
a=ssrc:4279128183 cname:{7cc599d1-10d9-4d41-9e53-eb3e74ad54fa}
a=ssrc:1635836235 cname:{7cc599d1-10d9-4d41-9e53-eb3e74ad54fa}
a=ssrc:921425862 cname:{7cc599d1-10d9-4d41-9e53-eb3e74ad54fa}
目前要支持多浏览器的Simulcast的互通,WebRTC的服务器必须能实现两种SDP的格式转换。Janus的Video Call Demo里面已经有了实现,可以参考:
https://janus.conf.meetecho.com/videocalltest.html?simulcast=true