WebRTC:浏览器中的点对点音视频与数据
一句话: WebRTC 与 Media Capture and Streams API 一起,为 Web 带来了音视频通话、 文件交换与屏幕共享——建立点对点连接不需要特殊驱动或插件,一旦连接建立,往往也不需要 任何中间服务器。
RTCPeerConnection表示本机与远端对等方之间的一条 WebRTC 连接;一旦建立并打开, 就可以向其添加媒体流和/或数据通道。MediaStreamTrack表示流中的单条媒体轨道——音频、视频或文本。RTCDataChannel添加到已打开的RTCPeerConnection上,用于在对等方之间直接携带 任意应用数据,可与媒体一起使用,也可单独使用。
采集本地媒体
Section titled “采集本地媒体”MediaDevices.getUserMedia() 请求访问用户的摄像头和麦克风,返回的 Promise 会以
MediaStream resolve:
const constraints = { audio: true, video: { width: 1280, height: 720 } };const stream = await navigator.mediaDevices.getUserMedia(constraints);videoElement.srcObject = stream;navigator.mediaDevices.enumerateDevices() 列出可用的输入设备。把某个设备的
deviceId 作为普通约束值传入,只是一种偏好,浏览器可以不遵循;要强制使用该特定
设备,需要传入 { exact: deviceId }。
信令不属于 WebRTC 的一部分
Section titled “信令不属于 WebRTC 的一部分”WebRTC 在建立连接之前,必须先在两个对等方之间交换会话信息——offer、answer 与网络候选 地址——MDN 明确指出这个交换过程需要「某种中间服务器」:WebRTC 本身并不定义这条信令 通道,因此它可以通过应用已有的任何传输方式(WebSocket、既有 API 等)承载。典型流程 如下:
const pc = new RTCPeerConnection();pc.addTrack(stream.getTracks()[0], stream);
const offer = await pc.createOffer();await pc.setLocalDescription(offer);// 通过你自己的信令通道,把 `offer` 发送给远端对等方。接收方使用该 offer 调用 setRemoteDescription(),创建自己的 answer 并通过同一条信令
通道发回——之后两端的 RTCPeerConnection 会协商彼此之间的媒体/数据流转,往往(但并非
总是)不需要任何服务器来中转媒体本身。
根据 MDN 的兼容性数据,RTCPeerConnection() 构造函数具有 Baseline「广泛可用」状态:
该特性自 2017 年 9 月起就已在各主流浏览器中生效。
| Browser / Platform | Support | Since | Confidence | Source | Notes |
|---|---|---|---|---|---|
| Chrome (Desktop) | ✅ yes | 56 | high | ref | Prefixed `webkitRTCPeerConnection` supported since Chrome 23. |
| Edge (Desktop) | ✅ yes | 15 | high | ref | — |
| Firefox (Desktop) | ✅ yes | 44 | high | ref | Prefixed `mozRTCPeerConnection` supported since Firefox 22. |
| Firefox (Android) | ✅ yes | 44 | high | ref | Prefixed `mozRTCPeerConnection` supported since Firefox for Android 24. |
| Safari (macOS) | ✅ yes | 11 | high | ref | — |
async function startCall(constraints) { if (!('RTCPeerConnection' in window) || !navigator.mediaDevices?.getUserMedia) { // WebRTC 不可用——回退到非实时路径 // (例如上传表单),而不是尝试发起通话。 return null; } const stream = await navigator.mediaDevices.getUserMedia(constraints); const pc = new RTCPeerConnection(); stream.getTracks().forEach((track) => pc.addTrack(track, stream)); return pc;}- 在发起通话之前,同时对
RTCPeerConnection与navigator.mediaDevices.getUserMedia做特性检测,并在缺失任一项时提供回退路径。 - 只在用户能理解的上下文中调用
getUserMedia()——除非浏览器已经记住了此前对该 源的授权,否则它会触发摄像头/麦克风的权限提示。 - 自行搭建信令通道;WebRTC 不提供信令,只在 offer/answer/candidate 交换完成后 提供连接本身。
- 在创建 offer 之前先向
RTCPeerConnection添加轨道,这样它们才会被包含在协商的 会话中。 - 当需要强制指定特定摄像头或麦克风而非默认设备时,使用
enumerateDevices()配合deviceId: { exact: deviceId }约束。
- Web 能力索引 —— 本参考中其他与设备、网络相关的浏览器 API。
- WebTransport —— 本参考中记录的另一项浏览器 网络能力。