FreeCut 浏览器视频剪辑器架构解析:features/runtime/infrastructure/shared 四层设计与功能边界之道
【免费下载链接】freecutFreeCut is a professional-grade video editor that runs entirely in your browser. Professional video editing, zero installation. Create stunning videos with multi-track editing, keyframe animations, real-time preview, and high-quality exports.项目地址: https://gitcode.com/gh_mirrors/free/freecut
FreeCut 是一款完全运行在浏览器里的专业视频剪辑工具,支持多轨剪辑、关键帧动画、实时预览与高质量导出。它的代码库用一套清晰的四层架构——features、runtime、infrastructure、shared——把上千个源文件组织得井井有条,并配有一套自动化脚本守护"功能边界",让新功能可以安全落地、老功能不被悄悄污染。本文将带你用最短的时间读懂这套设计。
先看全貌:四层架构一张表
在src/目录下,FreeCut 按职责划分了四个核心区域,各层关系可以概括为"上层调用下层,功能之间不越界":
| 层级 | 目录 | 核心职责 | 典型内容 |
|---|---|---|---|
| 功能层 | src/features/ | 按剪辑域划分的产品功能 | 时间线、预览、关键帧、导出、媒体库 |
| 运行时层 | src/runtime/ | 播放与合成的"引擎" | 组合运行时、播放器时钟 |
| 基础设施层 | src/infrastructure/ | GPU、存储、AI 等底层能力 | WebGPU 管线、OPFS 存储、场景检测 |
| 共享层 | src/shared/ | 跨功能复用的工具与状态 | 时间工具、缓动曲线、状态管理 |
这套分层的直观效果是:当你想改动"关键帧动画"时,只需在 src/features/keyframes/ 内打转;而它依赖的 GPU 效果与工具函数,则被隔离在各自负责的层里。
功能层 src/features:按剪辑域切分,改一处不影响全身
src/features/是产品功能的"主战场",每个子目录就是一个独立的剪辑域:时间线(timeline/)、预览(preview/)、关键帧(keyframes/)、导出(export/)、媒体库(media-library/)、场景浏览器(scene-browser/)等。
以时间线为例,src/features/timeline/ 内部自己又分成stores/(状态)、hooks/(React 钩子)、components/(界面)、utils/(纯逻辑)、services/(服务)五个子目录——一个功能的"脑、手、脸"全部自包含。
功能层最大的特点是:功能与功能之间不能直接互相 import。这是 FreeCut 架构边界的第一道铁律,也是它能在功能越做越多的情况下保持可维护性的关键。
运行时层 src/runtime:帧级精确播放的"引擎舱"
src/runtime/ 只承载两样东西:composition-runtime/(组合运行时)和player/(播放器)。
为什么单独拎出来?因为视频剪辑最核心的体验是"帧级精确"——播放、拖拽、回看都必须精确到帧。这一层封装了自定义的Clock时钟机制与合成运行时,负责把多个轨道上的图层、效果、转场按帧调度起来。它只暴露稳定的接口给功能层调用(例如 editor 通过 composition-runtime-contract.ts 访问它),而功能层无需关心底层如何驱动画面。
简单类比:runtime就像汽车发动机舱,你只需要踩油门(调用接口),不必了解活塞怎么运动。
基础设施层 src/infrastructure:GPU 与本地 AI 的"地基"
FreeCut 的"硬功夫"——WebGPU 效果、WebCodecs 解码、OPFS 本地存储、本地 AI 分析——全部沉在 src/infrastructure/ 这一层:
- GPU 系列:
gpu-effects/(模糊、调色、扭曲等效果管线)、gpu-transitions/(转场)、gpu-scopes/(波形/矢量示波器)、gpu-compositor/(合成) - 存储:
storage/workspace-fs/把工程、缩略图、波形、字幕全部写成磁盘上的普通文件,做到"本地优先、零上传" - AI 分析:
analysis/(场景检测、字幕生成)、llm/、interpolation/(补帧)
把这类重资源、强技术约束的能力单独分层后,功能层只需"点菜",而不必理解 GPU 管线细节——将来更换实现(比如 WebGPU 降级到 Canvas),改动被锁在这一层内。
共享层 src/shared:小而精的"公共工具箱"
src/shared/ 存放被多个功能共同依赖的通用能力:utils/(时间换算 time-utils.ts、缓动 easing.ts、音频处理)、state/(跨组件状态)、timeline/(时间线通用逻辑,如转场、标注)、typography/(文字排版)。
判断一段代码该不该进 shared 的简单标准:至少两个功能层需要它。只被单一功能使用的工具,就应该留在该功能自己的目录里——这正是四层设计"防止 shared 变垃圾场"的内建纪律。
功能边界:靠 deps 契约 + 自动脚本守护
FreeCut 的"功能边界"不靠口头约定,而由两部分机制强制执行:
1. deps 契约模式(单一导入缝)
功能 A 想用功能 B 的能力时,必须经过src/features/A/deps/下的契约模块。例如 editor 访问 timeline 的入口是 timeline-contract.ts,它注释写着"Single import seam for editor -> timeline"(editor 到 timeline 的唯一导入缝),再由 timeline.ts 适配器把 store、hooks、UI 等聚合导出。
2. 自动边界检查脚本
仓库用 CI 脚本持续"巡边":
- check-feature-boundaries.mjs:扫描所有 features 文件,一旦发现功能间的直接跨目录 import(绕过 deps),立即报错并列出违规文件
- check-feature-edge-budgets.mjs:为每条"合法依赖边"设定预算,例如
editor -> timeline最多允许 73 处导入、2 个文件,超了就要回炉重构——防止某条依赖边悄悄膨胀 - check-legacy-lib-imports.mjs、check-deps-contract-boundaries.mjs:继续堵住其他绕行路径
这套"契约 + 预算 + 自动检查"的组合拳,让四层架构在团队与时间推进中不腐化,新人也能放心改动。
新手代码导读:5 分钟找到你想看的模块
| 你想看什么 | 去哪里 |
|---|---|
| 剪辑主界面如何拼装 | src/features/editor/ 与 src/routes/ |
| 时间线交互与状态 | src/features/timeline/ |
| 关键帧与贝塞尔曲线 | src/features/keyframes/ |
| 导出与渲染队列 | src/features/export/ |
| 播放/合成引擎 | src/runtime/ |
| GPU 效果与本地 AI | src/infrastructure/ |
| 边界规则如何落地 | scripts/ 下的 check-feature-* 脚本 |
总结
FreeCut 的四层架构可以浓缩成三句话:
features管产品,runtime管引擎,infrastructure管硬件,shared管复用——每一层只回答自己领域的问题。- 功能之间必须走
deps/契约,禁止直接跨功能 import,让"editor 改了 timeline 会崩"这类问题在设计上就难以发生。 - 自动脚本持续巡边 + 依赖预算,把架构纪律从"靠自觉"变成"靠 CI"。
对于想深入 FreeCut 源码的新手,记住一条主线就够了:从一个功能(如timeline)入手,看它自己的 stores/hooks/utils,再看它通过deps/契约向外伸出的每一根"线"——你就能快速建立起对整个浏览器视频剪辑器架构的全局认知。
【免费下载链接】freecutFreeCut is a professional-grade video editor that runs entirely in your browser. Professional video editing, zero installation. Create stunning videos with multi-track editing, keyframe animations, real-time preview, and high-quality exports.项目地址: https://gitcode.com/gh_mirrors/free/freecut
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考