屏幕分享
使用 WetRTC 实现屏幕分享功能。若只想在浏览器中体验桌面捕获,可先查看 桌面媒体捕获。
需要降低操作延迟时,请参阅 低延迟屏幕共享。
生产级参考
Electron + Socket.IO + 手机接收的完整实现见 virt-screen 集成示例(提炼自 virt-screen/ 源码,含双端 initiator/polite 配对与信令事件表)。
发送端
ts
import { WetRTC, type SignalChannel } from '@wetspace/wetrtc'
declare const signal: SignalChannel
const rtc = new WetRTC({
signal,
direction: 'sendonly',
logLevel: 'info',
})
const screenStream = await rtc.media.getDisplayMedia({
width: 1920,
height: 1080,
frameRate: 30,
audio: true,
})
for (const track of screenStream.getTracks()) {
rtc.addTrack(track, screenStream)
}
screenStream.getVideoTracks()[0].addEventListener('ended', () => {
console.log('屏幕分享已停止')
rtc.disconnect()
})
await rtc.connect()接收端
ts
import { WetRTC, type SignalChannel } from '@wetspace/wetrtc'
declare const signal: SignalChannel
declare const remoteVideo: HTMLVideoElement
const rtc = new WetRTC({
signal,
direction: 'recvonly',
})
rtc.on('track', (ev) => {
remoteVideo.srcObject = ev.streams[0]
})
await rtc.connect()低延迟配置
发送端与接收端可组合 videoEncoding、preferredVideoCodec 与 applyReceiverPlayoutDelay:
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()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()Electron 屏幕分享
在 Electron 中使用 desktopCapturer 获取屏幕源:
ts
// main process
import { desktopCapturer } from 'electron'
const sources = await desktopCapturer.getSources({ types: ['screen'] })
// renderer process
declare const rtc: import('@wetspace/wetrtc').WetRTC
const sourceId = sources[0].id
const screenStream = await rtc.media.getDisplayMedia({
sourceId,
audio: false,
})