Skip to content

低延迟屏幕共享

屏幕共享相比音视频通话对延迟更敏感。WetRTC 提供发送端编码调优、H.264 优先与接收端播放缓冲控制,可组合使用以降低端到端延迟。

发送端完整示例

ts
import { WetRTC, type SignalChannel } from '@wetspace/wetrtc'

declare const signal: SignalChannel

const rtc = new WetRTC({
  signal,
  direction: 'sendonly',
  initiator: false,
  polite: true,
  preferredVideoCodec: 'h264',
  videoEncoding: {
    contentHint: 'motion',
    maxFrameRate: 30,
    maxBitrate: 4_000_000,
    degradationPreference: 'maintain-framerate',
  },
})

const screenStream = await rtc.media.getDisplayMedia({
  width: 1920,
  height: 1080,
  frameRate: 30,
  audio: false,
})

for (const track of screenStream.getVideoTracks()) {
  rtc.addTrack(track, screenStream)
}

await rtc.connect()

要点:

配置作用
videoEncoding.contentHint: 'motion'告知编码器内容为动态画面(鼠标、窗口拖动)
videoEncoding.maxFrameRate限制发送帧率,减轻编码负载
videoEncoding.maxBitrate限制峰值码率
videoEncoding.degradationPreference: 'maintain-framerate'带宽不足时优先保帧率而非分辨率
preferredVideoCodec: 'h264'SDP 协商优先 H.264,Electron/Chrome 下通常走硬件编码

Electron 桌面捕获可配合 getUserMedia + chromeMediaSourceId 限制分辨率与帧率,参见 屏幕分享示例

接收端完整示例

ts
import {
  WetRTC,
  applyReceiverPlayoutDelay,
  type SignalChannel,
} from '@wetspace/wetrtc'

declare const signal: SignalChannel
declare const videoEl: HTMLVideoElement

const rtc = new WetRTC({
  signal,
  direction: 'recvonly',
  initiator: true,
  polite: false,
  preferredVideoCodec: 'h264',
})

rtc.on('statechange', (state) => {
  if (state === 'connected') {
    applyReceiverPlayoutDelay(rtc.peerConnection!, 0)
  }
})

rtc.on('track', (ev) => {
  if (ev.streams[0]) {
    videoEl.srcObject = ev.streams[0]
    applyReceiverPlayoutDelay(rtc.peerConnection!, 0)
  }
})

await rtc.connect()

applyReceiverPlayoutDelay(pc, 0)音频与视频接收器的 playoutDelayHint 设为 0,减少 jitter buffer 带来的额外延迟(浏览器支持有限,不支持时静默忽略)。

带音频的场景

若同时共享系统声或麦克风,可叠加 audioEncodingpreferredAudioCodec: 'opus'

ts
const rtc = new WetRTC({
  signal,
  direction: 'sendrecv',
  preferredVideoCodec: 'h264',
  preferredAudioCodec: 'opus',
  videoEncoding: { contentHint: 'motion', maxFrameRate: 30, maxBitrate: 4_000_000 },
  audioEncoding: { maxBitrate: 64_000 },
})

详见 音频编码调优

验证调优效果

ts
rtc.on('stats', (snap) => {
  console.log('codec:', snap.codec)       // 期望 H264
  console.log('fps:', snap.frameRate)
  console.log('rtt:', snap.roundTripTime, 'ms')
})

详见 监控诊断

API 参考

Released under the MIT License.