漫谈 WebRTC 一: 何谓Simulcast, WebRTC中的Simulcast

写作本文的初衷是: 前些日子为WebRTC设计Simulcast, 把所有相关的代码又重新阅读了一遍, 想着WebRTC代码结构复杂, 代码量巨大, Google的release迭代改动快, 改动量大, 代码常读常忘, 忘了再读, 也许应该写点啥东西保存起来。 适之先生说, 要使你所得印象变成你自己的, 最有效的方式是记录或者表现成文章。 故此不揣浅薄, 记录一些东西, 以为未来参考, 也算是响应胡先生之格言。 因为担心老板看到要砍我��, 此文不打算写一些具体的设计方法。 所以题目叫漫谈,随意而写, 兴尽即止, 以追古人遗风.
那么什么叫Simulcast呢? 我以为 B. Burman等人的IETF draft: Using Simulcast in SDP and RTP Sessions 写的很精辟, 引用如下:
Most of today's multiparty video conference solutions make use of
centralized servers to reduce the bandwidth and CPU consumption in
the endpoints. Those servers receive RTP streams from each
participant and send some suitable set of possibly modified RTP
streams to the rest of the participants, which usually have
heterogeneous capabilities (screen size, CPU, bandwidth, codec, etc).
One of the biggest issues is how to perform RTP stream adaptation to
different participants' constraints with the minimum possible impact
on both video quality and server performance.
Simulcast is defined in this memo as the act of simultaneously
sending multiple different encoded streams of the same media source,
e.g. the same video source encoded with different video encoder types
or image resolutions.

WebRTC的设计者们,当然也在考虑Simulcast的设计, WebRTC 1.0: Realtime Communication Between Browser 一文中就提到了Simulcast的示例:

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",
                      scaleResolutionDownBy: 2.0
                    },
                    {
                      rid: "q",
                      scaleResolutionDownBy: 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);
}

可是, 虽然有这个示例了, 但是实际上WebRTC自己对Simulcast的支持却是极糟糕, 此接口在Native层根本未曾实现, WebRTC内部有一个为VP8设计的Simulcast对象, 不过从其设计实现来看, 根本是一个demo, 完全不是产品级的。

未完待续.

Reference

  • http://blog.csdn.net/sandfox/article/details/77130912
  • https://datatracker.ietf.org/doc/html/draft-ietf-mmusic-sdp-simulcast-10
  • https://www.w3.org/TR/webrtc/

你可能感兴趣的:(多媒体)