Circleback 用 Swift 重写 Electron 录音引擎:界面可以跨平台,实时采集不能只靠渲染进程
据 Circleback 的工程复盘,这家会议记录产品把原先运行在 Electron 渲染进程里的录音引擎迁到原生层:macOS 使用 ScreenCaptureKit,Windows 使用 libobs,并用一套 Swift 运行时连接 React 界面。
作者:周白|OC 产品体验编辑
据 Circleback 的工程复盘,这家会议记录产品把原先运行在 Electron 渲染进程里的录音引擎迁到原生层:macOS 使用 ScreenCaptureKit,Windows 使用 libobs,并用一套 Swift 运行时连接 React 界面。
一句话结论:这不是一次“用原生语言重写更快”的炫技,而是把不能容忍 GC 暂停、页面节流和渲染抖动的实时任务,移回更合适的系统边界。
Circleback 起初尝试过常见补丁:收紧生命周期、把工作移出主线程、减少 React 渲染影响。它们能缓解症状,却改变不了录音与浏览器运行时争夺时序的事实。会议录制里,偶发的一次停顿可能意味着音画漂移、空白帧或整段文件损坏,这和普通 UI 卡顿不是同一等级的问题。
跨平台并没有因此消失,只是换了位置。macOS 端从三个独立来源接收样本,各自带着不同硬件时钟;混音器把时间戳换成全局帧序号,等待两个队列同步输出。如果一个来源停顿超过 500 毫秒,系统临时进入单源模式。对“声称 48kHz、实际却按 44.1kHz 送数据”的虚拟驱动,系统连续观察缓冲节奏后重新解释采样率,并用交叉淡化避免爆音。

Windows 端则把采集、混音、编码和封装交给 libobs 图执行,主要用 Windows Graphics Capture,收不到帧时回退 BitBlt,检测到全黑画面也能中途切换。它牺牲部分细粒度控制,换来成熟管线。
另一个关键选择是 fragmented MP4。普通 MP4 常在文件结尾写关键元数据,崩溃可能让整段录制不可用;分段文件让每段可以独立恢复,Circleback 称崩溃时最多丢失最后约一秒。数据同时写本地和上传云端,网络恢复后继续补传。
为了避免原生层和 React 之间堆满手写胶水,团队制作了 Atomic:Swift 的 @Published 属性经编译期宏导出为 Jotai atom,类型和事件流自动映射。真正降低维护成本的不是 Swift 三个字,而是这条桥让 UI 仍保持熟悉的前端开发体验。
关键事实
- macOS:ScreenCaptureKit 与自建多源混音管线。
- Windows:libobs,WGC 失败时回退 BitBlt。
- 可靠性:fragmented MP4、本地与云端双写、断网续传。
- 交付周期:团队称整个重写在两个月内上线。
OC 判断
Electron 的问题不在“性能一定差”,而在边界用错。产品可以保留跨平台 UI,同时把实时采集、编码和设备时钟交给原生层。Circleback 值得学的,是用清晰接口隔开两种运行时,而不是把一次成功重写概括成“全面去 Electron”。
为什么重要
- 对桌面开发者:实时音视频、系统权限和硬件设备应优先评估原生边界。
- 对产品团队:原生重写只有在桥接成本可控时才不会拖慢迭代。
- 对用户:真正可感知的收益是少丢录音、少漂移、崩溃后可恢复。
评论
围绕这篇文章补充信息、提出问题或分享观察。