跳转到正文

媒体传输与录制 ​

Weblink 将媒体采集、连接协商、解码、显示和录制分开处理。连接成功只完成了这条链路的一部分。浏览器与 Windows 桌面端共用应用流程,但可以使用不同的媒体实现。

从媒体源到画面显示 ​

采集内容经过编码与 WebRTC,由接收端解码呈现。录制按实际来源选择 MediaRecorder 或编码包封装器,两者均通过有界 VFS 写入,停止时完成文件。

上方是实时媒体传输,下方是按实际来源选择的两种录制通路;直接封装编码包时会保留原编码。
阶段处理内容相关限制
采集获取摄像头、麦克风、屏幕或窗口内容系统或浏览器权限,以及来源是否可用
编码将采集内容转为协商好的编码可用编码器、分辨率、帧率和码率
传输通过 WebRTC RTP 传输编码后的媒体直连或 TURN 通路、带宽、丢包与拥塞
解码重建画面或音频采样接收端实际的 WebRTC 解码支持
呈现显示视频并播放音频渲染资源、输出设备与播放策略

控制消息标识媒体来源并协调发布;媒体字节走媒体通路,不放进聊天 JSON。浏览器轨道与协商后的媒体段关联,原生来源还具有平台管理的来源标识。界面中的视频卡片是来源的视图,不拥有其采集或连接生命周期。

房间中的摄像头、麦克风和屏幕发布可以具有独立生命周期。向多个参与者共享会占用发送方的上行资源;信令后端不会混流,也不会为解码能力较弱的接收方转码。

根据实际通路协商编码 ​

发送和接收能力是分开的。浏览器可能提供某种编码器,却没有对应的接收支持;文件播放器支持的格式,也未必出现在浏览器 WebRTC 接收能力中。桌面原生实现还有自己的能力范围,独立于 WebView 的浏览器媒体 API。

自动编码会综合发送端编码器与目标接收端的解码器。原生屏幕和摄像头发布按接收方分别选择,因此不同观看者可以使用不同的兼容格式。手动指定编码,也不能让接收方凭空获得缺失的解码器。选择顺序和硬件偏好见编码、解码与 GPU 显示。

H.265/HEVC 尤其需要区分这些条件。浏览器版本、平台和启用的能力都会影响结果,当前已验证的浏览器情况及适用范围集中在 H.265 兼容性问题。更换信令服务器或增加 TURN 不会把 H.265 转码成其他编码。

Weblink 不只检查 setRemoteDescription() 是否成功。对于屏幕接收会话,如果 answer 拒绝视频段,或协商出无法接收视频的方向,就会被视为不支持的接收通路。这种协商可能正常返回一个 answer,浏览器自身却不抛异常。

协商之后,收到数据包也不等于解码出了画面。解码进度监测可以在仍有网络流量时发现视频停滞。因此,选中某种编码、SDP 接受该编码、实际有解码帧,是三层不同的证据。

浏览器与原生桌面实现 ​

浏览器实现使用浏览器采集、WebRTC 和渲染 API。其编解码可以使用硬件或 CPU,与 GPU 合成显示分别决定,见浏览器媒体链路和加速条件。Windows 桌面实现通过平台适配层同时提供原生发送和原生接收链路,并保留共用的前端和应用服务。

音频具有独立的采集、编解码与播放链路。Windows 系统声音可以通过 WASAPI 进入原生 WebRTC,原生解码音频则经有界 PCM/Web Audio 桥接回到共用播放器。麦克风路径以及浏览器与原生端的区别,见音频采集、编解码与播放。

硬件编码可以消费 D3D11 纹理,硬件解码也可以将纹理直接交给共用的 GPU 呈现层;原生软件解码则上传输出,接入同一个显示层。完整数据流与有条件使用的 CPU 回读,见原生编解码通路。

原生画面呈现使用 GPU 资源,包括 D3D11 纹理与 DirectComposition。有界的最新帧队列避免显示跟不上时不断堆积旧帧。帧资源要保留到 GPU 使用结束,不能仅因为 JavaScript 回调已经返回就立即回收。

原生画面表面与 HTML 控件彼此分开,需要协调来源身份、可见性和清理。DOM 中用于占位的视频元素,本身不是录制来源。这样原生媒体可以使用真实的采集或接收通路,无需强制让每帧经过浏览器画布。

远程输入是另一项受授权保护的操作。显示共享屏幕不授予控制权,有效输入授权也绑定到发起授权的设备和来源。撤销授权或结束会话,会停止对应输入活动。设备身份文章进一步说明这一权限边界。

录制:编码数据与文件容器 ​

一次录制跟随一个选定的视频来源及其关联音频,不会自动把整个会议合成为一个画面。录制服务根据实际来源和平台选择引擎,再通过统一存储服务写入结果。

能够取得编码包时,录制器可以保留原编码,将数据封装进容器。封装只组织已有编码数据,不会通过转换让原本不支持的编码变得可播放。浏览器 MediaRecorder 通路则选择可用的 MIME 类型,并可能使用浏览器自己的编码流程。

对于直接处理编码包的通路,当前自动容器选择规则如下:

已有编码轨道自动选择的容器
G.722 或 G.711 音频(g722、ulaw、alaw)Matroska(.mkv),保留原音频编码
H.264/AVC 或 H.265/HEVC 视频,且不属于上述音频情况MP4(.mp4)
其他支持的视频编码Matroska(.mkv)

浏览器录制器则可能输出 WebM 或其他支持的 MIME 类型,保存的扩展名跟随实际格式。选择 MP4 不意味着所有输入编码都能直接装入其中;修改扩展名也不会改变容器或编码。

原生来源根据实际通路,向录制引擎提供真实的编码媒体,或通过显式像素回读提供输入。界面的生命周期轨道不等于被录制的画面。本地编码来源与接收原生画面的区别,见 GPU 显示与录制。录制任务的归属也独立于设置面板是否显示。

停止与保存 ​

暂停会保留录制引擎和输出文件,同时从录制时间线中排除暂停时段。停止则开始收尾:等待最后的媒体数据、排空待写队列、完成容器元数据,再发布完整文件。

写入器使用有界缓冲,避免目标存储较慢时无限积压数据。完成存储是录制操作的一部分,关闭面板不能代替停止录制。应用在收尾前崩溃,可能留下无法保证正常播放的草稿。

所选保存位置影响新录制;修改默认存储时,已有录制写入器仍使用原挂载点。收到字节与发布完整文件的区别,见存储完成过程。

实现入口 ​

以下路径相对于仓库根目录:

路径职责
apps/web/src/libs/domain/media-codecs.ts编码描述与兼容性判断
apps/web/src/libs/domain/native-screen/屏幕会话协商与解码监测
apps/web/src/libs/application/media-receive-service.ts应用接收生命周期
apps/web/src/libs/application/recording-service.ts录制归属与任务编排
apps/web/src/libs/application/recording-engine.ts通用录制生命周期与浏览器录制器选择
apps/web/src/libs/application/recording-options.ts录制容器与输出格式选择
packages/platform、apps/desktop、crates/desktop-capture平台契约与原生集成

接下来想了解什么? ​

以 MIT 许可证开源 · 为设备之间的连接而构建