Screen Studio 的自动缩放与光标平滑:33ms 光标遥测、聚类管线与弹簧闭式解
项目信息
- Screen Studio 官网:https://screen.studio/
- OpenScreen:https://github.com/siddharthvaddem/openscreen
- Capptivo:https://github.com/SECHAK-AG/capptivo
- Recordly 自动缩放实现拆解:https://wangruofeng007.com/blog/2026-09/recordly-auto-zoom-cursor-telemetry/
Screen Studio 是什么
macOS 原生录屏工具,仅支持 macOS,需要 Ventura 13.1+,官方明确没有 Windows/Linux 计划,为 Apple silicon 原生构建。录制对象可以是整个屏幕、单个窗口或指定区域,同时接入 webcam、麦克风、系统声音,自动补缩放、运动、光标平滑、背景与内边距。
采集走系统框架 ScreenCaptureKit,避开大屏下的性能问题。
它和普通录屏工具的关键差异在于:录制屏幕时忽略鼠标光标,光标是在最终视频里再加回来的。因为鼠标移动数据被单独记录并与视频同步,所以录完之后仍能做光标效果——平滑移动、改光标大小/形状、隐藏静止光标。
大量处理在本机完成:转写(本地 Whisper 或 Apple 语音识别)、降噪/播客模式、人脸追踪与抠像、去色带/超分/编码都在 Mac 上跑;云功能可选,且会事先告知。
商业模式在 2025 年 9 月之后对新用户改为纯订阅制:免费下载只能录制和预览,导出需要付费(约 $29/月或 $108/年,早前曾有一次性买断)。
导出侧支持 4K/60fps、优化的 GIF 导出,以及平台预设的横竖屏。
底层框架 ScreenCaptureKit(WWDC22)
整条链路以 SCStream 为中心,配合 SCContentFilter 与 SCStreamConfiguration 创建:
SCContentFilter:窗口过滤器,可跨显示器跟随窗口;也可以按显示器包含/排除 App。SCDisplays:只读属性,含显示标识符、宽高。SCStreamConfiguration:可设置输出分辨率(如 1080p)、最小帧间隔(如 1/60 即 60fps)、showsCursor=false隐藏鼠标光标、capturesAudio加 48kHz/2 声道音频捕获。
窗口捕获做的是硬件缩放,源窗口被遮挡或移出屏幕仍会包含完整内容;窗口最小化时暂停,恢复后继续。
输出帧带 IOSurface 与逐帧元数据:脏矩形(只编码更新区域)、内容矩形、内容比例、比例因数(Retina 2x)。
自动缩放:从光标遥测到缩放区间
以开源 Recordly 的实现为例,这是一个 530 行的纯函数模块,路径 src/components/video-editor/timeline/zoomSuggestionUtils.ts:输入光标遥测,输出一组建议缩放区间。机器的建议永远不会覆盖手动缩放。
遥测格式
定义在 electron/ipc/cursor/telemetry:
- 采样节奏由
CURSOR_SAMPLE_INTERVAL_MS控制,30 Hz 记一次光标位置,约 33ms。 - 坐标是归一化值而不是像素,换分辨率、换窗口不影响回放。
- 样本有上限(注释写的是 1 hour @ 30 Hz)。
- 数据带版本号
CURSOR_TELEMETRY_VERSION(已到 2),存 sidecar,不塞进视频流。
清洗
normalizeCursorTelemetry 负责纠偏:click 之后 160ms 以上、位移超过 1.5% 屏幕的拖拽,把光标类型改写成 text 或 closed-hand;水平位移超过垂直 1.8 倍判为文本选择。
三路候选
显式点击:来自 uiohook 报告的 click / double-click / right-click / middle-click。每个点击往后看 2 秒轨迹,由
classifyPostClickBehavior分类:- 点击后净向下位移超 3%,且垂直位移是水平的 1.5 倍以上 →
dropdown-open - 最大位移不到 2% →
text-field-click - 水平拖拽超 3% 屏宽 →
text-selection
权重:double-click 1500、text-selection 1300、dropdown-open 1200、text-field-click 1100、普通点击 900。
- 点击后净向下位移超 3%,且垂直位移是水平的 1.5 倍以上 →
驻留兜底
detectZoomDwellCandidates:相邻采样位移小于 2% 视为停住,停住 450–2600ms 算候选。两短驻留拼双击:两次都 ≤900ms 驻留、间隔 ≤450ms、空间距离 ≤3.5%,合成一个 double-click-like 事件,权重为两次时长之和 +500。
聚类与输出
buildClickClusters 把间隔 ≤2500ms 的点击并成一簇,簇的焦点取权重最高的点击,否则取质心;每簇前后各垫 500ms padding 生成缩放区间;所有与手动缩放重叠的建议会被跳过。
dwell 与合成双击这两路候选在 buildInteractionZoomSuggestions 入口处被 filter 掉,最终只有显式点击能变成缩放建议——注释里的说法是只信显式交互。
光标平滑:阻尼谐振弹簧的闭式解
motionSmoothing.ts 实现的是阻尼谐振弹簧的闭式解析解,公式 F = −kx − cv(刚度 k、阻尼 c、质量 m)。因为有精确解,三种阻尼状态是可直接选出来的:
- 欠阻尼:过冲回弹
- 临界阻尼:最快收敛且不振荡
- 过阻尼:慢慢逼近
也就是说,那种「跟手但不生硬」的光标,是选定阻尼比之后的解析积分结果,而不是靠调参调出来的黑盒缓动。
架构决策:录制那一刻就把视频变成数据
这套设计的核心不是「录得清楚」或「特效好看」,而是在录制那一刻就把一次性的屏幕活动变成结构化数据:33ms 一次的光标轨迹、点击类型、拖拽方向与时长。
数据存在之后,剩下的问题都换了形态:
- 自动缩放 = 聚类问题
- 光标动画 = 弹簧求解问题
- 循环导出 = 把遥测首尾对齐的问题
编辑器消费的是数据,视频只是数据的渲染结果之一。
开源替代
OpenScreen
https://github.com/siddharthvaddem/openscreen ,MIT,TypeScript / Electron / PixiJS,约 4 万 star,免费商用、无订阅无水印,定位就是 Screen Studio 替代。
macOS 上把录制路由到 ScreenCaptureKit helper(openscreen-screencapturekit-helper),让真实的系统光标不出现在视频帧内;光标位置与位图由 cursor helper 独立捕获,在编辑器和导出管线里合成。
cursor helper 作为 Electron 子进程运行,做五件事:
- 按采样间隔轮询
NSCursor.currentSystem拿 AppKit 系统光标 - 把光标图像编码成 PNG,算 SHA-256 内容哈希作为稳定
assetId - 每个唯一光标形状整场只发一次完整 base64 位图,后续只带
assetId,保持 stdout 体积小 - 用 CGEventTap(listen-only)跟踪左键按下/抬起,给每个样本打
interactionType - 获得辅助功能授权时用 Accessibility API 检测 text/pointer 亲和:文本类角色(
AXTextField/AXTextArea/AXTextView/AXComboBox)返回"text",指针类角色(AXLink/AXButton/AXMenuButton/AXCheckBox/AXTab/AXMenuItem)返回"pointer",其余返回nil,回退到原生位图
main.swift 里的 currentCursorAsset():NSCursor.currentSystem → NSBitmapImageRep → 编码 PNG → SHA256 生成 id。scaleFactor 由 pixelsWide / pointSize.width 推出(Retina 2.0),hotspot 乘 scaleFactor 转成像素;emittedAssetIds: Set 保证同一形状只序列化一次;采样循环包在 autoreleasepool 里,避免长录制内存持续增长。
TS 端的 MacNativeCursorRecordingSession 按行解析事件,唯一资产收进 assets Map,stop() 输出 provider: "native" 或 "none"。数据结构版本 2,字段包括 provider、samples[](归一化 cx/cy、visible、interactionType、可选 assetId/cursorType)、assets[](platform: darwin、hotspot、scaleFactor)。captureSample() 用 OUTSIDE_HIDE_THRESHOLD=3 处理越界样本,置 visible=false。
构建两个 helper:npm run build:native:mac;本地诊断用 OPENSCREEN_MAC_CURSOR_HELPER_EXE 叠加 npm run dev。两条链路可以独立调试:视频侧看 SCK helper 的 warning/error,光标侧看 cursor helper 的 NDJSON 输出与 sidecar 文件。
Capptivo
免费开源 MIT,作者 Abdessamad (idboussadel),仓库 SECHAK-AG/capptivo,v1.0.3(2026-08-05),跨 macOS / Windows / Linux,基于 Tauri(Rust + React + PixiJS)。
macOS 上用 ScreenCaptureKit 采集加 VideoToolbox 硬件 H.264;同时存系统音频和一个 cursor.json(60 Hz 记录光标轨迹和点击事件),所以录完还能改光标样式。时间线上有 zoom fragment,可按点击自动建议缩放,'Z' 手动添加;两类缩放(跟随光标 / 固定区域),转场自动补;内置光标样式、尺寸、运动模糊、点击弹跳、闲置隐藏、光标路径循环;字幕用本机 Whisper。
Recordly
自动缩放实现见 https://wangruofeng007.com/blog/2026-09/recordly-auto-zoom-cursor-telemetry/ 。
横向参考
Loom 是浏览器端、跨平台、面向快速异步分享;Screen Studio 是原生 macOS、产出打磨好的可导出视频文件;内置 QuickTime/系统录屏只支持麦克风、无系统音频、无缩放无光标平滑。
取舍
- macOS only,没有 Windows/Linux 路线图。
- 新买家只剩订阅,没有终身买断。
- 强自动化意味着想要像素级控制缩放时余地受限,且需要 macOS Ventura 13.1+。
- 开源替代(OpenScreen / Capptivo)能覆盖大部分「跟随光标自动缩放 + 光标美化 + 本机字幕」,但多轨精细剪辑仍建议交给专业剪辑器。