跳到主要内容

浏览器三大API

WebRTC 在浏览器里的全部能力就是三套 API。把这三个学透,剩下都是工程化封装。

阅读顺序

顺序文件解决的问题
1MediaStream与采集.mdgetUserMediagetDisplayMediaMediaStreamTrack 全套
2RTCPeerConnection.md生命周期、Transceiver、addTrack vs addTransceiver
3RTCDataChannel.md可靠/不可靠语义、背压、典型用法
4编解码与协商.mdVP8/VP9/H.264/AV1/Opus、setCodecPreferences

三件套的职责切分

MediaStream / MediaStreamTrack
└── 采集层:从硬件拿数据 → 输出 Track

RTCPeerConnection
└── 连接层:建链、协商、收发 Track、控制带宽和码率

RTCDataChannel
└── 数据层:任意二进制/字符串 P2P 通道

必须用 Unified Plan

WebRTC 历史上有两种 SDP 表示方式:

  • Plan B(Chrome 旧):所有视频 Track 共享一条 m-line。已废弃
  • Unified Plan(标准,Chrome 72+ / Firefox / Safari):一条 Track 一条 m-line,标准化 Transceiver 模型。

new RTCPeerConnection() 在所有现代浏览器都默认 Unified Plan。禁止通过 sdpSemantics: 'plan-b' 切回去——只会带来兼容问题。

addTrack vs addTransceiver

选择何时用关键差异
pc.addTrack(track, stream)简单场景,先有 Track 再加自动创建 sendrecv transceiver
pc.addTransceiver(kind, options)先建好通道、Track 后续设置可指定 directionsendEncodingsstreams

服务端订阅模型(先建 transceiver 等服务端推流)必须用 addTransceiver。Simulcast 配置也只能在 addTransceiver({sendEncodings}) 时指定。

关键事件速查

事件时机通常处理
negotiationneeded需要重新协商触发 createOffer 流程
icecandidate收到本地新候选通过信令发给对端
track收到对端媒体挂到 <video>.srcObject
datachannel对端创建 DataChannel监听消息
connectionstatechange整体连接状态变化监控 connected/failed
iceconnectionstatechangeICE 状态变化触发 ICE Restart
signalingstatechangeSDP 协商状态变化调试用

反模式总览

反模式后果修复
getUserMedia 后立刻 track.stop() 想"预热"直接释放设备,下次还得等用户授权MediaStreamTrack.enabled = false 静音
<video>.srcObject = null 想停止采集只断开展示,硬件还在采必须 track.stop()
给同一个 RTCPeerConnection 反复 addTrack 然后 removeTrack协商风暴transceiver.sender.replaceTrack(newTrack) 切换
DataChannel 不监听 bufferedamountlow大文件发送时浏览器 OOMbufferedAmount 做背压
不监听 negotiationneeded 自己手动触发漏掉补充协商让浏览器告诉你什么时候需要