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),
1)g
看g成立不成立,g为false,说明不是IE浏览器。
2)g不成立
走如下:
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浏览器。

webrtc底层一对一连接过程探索(三)的更多相关文章
- webrtc底层一对一连接过程探索(二)
一.连接过程继续解读-----fun32解读 1.1 fun32.02 "undefined" != typeof cordova && (N = !0, D = ...
- webrtc初探之一对一的连接过程(一)
说明,我研究的是muan-khan的一个github项目,针对的是chrome对chrome,也就是pc对pc的一对一,一对多通话,感兴趣的可以继续往下看. github地址:https://gith ...
- WebRTC 源码分析(五):安卓 P2P 连接过程和 DataChannel 使用
从本篇起,我们将迈入新的领域:网络传输.首先我们看看 P2P 连接的建立过程,以及 DataChannel 的使用,最终我们会利用 DataChannel 实现一个 P2P 的文字聊天功能. P2P ...
- tcp连接过程中的三次握手和四次挥手
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手握手建立连接 @第一次握手: 建立连接是,客户端A发送SYN包到服务器B,并进入SYN_SEND状态,等待B确认. @第二次握手: 服务 ...
- PHP的学习--连接MySQL的三种方式
记录一下PHP连接MySQL的三种方式. 先mock一下数据,可以执行一下sql. /*创建数据库*/ CREATE DATABASE IF NOT EXISTS `test`; /*选择数据库*/ ...
- Java虚拟机JVM学习03 连接过程:验证、准备、解析
Java虚拟机JVM学习03 连接过程:验证.准备.解析 类被加载后,就进入连接阶段. 连接就是将已经读入到内存的类的二进制数据合并到虚拟机的运行时环境中去. 连接阶段三个步骤:验证.准备和解析. 类 ...
- [网络技术][转]PPTP连接过程
转自:http://blog.csdn.net/zhu_hit/article/details/5698958 在未来几天会总结一下PPTP的工作过程,分为以下3篇讲述. 1. PPTP连接过程: 2 ...
- Android IOS WebRTC 音视频开发总结(三十)-- ice协议异同
本文主要介绍ICE与SDP交互过程中的一些知识,支持原创,文章来博客园RTC.Blacker,转载请说明出处. 用过libjingle模块的同学都知道连接过程中candidate的获取与连接流程,一边 ...
- iOS socket原理及连接过程详解
连接过程图解(度娘的拿过来用)
随机推荐
- Git 忽略提交 .gitignore
在使用Git的过程中,我们喜欢有的文件比如日志,临时文件,编译的中间文件等不要提交到代码仓库,这时就要设置相应的忽略规则,来忽略这些文件的提交. Git 忽略文件提交的方法 有三种方法可以实现忽略Gi ...
- 多文件中的static
这里借鉴一篇文章:http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777431.html#undefined 在这里举个例子,先和你说说 ...
- Document类型知识大全
Document类型 1.文档的子节点 Document类型可以表示HTML页面或者其他基于XML的文档.不过,最常见的应用还是作为HTMLDocument实例的document对象.通过这个文档对 ...
- python+appium+unittest
一个流行语言,一个主流工具,一个实用框架: For android 实例如下: import unittest from appium import webdriver from time impor ...
- 在Android studio模拟器中运行apk文件
菜鸟级玩家比看文. win平台下下载的apk文件,怎么能模拟运行出来. 首先得安装Android SDK,不会的自行百度一下. 接下来,打开AVD模拟器,自己创建一个模拟器(过程自己实践) 然后,将你 ...
- dede:list及dede:arclist 按权重排序的方法
有时我们需要做文章排名,比如指定第一名到第三名在前面,这样就用到这个权重排序方法.稍改下就可以完美支持.. dede:list 的方法 1 找到"根目录\include\arc.listvi ...
- 基于FPGA的HDMI高清显示接口驱动
HDMI是(High Definition Multimedia Interface)的缩写,意思是高清晰度多媒体接口,是一种数字化视频/音频接口技术,适合影像传输的专用型数字化接口,可同时传送音频和 ...
- Codeforces 448 E. Divisors (DFS,储存结构)
题目链接:E. Divisors 题意: 给出一个X,f(X)是X所有约数的数列(例6:1 2 3 6),给出一个k,k是递归的次数(例:k=2 : f(f(X)) ; X=4,k=2: 1 1 2 ...
- jquery 遍历表格,需要表格中每个td的内容
$("table tr:gt(0)").each(function(i){ alert("这是第"+i+"行内容"); $(this).ch ...
- Select、Poll、Epoll、 异步IO 介绍
一.概念相关介绍 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的net ...