20822 star 的开源录屏软件弃 Tauri 换 Electron:表层是换壳,里子是 46 个 Rust 模块

8 月 12 日晚上,Cap 的主维护者 richiemcilroy 提交了一个 PR,标题很短,Migrate from Tauri to Electron。这个项目从 2023 年 11 月写下第一行代码起就押在 Tauri 上,Rust 后端加 SolidJS 前端,三年没动摇过。现在他们决定把整个桌面运行时换成 Electron,理由是各操作系统自带的浏览器内核版本不一,bug 报告源源不断,而 Electron 自带一份稳定的 Chromium。

一个 20822 star 的开源项目,在最核心的架构决策上掉头。

这事本身就值得写一篇。但真去读它的源码之后我发现,换壳只是表层,Cap 真正的故事藏在 Rust 那一层,为了录一块屏幕,他们写了 46 个 crate(Rust 里对独立代码包的叫法),把封装做成了独立进程,还专门写了一个模块去修复已经损坏的录像文件。

先把基本盘交代了。Cap 的定位是开源版 Loom,录屏、本地剪辑、生成分享链接、评论和转录,一整套异步视频协作流程。Loom 在 2023 年被 Atlassian 以约 9.75 亿美元收购,证明了这个品类的商业价值,也留下了数据锁在别人云里的隐忧。Cap 想接住的正是这批在意数据主权的团队,可以接自己的 S3 桶,可以用 Docker Compose 把整个平台自托管,甚至能把分享页面挂在自己的域名下。

录屏这活,比看起来深多了

你想想看,一个录屏软件的需求清单拆开是什么。采集屏幕、采集摄像头、采集麦克风,三条流。macOS 上采集要走 ScreenCaptureKit,Windows 上要走 Windows Graphics Capture 加 Direct3D,摄像头一边是 AVFoundation 一边是 Media Foundation。采集完要编码,编码完要把三条流封装成一个视频文件,然后才有编辑、渲染、导出那一摊事。

每个环节的平台差异都是一座山。这也是为什么 Cap 的 crates 目录会膨胀到 46 个,它不是过度设计,是被平台现实碾出来的。看几个 crate 名字你就明白了,scap-screencapturekit 对应 macOS 采集,scap-direct3d 对应 Windows 采集,camera-avfoundation 和 camera-mediafoundation 各管一边的摄像头,enc-avfoundation、enc-ffmpeg、enc-mediafoundation、enc-gif 是四条编码路径,rendering-skia 负责渲染。采集、编码、封装、渲染、导出,五段流水线,每段再按平台摊开。

拿 macOS 的采集实现说个细节。crates/scap-screencapturekit/src/capture.rs 里,他们用 cidre 这个 Rust 绑定直接对接 ScreenCaptureKit 的 Objective-C 回调,每个回调内部都包了一层 catch_unwind。为什么,因为 Rust 的 panic 一旦穿过 FFI 边界进到 Objective-C 的世界,行为是未定义的,直接崩给你看。这种代码不读源码你永远不知道,README 里一个字不会提。

整个录制管线从上到下串起来是这样一张图,桌面壳层只管界面和系统桥接,录制编排层调度双模式管线,平台采集层按操作系统拆采集后端,编码封装层做进程隔离,最后修复渲染导出层和分享平台层收尾。

封装是另一个进程的事

Cap 架构里我觉得最值得讲的一笔,是 muxer 的位置。

大部分应用的思路是,采集和写文件在同一个进程里跑,简单直接。Cap 的做法是把封装单独拆出去,crates/cap-muxer 是一个独立的可执行文件,录制进程把编码后的帧通过管道喂给它,两边用 cap-muxer-protocol 这个 crate 约定一套带帧头的协议通信。

拆出去图什么,看 main.rs 里的退出码就懂了。EXIT_PROTOCOL_ERROR 是 10,EXIT_FFMPEG_ERROR 是 20,EXIT_INIT_ERROR 是 30,EXIT_ABORT 是 40,EXIT_BAD_STATE 是 50,最扎眼的是 EXIT_DISK_FULL,专门占了个 60。磁盘写满是录屏软件的经典死法,封装进程崩了,录制进程还活着,至少能知道发生了什么、已经录到哪了。这是拿进程边界换崩溃隔离,muxer 炸了不至于把整个录制会话拖进坟墓。

已经坏掉的录像,也要救回来

如果说进程隔离是事前设防,那 crates/recording/src/track_heal.rs 就是事后抢救,这个文件值得整段讲。

它的模块注释写了一段生产环境的血泪史。有些视频源会以超过标称帧率的速度吐帧,Windows 的 WGC 采集在高刷新率显示器上就是这样,一台 165Hz 的显示器,实际投递帧率冲到标称的两倍多,封装时还按 30fps 打时间戳,结果就是视频慢放 2.24 倍,音画彻底脱节。另一路坑是 AVFoundation 的摄像头,标称 30fps 实际跑 60fps,camera.mp4 同样被拉长。录制侧的 bug 后来修了,但用户磁盘上已经躺着一批坏录像,怎么办。

他们的答案是这个 track heal 模块,在编辑器打开项目的时候检测这些坏轨道的特征签名,然后无损地重写时间戳,把视频救回来。甚至处理了同一个项目被并发打开的竞态,用一个进程内的 HealInFlightGuard 保证同一时间只有一次修复在跑。

同目录下还有个 sync_calibration.rs,思路一脉相承。音画同步不靠录的时候硬对齐,而是录完之后做分析,SyncAnalyzer 配合 calculate_frame_motion_score 算帧间运动分数去校准偏移,再把每个设备的校准结果存进 CalibrationStore。下次用同一个摄像头配同一个麦克风,偏移直接查表。这是把媒体工程当测量问题在做。

坦白讲,读到这里我对这个项目的观感变了很多。一个录屏软件肯为「已经发生且不可逆的损坏」写专门的修复代码,说明团队真的被用户的真实损失教育过。

两个模式,两种取舍

产品层面 Cap 分了 Instant 和 Studio 两种录制模式。Instant 模式边录边传,crates/recording/src/fragmentation/ 目录下是一套分片加 manifest 的机制,录制切成片段推进上传队列,停录的瞬间链接就能用。Studio 模式则全部落在本地,recording crate 里 instant_recording.rs 和 studio_recording.rs 是两条独立的管线,后者接完整的编辑器,背景、缩放、裁剪、字幕,最后按需导出。

一个求快,一个求好,中间不搞妥协的混合态,这个产品判断我觉得比很多「智能模式」式的和稀泥强。

三年 Tauri,一朝 Electron

回到开头那个 PR。

richiemcilroy 给出的迁移理由没有绕弯子,各操作系统自带的 WebView 版本碎片化,导致同样的代码在不同系统 release 上行为不一致,这类 bug 报告他们收到手软。Electron 虽然背着内存占用大的骂名,但它捆绑一份固定的 Chromium,跨版本一致性是买断的。迁移方案保留了 Rust 后端和现有 UI,只替换运行时和桥接层,新增的 apps/desktop/electron/backend.cjs 负责拉起 Rust 后端并通过 framed localhost transport 通信,Rust 那一侧对应 crates/desktop-runtime/src/transport.rs。PR 的验证清单写着 Rust 检查、clippy 和 141 个测试。

这事对 Tauri 生态不是好消息,但对选型中的人是个提醒,WebView 的「轻」是用一致性换的,桌面媒体应用对渲染行为的确定性要求极高时,这笔账要重新算。

顺带一提这个 PR 的评论区,挺有时代特色的。richiemcilroy 对着 AI 代码审查机器人 greptile 连发了 17 次 re-review 请求,时间从 8 月 13 日凌晨一直排到 14 日中午。再看贡献者榜,第一名 richiemcilroy 本人 6078 次贡献,第二名 Brendonovich 1018 次,而第五名是一个叫 cursoragent 的账号,93 次。一个 AI 编程代理排进了核心贡献者,这个项目大概是目前「AI 协作开发」浓度最高的明星项目之一。

该省着信的地方

夸了这么多,轮到泼冷水。

先看定价页。免费版功能很全,本地录制、完整编辑器、4K 60fps 导出都有,但分享链接单条限 5 分钟。宣传语里的 AI 标题、摘要、可点击章节、转录,全部锁在 Pro 计划里,每人每月 12 美元,而且这些 AI 能力依赖云端,自托管用户想用还得自己配 AI provider。所谓开源,开的是客户端和平台框架,云上增值那部分是闭源的,这是标准的 commercial open source 打法,不丢人,但要看清。

协议上也有讲究。LICENSE 是 AGPLv3,但 cap-camera 和 scap 两个系列的 crate 单独以 MIT 发布。这个拆分很见心思,采集和封装这些下游可能复用的基础件放出去换生态,业务主体留在 AGPL 后面挡商业化白嫖。你要是想把 Cap 的代码嵌进自己的闭源产品,基本没有合规路径,只能走 API 或自托管。

最悬的其实是人。6078 对 1018 的贡献分布,bus factor 是肉眼可见的 1。好消息是项目足够活跃,0.5.9 版本 8 月 11 日刚发,7 月连发两版,节奏稳定在两到四周一个 release,Algora 上挂着公开悬赏吸外部贡献。坏消息是,一个还没盈利验证的开源公司,命脉系于一人。

另外 README 里轻描淡写提了一句分析功能依赖 Tinybird,自托管想完整复刻 viewer analytics 还得再去接一家第三方服务,这属于文档里不细说的隐藏成本。

不可重放的事件流

拆完 Cap,我一直在想它给我的最大启发是什么,想来想去是这四个字,不可重放。

录屏和普通应用的根本区别在于,用户按下的每一秒录制都是一次性事件流,崩了不能重录,同步错了不能重来,磁盘满了不能撤销。所以你会看到 Cap 的工程重心几乎全押在「出错之后怎么办」上,封装拆进程换隔离,退出码分六档让父进程有得判断,加载时修复救存量坏数据,按设备存校准做增量纠偏。

这套思路是可以带走的。任何处理「单次不可重来」数据的系统,直播推流、面试录音、行车记录仪、交易日志,都值得把防御工事从「避免出错」往「出错后保住多少」倾斜一档。Cap 用 46 个 crate 证明了一件事,录屏软件的护城河不在按钮和滤镜,在那些你永远希望用不上、但出事时救命的一层层兜底里。

至于 Tauri 到 Electron 的转身,我倒觉得没什么惋惜的。技术选型本来就该跟着真实 bug 报告走,而不是跟着社区声量走。三年前选 Tauri 是对的,今天换 Electron 也是对的,能大大方方承认框架的局限并付出行动,比死守立场体面多了。

相关推荐
CAD老兵3 小时前
一行代码集成 DWG/DXF 图纸查看:测量批注,数据不出站
前端·javascript·github
zh_xuan5 小时前
github搭建个人主页
html·github
fthux6 小时前
装闭 RenoPit 源码解析(10):AI如何审查装修合同与报价单
人工智能·ai·开源·github·open source·renopit
TunerT_TQ6 小时前
Google|LangExtract 源码静态评测:从 90 个 Python 文件看大模型结构化信息抽取工程基础
google·开源·github
Vuhao7 小时前
DeepSeek Harness:我 vibe coding 一个会陪你的桃濑日和
开源·github
Jay-r7 小时前
DeepSeek Harness 极简上手:装好、玩熟、让它自己长新能力
人工智能·windows·ai·github·ai编程·deepseek·harness
CAD老兵10 小时前
让 AI Coding Agent 直接访问 CAD 文档:GitMCP 实战指南
前端·人工智能·github
Revolution6110 小时前
DeepSeek Harness 最近上线:Everything is a Plugin 有什么特别之处
llm·github·deepseek
fthux20 小时前
装闭 RenoPit 源码解析(09):AnalysisEngine装修闭坑分析主流程
人工智能·ai·开源·github·open source·renopit