1. WebRTC基础:WebRTC是什么、WebRTC发展史、WebRTC核心API概览、浏览器兼容性
各位同学好,我是你们这门课的老司机。今天咱们先不急着写代码,把地基打牢再说。WebRTC这东西,说白了就是让浏览器之间能直接视频通话、传文件、共享屏幕,不需要装任何插件。嗯,就是这么个玩意儿。
1.1 WebRTC到底是什么?
WebRTC的全称是 Web Real-Time Communication,即网页实时通信。它是一套由W3C和IETF共同制定的标准,允许浏览器、移动应用之间通过点对点(P2P)的方式传输音视频数据。
我个人习惯把它理解成「浏览器的对讲机」。你想想看,以前想在网页上做视频通话,得装Flash、装插件,麻烦得要命。WebRTC把这些全干掉了,直接用浏览器原生API就能搞定。
核心特点:
- 无需安装插件或第三方软件
- 基于P2P架构,延迟低
- 支持音视频通话、屏幕共享、文件传输
- 开源免费,主流浏览器都支持
我在项目中遇到过不少新手,以为WebRTC只是个视频通话库。其实它是一整套协议栈,包括媒体捕获、编码传输、NAT穿透、安全加密等等。说白了,它把实时通信的脏活累活都替你干了。
1.2 WebRTC发展史:从实验室到工业标准
WebRTC的历史不算长,但发展速度惊人。我简单梳理一下关键节点:
| 时间 | 事件 | 意义 |
|---|---|---|
| 2011年 | Google开源WebRTC项目 | 收购Global IP Solutions后开源,奠定技术基础 |
| 2013年 | Chrome和Firefox首次实现互通话 | 证明跨浏览器通信可行 |
| 2017年 | W3C发布WebRTC 1.0候选推荐标准 | API趋于稳定 |
| 2021年 | WebRTC 1.0成为正式W3C推荐标准 | 成为真正的Web标准 |
| 至今 | 持续演进,支持AV1、SVC等新编码 | 性能和质量不断提升 |
我记得2015年刚接触WebRTC时,文档少得可怜,踩坑全靠自己试。那时候Chrome和Firefox的API还不完全兼容,写个简单的视频通话得折腾好几天。现在好多了,文档齐全,社区活跃,工具链也成熟了。
一个小八卦:WebRTC最初是Google为了Google Hangouts(后来的Google Meet)开发的。Google发现市面上没有好用的浏览器实时通信方案,干脆自己搞了一套,然后开源了。嗯,这就是大厂的任性。
1.3 WebRTC核心API概览
WebRTC的核心API其实不多,但每个都挺重要。我按功能分成三块来讲:
1.3.1 MediaStream(媒体流)
这个API负责获取音视频设备的数据。比如打开摄像头、麦克风,或者捕获屏幕。
// 获取摄像头视频
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true
});
// 获取屏幕共享流
const screenStream = await navigator.mediaDevices.getDisplayMedia({
video: true
});
这里有个坑:getUserMedia和getDisplayMedia的权限机制不一样。前者需要用户授权,后者是浏览器直接弹出选择窗口。我曾经在项目里把两者搞混,结果屏幕共享死活调不出来……
1.3.2 RTCPeerConnection(对等连接)
这是WebRTC的核心,负责建立和管理两个浏览器之间的P2P连接。它处理了信令交换、NAT穿透、媒体协商、数据加密等一系列复杂工作。
const pc = new RTCPeerConnection({
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' }
]
});
// 添加本地流
stream.getTracks().forEach(track => {
pc.addTrack(track, stream);
});
// 创建并发送Offer
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
// 通过信令通道发送给远端
我个人习惯把RTCPeerConnection想象成「虚拟网线」——它把两个浏览器直接连起来,数据不用经过服务器中转。当然,实际落地时还需要STUN/TURN服务器帮忙打洞,这个后面会细讲。
1.3.3 RTCDataChannel(数据通道)
除了音视频,WebRTC还支持传输任意二进制数据。这个API就是干这个的。
const dc = pc.createDataChannel('myChannel');
dc.onopen = () => {
dc.send('Hello from peer!');
};
dc.onmessage = (event) => {
console.log('收到消息:', event.data);
};
数据通道基于SCTP协议,支持可靠传输和不可靠传输两种模式。做屏幕共享时,我经常用它来传输控制信令或元数据,比如鼠标位置、标注信息等。
核心API总结:
MediaStream— 获取音视频/屏幕数据RTCPeerConnection— 建立P2P连接RTCDataChannel— 传输任意数据
1.4 浏览器兼容性
说到兼容性,我得先叹口气。WebRTC虽然已经是标准了,但各家浏览器的实现还是有差异的。你想想看,Chrome用的是自家引擎,Safari用的是WebKit,Firefox用的是Gecko,底层实现不同,API细节自然有出入。
目前主流浏览器的支持情况:
| 浏览器 | WebRTC支持 | 屏幕共享支持 | 注意事项 |
|---|---|---|---|
| Chrome 28+ | ✅ 完整 | ✅ 完整 | 使用getDisplayMedia标准API |
| Firefox 22+ | ✅ 完整 | ✅ 完整 | 早期使用moz前缀,现已标准 |
| Safari 11+ | ✅ 完整 | ✅ 支持 | 需用户授权,部分API命名不同 |
| Edge 12+ | ✅ 完整 | ✅ 支持 | 新版Edge基于Chromium,兼容性好 |
| IE 11 | ❌ 不支持 | ❌ 不支持 | 需要插件或放弃支持 |
避坑指南:我曾经在Safari上踩过一个坑——它的RTCPeerConnection构造函数不支持iceServers参数中的某些字段。后来发现Safari对ICE候选者的处理方式跟Chrome不一样,需要额外做兼容处理。建议使用adapter.js这个polyfill库,能省不少事。
另外,移动端浏览器的情况更复杂。Android上的Chrome和Firefox支持得不错,但iOS上的Safari(以及所有iOS浏览器,因为iOS强制使用WebKit内核)有些限制。比如屏幕共享在iOS上只能共享整个屏幕,不能选择特定窗口或标签页。
1.5 本章知识体系
说了这么多,咱们用一张图把WebRTC的基础知识串起来:
这张图把咱们这章讲的内容都串起来了。WebRTC的核心就是那三个API,再加上浏览器兼容性和发展史,构成了整个知识框架。后面的章节,我们会围绕这些核心API,一步步实现屏幕共享功能。
给新手的建议:刚开始学WebRTC,别急着看底层协议。先把三个核心API用熟,能跑通一个简单的视频通话demo,就算入门了。我当年就是这么过来的。
公众号:蓝海资料掘金营,微信deep3321