作者:布拉格mi_716 | 来源:互联网 | 2023-07-13 15:25
每日一句
人生的挑战,无处不在,满怀信心,轻装上路,明天永远是充满希望的战场。
承接上文
承接上文的内容介绍完相关WebRTC技术的概念和发展历程后,开始初步摸索一下相关WebRTC技术的功能和原理。
技术回顾
WebRTC概念定义
WebRTC名称源自网页实时通信(Web Real-Time Communication)的缩写,是一个支持网页浏览器进行实时语音对话或视频对话的技术,是谷歌2010年以6820万美元收购Global IP Solutions公司而获得的一项技术。
WebRTC功能范畴
WebRTC应用包括下面四个主要的概念
WebRTC已经纳入HTML5标准
目前支持WebRTC协议的浏览器有:Chrome、Firefox Opera,IE不支持~
WebRTC的核心组件
下图为WebRTC内部结构简化图:
-
最底层是硬件设备。
-
上面是音频捕获模块和视频捕获模块。
在音视频引擎之上是一套C++ API,在C++ 的API之上是提供给浏览器的Javascript API。
【学习地址】:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【文章福利】:免费领取更多音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击1079654574加群领取哦~
JSEP
-
JSEP(Javascript Session Establishment Protocol,Javascript会话建立协议)是一个信令API,允许开发者构建更强大的应用程序以及增加在信令协议选择上的灵活性。
-
JSEP是干什么的呢,一方面提供接口如createOffer()供web应用程序调用生成SDP,另一方面提供ICE功能接口。这些功能都由浏览器实现,浏览器WebRTC传输信令(offer/answer)采用Websocket。
-
github上codelabdemo就是不用其他信令协议,直接使用JSEP生成offer/answer信令,然后采用ws协议传输实现的。
-
JSEP并不是信令协议,可以在JSEP的基础上引入SIP等信令协议,使WebRTC应用功能更加完备。
信令服务器
WebRTC没有定义用于建立信道的信令的协议,因此可以使用任意的传输方式,例如 WebSocket, XMPP, SIP, AJAX。
信令服务器传送的数据有
-
协商媒体功能和设置
-
标识和验证会话参与者的身份
-
控制媒体会话、指示进度、更改会话和终止会话
其中只有第一项的必备功能。其他都可以根据业务需求自由调整。
SDP协议
此外,信令通道还用于交换候选地址,以便进行ICE打洞。
信令互通方案
WebRTC与SIP互通
要想让WebRTC与SIP互通,要解决两个层面的问题:信令层和媒体层。
两个网络使用的信令机制不同,所以要进行信令的转换,才能完成媒体的协商,建立会话。媒体层要完成编码的转换,以及RTP/SRTP转换等功能。
这里主要说项信令层面的互通。
目前SIP和WebRTC信令上互通有两种解决方案:
ICE服务器
-
实现点对点通信的关键在于两个浏览器之间能直接发送和接收数据包,但一般情况下,浏览器或手机都是通过路由器访问Internet,所以存在网络地址转换(NAT)。
-
NAT之内的IP地址是私有地址,外部无法访问。分配给NAT的IP地址才是公共地址。NAT每次从内部到外部转发数据包时都使用公共地址。
-
交互式建立连接(ICE)是一种标准穿透协议,它利用STUN和TURN服务器来建立连接。
-
STUN服务器可以遍历NAT,获取浏览器的候选地址,包括私有地址、外层NAT的公共 IP地址等。
-
通信信令通道可以交换候选地址,浏览器一旦发送并收到了候选地址,就会开始进行连接检查,若检查成功,便使用该候选项发送媒体。
-
在大多情况下,通过穿透可以建立直接对等连接。但是,若NAT或防火墙限制非常严格,无法建立连接,就只能通过TURN服务器中继媒体。
媒体服务器
媒体服务器不是必须的,但在多方会话或需要对媒体做额外处理的情况下可以考虑加入。对于有多个浏览器参与的会议,可以采用一个集中式媒体服务器。在这种情况下,美国浏览器都只需与媒体服务器建立单个连接即可,这种结构的优势是额能够扩展非常大的会话,同时可以在最大限度上减少当有新加入者加入会话事美国浏览器所需的处理工作量。同时,媒体服务器也可对媒体进行分析、处理、保存等工作。
Javascript接口
getUserMedia
通过调用navigator.getUserMedia()可以获取视频或音频的数据,constraints 参数可以选择是否获取视频音频。下面是一个简单的示例
var cOnstraints= {audio: false,video: true
};
var video = document.querySelector('video');
function successCallback(stream) {
if (window.URL) {video.src = window.URL.createObjectURL(stream);} else {video.src = stream;}
}
function errorCallback(error) {console.log('navigator.getUserMedia error: ', error);
}
navigator.getUserMedia(constraints, successCallback, errorCallback);
RTCPeerConnection
RTCPeerConnection是WebRTC中最重要的一个接口,用于确定ICE服务器、交换 SDP。连接过程如下:
创建RTCPeerConnection对象
-
RTCPeerConnection的参数用于确定ICE服务器,下面是使用了 google 开放的 STUN 服务器
let iceServer = {"iceServers": [{"url": "stun:stun.l.google.com:19302"}]
};
let pc = new RTCPeerConnection(servers);
2.将媒体流放入 RTCPeerConnection 对象中
pc.addStream(localStream);
通过offer和answer交换SDP描述符
-
甲和乙各自建立一个PC实例
-
甲将offer信令通过服务器发送给乙
-
乙将甲的offer信令中所包含的的SDP描述符提取出来,通过PC所提供的 setRemoteDescription()方法交给乙的PC实例
-
乙通过PC所提供的createAnswer()方法建立一个包含乙的SDP描述符 answer信令
-
乙通过PC所提供的setLocalDescription()方法,将乙的SDP描述符交给乙的PC实例
-
乙将answer信令通过服务器发送给甲
甲接收到乙的answer信令后,将其中乙的SDP描述符提取出来,调用setRemoteDescripttion()方法交给甲自己的PC实例。
ICE打洞
1.当网络候选可用时,通过信令服务器将其发送到对方浏览器
pc.Onicecandidate= function(event) {if (event.candidate) {sendToServer(event.candidate)}
};
2.当接受到对方网络候选时,将其加入
let candidate = new RTCIceCandidate(candidate);
pc.addIceCandidate(candidate);
3.监听对方发送的媒体是否可用,并播放媒体
pc.Onaddstream= event => {remoteVideo.src = window.URL.createObjectURL(event.stream);
}
RTCDataChannel
RTCDataChannel是RTCPeerConnectionAPI的一部分,只有在创建了 RTCPeerConnection实例后才能创建数据通道。
数据通道可以用于发送文本或是文件。
pc = new RTCPeerConnection();
dc = pc.createDataChannel('dc');
dc.Onmessage= event => console.log(event.data);
dc.send('text');
dc.sed(new arraybuffer(32))
在另一端可以使用 ondatachannel 获得 RTCDataChannel 对象
pc.Ondatachannel= event => dc = event.channel;