1. 程式人生 > >WebRTC對Simulcast的支援

WebRTC對Simulcast的支援

最近在調研基於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