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
});

这里有个坑:getUserMediagetDisplayMedia的权限机制不一样。前者需要用户授权,后者是浏览器直接弹出选择窗口。我曾经在项目里把两者搞混,结果屏幕共享死活调不出来……

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基础知识体系 WebRTC MediaStream RTCPeerConnection RTCDataChannel 获取音视频/屏幕数据 建立P2P连接,处理NAT穿透 传输任意二进制数据 浏览器兼容性:Chrome ✅ | Firefox ✅ | Safari ✅ | Edge ✅ | IE ❌ 发展史时间线 2011 Google开源 2013 跨浏览器通话 2017 候选标准 2021 正式标准

这张图把咱们这章讲的内容都串起来了。WebRTC的核心就是那三个API,再加上浏览器兼容性和发展史,构成了整个知识框架。后面的章节,我们会围绕这些核心API,一步步实现屏幕共享功能。

给新手的建议:刚开始学WebRTC,别急着看底层协议。先把三个核心API用熟,能跑通一个简单的视频通话demo,就算入门了。我当年就是这么过来的。


公众号:蓝海资料掘金营,微信deep3321