webRTC脱坑笔记(三)— webRTC API之RTCPeerConnection
RTCPeerConnection API是每个浏览器之间点对点连接的核心,RTCPeerConnection是WebRTC组件,用于处理对等体之间流数据的稳定和有效通信。
RTCPeerConnection可以保护Web开发人员免受潜伏在其中的无数复杂性的影响。WebRTC使用的编解码器和协议可以进行大量工作,即使在不可靠的网络上也可以进行实时通信:
- 丢包隐藏
 - 回声消除
 - 带宽适应性
 - 动态抖动缓冲
 - 自动增益控制
 - 降噪和抑制
 - 图像’清洁’。
 
// 创建实例
let pc = RTCPeerConnection(serverConfig);
根据你是发起者还是被发起对象,在连接的每一边会使用稍微不同的方式使用RtcPeerConnection对象。
serverConfigconfig配置参数中包含iceServers参数。它是包含有关STUN和TURN服务器的信息的URL对象数组,在查找ICE候选时使用。可以在code.google.com找到可用的公共STUN服务器的列表。
现实中,无论你的应用如何见到那,webRTC都需要服务器,因为:
- 通信用户发现彼此并交换自己的“真实世界”的详细信息;
 webRTC客户端(对等方)交换网络信息;peers交换有关每天的数据,如视频格式和分辨率webRTC客户端遍历NAT网关和防火墙
换句话说,WebRTC需要四种类型的服务器端功能:
- 发现用户并沟通。
 - 使用
STUN服务器连接用户信号。 - 使用
NAT/防火墙遍历。 - 在对等通信失败的情况下,使用中继服务器。
 
ICE是用于连接对等体的框架,例如两个视频聊天客户端。最初,ICE尝试通过UDP直接连接对等端,以尽可能低的延迟。在此过程中,STUN服务器只有一个任务:使NAT后面的对等体能够找到其公共地址和端口。
下面是调用流程:
1.获取本地媒体设备成功之后,创建一个新的RTCPeerConnection对象,初始化将本地音视频轨道加入到RTCPeerConnection
 function createConn(stream) {
     localStream = stream
     // 显示本地视频流
    localVideo.srcObject = stream;
     //谷歌公共stun服务器
    let serverConfig = {
        "iceServers": [
            { "urls": ["turn:192.168.1.133:3478"],
            "username": "webrtc",
            "credential": "webrtc"
            }
        ]
    };
     // 呼叫者
    let localPeer = new RTCPeerConnection(serverConfig)
    // 被呼叫者
    let remotePeer = new RTCPeerConnection(serverConfig)
    // 设置媒体流监听,将本地流添加到RTCPeerConnection对象
    localStream.getTracks().forEach((track) => {
      localPeer.addTrack(track, localStream);
    });
    localPeer.addStream(stream)
 }
2.注册onicecandidate处理程序,并监听获取自己的ICE协商信息,它将任何ICE候选发送给其他对等方
function createConn(stream) {
    ...
    // 当获得到自己的公网地址后,发送给其它客户端
    localPeer.onicecandidate = function(event) {
    console.log('I got my icecandidate info')
    if (event.candidate) {
        console.log(event.candidate.candidate)
    }
        socket.emit('onicecandidate', event.candidate);
    }
    // 如果监测到本地媒体流连接到本地,将其绑定到一个video标签上输出
     localPeer.ontrack = function(e) {
         // 因为媒体流是一个数组
        if (remoteVideo.srcObject !== e.streams[0]) {
        remoteVideo.srcObject = e.streams[0];
        console.log('received remote stream');
    }
    };
}
3.提前注册消息处理程序。信令服务器还应该有一个处理来自远程计算机的消息处理程序。如果消息包含RTCSessionDescription对象,则应该使用RTCSessionDescription()方法将其添加到RTCPeerConnection对象。如果消息包含RTCIceCandidate对象,则应该使用addIceCandidate()方法将其添加到RTCPeerConnection对象。
消息处理程序会根据谁是呼叫方和被呼叫方被调用。
//呼叫方收到对方回复的SDP时调用的消息处理程序
localPeer.setRemoteDescription(new RTCSessionDescription(answer)); //被呼叫方收到对方发送的SOP时调用的消息处理程序
localPeer.addIceCandidate(new RTCIceCandidate(candidate));
4.拨通对方,发送自己的SDP信息,开始提供/回答协商过程,这是呼叫者的流量不同于被呼叫者的唯一步骤。呼叫者使用createoffer( )方法开始协商,并注册一个收到RTCSessiondescription对象的回调。然后这个回调应该使用setlocaldescription( )将这个rtcsessiondescription对象添加到rtcpeerconnection对象中。最后,调用者应该使用信令服务器将这个rtcsessiondescription发送到远程计算机。另一方面,被呼叫者,在createanswer()方法中注册相同的回调。请注意,只有在从调用者收到通知后,才会启动流。
//当本地开始拨打对方的时候,发送自己的SDP信息
const offerOptions = {
offerToReceiveAudio: 1,
offerToReceiveVideo: 1
};
function call() {
console.log('Starting call'); try {
console.log('localPeerConnection createOffer start');
const offer = await pc1.createOffer(offerOptions);
console.log(offer);
localPeer.setLocalDescription(offer)
socket.emit('offer', offer);
} catch (e) {
console.log(`Failed to create session description: ${e.toString()}`);
}
} // 当本地收到对方的拨号通知时 收到对方的SDP信息,然后生成回复SDP信息
function handleOffer(offer, name) {
connectedUser = name;
console.log("I got offer: ");
localPeer.setRemoteDescription(new RTCSessionDescription(offer));
//create an answer to an offer
localPeer.createAnswer(function(answer) {
localPeer.setLocalDescription(answer);
console.log("I will reply a answer")
send({
type: "answer",
answer: answer
});
}, function(error) {
alert("Error when creating an answer");
});
};
// 当拨号方收到对方回复的SDP后,设置到连接中,调用消息处理程序
socket.on('answer', (desc) => {
console.log("I got answer: ", desc.sdp);
localPeerConnection.setRemoteDescription(desc);
})
webRTC脱坑笔记(三)— webRTC API之RTCPeerConnection的更多相关文章
- webRTC脱坑笔记(一)— 初识webRTC
		
webRTC概述 WebRTC--- `Web browsers with Real-Time Communications (RTC)` WebRTC是一个开源项目,可以在`Web`和本机应用程序中 ...
 - webRTC脱坑笔记(二)— webRTC API之MediaStream(getUserMedia)
		
webRTC API WebRTC API包括媒体捕获.音频视频的编码和解码.传输层和会话管理. getUserMedia():捕获音频和视频. MediaRecorder:录制音频和视频. RTCP ...
 - webRTC脱坑笔记(四)— windows下Nginx对Node服务的反向代理
		
Nginx反向代理 1.什么是反向代理 当我们有一个服务器集群,并且服务器集群中的每台服务器的内容一样的时候,同样我们要直接从个人电脑访问到服务器集群服务器的时候无法访问,必须通过第三方服务器才能访问 ...
 - es6 入坑笔记(三)---数组,对象扩展
		
数组扩展 循环 arr.foreach(){ //回调函数 function(val,index,arr){ //val:当前读取到的数组的值,index:当前读取道德数组的索引,arr:当前的数组名 ...
 - 一步步yum安装LNMP,脱坑笔记!!!
		
更改国内yum源: 1.备份yum源文件,位置在/etc/yum.repos.d/CentOS-Base.repo mv /etc/yum.repos.d/CentOS-Base.repo /etc/ ...
 - angular学习笔记(三十一)-$location(2)
		
之前已经介绍了$location服务的基本用法:angular学习笔记(三十一)-$location(1). 这篇是上一篇的进阶,介绍$location的配置,兼容各版本浏览器,等. *注意,这里介绍 ...
 - WebRTC入门学习之初识WebRTC (转)
		
一.WebRTC基本架构 图一 WebRTC总体架构,摘自百度百科 先说说WebRTC大致的实现思路:我们创建的web app,然后在app中调用W3C提供的JS API,JS API 会调用浏览器 ...
 - 《CMake实践》笔记三:构建静态库(.a) 与 动态库(.so) 及 如何使用外部共享库和头文件
		
<CMake实践>笔记一:PROJECT/MESSAGE/ADD_EXECUTABLE <CMake实践>笔记二:INSTALL/CMAKE_INSTALL_PREFIX &l ...
 - EntityFramework CodeFirst SQLServer转Oracle踩坑笔记
		
接着在Oracle中使用Entity Framework 6 CodeFirst这篇博文,正在将项目从SQLServer 2012转至Oracle 11g,目前为止遇到的问题在此记录下. SQL Se ...
 
随机推荐
- 转Oracle、MySql、SQLServer 数据分页查询
			
最近简单的对oracle,mysql,sqlserver2005的数据分页查询作了研究,把各自的查询的语句贴出来供大家学习..... (一). mysql的分页查询 mysql的分页查询是最简单的,借 ...
 - 【HDOJ6641】TDL(数论)
			
题意:定义f(n,m)是第m小的数字x,使得x>n且gcd(x,n)=1 已知 求最小的n使得 k<=1e18,m<=1e2 思路: #include<bits/stdc++. ...
 - windows下使用Ant编译Android项目
			
1. 安装ant,配置环境变量 2. 执行命令: android update project -p 项目路径 例:android update project -p D:\project\UI_de ...
 - Linux系统中imp导入dmp文件
			
[oracle@ocm1 ~]$ lltotal 32-rw-r--r-- 1 oracle oinstall 24576 Mar 27 15:26 COUNTRIES.dmpdrwxr-xr-x 2 ...
 - 不间断电源(UPS)
			
UPS电源一般指不间断电源 UPS(Uninterruptible Power System/Uninterruptible Power Supply),即不间断电源,是将蓄电池(多为铅酸免维护蓄电池 ...
 - springboot编程之全局异常捕获
			
springboot编程之全局异常捕获 1.创建GlobalExceptionHandler.java,在类上注解@ControllerAdvice, 在方法上注解@ExceptionHandler( ...
 - MSSQL  sql常用判断语句
			
.判断数据库是否存在 if exists (select * from sys.databases where name = '数据库名') drop database [数据库名] 2 判断 ...
 - Recurrent Neural Network(3):LSTM Basics and 《Inside Out》
			
下图是Naive RNN的Recurrent Unit示意图,可以看到,在每个时间点t,Recurrent Unit会输出一个隐藏状态ht,对ht加工提取后将产生t时刻的输出yt.而在下一个时间节点t ...
 - Ubuntu安装byzanz截取动态效果图
			
byzanz-record主要参数选项 用法: byzanz-record [选项...] 录制您的当前桌面会话 帮助选项: -?, --help 显示帮助选项 --help-all 显示全部帮助选项 ...
 - C# 中定义斜杠 \
			
\ 是转义符 如 \’ 单引号 \” 双引号 \\ 反斜杠 \0 空 \a 警告(产生峰鸣) \b 退格 \f 换页 \n 换行 \r 回车 ...