Skip to content

MediaManager

媒体管理子系统,提供设备枚举、本地媒体采集、屏幕分享和远端流管理。通过 rtc.media 访问。

导入

ts
import { MediaManager } from '@wetspace/wetrtc'

可通过 rtc.media 调用实例方法,也可直接使用 MediaManager 静态方法(无需建立 WebRTC 连接):

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

declare const signal: SignalChannel

// 方式一:通过 WetRTC 实例访问(rtc.media)
const rtc = new WetRTC({ signal })
const devices = await rtc.media.enumerateDevices()

// 方式二:MediaManager 静态方法(无需建立连接)
const previewStream = await MediaManager.getUserMedia({
  video: { width: 1280, height: 720 },
  audio: true,
})

方法

enumerateDevices()

ts
enumerateDevices(): Promise<DeviceInfo[]>

枚举可用媒体设备。

加载交互 Demo…
ts
import { MediaManager } from '@wetspace/wetrtc'

// 通过 WetRTC 实例(rtc.media)
// const devices = await rtc.media.enumerateDevices()

// 静态调用,无需创建实例
const devices = await MediaManager.enumerateDevices()
// [{ deviceId, groupId, kind: 'videoinput', label: '摄像头' }, ...]

const total = devices.length
const cameras = devices.filter(d => d.kind === 'videoinput').length
const mics = devices.filter(d => d.kind === 'audioinput').length
const speakers = devices.filter(d => d.kind === 'audiooutput').length

console.log(`共 ${total} 个设备:摄像头 ${cameras}、麦克风 ${mics}、扬声器 ${speakers}`)

getUserMedia()

ts
getUserMedia(constraints?: MediaConstraints): Promise<MediaStream>

获取本地媒体流(摄像头 + 麦克风)。

加载交互 Demo…
ts
import { MediaManager } from '@wetspace/wetrtc'

// 摄像头 + 麦克风(静态调用,无需 WetRTC 实例)
const stream = await MediaManager.getUserMedia({
  video: { width: 1280, height: 720 },
  audio: true,
})
// 或在连接实例上:await rtc.media.getUserMedia({ ... })

// 绑定到 video 预览(含音频轨时可同时播放声音)
const video = document.querySelector('video')!
video.srcObject = stream
await video.play()

// 仅音频
const audioStream = await MediaManager.getUserMedia({ audio: true })

// 添加到 WebRTC 连接(rtc 为 WetRTC 实例)
// for (const track of stream.getTracks()) {
//   rtc.addTrack(track, stream)
// }

getDisplayMedia()

ts
getDisplayMedia(options?: DisplayMediaOptions): Promise<MediaStream>

获取屏幕分享流。浏览器使用 getDisplayMedia,Electron 需传入 sourceId

加载交互 Demo…
ts
import { MediaManager } from '@wetspace/wetrtc'

// 通过 WetRTC 实例
// const stream = await rtc.media.getDisplayMedia({ audio: true })

// 浏览器:弹出屏幕/窗口选择器
const stream = await MediaManager.getDisplayMedia({
  width: 1920,
  height: 1080,
  frameRate: 30,
  audio: true,
})

// Electron:传入 desktopCapturer 的 sourceId
const electronStream = await MediaManager.getDisplayMedia({
  sourceId: 'screen:0:0',
  audio: false,
})

addTrack()

ts
addTrack(track: MediaStreamTrack, stream: MediaStream): void

添加本地 track。通常配合 getUserMedia / getDisplayMedia 获取的流使用。

removeTrack()

ts
removeTrack(track: MediaStreamTrack): void

移除本地 track。

replaceTrack()

ts
replaceTrack(oldTrack: MediaStreamTrack, newTrack: MediaStreamTrack): void

替换本地 track 记录。若需要同步替换底层 sender,优先使用 rtc.replaceTrack()

ts
// rtc 为 WetRTC 实例

// 添加本地 track 到连接
const stream = await rtc.media.getUserMedia({ video: true, audio: true })
for (const track of stream.getTracks()) {
  rtc.addTrack(track, stream)
  // 等价于 rtc.media.addTrack(track, stream)
}

// 停止并移除某个 track
const videoTrack = stream.getVideoTracks()[0]
rtc.removeTrack(videoTrack)

// 替换 track(仅更新 MediaManager 记录;同步 sender 请用 rtc.replaceTrack)
const newStream = await rtc.media.getUserMedia({ video: { facingMode: 'user' } })
const newTrack = newStream.getVideoTracks()[0]
rtc.media.replaceTrack(videoTrack, newTrack)

addRemoteStream()

ts
addRemoteStream(stream: MediaStream): void

添加远端流(内部由 track 事件自动调用)。

getRemoteStreams()

ts
getRemoteStreams(): ReadonlyMap<string, MediaStream>

获取所有远端媒体流。

ts
// rtc 为 WetRTC 实例;remoteVideo 为 HTMLVideoElement

// 远端流通常由 track 事件自动注册,也可手动添加
rtc.on('track', (ev) => {
  const remoteStream = ev.streams[0]
  remoteVideo.srcObject = remoteStream
})

// 手动添加远端流
rtc.media.addRemoteStream(remoteStream)

// 获取所有远端流
const remoteStreams = rtc.media.getRemoteStreams()
for (const [id, stream] of remoteStreams) {
  console.log(id, stream.getTracks().map(t => t.kind))
}

dispose()

ts
dispose(): void

停止所有本地流并释放资源。

ts
// rtc 为 WetRTC 实例

// 停止所有本地流并释放 MediaManager 资源
rtc.media.dispose()

// 断开整个 WetRTC 连接时会自动调用各子系统的 dispose
await rtc.disconnect()

类型

ts
interface DeviceInfo {
  deviceId: string
  groupId: string
  kind: MediaDeviceKind
  label: string
}

interface DisplayMediaOptions {
  sourceId?: string
  audio?: boolean
  width?: number
  height?: number
  frameRate?: number
}

interface MediaConstraints {
  audio?: boolean | MediaTrackConstraints
  video?: boolean | MediaTrackConstraints
}

Released under the MIT License.