webrtc底层一对一连接过程探索(三)


一、连接过程继续解读-----fun33-fun37解读

完整代码如下:

    //fun33-37
    console.error('fun35-37==>2332==>2332');
    var q = window.MediaStream;
    void 0 === q && 
    "undefined" != typeof webkitMediaStream && 
    (q = webkitMediaStream), 
    void 0 !== q &&
    (   "getVideoTracks" in q.prototype 
        || (q.prototype.getVideoTracks = function() {
                console.info('fun3537.03b==>2348==>2348');
                if (!this.getTracks) return [];
                var e = [];
                return this.getTracks.forEach(function(n) {
                    -1 !== ("" + n.kind).indexOf("video") && e.push(n)
                }), e
           }, 
        console.info('fun3537.04==>2357==>2357'),
        q.prototype.getAudioTracks = function() {
            console.info('fun3537.04==>2356==>2356');
            if (!this.getTracks) return [];
            var e = [];
            return this.getTracks.forEach(function(n) {
                -1 !== ("" + n.kind).indexOf("audio") && e.push(n)
            }), e
        }), 
    console.info('fun3537.05==>2367==>2367'),
    "stop" in q.prototype || (q.prototype.stop = function() {
        console.info('fun3537.05==>2367==>2367');
            this.getAudioTracks().forEach(function(e) {
                e.stop && e.stop()
            }), 
            this.getVideoTracks().forEach(function(e) {
                e.stop && e.stop()
            })
        })
),

1.1 代码段一

var q = window.MediaStream;

 q是个函数,用于获取媒体数据。

1.2 代码段二

void 0 === q &&

"undefined" != typeof webkitMediaStream &&

(q = webkitMediaStream),

注:经测试,void ===q为false,所以就没必要向后执行了,实际上,webkitMediaStream也是个函数,不是undefined.

1.3 代码段三

    void 0 !== q &&

    (   console.info('fun3537.03a==>2345==>2345')&&

        "getVideoTracks" in q.prototype

        || (q.prototype.getVideoTracks = function() {

                console.info('fun3537.03b==>2348==>2348');

                if (!this.getTracks) return [];

                var e = [];

                return this.getTracks.forEach(function(n) {

                    -1 !== ("" + n.kind).indexOf("video") && e.push(n)

                }), e

           },

注:q.prototype是向对象里面添加属性的方法,如下:

因为"getVideoTracks" in q.prototype是成立的,所以,后面的函数没有走。

1.4 代码段四      

console.info('fun3537.04==>2357==>2357'),

        q.prototype.getAudioTracks = function() {

            console.info('fun3537.04==>2356==>2356');

            if (!this.getTracks) return [];

            var e = [];

            return this.getTracks.forEach(function(n) {

                -1 !== ("" + n.kind).indexOf("audio") && e.push(n)

            }), e

        })

注:这个函数是紧接着上面那个函数,逗号表达式里面的。 因为"getVideoTracks" in q.prototype成立,就不走这个函数了。

1.5 代码段五

console.info('fun3537.05a==>2367==>2367'),

    "stop" in q.prototype || (q.prototype.stop = function() {

        console.info('fun3537.05b==>2367==>2367');

            this.getAudioTracks().forEach(function(e) {

                e.stop && e.stop()

            }),

            this.getVideoTracks().forEach(function(e) {

                e.stop && e.stop()

            })

        })

),

注:如果成立,就是说如果stop在q.prototype中,就不管了,如果不在就定义个函数过去。

二、连接过程继续解读-----fun38尝试理解

2.1 fun38代码整体

 整体代码太多,不再展示,只能分段展示。

2.2 fun38.01

            //fun38.01

            function e() {

                var e, n, t, o = (c.appVersion, c.userAgent),

                    i = c.appName,

                    r = "" + parseFloat(c.appVersion),

                    s = parseInt(c.appVersion, 10);

                if (f) {

                    i = "Opera";

                    try {

                        r = c.userAgent.split("OPR/")[1].split(" ")[0], s = r.split(".")[0]

                    } catch (a) {

                        r = "0.0.0.0", s = 0

                    }

                } else g ? (n = o.indexOf("MSIE"), i = "IE", r = o.substring(n + 5))

                : v ? (n = o.indexOf("Chrome"), i = "Chrome", r = o.substring(n + 7))

                : p ? (n = o.indexOf("Safari"), i = "Safari", r = o.substring(n + 7),

                -1 !== (n = o.indexOf("Version")) && (r = o.substring(n + 8))) : m

                ? (n = o.indexOf("Firefox"), i = "Firefox", r = o.substring(n + 8))

                : (e = o.lastIndexOf(" ") + 1) < (n = o.lastIndexOf("/"))

                && (i = o.substring(e, n),

                    r = o.substring(n + 1),

                    i.toLowerCase() === i.toUpperCase() && (i = c.appName));

                return l && (i = "Edge", r = "" +

                parseInt(c.userAgent.match(/Edge\/(\d+).(\d+)$/)[2], 10)),

                -1 !== (t = r.indexOf(";")) && (r = r.substring(0, t)),

                -1 !== (t = r.indexOf(" ")) && (r = r.substring(0, t)),

                s = parseInt("" + r, 10),

                isNaN(s) && (r = "" + parseFloat(c.appVersion),

                s = parseInt(c.appVersion, 10)),

                {

                    fullVersion: r,

                    version: s,

                    name: i,

                    isPrivateBrowsing: !1

                }

            }

分析如下:

1)定义几个变量如下:

 var e, n, t,

o = (c.appVersion, c.userAgent),

    i = c.appName,

    r = "" + parseFloat(c.appVersion),

s = parseInt(c.appVersion, 10);

a.) e,n,t定义的值是一样的,都是未定义。如下:

b.) o = (c.appVersion, c.userAgent),

对于o来说,c.userAgent是o的最终值,哪怕为空。

注:现在的关键问题是o = (c.appVersion, c.userAgent)中c从哪里来的。

c.) i,r,s

注:i,r,s的值上面截图中已给出,不再详述。

2)代码段二

  if (f) {

    i = "Opera";

    try {

       r = c.userAgent.split("OPR/")[1].split(" ")[0], s = r.split(".")[0]

    } catch (a) {

     r = "0.0.0.0", s = 0

    }

 }

注:经打日志,f为false,从代码可知,f用于判断是不是Opera浏览器,false表示不是,true表示是。不是的话,就不走下面里的代码,直接看else即可。

3)代码段三

else g ? (n = o.indexOf("MSIE"), i = "IE", r = o.substring(n + 5))

     : v ? (n = o.indexOf("Chrome"), i = "Chrome", r = o.substring(n + 7))

       : p ? (n = o.indexOf("Safari"), i = "Safari", r = o.substring(n + 7),

1g

  看g成立不成立,g为false,说明不是IE浏览器。

2g不成立

走如下:

v ? (n = o.indexOf("Chrome"), i = "Chrome", r = o.substring(n + 7))

       : p ? (n = o.indexOf("Safari"), i = "Safari", r = o.substring(n + 7)

注:v成立不成立,v成立,说明是Chrome浏览器。