📄 文档列表
🎬 口播文案
✏️ 编辑文档
标题
工具栏
加粗
H2 标题
H3 标题
引用
无序列表
有序列表
代码块
📷 上传图片
点击或拖拽上传图片
支持 PNG, JPG, GIF, WebP 格式
内容 (Markdown 格式)
最近在 GitHub 上看到了一个挺有意思的项目——**HyperFrames**(heygen-com/hyperframes,Apache-2.0 协议,21,219 Stars)。 简单说,它就是一个 HTML → 视频的渲染器。你用网页技术写动画,它给你输出 MP4。 为什么值得写?最近 AI 视频赛道挺热闹的,Runway、Pika、Minimax 都在卷。但我更感兴趣的是**生产级工具**——能流水线跑的那种。HyperFrames 解决了这个问题:不管你有多少条视频要出,只要模板固定,AI 帮你批量生成。 正好最近在研究 pi(earendil-works/pi,56,679 Stars,MIT 协议),它和 HyperFrames 配合起来很有意思——**pi 写代码,HyperFrames 出视频**,整个链路都是 AI 驱动。 今天分享一下这个组合怎么用。 --- ## 一、这两个工具是怎么配合的? 先说清楚它们的定位: **pi** 是终端编程 harness,写 HTML/CSS/JS 能力的,但本身不输出视频。 **HyperFrames** 是渲染器,接收 HTML 文件,输出 MP4/WebM。 这两者之间没有原生集成——pi 写完 HTML,人把文件复制到 HyperFrames 项目目录里,跑 CLI 命令。所以流程是这样的: ``` 用户(描述需求) → pi(写 HTML,含 HyperFrames 标记) ↓ HyperFrames CLI(lint → inspect → render) ↓ MP4 视频输出 ``` 核心连接点就是**剪贴板**——pi 输出代码,你复制进 HyperFrames 项目目录。 --- ## 二、实战:生成一条 Pi Agent 介绍视频 ### 2.1 初始化项目 ```bash npx hyperframes init pi-agent-video --example product-promo --non-interactive ``` 这条命令做了几件事: - 创建项目目录结构(`index.html` + `compositions/` 文件夹) - 复制示例资源到 `assets/` - 安装依赖 项目长这样: ``` pi-agent-video/ ├── index.html # 主时间线(场景调度) ├── compositions/ # 各场景组件 ├── assets/ # 资源文件 ├── package.json └── meta.json ``` ### 2.2 写主时间线 index.html 主时间线文件负责把各个场景组件**按时间顺序拼起来**,类似视频编辑器里的序列轨道。 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=1920, height=1080" /> <title>Pi Agent - AI 编程助手</title> <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script> <style> * { margin: 0; padding: 0; box-sizing: border-box; } html, body { margin: 0; width: 1920px; height: 1080px; overflow: hidden; background: #0a0a0f; font-family: "Inter", sans-serif; } .scene { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } </style> </head> <body> <div id="root" data-composition-id="main" data-start="0" data-duration="20" data-width="1920" data-height="1080"> <!-- 背景音乐 --> <audio id="bg-music" src="E:/hermes-agent/share-video/static/music.mp3" data-start="0" data-volume="0.3" data-media-start="0"></audio> <!-- 场景 1: Logo 开场 (0-2秒) --> <div data-composition-id="scene1-logo-intro" data-composition-src="compositions/scene1-logo-intro.html" data-start="0" data-duration="2" data-track-index="1" data-width="1920" data-height="1080"></div> <!-- 场景 2: 什么是 Pi (2-6秒) --> <div data-composition-id="scene2-what-is-pi" data-composition-src="compositions/scene2-what-is-pi.html" data-start="2" data-duration="4" data-track-index="1" data-width="1920" data-height="1080"></div> <!-- 场景 3: 核心能力 (6-11秒) --> <div data-composition-id="scene3-core-features" data-composition-src="compositions/scene3-core-features.html" data-start="6" data-duration="5" data-track-index="1" data-width="1920" data-height="1080"></div> <!-- 场景 4: 技能展示 (11-16秒) --> <div data-composition-id="scene4-skills-tools" data-composition-src="compositions/scene4-skills-tools.html" data-start="11" data-duration="5" data-track-index="1" data-width="1920" data-height="1080"></div> <!-- 场景 5: 结尾 (16-20秒) --> <div data-composition-id="scene5-outro" data-composition-src="compositions/scene5-outro.html" data-start="16" data-duration="4" data-track-index="1" data-width="1920" data-height="1080"></div> </div> <script> window.__timelines = window.__timelines || {}; const mainTl = gsap.timeline({ paused: true }); window.__timelines["main"] = mainTl; </script> </body> </html> ``` 关键参数: - `data-composition-id` — 每个场景的唯一标识(必须是有效 UUID 或字符串,不能留空) - `data-start` — 在主时间线上的起始时间(秒) - `data-duration` — 持续时长(秒) ### 2.3 写场景组件 场景组件是独立的 HTML 文件,放在 `compositions/` 目录下。每个场景有自己的动画时间线。 **场景 1:Logo 开场** ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=1920, height=1080" /> <title>Pi Logo 开场</title> <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { margin: 0; width: 1920px; height: 1080px; overflow: hidden; background: linear-gradient(135deg, #0a0a0f 0%, #1a1a2e 50%, #16213e 100%); font-family: "Inter", sans-serif; } #scene1-logo-intro { width: 1920px; height: 1080px; display: flex; align-items: center; justify-content: center; position: relative; } .logo-container { display: flex; flex-direction: column; align-items: center; gap: 20px; } .glow-ring { position: absolute; width: 400px; height: 400px; border: 2px solid rgba(108, 99, 255, 0.3); border-radius: 50%; } .pi-symbol { font-size: 180px; font-weight: 700; color: #fff; text-shadow: 0 0 80px rgba(108, 99, 255, 0.6); } .pi-wordmark { font-size: 72px; font-weight: 700; color: #fff; letter-spacing: 4px; } .tagline { font-size: 28px; font-weight: 400; color: rgba(255, 255, 255, 0.7); letter-spacing: 8px; margin-top: 20px; } </style> </head> <body> <div id="scene1-logo-intro" data-composition-id="scene1-logo-intro" data-width="1920" data-height="1080"> <div class="glow-ring"></div> <div class="logo-container"> <div class="pi-symbol">π</div> <div class="pi-wordmark">Pi Agent</div> <div class="tagline">你的 AI 编程助手</div> </div> </div> <script> (function () { const tl = gsap.timeline({ paused: true }); // 光环动画:从小到大淡出 tl.fromTo(".glow-ring", { scale: 0, opacity: 0 }, { scale: 1, opacity: 1, duration: 0.8, ease: "power2.out" }, 0.2); tl.to(".glow-ring", { scale: 1.8, opacity: 0, duration: 0.6, ease: "power2.in" }, 1.0); // Pi 符号弹入 tl.fromTo(".pi-symbol", { scale: 0, opacity: 0 }, { scale: 1, opacity: 1, duration: 0.6, ease: "back.out(1.7)" }, 0.4); // 文字滑入 tl.fromTo(".pi-wordmark", { y: 30, opacity: 0 }, { y: 0, opacity: 1, duration: 0.5, ease: "power2.out" }, 0.8); tl.fromTo(".tagline", { y: 20, opacity: 0 }, { y: 0, opacity: 1, duration: 0.5, ease: "power2.out" }, 1.1); // 淡出结束 tl.to(".logo-container", { opacity: 0, duration: 0.4, ease: "power2.in" }, 1.6); window.__timelines = window.__timelines || {}; window.__timelines["scene1-logo-intro"] = tl; })(); </script> </body> </html> ``` **场景 2:产品定位** ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=1920, height=1080" /> <title>什么是 Pi</title> <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { margin: 0; width: 1920px; height: 1080px; overflow: hidden; background: linear-gradient(135deg, #0a0a0f 0%, #1a1a2e 50%, #16213e 100%); font-family: "Inter", sans-serif; } #scene2-what-is-pi { width: 1920px; height: 1080px; display: flex; flex-direction: column; align-items: center; justify-content: center; position: relative; } .content { text-align: center; max-width: 1200px; } .headline { font-size: 80px; font-weight: 700; color: #fff; line-height: 1.2; margin-bottom: 40px; } .highlight { color: #6c63ff; } .description { font-size: 32px; font-weight: 400; color: rgba(255, 255, 255, 0.7); line-height: 1.6; max-width: 900px; margin: 0 auto; } .particles { position: absolute; width: 100%; height: 100%; pointer-events: none; } .particle { position: absolute; width: 6px; height: 6px; background: rgba(108, 99, 255, 0.5); border-radius: 50%; } </style> </head> <body> <div id="scene2-what-is-pi" data-composition-id="scene2-what-is-pi" data-width="1920" data-height="1080"> <div class="particles"> <div class="particle" style="top: 15%; left: 20%;"></div> <div class="particle" style="top: 25%; left: 75%;"></div> <div class="particle" style="top: 60%; left: 15%;"></div> <div class="particle" style="top: 70%; left: 85%;"></div> <div class="particle" style="top: 40%; left: 30%;"></div> <div class="particle" style="top: 80%; left: 60%;"></div> <div class="particle" style="top: 35%; left: 50%;"></div> <div class="particle" style="top: 55%; left: 70%;"></div> </div> <div class="content"> <h1 class="headline">AI 协作的<br/><span class="highlight">新时代</span></h1> <p class="description">Pi 是你的私人 AI 编程助手,实时理解上下文、执行任务,<br/>从你的工作流程中不断学习进化。</p> </div> </div> <script> (function () { const tl = gsap.timeline({ paused: true }); // 标题滑入 tl.fromTo(".headline", { y: 50, opacity: 0 }, { y: 0, opacity: 1, duration: 0.8, ease: "power3.out" }, 0); // 描述文字滑入 tl.fromTo(".description", { y: 30, opacity: 0 }, { y: 0, opacity: 1, duration: 0.6, ease: "power3.out" }, 0.5); // 粒子渐入 + 漂浮动画 tl.to(".particle", { opacity: 1, duration: 0.4, stagger: 0.1 }, 0.2); tl.to(".particle", { y: -15, duration: 2.5, ease: "sine.inOut", stagger: 0.4 }, 0.5); // 场景结束淡出 tl.to(".content", { opacity: 0, duration: 0.4 }, 3.6); window.__timelines = window.__timelines || {}; window.__timelines["scene2-what-is-pi"] = tl; })(); </script> </body> </html> ``` 其他三个场景(核心能力、技能展示、结尾 CTA)用类似结构编写,完整代码就不在这里展开了。 ### 2.4 验证与渲染 写完组件之后,跑两条命令检查有没有问题: ```bash # 语法和结构检查 npx hyperframes lint # 布局溢出检查(文字有没有跑到框外) npx hyperframes inspect ``` `lint` 会告诉你缺少什么属性、语法错误在哪;`inspect` 会渲染一遍时间线,报告布局问题。 都没问题的话,预览一下: ```bash npx hyperframes preview --port 3002 ``` 这条命令会启动本地服务,给你一个 Studio URL,在浏览器里可以看到视频预览效果,带时间轴和播放控制。 最后,渲染输出 MP4: ```bash npx hyperframes render --output "E:/pi-agent/hyperframes-video/pi-agent-intro.mp4" --quality high ``` 输出参数说明: | 参数 | 选项 | 默认值 | |------|------|--------| | `--output` | 文件路径 | `renders/name_timestamp.mp4` | | `--quality` | `draft` / `standard` / `high` | `standard` | | `--fps` | `24` / `30` / `60` | `30` | | `--format` | `mp4` / `webm` | `mp4` | --- ## 三、跑通这条链路的关键细节 ### 坑 1:`data-composition-id` 必须有效 如果属性值不合法(空字符串、格式错误的 UUID),`lint` 会报错但不说清楚原因。 修复方法:用标准 UUID 格式,比如 `scene1-logo-intro`(字符串也行,关键是**不能为空**)。 ### 坑 2:CSS `transform` 和 GSAP 混用会冲突 ```css /* 错误:GSAP 会覆盖 CSS transform */ .pi-symbol { transform: scale(0); } /* 正确:用 fromTo 从初始状态开始动画 */ tl.fromTo(".pi-symbol", { scale: 0, opacity: 0 }, { scale: 1, opacity: 1, duration: 0.6 }, 0.4); ``` 记住规则:**动画元素的初始状态交给 GSAP 管理,不要写在 CSS 里**。 ### 坑 3:音频文件路径 背景音乐要用 `<audio src="..." data-start="0">` 的形式,直接把 `src` 写在元素上,不要用子元素 `<source>`。否则 `lint` 会报 `media_missing_src` 错误。 --- ## 四、这套组合适合什么场景? | 适合 | 不适合 | |------|--------| | 批量视频生产(相同模板,不同内容) | 单条需要逐帧精修的视频 | | AI 驱动的自动化流水线 | 一次性的创意视频(用 AE/Pr 更顺手) | | 有明确时间线的结构化内容 | 复杂嵌套时间线、互相依赖的动画 | 总结一下:如果你有大量同类型的视频要出(产品介绍、教程合集、品牌宣传片),这条链路值得跑通。**pi 负责写代码,HyperFrames 负责渲染**,人只需要描述需求和最终质检,中间环节全自动化。 --- ## 写在最后 AI 工具的价值不在于单个有多强,而在于**能不能串成一条高效的工作流**。pi + HyperFrames 这个组合,恰好说明了这一点。 工具本身没有壁垒——会用的人多了,壁垒就变成了**用得熟练的程度**。 **你平时有跑通过什么 AI 工作流?是怎么串起来的?评论区聊聊。** --- ## 评论区预置内容 Pi + HyperFrames 这个组合上手真的快 原来还能这样用 AI 做视频 我之前用 Remotion,比这个麻烦多了 pi 写 HTML + HyperFrames 出视频,这条链路确实顺
摘要
标签
多个标签用逗号分隔
分类
技术文章
教程指南
工具测评
项目实战
行业观察
默认
💾 保存修改
← 返回查看
返回列表