关于 short-form-video
这项技能用于维护旧版 10–30 秒竖屏 HyperFrames 视频,涵盖音频同步、场景构建、字幕和验证。适用于维护文档中的 May Shorts 示例,而非制作新录音。
主要功能
- 01按剪辑后时间同步音频
- 02四层合成结构
- 03场景与人物画面模式编排
- 04逐词同步卡拉 OK 字幕
- 05渲染与逐帧验证
适用场景
- 01维护 May Shorts 示例
- 02音频剪辑后调整场景时间
- 03核对字幕与画面时序
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nateherkai/ hyperframes-student-kit --skill short-form-video安装后在 Claude Code 中输入/short-form-video确认已加载。
详细介绍
短视频竖屏(Hyperframes)
短视频竖屏的规格为 1080x1920、时长 10–30s,包含真人讲述、动态视觉场景叠层和卡拉 OK 字幕。本技能的所有内容均提炼自 May Shorts 的第 19 次迭代复盘(v1 → v4),用于维护这些示例。新录制内容请使用 short-form-edit。
始终先调用 /hyperframes。 本技能建立在其基础之上,并不取代框架规则(data-* 属性、window.__timelines、合成结构)。无论格式如何,这些规则都不可更改。
适用场景
- 维护现有的 May Shorts 示例。
- 明确要求使用其旧版四层框架。
操作手册(概览)
- 音频是事实依据。 先编辑音频(剪掉重录片段和停顿)。保存为
<name>-edit.mp4。使用ffprobe测量精确时长,即合成的data-duration。 - 使用根目录中的
scripts/transcribe-elevenlabs.mjs辅助脚本(ElevenLabs Scribe)转录编辑后的音频;也可使用学生选定且根据docs/TOOLS-AND-API-KEYS.md进行标准化的替代方案;或者,在通过字幕中的shift()函数调整现有构建的时间时,保留现有字幕,只移动场景的起始时间。 - 根据编辑后的时间确定场景边界——绝不要在同一文件中混用原始时间和编辑后时间锚点。请参阅下文的“音频同步流程”。
- 构建合成框架(4 层:ambient-bg、seam-treatment、captions、face)——请参阅下文的“合成框架”。
- 使用相对于各场景
data-start的局部偏移量编写场景。 每个场景都是一个独立的子合成,位于compositions/scene<N>-<label>.html。 - Lint → 草稿渲染 → 逐字帧验证 → 最终渲染。 这是验证关卡。绝不要跳过第 3 步(帧验证)。
合成框架(始终启用的 4 层)
每个短视频竖屏都包含以下 4 个位于 compositions/ 下的子合成,并加载到共享轨道:
index.html (root, 1080x1920, data-composition-id="main")
├── ambient-bg.html track-index="3" — radial gradient + drift grid + particles + vignette
├── face-wrapper + <video> track-index="0" — talking head (see face-mode choreography)
├── seam-treatment.html track-index="5" — feathers y=960 edge (bottom-half scenes only)
├── scene1-<label>.html track-index="1" — scene overlays (back-to-back, no gaps)
├── scene2-<label>.html track-index="1"
├── …
└── captions.html track-index="2" — karaoke captions, word-synced
data-duration在 root、ambient-bg、seam-treatment、face-video、face-audio 和 captions 中完全相同。只有场景叠层会随时间变化。- 真人视频的
<audio>必须是独立元素(混音器需要),绝不要使用视频自身的音轨。 class="clip"应添加到带定时的 div 上——绝不要添加到<video>或<audio>上。
人脸模式编排(短视频竖屏的标志性手法)
人脸位于一个尺寸与源视频原生横屏尺寸相同(1920x1080)的包装 div 中。GSAP 对包装元素进行动画处理(绝不要对视频元素进行动画处理——改变 <video> 尺寸会导致画面冻结)。
两种模式:
const BOTTOM = { x: 0, y: 1136, scale: 0.5625 }; // bottom-half, full landscape visible
const FULLSCREEN = { x: -1166.5, y: 0, scale: 1.7778 }; // cropped-cover, fills 1080x1920
const MODE_DUR = 0.32;
BOTTOM 会将 1920x1080 的源视频以 1080x607.5 的尺寸渲染,并居中放在底部 960px 区域内。FULLSCREEN 会水平裁切以填满竖屏画面。
在新场景内容出现前 0.15s 完成转场,使用 ease: "expo.inOut":
[
{ t: <scene-4-start>, mode: FULLSCREEN },
{ t: <scene-5-start>, mode: BOTTOM },
…
].forEach(({ t, mode }) => {
mainTl.to("#face-wrapper", { ...mode, duration: MODE_DUR, ease: "expo.inOut" }, t - 0.15);
});
人脸模式瞬间切换,是竖屏视频中最突兀的单帧效果。务必使用插值。
人脸调色(每条短视频都必须做,无一例外)
#face-video {
filter: contrast(1.08) saturate(1.08) brightness(0.97);
}
此外,还要在完整时长内进行细微的 1.00 → 1.025 Ken Burns 缩放(ease: "none"),并添加侧边暗角 ::after 伪元素,让人脸自然融入周围的藏青色背景,而不是与锐利的边缘生硬相接。
接缝处理(底部半屏场景必需)
在 y=960 处添加一条从藏青色渐变至透明的渐变带(60–100px),以及一条带柔和辉光的 2px 强调色扫描线。应在人脸之后绘制,使其位于人脸上方;全屏场景接管画面时会遮住它。y=960 处锐利的切线是 AI 编辑内容最明显的特征之一(仅次于背景平坦)。
音频同步协议(请勿跳过)
**问题:**如果音频经过编辑(重录/删去停顿),源转录稿中的时间戳就会与编辑后的视频不匹配。按原始时间编写的场景起始时间会延迟触发。
**规则:**所有时间都必须使用编辑后时间。绝不可混用。
任何短视频重新定时的验证流程:
- 测量两个音频文件:
差值 = 剪掉的总时长。ffprobe -v error -show_entries format=duration -of csv=p=0 assets/original.mp4 ffprobe -v error -show_entries format=duration -of csv=p=0 assets/<name>-edit.mp4 - 如果使用
captions.html中的shift()函数来映射转录稿中的词语,则以该函数为准。映射shift(originalTime) = editedTime也适用于每个场景的data-start。 - 场景内部偏移(位于
compositions/sceneN.html中)相对于场景的data-start,属于本地时间。如果场景父级的data-start使用了正确的编辑后时间,内部偏移无需修改即可保持正确——除非场景跨越了剪辑点;这种情况下,父级时长和内部偏移都要调整。 - 人脸模式转换数组中的时间必须使用编辑后时间。它们不会自动调整。
重新定时的计划格式(每次都使用此表格结构):
| 场景 | 当前起始时间 | 当前时长 | 新起始时间 | 新时长 | 原因 |
|---|---|---|---|---|---|
| ... | ... | ... | ... | ... | ... |
然后列出人脸模式数组,再列出任何内部偏移更改,最后列出帧验证清单。
场景编写
一个场景对应一个子合成文件。场景在同一个 data-track-index 上首尾相接(无间隔)。每个场景内部:
data-duration与父级的时间段完全一致- 所有 GSAP 锚点都是本地时间(从场景起始处的 0 开始)
- 使用
tl.set({}, {}, <data-duration>)补齐时间轴,使 GSAP 的tl.duration()与data-duration一致
场景节奏规则(基于 10 项原则)
- 不能有静止帧。 每 100 ms 至少有 1 个元素在动。第一个元素的入场偏移 0.1–0.3 秒,不要从 t=0 开始。
- 高潮效果至少停留 1 秒。 场景的「重大揭晓」(印章、数字锁定、笑点)必须在屏幕上至少停留 1 秒,理想情况下为 1.5 秒。应根据揭晓效果的停留时间规划场景,而不是根据总时长。
- 整个场景时长内都要有动效。 如果入场动画在 4 秒场景的本地时间 2 秒前全部结束,就加入次要动效:下划线扫过、勾号弹出、卡片缓慢漂移、胶囊形元素上的微弱脉动光晕。节奏停滞会让观众划走。
- 变换缓动方式。 每个场景的入场动画至少使用 3 种不同的缓动方式。
- 每 5 秒播放时长至少有 1 个令人惊艳的效果。 字体猛击、故障/色差揭晓、快速摇摄、音频同步猛击。缺少这些效果时,视频看起来就像「带标签的对镜头讲话」——虽然正确,却令人难忘不了。
字幕(卡拉 OK 风格)
- Montserrat 900,46–58px(适用于 1080 宽度),底色为 100% 白色
- 当前词语:放大至 1.08 倍并弹出 + 更改为强调色(AIS 使用
#37bdf8,也可根据品牌调整) - 通过多层
text-shadow添加描边,绝不要使用-webkit-text-stroke(在 Chromium 渲染中显示不一致) - 去掉 rgba 背景胶囊条——依靠描边保持可读性。字幕应像画面上的涂鸦,而不是字幕轨道。
- 重新定时时,在
captions.html中使用shift()函数,将转录稿词语时间戳映射到编辑后时间。这样无需改动转录稿 JSON,重新定时也能按机械流程完成。
完整的卡拉 OK 实现请参阅 /hyperframes 下的 references/captions.md。简而言之:每个词使用一个 <span> 元素,通过 data-word-start 指定时间戳,GSAP 补间动画作用域限定在各个 span 内,弹出动画时长控制在 0.08–0.12 秒。
环境背景(绝不交付纯色藏青背景)
最低可行的背景层:
- 径向渐变底色(中心比边缘亮 15–20%)
- 动画噪点/颗粒叠加层,不透明度为 8–12%
- 4–8 个漂移的粒子点或网格轨迹
- 微妙的暗角
background: #07121c 本身只是占位符,不是设计。若要营造科技感/控制室美学,请使用 feedback_techy_background_layers.md 中的 6 层结构(通过暗角遮罩的 HUD 网格 + 电路轨迹 + 脉冲节点 + 扫描光束 + 遥测滚动条 + 角落的等宽字体标签)。
音频响应
- 标题随节拍脉动 3–6%。背景可随低音脉动 10–30%。
- 文字响应幅度保持轻微(3–6%),以确保字幕清晰易读;背景可以更强烈。
- 使用带种子的离线分析器(预先计算音频特征轨迹),确保渲染结果具有确定性。渲染流程中不要使用
AnalyserNode——Math.random()和实时音频节点会破坏确定性。
转场
- 轮换转场类型。 不要连续两次使用相同类型的转场。一连六次硬切是 AI 剪辑最明显的破绽。
- 面部模式转场(
BOTTOM ↔ FULLSCREEN)在场景间切换模式时,也可作为场景转场。 - 对于纯叠加层的场景间转场,从注册表安装:
push-up、flash-through-white、sdf-iris,或完整的 shader-transitions 包。运行npx hyperframes catalog --type block浏览。
验证关卡(强制要求——未通过前不得交付)
Lint 通过 ≠ 设计有效。只有在精确到词语时间戳提取帧并逐张读取所有 PNG 后,才能报告短视频渲染完成。
步骤 1——草稿渲染
cd video-projects/<slug>
npx hyperframes lint
npx hyperframes render --quality draft --output renders/<slug>-vN-draft.mp4
步骤 2——精确到词语的帧提取
选择 8–15 个时间戳,每个时间戳都对应一个口播词,且该时刻应显示特定视觉内容。不要选整数时间,也不要选场景中间的时间。要精确对应到词语。
mkdir -p renders/frames-vN
for pair in "<t>:<label>" "<t>:<label>" ...; do
t="${pair%%:*}"; label="${pair##*:}"
ffmpeg -y -ss "$t" -i renders/<slug>-vN-draft.mp4 \
-frames:v 1 -q:v 2 "renders/frames-vN/t${t}-${label}.png"
done
步骤 3——读取每张 PNG
对每张 PNG 调用 Read,将图像加载到上下文中。不要只列出文件名。逐帧确认:
- 预期视觉内容在预期时刻出现(不能晚 1 秒,也不能提前)
- 所有下半屏场景中,发言者的脸都没有被裁切
- 该场景的全屏或下半屏面部模式正确
- 字幕符合品牌风格、清晰易读且没有溢出
- 没有空白帧、意外重叠或画布外文字
步骤 4——若有任何问题,修复并重新验证。切勿交付有问题的成品。
步骤 5——最终渲染
npx hyperframes render --quality standard --output renders/<slug>-vN.mp4
从最终渲染中抽查 3–4 帧(使用相同时间戳,存放在不同的 frames-vN-final/ 文件夹中),确认标准质量编码没有改变任何内容。
10 条规则(质量检查清单——首次草稿前执行)
每个短视频项目都必须遵循。创作时就执行清单,不要等到完成后再检查。
- 不要出现静止帧。 每 100ms 都必须有元素在动。
- 场景重点内容至少停留 1 秒。 根据揭示时间安排时长,而不是根据总时长。
- 面部是角色的一部分。 调色 + Ken Burns 效果 + 侧边暗角。
- 不要出现明显接缝。 在 y=960 处使用渐变 + 扫描线进行羽化。
- 每 5 秒安排一个震撼瞬间。 字体重击、故障效果、快速摇镜、音频重击。
- 音频响应不可妥协。 文字响应 3–6%,背景响应 10–30%。
- 轮换转场类型。 不要连续两次使用相同类型。
- 字幕要醒目,不要只是礼貌地标注。 使用描边,不要使用药丸形底色。当前词要缩放并变色。
- 运动贯穿整个场景时长。 若入场动画结束得太早,就添加次级运动。
- 背景应该是一个图层,而不是一种颜色。 至少包含径向效果 + 噪点 + 粒子 + 暗角。
- 重击/印章叠加层应在目标文字完全显示后出现。 揭示逻辑优先于词语同步。印章的
t≥ 目标内容完全显示的t+ 0.10–0.25s。否则笑点会在铺垫之前出现。
项目结构(每个短视频项目)
video-projects/<slug>/
├── hyperframes.json
├── meta.json (id, name, dimensions 1080x1920, fps 30)
├── index.html (root composition, the 4-layer scaffold)
├── compositions/
│ ├── ambient-bg.html
│ ├── seam-treatment.html
│ ├── captions.html (with shift() function if retiming)
│ ├── scene1-<label>.html
│ ├── scene2-<label>.html
│ └── ...
├── assets/
│ ├── <name>.mp4 (original recording)
│ ├── <name>-edit.mp4 (edited — cuts removed — this is what the comp uses)
│ ├── transcript.json (whisper output)
│ └── brand assets (logo, brand-tokens.css, background music)
└── renders/
├── <slug>-v1-draft.mp4
├── frames-v1/
├── <slug>-v1.mp4
└── ...
重新定时流程(音频重新剪辑或时间戳发生偏移时)
- 使用
ffprobe测量编辑前后音频的时长。差值 = 总剪切时长。 - 确定剪切区间:删除了哪些秒数,以及从哪里删除。
- 编写计划表:列出每个场景的
data-start、data-duration,每个面部模式转场的t,以及内部偏移跨越剪切点的场景。 - 对于跨越剪切点的场景,其父级时长和内部偏移都要更改。完全位于剪切点某一侧的场景只需调整父级
data-start。 - 执行 Lint → 草稿渲染 → 精确到词语的帧验证 → 最终渲染。不得走捷径。
短视频中不该做的事
- 不要对
<video>元素的尺寸做动画——会导致画面冻结。应对包装 div 做动画。 - 不要在任何时间轴上使用
repeat: -1——这会破坏捕获引擎。只能使用有限次数。 - 不要使用
Math.random()或Date.now()——会破坏确定性。如果需要伪随机数,请使用带种子的 PRNG。 - 不要在字幕中使用
<br>——自然换行再加上<br>会产生多余的换行。 - 不要跳过帧验证关卡。Lint 的退出代码不能代表视觉效果是否正确。
- 如果音频经过剪辑,就不要按原始时间编写。必须使用剪辑后的时间,否则就别做。
- 不要让
background: #07121c保持单调。要叠加图层。 - 不要在场景之间硬切。轮换使用不同的转场风格。
- 不要给字幕加得太客气。要让它们跳出来。
- 不要让人脸画面静止不动。始终进行调色和 Ken Burns 效果。
从 may-shorts-18 中吸取的经验(v1 → v2)
这些经验总结自 v1 渲染中的 4 个具体问题,以及 v2 中的修复方法。每次制作新短视频时都要应用。
1. 重击/印章效果的时机——揭示顺序比逐词同步更重要
SLAM/STAMP 覆盖效果(KILLED、DEAD、STOP 等)应在目标文本完全可见后出现,而不是在口播对应词语时出现。在 may-shorts-18 v1 的场景 1 中,CLAUDE 和 CHATGPT 被设定为对手——KILLED 在本地时间 0.46s 时出现,而 CHATGPT 直到 0.66s 才出现,因此观众看到的是“Claude … KILLED”,目标却尚未显示出来。笑点就此垮掉。
规则: stamp_t ≥ target-text-visible_t + 0.10–0.25s。所谓“可见”的时间戳,是目标文本的入场动画结束时间,而不是开始时间。逐词同步只是参考;视觉揭示顺序才是约束。
2. BOTTOM 人脸模式的缩放——不要直接使用默认值
默认值 BOTTOM = { x: 0, y: 1136, scale: 0.5625 }(对 1920×1080 源视频来说恰好能水平铺满)会让讲者两侧露出空荡的演播室背景,前提是讲者在源视频画面中占比不到 70%。may-shorts-19 默认使用了这个值,may-shorts-18 v1 也照搬了它——两支视频的每个 BOTTOM 场景中,讲者左右两侧都有明显的空白区域。
规则: 优先使用 BOTTOM = { x: -180, y: 1110, scale: 0.75 }——左右各裁掉 180px,底部锚定到 y=1920。在确定这个常量之前,先针对实际源视频预览一帧 BOTTOM 模式。如果源视频中的讲者本来就被紧凑取景,缩放到 0.65 可能就够了;如果源视频是宽幅演播室取景,就将缩放提高到 0.80,并重新调整 x。
始终让 HIDDEN 的 x、y、scale 与 BOTTOM 完全相同——它们只应在 opacity 上有所不同,这样淡入淡出场景才不会在过程中发生几何偏移。
3. 人脸模式转场——同时做好三件事,而不是只做一件
相邻场景之间切换人脸模式时,如果只对人脸包装层进行默认的 0.15s 预滚动和 0.32s 时长的 expo.inOut 动画,效果会显得僵硬——变形的人脸后面,上一场景的面板仍完全不透明,因此观众会看到两个元素互相争抢,而不是交叉淡化。
规则: 对任何“主视觉”场景之间的人脸模式切换(尤其是 BOTTOM ↔ FULLSCREEN),都要同时做到以下三点:
- 将该转场的时长延长至 0.45–0.55s(而非默认的 0.32s)
- 在新场景的
data-start前 0.25–0.30s 开始(而非默认的 0.15s) - 在场景结束前 0.25s 开始,对上一场景的面板包装层进行淡出和模糊处理,在 0.20–0.25s 内过渡到
opacity: 0, filter: blur(6px)
在实现上,将人脸模式转场数组改为按条目设置 dur,这样其中一个转场就可以比其他转场更长:
[ { t: 2.06, mode: FULLSCREEN, dur: 0.50 }, { t: 3.71, mode: HIDDEN, dur: 0.32 }, ... ]
.forEach(({ t, mode, dur }) => mainTl.to("#face-wrapper", { ...mode, duration: dur, ease: "expo.inOut" }, t));
三项同时调整 = “真正的剪辑师剪辑过”。单独调整任何一项 = 僵硬。
4. 视频中段的数据感场景胜过装饰性场景
对于 15–20 秒短视频的第 3–5 个场景(也就是观众注意力最容易流失的“中段苦熬期”),优先使用看起来像信息的视觉元素——条形图竞速、数字递增的统计网格、热力图、迷你趋势线、流程图、数据不断跳动的仪表盘界面,以及依次闪红的痛点网格。may-shorts-18 v1 的场景 4 将雷达环、终端芯片和火花组合在一起——功能齐全,却偏向装饰性,Nate 称它“乏味”。v2 将它替换为一个依次亮起红橙色的 3×3 痛点网格、一条逐步绘制的迷你趋势线(带有 YOU-ARE-HERE 标记),再加上有力的收尾——时长不变,参与度却高得多。
**规则:**纯文字加图标的场景看起来像幻灯片。数据感场景看起来像证据。当中段场景显得乏味时,就用看起来像信息的元素替换装饰:逐渐增大的小数字、逐渐填满的条形、逐步绘制的图表,或依次闪烁的网格。
参考构图
video-projects/may-shorts-19/— 短视频的标准示例(18.84 秒,1080x1920,7 个场景、人脸模式调度、使用 shift() 的卡拉 OK 字幕、环境背景加接缝处理)。制作新短视频前,请阅读index.html和所有compositions/scene*.html。video-projects/may-shorts-18/— 次要参考示例,融入了上述 4 条经验:BOTTOM scale=0.75、KILLED 印章在 CHATGPT 揭示后出现、场景 1→2 流畅淡入淡出、场景 4 数据仪表盘式的 “THE PATTERN” 网格。
相关技能(同时调用)
/hyperframes— 框架规则(始终最先调用)/hyperframes-cli— CLI 命令(init、lint、preview、render)/gsap— 动画库参考/hyperframes-registry— 安装转场模块/seedance-loop-prompt— 如果短视频需要 AI 生成的循环背景视频
记忆参考(相关反馈条目)
feedback_short_form_principles.md— 10 条规则及完整理由feedback_contrast_technique.md— 光效局部化、text-shadow 光晕,以及提亮较暗文字feedback_techy_background_layers.md— 6 层控制室背景堆叠feedback_visual_verification.md— 验证关卡project_ais_brand_specs.md— 如果短视频采用 AIS 品牌风格(十六进制色值、字体、Logo 光效)