From fd5627270fcacdcd1653f8e912de2d85bba71c49 Mon Sep 17 00:00:00 2001 From: Vincent-Mac Date: Thu, 9 Jul 2026 23:21:59 +0800 Subject: [PATCH 1/5] =?UTF-8?q?docs(zh):=20=E6=B7=BB=E5=8A=A0=20README?= =?UTF-8?q?=E3=80=81=E9=A1=B9=E7=9B=AE=E6=A6=82=E8=A7=88=E5=8F=8A=E6=8A=80?= =?UTF-8?q?=E8=83=BD=E6=96=87=E6=A1=A3=E4=B8=AD=E6=96=87=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为中文用户提供本地化文档,包括 README_zh、项目概览,以及 skills 目录下各技能的中文版本。 Co-authored-by: Cursor --- README_zh.md | 286 ++++++++ docs/project-overview.md | 632 ++++++++++++++++++ .../adapters/animejs-zh.md | 114 ++++ .../adapters/css-animations-zh.md | 124 ++++ .../hyperframes-animation/adapters/gsap-zh.md | 240 +++++++ .../adapters/lottie-zh.md | 112 ++++ .../adapters/three-zh.md | 106 +++ .../adapters/typegpu-zh.md | 174 +++++ .../adapters/waapi-zh.md | 94 +++ skills/hyperframes-cli/SKILL_zh.md | 140 ++++ skills/hyperframes-registry/SKILL_zh.md | 104 +++ .../references/SKILL_zh.md | 211 ++++++ skills/hyperframes/SKILL_zh.md | 491 ++++++++++++++ skills/media-use/SKILL_zh.md | 243 +++++++ skills/remotion-to-hyperframes/SKILL_zh.md | 120 ++++ skills/tailwind/SKILL_zh.md | 148 ++++ skills/website-to-video/SKILL_zh.md | 140 ++++ 17 files changed, 3479 insertions(+) create mode 100644 README_zh.md create mode 100644 docs/project-overview.md create mode 100644 skills/hyperframes-animation/adapters/animejs-zh.md create mode 100644 skills/hyperframes-animation/adapters/css-animations-zh.md create mode 100644 skills/hyperframes-animation/adapters/gsap-zh.md create mode 100644 skills/hyperframes-animation/adapters/lottie-zh.md create mode 100644 skills/hyperframes-animation/adapters/three-zh.md create mode 100644 skills/hyperframes-animation/adapters/typegpu-zh.md create mode 100644 skills/hyperframes-animation/adapters/waapi-zh.md create mode 100644 skills/hyperframes-cli/SKILL_zh.md create mode 100644 skills/hyperframes-registry/SKILL_zh.md create mode 100644 skills/hyperframes-registry/references/SKILL_zh.md create mode 100644 skills/hyperframes/SKILL_zh.md create mode 100644 skills/media-use/SKILL_zh.md create mode 100644 skills/remotion-to-hyperframes/SKILL_zh.md create mode 100644 skills/tailwind/SKILL_zh.md create mode 100644 skills/website-to-video/SKILL_zh.md diff --git a/README_zh.md b/README_zh.md new file mode 100644 index 0000000000..52a48f5067 --- /dev/null +++ b/README_zh.md @@ -0,0 +1,286 @@ +

+ + + + HyperFrames + +

+ +

+ npm version + npm downloads + License + Node.js + Discord +

+ +

编写 HTML。渲染视频。为 Agent 而生。

+ +

+ 快速入门 | + 作品展示 | + Playground | + 目录 | + 文档 | + Discord +

+ +

+ HyperFrames 演示:左侧 HTML 代码转换为右侧渲染视频 +

+ +HyperFrames 是一个开源框架,可将 HTML、CSS、媒体与可寻址动画(seekable animations)转换为确定性的 MP4 视频。你可以在本地通过 CLI 使用,通过 AI 编程 Agent 配合 skills 使用,或作为托管创作工作流背后的渲染核心。 + +## 快速入门 + +### 使用 AI 编程 Agent + +安装 HyperFrames skills,然后描述你想要的视频: + +```bash +npx skills add heygen-com/hyperframes +``` + +可以尝试这样的提示词: + +> 使用 `/hyperframes`,创建一个 10 秒的产品介绍视频,包含淡入标题、背景视频和轻柔的背景音乐。 + +这些 skills 会教 Agent 掌握 HyperFrames 的制作流程:规划视频、编写合法 HTML、接入可寻址动画、添加媒体、lint、预览和渲染。它们适用于 Claude Code、Cursor、Gemini CLI、Codex 以及其他支持 skills 的编程 Agent。 + +关于视觉设计交接工作流,请参阅 [Claude Design 指南](https://hyperframes.heygen.com/guides/claude-design) 和 [Open Design 指南](https://hyperframes.heygen.com/guides/open-design)。 + +### 手动使用 CLI + +```bash +npx hyperframes init my-video +cd my-video +npx hyperframes preview # preview in browser with live reload +npx hyperframes render # render to MP4 +``` + +**要求:** Node.js 22+、FFmpeg + +## 你可以构建什么 + +需要灵感?浏览 [作品展示](https://hyperframes.heygen.com/showcase),观看、阅读、运行并改编已完成的视频。 + +- 产品发布视频与功能公告 +- 带动画代码 diff、旁白和字幕的 PR 演示 +- 数据可视化、图表竞赛与地图动画 +- 带动态字幕、叠加层和音乐的社会化视频 +- 文档转视频、PDF 转视频、网站转视频讲解 +- 用于自动化内容流水线的可复用动态图形 + +## Frame.md + +**frame.md — 你的设计系统,已为视频就绪。** + +每个品牌都有 `design.md`,但都不是为镜头而写。`frame.md` 是缺失的转换层:它接收你的 Web 上下文设计规范,并为画面(frame)做反向适配——同样的 token、同样的规则,但重写后 AI Agent 可以创作宣传视频,而无需猜测缩放或依赖 Web 界面元素。 + +输出是整套工具链都能读取的 `DESIGN.md` 超集。原子级元素保持神圣不可侵犯。构图保持自由。数值来自脚本。 + + + + + + + + + + + + + + + + + + + + + + +
+ Biennale Yellow +
Biennale Yellow +
+ BlockFrame +
BlockFrame +
+ Blue Professional +
Blue Professional +
+ Bold Poster +
Bold Poster +
+ Broadside +
Broadside +
+ Capsule +
Capsule +
+ Cartesian +
Cartesian +
+ Cobalt Grid +
Cobalt Grid +
+ Coral +
Coral +
+ Creative Mode +
Creative Mode +
+ +在 [hyperframes.dev/design](https://www.hyperframes.dev/design) 浏览并改编全部模板。 + +## 工作原理 + +将视频定义为 HTML。用 data 属性标注时间与轨道。使用 GSAP、CSS、Lottie、Three.js、Anime.js、WAAPI 或你自己的 frame adapter 实现可寻址动画。 + +```html +
+ + +

Launch day

+ + + + + +
+``` + +在浏览器中即时预览。在本地或 Docker 中渲染。渲染器在无头 Chrome 中逐帧寻址,并用 FFmpeg 编码结果,因此相同输入产生相同视频。 + +## HyperFrames 技术栈 + +HyperFrames 是开源渲染引擎,以及围绕 HTML 原生视频创作的一整套不断扩展的工具。 + +| 组件 | 状态 | 功能说明 | +| ----------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------- | +| CLI | 可用 | 搭建、预览、lint、检查并渲染本地视频项目 | +| Core / Engine / Producer | 可用 | 解析合成、驱动无头 Chrome、编码视频并混音 | +| Catalog | 可用 | 可复用的 blocks 与 components:转场、叠加层、字幕、图表、地图与特效 | +| Agent skills | 可用 | 教编程 Agent 掌握通用 Web 文档未涵盖的视频制作模式 | +| Studio | 可用,持续演进 | 用于预览与编辑合成的浏览器界面 | +| AWS Lambda rendering | 可用 | 部署分布式渲染栈,从笔记本或 CI 驱动渲染 | +| [hyperframes.dev](https://www.hyperframes.dev/) | 可用 | 社区 Playground:预览、迭代、分享并渲染 HTML 原生视频项目 | +| [frame.md](https://www.hyperframes.dev/design) | 可用 | 将设计系统反向适配为镜头语言——Agent 可据此创作视频的 DESIGN.md 超集 | + +## 目录 + +安装即用 blocks 与 components: + +```bash +npx hyperframes add flash-through-white # shader transition +npx hyperframes add instagram-follow # social overlay +npx hyperframes add data-chart # animated chart +``` + +在 [hyperframes.heygen.com/catalog](https://hyperframes.heygen.com/catalog/blocks/data-chart) 浏览目录。 + +## 为什么选择 HyperFrames? + +- **HTML 原生:** 合成即带 data 属性的 HTML 文件。无需 React,无专有时间线格式。 +- **Agent 友好:** Agent 本来就会写 HTML,且 CLI 默认非交互式。 +- **确定性:** 相同输入、相同帧、相同输出。为 CI、回归测试与自动化渲染而设计。 +- **无构建步骤:** `index.html` 合成可直接播放,并在浏览器中直接预览。 +- **基于适配器的动画:** 支持 GSAP、CSS 动画、Lottie、Three.js、Anime.js、WAAPI 或自定义运行时。 +- **开源:** Apache 2.0 许可证,无按次渲染费用或商业使用门槛。 + +## HyperFrames vs Remotion + +HyperFrames 受 [Remotion](https://www.remotion.dev) 启发。两者都用无头 Chrome 与 FFmpeg 渲染视频。主要区别在于创作模型:Remotion 押注 React 组件;HyperFrames 押注人类与 Agent 都能轻松编写的纯 HTML。 + +| | **HyperFrames** | **Remotion** | +| ------------------------ | ------------------------------------- | --------------------------------------- | +| 创作方式 | HTML + CSS + 可寻址动画 | React 组件 | +| 构建步骤 | 无;`index.html` 可直接播放 | 需要打包工具 | +| Agent 交接 | 纯 HTML 文件 | JSX / React 项目 | +| 库时钟动画 | 通过适配器可寻址、逐帧精确 | 墙钟动画模式需额外注意 | +| 分布式渲染 | 本地与 AWS Lambda 渲染路径 | Remotion Lambda,成熟的云渲染器 | +| 许可证 | Apache 2.0 | 源码可用的 Remotion License | + +完整对比见 [HyperFrames vs Remotion 指南](https://hyperframes.heygen.com/guides/hyperframes-vs-remotion)。 + +## 文档 + +完整文档:[hyperframes.heygen.com/introduction](https://hyperframes.heygen.com/introduction) + +- [快速入门](https://hyperframes.heygen.com/quickstart) +- [作品展示](https://hyperframes.heygen.com/showcase) +- [指南](https://hyperframes.heygen.com/guides/gsap-animation) +- [API 参考](https://hyperframes.heygen.com/packages/core) +- [目录](https://hyperframes.heygen.com/catalog/blocks/data-chart) +- [示例](https://hyperframes.heygen.com/examples) +- [AWS Lambda 渲染](https://hyperframes.heygen.com/deploy/aws-lambda) + +## 软件包 + +| 软件包 | 说明 | +| ---------------------------------------------------------------- | ----------------------------------------------------------------- | +| [`hyperframes`](packages/cli) | 用于创建、预览、lint 与渲染合成的 CLI | +| [`@hyperframes/core`](packages/core) | 类型、解析器、生成器、linter、运行时与 frame adapters | +| [`@hyperframes/engine`](packages/engine) | 基于 Puppeteer 与 FFmpeg 的可寻址页面到视频捕获引擎 | +| [`@hyperframes/producer`](packages/producer) | 完整渲染流水线:捕获、编码与音频混音 | +| [`@hyperframes/studio`](packages/studio) | 基于浏览器的合成编辑器 UI | +| [`@hyperframes/player`](packages/player) | 可嵌入的 `` Web 组件 | +| [`@hyperframes/shader-transitions`](packages/shader-transitions) | 用于合成的 WebGL shader 转场 | +| [`@hyperframes/aws-lambda`](packages/aws-lambda) | 用于分布式渲染的 AWS Lambda SDK 与部署面 | + +## 社区 + +HyperFrames 已在 [HeyGen](https://www.heygen.com) 投入生产使用;[tldraw](https://tldraw.com)、[TanStack](https://tanstack.com) 等团队的社区示例见 [ADOPTERS.md](ADOPTERS.md)。若你的团队在使用 HyperFrames,欢迎提交 PR。 + +- 问题与想法:[Discord](https://discord.gg/EbK98HBPdk) +- Bug 与功能请求:[GitHub Issues](https://github.com/heygen-com/hyperframes/issues) +- 安全报告:[SECURITY.md](SECURITY.md) +- 贡献指南:[CONTRIBUTING.md](CONTRIBUTING.md) + +## 开发说明 + +本仓库对 `packages/producer/tests/**/output.mp4` 下的黄金回归测试基线使用 [Git LFS](https://git-lfs.com)(约 240 MB 的 `.mp4` 文件)。若需克隆完整仓库进行开发,请先安装 Git LFS: + +```bash +# macOS +brew install git-lfs + +# Ubuntu / Debian +sudo apt install git-lfs + +# Windows +winget install GitHub.GitLFS + +# Then, once per machine +git lfs install +``` + +若只需源码文件,可跳过 LFS 内容: + +```bash +GIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/heygen-com/hyperframes.git +``` + +## 许可证 + +[Apache 2.0](LICENSE) diff --git a/docs/project-overview.md b/docs/project-overview.md new file mode 100644 index 0000000000..fbf8663e18 --- /dev/null +++ b/docs/project-overview.md @@ -0,0 +1,632 @@ +# HyperFrames — 开源 HTML 视频渲染框架 + +## 1. 项目定位 + +**HyperFrames** 是一个开源框架,核心理念是 **"Write HTML. Render video."**(编写 HTML,渲染视频)。它让开发者/AI Agent 用 HTML、CSS、JavaScript 编写可定位的动画页面,然后将同一份 HTML 确定性(deterministically)渲染为 MP4 视频文件。由 HeyGen 开源并用于生产环境。 + +它解决了传统视频制作的痛点:无需掌握 Premiere/After Effects,无需学习 React(像 Remotion 那样),只需写 HTML 就能生成视频。特别适合 AI Agent 自动生成视频内容、自动化内容管线、以及开发者驱动的视频制作场景。 + +## 2. 核心功能 + +- **HTML 原生视频创作** — 用 HTML + CSS + 数据属性定义视频合成(composition),无需构建工具 +- **确定性渲染** — 相同的 HTML 输入始终产生相同的逐帧输出,适合 CI/回归测试 +- **多动画框架适配** — 支持 GSAP、CSS 动画、Lottie、Three.js、Anime.js、WAAPI 等 +- **CLI 工具链** — 项目初始化、预览(热重载)、代码检查、渲染输出一条龙 +- **浏览器预览** — 在浏览器中实时预览动画,所见即所得 +- **音视频处理** — 视频帧注入、音频混合、音量包络、多轨道支持 +- **Shader 过渡** — WebGL 着色器过渡效果 +- **分布式渲染** — 支持 AWS Lambda 大规模分布式渲染 +- **HDR 渲染** — 支持 HDR10/PQ 色域、HDR 视频编码 +- **可嵌入播放器** — `` Web Component,可嵌入任何页面 +- **Studio 编辑器** — 浏览器端的合成编辑器 UI +- **Agent 技能包** — 教导 AI 编码助手(Claude Code、Cursor 等)理解视频创作模式 +- **frame.md 设计系统** — 将品牌设计规范转化为视频创作可用的设计令牌(design tokens) +- **Catalog 组件市场** — 可复用的过渡、叠加层、字幕、图表等组件 + +## 3. 项目架构 + +### 3.1 整体架构图 + +```mermaid +%% 图说明: HyperFrames 整体模块关系图 +graph TD + subgraph User["用户层"] + CLI["CLI 命令行工具
hyperframes CLI"] + Agent["AI Agent
Claude Code / Cursor"] + Studio["Studio 编辑器
浏览器 UI"] + Player["播放器
"] + end + + subgraph Core["核心层 - @hyperframes/core"] + Types["类型系统
FPS、Timeline、Canvas"] + Parser["HTML 解析器
parseHtml()"] + GSAP_Parser["GSAP 解析器
parseGsapScript()"] + Runtime["运行时
Runtime (浏览器内)"] + Linter["代码检查器
lintHyperframeHtml()"] + Generators["HTML 生成器
generateHyperframesHtml()"] + Adapters["帧适配器
GSAP / CSS / Lottie / Three / Anime / WAAPI"] + Compiler["时序编译器
compileTimingAttrs()"] + end + + subgraph Engine["捕获引擎 - @hyperframes/engine"] + Browser["浏览器管理
acquireBrowser()"] + FrameCapture["帧捕获
captureFrame()"] + Screenshot["截图服务
BeginFrame API"] + VideoExtract["视频帧提取
extractVideoFramesRange()"] + AudioMixer["音频混合器
processCompositionAudio()"] + ChunkEncoder["分块编码器
encodeFramesChunkedConcat()"] + StreamingEncoder["流式编码器
spawnStreamingEncoder()"] + HDR["HDR 捕获
initHdrReadback()"] + Parallel["并行捕获
executeParallelCapture()"] + end + + subgraph Producer["编排层 - @hyperframes/producer"] + Orchestrator["渲染编排器
executeRenderJob()"] + Server["HTTP 服务
POST /render"] + Distributed["分布式渲染
plan() / renderChunk() / assemble()"] + CompileStage["阶段1: 编译"] + ProbeStage["阶段1b: 探测"] + ExtractStage["阶段2: 视频提取"] + AudioStage["阶段3: 音频"] + CaptureStage["阶段4: 捕获"] + EncodeStage["阶段5: 编码"] + AssembleStage["阶段6: 组装"] + end + + subgraph Deploy["部署 - @hyperframes/aws-lambda"] + Lambda["AWS Lambda 渲染"] + end + + CLI --> Core + CLI --> Producer + Agent --> CLI + Studio --> Core + Player --> Core + Producer --> Engine + Core --> Parser + Core --> GSAP_Parser + Core --> Compiler + Core --> Linter + Core --> Runtime + Engine --> Browser + Engine --> FrameCapture + Producer --> Orchestrator + Orchestrator --> CompileStage + CompileStage --> ProbeStage + ProbeStage --> ExtractStage + ExtractStage --> AudioStage + AudioStage --> CaptureStage + CaptureStage --> EncodeStage + EncodeStage --> AssembleStage + Distributed --> Lambda + Server --> Orchestrator +``` + +### 3.2 核心渲染流程 + +```mermaid +%% 图说明: 从 HTML 到 MP4 的完整渲染流水线 +sequenceDiagram + participant User as 用户/Agent + participant CLI as hyperframes CLI + participant Producer as Producer (编排器) + participant Engine as Engine (捕获引擎) + participant Chrome as Headless Chrome + participant FFmpeg as FFmpeg 编码器 + + User->>CLI: hyperframes render + + CLI->>Producer: 创建 RenderJob
(fps, quality, 项目目录) + + Note over Producer: 阶段 1: 编译 + Producer->>Producer: 解析 HTML → 提取 Timeline 元素
(视频/音频/文本/合成) + Producer->>Producer: 解析 GSAP 脚本 → 提取动画定义 + + Note over Producer: 阶段 1b: 探测 + Producer->>Engine: 启动 Headless Chrome + Engine->>Chrome: 打开页面 + Chrome->>Chrome: 注入运行时脚本 (hyperframesRuntime) + Chrome-->>Engine: 返回 composition duration + + Note over Producer: 阶段 2: 提取视频帧 + Producer->>Engine: 提取所有视频元素的外部帧 + Engine->>FFmpeg: ffprobe 获取视频元数据 + Engine->>FFmpeg: ffmpeg 逐帧提取(按时间范围) + + Note over Producer: 阶段 3: 处理音频 + Producer->>Engine: 解析音频元素 + Engine->>Engine: 混合多轨音频、应用音量包络 + + Note over Producer: 阶段 4: 捕获视频帧 + loop 每帧 (fps * duration) + Producer->>Chrome: seek(time) + Chrome->>Chrome: 驱动所有动画到该时间点 + Chrome-->>Producer: 截图 (BeginFrame) + Producer->>Producer: 注入视频帧 / 合成图层 + end + + Note over Producer: 阶段 5: 编码 + Producer->>FFmpeg: 将所有帧编码为无音频视频 + FFmpeg-->>Producer: 编码后的视频流 + + Note over Producer: 阶段 6: 组装 + Producer->>FFmpeg: 混流(视频 + 音频轨道) + FFmpeg-->>Producer: 最终 MP4 文件 + + Producer-->>CLI: 渲染完成 ✓ + CLI-->>User: output.mp4 +``` + +### 3.3 运行时协议与页面适配器 + +```mermaid +%% 图说明: HyperFrames 的运行时协议 (HfProtocol) 和帧适配器架构 +classDiagram + class HfProtocol { + +duration: number + +seek(time: number): void + +media: HfMediaElement[] + +transitions: HfTransitionMeta[] + } + + class FrameAdapter { + +name: string + +type: string + +seek(time: number, duration: number): void + +parse(doc: Document): void + +getTimeline(): RuntimeTimelineLike + } + + class RuntimePlayer { + +play() + +pause() + +seek(time: number) + +getTime(): number + +getDuration(): number + } + + class TransportClock { + -baseTime: number + -playStartMs: number + +now(): number + +play(): boolean + +pause(): boolean + +seek(timeSeconds): void + } + + class GSAPAdapter { + +name: "gsap" + +seek(time, duration): void + +parse(doc): void + } + + class CssAdapter { + +name: "css" + +seek(time, duration): void + +parse(doc): void + } + + class LottieAdapter { + +name: "lottie" + +seek(time, duration): void + +parse(doc): void + } + + class ThreeAdapter { + +name: "three" + +seek(time, duration): void + +parse(doc): void + } + + class AnimeJsAdapter { + +name: "animejs" + +seek(time, duration): void + +parse(doc): void + } + + class WaapiAdapter { + +name: "waapi" + +seek(time, duration): void + +parse(doc): void + } + + Window "1" -- "1" HfProtocol : window.__hf + FrameAdapter <|-- GSAPAdapter + FrameAdapter <|-- CssAdapter + FrameAdapter <|-- LottieAdapter + FrameAdapter <|-- ThreeAdapter + FrameAdapter <|-- AnimeJsAdapter + FrameAdapter <|-- WaapiAdapter + RuntimePlayer --> TransportClock : 使用 + RuntimePlayer --> FrameAdapter : 驱动 + HfProtocol --> FrameAdapter : 通过 adapter.seek() 实现 seek() +``` + +## 4. 核心技术栈 + +| 技术 | 用途 | +| ---------------------------------------------------- | ------------------------------ | +| **TypeScript** | 全项目使用,强类型系统 | +| **Bun** | 包管理器、构建工具、测试运行器 | +| **Headless Chrome (Puppeteer)** | HTML 页面渲染和截图捕获 | +| **FFmpeg** | 视频编码、音频混合、帧提取 | +| **Chrome BeginFrame API** | 确定性帧捕获(同步帧生成) | +| **Hono** | Producer HTTP 服务框架 | +| **citty** | CLI 命令定义框架 | +| **linkedom** | 服务端 HTML 解析(轻量 DOM) | +| **GSAP** | 首推动画库(可定位时间线) | +| **Three.js / Lottie / CSS / Anime.js / WAAPI** | 其他支持的动画框架 | +| **WebGL** | 着色器过渡效果 | +| **oxlint / oxfmt** | 代码检查与格式化 | +| **tsup** | 构建打包 | +| **AWS Lambda** | 分布式渲染部署 | +| **PostgreSQL + Drizzle ORM** | Studio 后端数据存储 | +| **Lit** | Web Component(player) | +| **Vite + React** | Studio 前端 | + +## 5. 核心原理 + +### 5.1 关键设计思想:Seekable Animation(可定位动画) + +HyperFrames 最核心的设计是 **"可定位动画"** 而非传统的"逐帧播放": + +```python +def render_video(html_content: str, fps: int, duration: float) -> bytes: + """ + HyperFrames 视频渲染核心逻辑 + + 不是"逐帧播放并录像",而是"逐帧定位并截图"。 + 每一帧的渲染互相独立,因此可以并行。 + """ + # 1. 准备阶段:在 Chrome 中加载 HTML + page = open_page(html_content) + page.inject_runtime_script() # 注入 hyperframesRuntime + + # 2. 获取页面暴露的 seek 协议 + protocol = page.evaluate("window.__hf") + # protocol = { duration: 10, seek: fn, media: [...] } + + # 3. 并行渲染每一帧(帧间无依赖) + all_frames = [] + total_frames = fps * protocol.duration + + for time_s in all_frame_times(fps, protocol.duration): + # 每一帧都 seek 到精确时间点 + page.evaluate(f"window.__hf.seek({time_s})") + + # 注入外部视频帧(浏览器本身不播放