1、WebRTC初探:WebRTC是什么、为什么需要WebRTC、WebRTC的三大核心API、WebRTC的典型应用场景
大家好,我是你们这门课的老朋友。今天咱们来聊聊WebRTC——这个让浏览器也能做实时音视频通信的神奇技术。
说实话,我第一次接触WebRTC是在2015年。那时候客户要求做一个网页版的视频客服系统,我第一反应是「这得装插件吧?」。结果一查资料,发现Chrome和Firefox已经原生支持了,连Flash都不用。嗯,从那天起,我就知道这玩意儿要火。
1.1 WebRTC是什么?
WebRTC,全称Web Real-Time Communication,中文叫「网页实时通信」。说白了,就是让两个浏览器之间能直接传视频、音频和任意数据,不需要中间服务器转发媒体流。
你想想看,以前要实现视频通话,要么装Flash(现在已经被淘汰了),要么装插件,要么用原生App。WebRTC把这些全干掉了——打开浏览器,写几行JavaScript,就能点对点通信。
我个人习惯把WebRTC理解成「浏览器的P2P能力」。它不是一个库,也不是一个框架,而是一组W3C和IETF共同制定的标准。Chrome、Firefox、Safari、Edge都支持,只是实现细节上有点小差异。
1.2 为什么需要WebRTC?
这个问题我经常被问到。其实答案很简单:实时通信的需求太普遍了,但实现起来太复杂了。
我来给你拆解一下,如果没有WebRTC,你要实现一个视频通话功能需要做哪些事:
- 采集音视频: 调用摄像头和麦克风,不同浏览器API还不一样
- 编码解码: 视频要压缩成H.264或VP8,音频要压缩成Opus或G.711
- 网络传输: 要处理NAT穿透、防火墙、丢包重传、抖动缓冲
- 回音消除: 扬声器的声音不能又被麦克风采进去
- 自动增益控制: 说话声音大小时音量要稳定
这些技术,每一项都够写一本书。而WebRTC把这些全部封装好了,你只需要调用几个API就行。
我在项目中遇到过一家创业公司,他们想自己从零写一套视频通话方案。折腾了半年,连基本的NAT穿透都没搞定。最后换成了WebRTC,两周就上线了。这就是为什么需要WebRTC——别重复造轮子,尤其是这种带轮子的坦克。
1.3 WebRTC的三大核心API
WebRTC虽然复杂,但核心API只有三个。记住这三个,你就掌握了80%的WebRTC。
1.3.1 getUserMedia —— 采集音视频
这个API负责打开摄像头和麦克风。用法很简单:
// 请求摄像头和麦克风
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
})
.then(function(stream) {
// 把视频流绑定到video标签上
document.getElementById('localVideo').srcObject = stream;
})
.catch(function(err) {
console.log('获取媒体设备失败:', err);
});
嗯,这里要注意:getUserMedia必须在HTTPS或者localhost下才能用。 我曾经在HTTP环境下调试了半天,一直报错,后来才发现是协议问题。另外,用户必须手动点击页面上的某个按钮才能触发权限请求,不能一进页面就自动弹窗——这是浏览器的安全策略。
你还可以指定分辨率:
navigator.mediaDevices.getUserMedia({
video: {
width: { ideal: 1280 },
height: { ideal: 720 },
frameRate: { ideal: 30 }
},
audio: true
});
这里的ideal表示「理想值」,浏览器会尽量满足,但不保证一定能达到。如果你非要强制某个分辨率,可以用exact。
1.3.2 RTCPeerConnection —— 建立P2P连接
这是WebRTC最核心的API。它负责在两端之间建立一条点对点的音视频通道。
建立连接的过程大致是这样的:
- 发起方创建一个
RTCPeerConnection对象 - 发起方创建一个
offer(SDP协议,描述自己支持哪些编解码器、网络信息等) - 发起方通过信令服务器把offer传给接收方
- 接收方收到offer后,创建一个
answer,再传回去 - 双方交换ICE候选地址(用于NAT穿透)
- 连接建立成功,开始传输音视频
代码示例(简化版):
// 创建连接
const pc = new RTCPeerConnection({
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' }
]
});
// 添加本地流
localStream.getTracks().forEach(track => {
pc.addTrack(track, localStream);
});
// 创建offer
pc.createOffer()
.then(offer => pc.setLocalDescription(offer))
.then(() => {
// 通过信令服务器发送offer给对方
signalingServer.send({
type: 'offer',
sdp: pc.localDescription
});
});
这里有个坑:ICE服务器必须配置正确。 我曾经在生产环境忘了配TURN服务器,结果有些用户在公司内网能通,回到家就不行了。因为STUN只能处理简单的NAT,遇到对称型NAT就歇菜了。这时候必须用TURN服务器做中继。
1.3.3 RTCDataChannel —— 传输任意数据
这个API很多人会忽略,但其实它非常强大。它允许你在两个浏览器之间传输任意数据——文本、文件、二进制数据,而且延迟极低。
用法也很简单:
// 在RTCPeerConnection上创建数据通道
const dataChannel = pc.createDataChannel('myChannel');
// 监听消息
dataChannel.onmessage = function(event) {
console.log('收到数据:', event.data);
};
// 发送数据
dataChannel.send('Hello from browser!');
RTCDataChannel有两种模式:
| 模式 | 特点 | 适用场景 |
|---|---|---|
| 可靠模式 | 类似TCP,保证数据到达,有序 | 文件传输、聊天消息 |
| 不可靠模式 | 类似UDP,不保证到达,无序 | 游戏状态同步、实时位置 |
我个人习惯在游戏场景中用不可靠模式,因为丢一两个包无所谓,但延迟必须低。而在文件传输场景中,必须用可靠模式,否则文件会损坏。
1.4 WebRTC的典型应用场景
说了这么多理论,咱们来看看实际中WebRTC都在哪些地方发光发热。
- 视频会议: Zoom、Google Meet、腾讯会议,底层都是WebRTC。你想想看,疫情期间几亿人同时在线开会,WebRTC扛住了。
- 在线教育: 老师和学生实时互动,共享屏幕、白板。我参与过一个在线钢琴教学项目,用RTCDataChannel传输MIDI信号,延迟控制在20ms以内。
- 远程医疗: 医生通过高清视频查看患者状况,传输医疗影像。这个场景对画质要求极高,需要调整码率参数。
- 直播连麦: 主播和观众连麦互动,或者主播之间PK。WebRTC的延迟比传统RTMP低得多。
- IoT设备控制: 用RTCDataChannel传输控制指令,延迟低、实时性好。
- P2P文件传输: 不经过服务器,两个浏览器之间直接传大文件。我做过一个工具,传1GB的文件只需要几十秒。
1.5 本章知识体系
为了让你更直观地理解WebRTC的整体架构,我画了一张图:
从这张图你可以看到,WebRTC的核心就是三个API,配合信令服务器和STUN/TURN服务器,就能实现完整的实时通信。
好了,这一章的内容就到这里。WebRTC的三大核心API——getUserMedia、RTCPeerConnection、RTCDataChannel——你已经有了初步了解。下一章我们会深入每个API的细节,手把手带你写出第一个WebRTC应用。
公众号:蓝海资料掘金营,微信deep3321