“它(WebRTC)允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和(或)音频流或者其他任意数据的传输”。
这是 MDN 上对 WebRTC 的描述,初次接触时无法理解 WebRTC 为什么要和 WebSocket 搭配,明明说的很清楚 不借助中间媒介 ,那 WebSocket 充当的是什么角色?整个 WebRTC 通话建立的流程又是怎样的?
本示例主要使用了 WebRTC 和 WebSocket:
简单说一下流程,如浏览器 A 想和浏览器 B 进行音视频通话:
引用网上的有关WebRTC建立的时序图,可能更加直观:
从上述流程,可以发现通信双方在建立连接前需要交换信息,这也就是开头提到的 WebSocket 充当的角色:信令服务器,用于转发信息。而 WebRTC 不借助中间媒介 的意思是,在建立对等连接后,不需要借助第三方服务器中转,而是直接在两个实体(浏览器)间进行传输。
获取视频标签,连接信令服务器,创建 RTCPeerConnection 对象。其中 RTCPeerConnection 的作用是在两个对等端之间建立连接,其构造函数支持传一个配置对象,包含ICE“打洞”(由于本示例在本机进行测试,故不需要)。
const localVideo = document.querySelector('#local-video');
const remoteVideo = document.querySelector('#remote-video');
const socket = new WebSocket('ws://localhost:8080');
const peer = new RTCPeerConnection();
socket.onmessage = () => { // todo }
peer.ontrack = () => { // todo }
peer.onicecandidate = () => { // todo }
获取本地摄像头/麦克风(需要允许使用权限),拿到本地媒体流(MediaStream)后,需要将其中所有媒体轨道(MediaStreamTrack)添加到轨道集,这些轨道将被发送到另一对等方。
navigator.mediaDevices.getUserMedia({ video: true, audio: true })
.then(stream => {
localVideo.srcObject = stream;
stream.getTracks().forEach(track => {
peer.addTrack(track, stream);
});
});
创建发起方会话描述对象(createOffer),设置本地SDP(setLocalDescription),并通过信令服务器发送到对等端,以启动与远程对等端的新WebRTC连接。
peer.createOffer().then(offer => {
peer.setLocalDescription(offer);
socket.send(JSON.stringify(offer));
});
当调用 setLocalDescription 方法,PeerConnection 开始收集候选人(ice信息),并发送offer_ice到对等方。这边补充第一步中的peer.onicecandidate和socket.onmessage
对等方收到ice信息后,通过调用 addIceCandidate 将接收的候选者信息传递给浏览器的ICE代理。
peer.onicecandidate = e => {
if (e.candidate) {
socket.send(JSON.stringify({
type: 'offer_ice',
iceCandidate: e.candidate
}));
}
};
socket.onmessage = e => {
const { type, sdp, iceCandidate } = JSON.parse(e.data);
if (type === 'offer_ice') {
peer.addIceCandidate(iceCandidate);
}
}
接收方收到了offer信令后,开始获取摄像头/麦克风,与发起方操作一致。同时将收到offer SDP指定为连接的远程对等方属性(setRemoteDescription),并创建应答SDP(createAnswer),发送到对等端。这边补充第一步中的socket.onmessage。
socket.onmessage = e => {
const { type, sdp, iceCandidate } = JSON.parse(e.data);
if (type === 'offer') {
navigator.mediaDevices.getUserMedia(); // 与发起方一致,省略
const offerSdp = new RTCSessionDescription({ type, sdp });
peer.setRemoteDescription(offerSdp).then(() => {
peer.createAnswer(answer => {
socket.send(JSON.stringify(answer));
peer.setLocalDescription(answer)
});
});
}
}
注意:当 setLocalDescription 方法调用后,开始收集候选人信息,并发送 answer_ice 到对等方。与发送方同理,不赘述。
通过不断收集ICE信息(onicecandidate),发起方和应答方最终将建立一条最优的连接方式,此时会触发 ontrack 回调,即可获取到对等方的媒体流。
peer.ontrack = e => {
if (e && e.streams) {
remoteVideo.srcObject = e.streams[0];
}
};
整合发起方和应答方的代码,差不多50行,不算标题党!哈哈哈哈哈哈
完整示例相关代码已上传 github.com/shushushv/webrtc-p2p
原文:https://segmentfault.com/a/1190000020780854
在前面的章节中,已经对WebRTC相关的重要知识点进行了介绍,包括涉及的网络协议、会话描述协议、如何进行网络穿透等,剩下的就是WebRTC的API了。WebRTC通信相关的API非常多,主要完成了如下功能:
WebRTC API包括媒体捕获、音频视频的编码和解码、传输层和会话管理。getUserMedia():捕获音频和视频。MediaRecorder:录制音频和视频。RTCPeerConnection:在用户之间传输音频和视频。RTCDataChannel:用户之间的流数据。
RTCPeerConnection API是每个浏览器之间点对点连接的核心,RTCPeerConnection是WebRTC组件,用于处理对等体之间流数据的稳定和有效通信。RTCPeerConnection可以保护Web开发人员免受潜伏在其中的无数复杂性的影响。
目的 帮助自己了解webrtc 实现端对端通信,WebRTC(Web Real-Time Communication) 网页即时通信 ,是一个支持网页浏览器进行实时语音、视频对话的API。
本文介绍如何基于WebRTC快速实现一个简单的实时音视频通话。在开始之前,您可以先了解一些实时音视频推拉流相关的基础概念:流:一组按指定编码格式封装的音视频数据内容。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!