mcpField
H
html-reel

html-reel

github.com/mengto创意与媒体7.1k48 次安装3 天前更新
代码仓库

关于 html-reel

html-reel 是将帖子、网页或视频等现有素材制作成配音短片的 Skill。它把 HTML 场景与口播词语时间点同步,并可按创作者的实际录制节奏重新调整场景。

主要功能

  1. 01提取来源事实与视觉风格
  2. 02编写脚本并规划分镜
  3. 03渲染按词语定时的 HTML 场景
  4. 04按录制语音重新定时
  5. 05预览场景、字幕与音频
  6. 06通过 Fil 组装并导出

适用场景

  1. 01将帖子改编为配音短片
  2. 02把着陆页制作成视频
  3. 03用录制素材替换镜头占位图

MCP 相关

该 Skill 通过 MCP 使用 Fil 视频编辑器,组装场景、叠加画面、语音、字幕和章节。README 还说明 Fil 可逐帧播放 HTML 场景。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mengto/skills --skill html-reel

安装后在 Claude Code 中输入/html-reel确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

agents/
openai.yaml
demo/
PROMPT.md
index.html
references/
retime.md
judging.md
formula.md
source.md
structures.md
fil-editor.md
scripts/
bubble.mjs
choreo-example.mjs
flash-crop.mjs
fil-words.py
named-times.py
join-takes.py
decursor.py
frame-video.mjs
reel-clock.css
record-window.mjs
reel-clock.js
render-frames.mjs
split-flip.mjs
tighten-voice.py
timemap.py
read-source.mjs
preview-reel.mjs
verify-export.mjs
vo-words.py

详细介绍

HTML Reel

HTML 场景 · DreamCut · Fil 的 MCP 视频编辑器 · ffmpeg。 一个无需框架的场景引擎,位于 scripts/reel-clock.js。

Reel 是配上图片剪辑的声音。本技能从已有素材制作 Reel,例如推文、落地页、YouTube 视频或视频文件,因此 Reel 讲述的内容与素材一致,外观也与之相符:素材中的文字变成脚本,媒体素材变成画面,字体和颜色变成标题。每个画面都紧扣文字:标题在对应词语出现时落下,演示画面在提到它的那句台词处切换,音效在揭晓时响起。创作者从初稿起就置身其中:背光剪影站在他们拍摄的位置,因此他们还没录下一个字,Reel 就已经完整;他们录制的片段会替换剪影。由于场景是由同一个时钟驱动的 HTML,所有内容都会根据他们真实的表达节奏重新定时,无需重新制作任何动画。

适用范围。 网页上的实时应用窗口(不生成视频文件)请使用 html-demo。单独制作精致的屏幕录制,请使用 browser-video-recording。要将网页制作成固定时长、没有旁白的动态作品,请使用 website-to-motion-design。当交付内容是根据素材剪辑、配有人声的竖屏视频时,请使用本技能。

来源。 提取自 Meng To 于 2026 年 10 月制作的 HTML Demo 上线 Reel(fil.design/skills/html-demo):研究了一支 24.7 秒参考 Reel 中的八种布局;用他克隆的 ElevenLabs 声音录制了一段临时旁白;用 DreamCut 录制了四段技能页面素材;逐帧渲染了 HTML 开场和结尾;在 Fil 的视频编辑器中制作了三版草稿;每轮由两位盲评者评审;最后将他用手机录制的两段素材,按他本人的词语时间点剪辑成一支 33.7 秒的 Reel。之后,他又录制了一段横屏素材,剪去停顿,并用同样的方法重新定时,成片为 37.5 秒。随后将此方法推广:把他的三篇帖子(MiniMax 落地页、逆向工程智能家居、Anatomy 技能)分别按各自风格制作成 Reel,先不露脸,再使用镜头布局中的占位形象重做(先是他的墨水画肖像,随后是工作室里的背光剪影),并加入电影感字体和字幕,在 Fil 中处理之前先在本地预览。以下文件和数据均来自这些制作过程。

原理

所有内容都按词语时间点放置,所有绘制内容都是 t 的纯函数。 每个 HTML 场景都通过 window.__frame(t),根据场景内的时间 t(秒)设置每个元素;场景在固定的 540 × 960 舞台上以 2× 渲染(1080 × 1920)。渲染器每帧调用一次并截图;没有任何内容会读取时钟。因此,真实录制素材到位后,词语锚点就能建立从真实时间 τ 到临时旁白时间 t 的分段线性映射,场景再以 t = W(τ) 重新渲染:同一段动画适配新的表达节奏,不会产生抖动。

如果没有这一机制,Reel 就无法跟随录制者。使用 CSS 时间轴、GSAP 时间轴或计时器制作的动画场景会按自身节奏播放;要适配新的录制素材,就必须逐行手动重新制作动画,每次剪辑点都会偏移几帧。屏幕录制也无法重新定时,因此只能按录制内容中的事件剪辑,并单独调整每个片段的播放速度。

// hook.js, on reel-clock.js: times are the scratch voice's words.
const T = { look: 0.27, recording: 1.1, zoom: 3.25, sharp: 4.54, html: 7.22 };
HTMLReel.scene({
  dur: 8.6,
  anchors: ANCHORS,                       // [[τ, t], …] once the real take exists
  draw(t, $) {
    $('#win').style.transform = `scale(${1 + 2.8 * ease(t, T.zoom, T.zoom + 1.2)})`;
    $('#w-recording').style.transform = `translateY(${(1 - word(t, T.recording, 2.2)) * 135}%)`;
    $('#tags').style.opacity = ease(t, T.html - 0.3, T.html);
  },
});

scripts/render-frames.mjs 可将此类页面渲染成 MP4(并逐帧检查安全区域);Fil 的视频编辑器将同一页面作为 HTML 场景播放,逐帧推进时钟;浏览器则可通过 ?controls 实时播放。

工作流

  1. 阅读源内容(scripts/read-source.mjs <tweet | page | YouTube | file> --out source --follow、references/source.md)。完成 Source.md:逐字记录原文、短视频可以提及的事实、一个核心观点、钩子、作品归属和行动号召。根据测量结果和画面完成 Look.md:形状、底色、墨色、强调色,以及三种作用的字体(铺垫、揭晓、标签)、背景、母题和动态效果。
  2. 选择结构、画面比例和布局(references/structures.md):宣传片(参考短视频中研究得来的 references/formula.md)、作品展示、“发现了这个”、讲解、前后对比;9:16、4:5、1:1 或 16:9;并为每个节拍选择布局,让创作者的脸随着行动号召逐渐增大(钩子里不出现、气泡式、占半屏、行动号召时占满画面)。只有创作者不会出镜时才制作无露脸版本。创作者喜欢的参考短视频只用于借鉴结构和节奏,不能借鉴其视觉风格。
    • 制作摄像头占位图:一张逆光影棚剪影照,使用创作者(或任意模特)的照片;仅从背后打光,背景为柔和发光的暖奶油色,面部处于阴影中、五官隐约可见;人物头肩朝向镜头,直立的 9:16 构图,鼻子位于画面中央,鼻尖距画面底部约 60%,标注 CAMERA · PLACEHOLDER(在 Fil 中,使用由 Nano Banana 编辑照片的图像节点)。所有摄像头布局都先放入这张占位图,直到有正式拍摄镜头替换;如果正式镜头的构图相同,就无需重新构图。
  3. 用创作者的口吻撰写脚本,依据 Source.md,每个节拍写一行:使用创作者自己的句子并加以缩短;只写 Source.md 列出的事实;明确标注他人姓名。按说话速度而不是阅读速度控制篇幅:克隆语音每秒约读 2.2–2.4 个词(包含句间停顿),真人出镜约每秒 2.6 个词,因此 30 秒大约能容纳 65–70 个词。按听感来写:数字和姓名写成实际读法(“five point oh”、“Rea”),大写只用于画面文字。每行标出布局、画面内容,以及每个动作落下时对应的词。
  4. 制作带有逐词时间戳的语音(scripts/vo-words.py:ElevenLabs with-timestamps,使用创作者的克隆语音,密钥从环境中读取且绝不打印;脚本会保存完整回复,因此可以免费重新生成语音,并打印语速)。无露脸短视频使用最终语音;有正式拍摄镜头时先用临时语音。然后:
    • 开始制作前先核对语音内容:使用 Fil 的字幕,或本地 whisper,将语音逐词与脚本对照(尤其是姓名和数字);
    • 如果超时一两秒:运行 scripts/tighten-voice.py,剪掉每段长停顿的中间部分,并同步移动词语时间戳,无需再花钱录一遍;
    • 为每个词命名(scripts/named-times.py: T.zoom、T.skill2、T.htmlEnd),后续所有剪辑都使用这些名称。 任何超过 $1 的支出都要先询问。
  5. 按照源内容的视觉风格制作画面,所有场景都使用 scripts/reel-clock.js,并在其 :root 中设置 Look.md 的变量,再调用 HTMLReel.scene({ shape }):
    • 先制作封面:在短视频开头的 0.2 秒内呈现钩子的最佳时刻(完整标题出现在最佳画面上),然后从那里继续播放钩子(在完整场景中使用 HTMLReel.scene({ cover: T.payoffEnd });在带标题图层的主体视频上使用 scripts/frame-video.mjs --cover 3.6);标题必须位于网格预览所示的 3:4 裁切范围内;
    • 为屏幕录制画面去除光标,然后再裁切构图:3D 场景或画布的录制画面通常会显示 macOS 手形光标;scripts/decursor.py 会在片段实际播放的时间范围内识别它(抓取手势和张开手势,六种尺寸)(scan src.mp4 track.json --pieces pieces.json),并用前后画面对比的拼图检查识别结果(sheet),再将光标从 src-clean.mp4 中抹除(clean);之后 frame-video 都使用清理后的视频帧(--video src-clean.mp4);需要在 venv 中安装 OpenCV(references/source.md);
    • 让演示视频按词的时间戳完成裁切与构图:将片段(from、to,以及片段结束前最后一个词)传入 scripts/frame-video.mjs;在同一个主体中使用多个视频(帖子的视频和它引用的帖子的视频);可将完整画面卡片插入为一个片段;在视频上方绘制由 t 驱动的标题图层(scripts/render-frames.mjs --alpha);先将标题静帧叠在主体视频上检查(--test … --under body.mp4);
    • 钩子、标题卡或结尾使用由 scripts/render-frames.mjs 渲染的完整场景;如果钩子要在自身画框中展示源视频,则把视频帧绘制成图片(只提取一次,帧率为 60 fps,在 setup 中解码,在 draw 中设置 t 对应的帧并等待加载),这样它就能像其他内容一样重新定时;
    • 使用 DreamCut 录制源内容中没有展示的产品(scripts/record-window.mjs、scripts/flash-crop.mjs),并将指针移动时机对准词语。 所有需要阅读的内容都必须位于安全区域内(9:16 画面中,从 y 280 到 1640,画布高度为 1920)。
  6. 在本地预览(scripts/preview-reel.mjs plan.json):查看画面、每种摄像头布局中按编辑器自身 set 值放置的占位图、逐词呈现的电影风格字幕、语音和音效;响度为 −14 LUFS;同时生成联系表。此时检查文字叠加后的布局;在这里修改只需一分钟,导出却要等待一段时间。
  7. 通过 MCP 在 Fil 的视频编辑器中组装(references/fil-editor.md):以画面作为主体叙事;在每种摄像头布局中,将占位图作为覆盖层置于画面上方(全屏、缩小后的气泡式、半屏),这样之后便可用正式镜头替换占位图,同时保留所有裁切、位置和关键帧;语音单独放在一条轨道上;音效音量设为 0.1–0.2;电影风格字幕放在剪辑接缝处或画面下方;全屏人像布局中,字幕放在下巴以下(使用字幕范围),绝不能遮住脸;将各节拍设为章节。导出、下载并检查画面帧。
  8. 通过盲评达到 8/10(references/judging.md):安排两位只看画面帧和联系表的绝对评分员,取较低分;另安排一位评审对比修改前后的版本。根据两位评分员都指出的问题进行修改;连续两轮评分不变时停止。
  9. 创作者录制:将脚本放入画布文档,作为提词器(标题和 [directions] 会显示,但不会被读出);在手机上添加 Record,并把二维码图片交给创作者。录制片段会出现在画布上,语音也会经过清理。用正式镜头逐一 replace 占位图,然后根据创作者实际说出的词重新调整所有时间(references/retime.md):
    • 合并录制片段(scripts/join-takes.py):裁掉超过约 0.45 秒的停顿,添加 15 ms 淡入淡出,并在布局改变处拼接;
    • 从 Fil 的字幕获取词语时间(look.max_words: 1,然后使用 get_video 的字幕 list、scripts/fil-words.py);
    • 使用 scripts/timemap.py 将临时录音和正式录音中的词语对齐为锚点,再根据锚点重新渲染场景、拆分视频片段并调整播放速度;
    • 添加摄像头画面:气泡式布局(在编辑器中使用 set.corner_radius,或运行 scripts/bubble.mjs)和分屏布局(scripts/split-flip.mjs);
    • 根据正式语音重新生成字幕,添加章节,导出,并运行 scripts/verify-export.mjs。

规则及其防止的故障

  • 只说来源中写明的内容。 每个数字、名称和主张都必须来自 Source.md 中的事实。为一篇真实帖子制作短视频,却编造结果,是作者最不能容忍的事,而观众也会核查。
  • 从来源中获取视觉风格。 字体、颜色、图案和动效都来自 Look.md;时钟的默认样式(一种衬线字体、粗重的窄体重点字、一个橙色圆点)只是某一条短视频的风格。短视频风格不对,看起来就像在替别人打广告。
  • 电影感排版,放大到足够醒目。 来源提供字体;短视频则赋予字体尺寸和节奏:在钩子、尾声和每张标题卡中,铺垫句在 540 画布上约为 52 px,重点词为 90–110 px、粗重,并通过遮罩落在对应的词上,最后落在强调色上;号召语中的关键词要尽可能大,直到刚好能放进画面(窄体短词约为 200 px,长词或较宽的字体则要小一些)。把标题挤在带框视频上方的一条窄带里,看起来就像幻灯片;大字才是让人停下滑动的关键。
  • 字幕也要有电影感。 使用约 78 px 的粗黑体(Inter Tight 800,或 Fil 字体列表中的来源自带粗体),文字用墨色,正在说的词用强调色,添加 5 px 深色描边,逐词显示,每行最多 3 个词,放在分屏接缝处或画面下方。普通的小字幕会破坏排版效果。
  • 第一帧就是封面。 Instagram 和 TikTok 的个人主页网格、短视频播放前的信息流,以及 Fil 的视频编辑节点,都会显示短视频的第一帧,除非设置了封面。因此,如果钩子从动画中途开始,开场就会是空白画面上一个只升起一半的词(前四版草稿都是如此:“This”“Reverse engin…”“One”)。应直接以封面开场:选用钩子的最佳瞬间,让完整标题落在最佳画面上,停留前 0.2 秒,然后再从头播放钩子。标题应放在 3:4 裁切范围内(1920 高度中的 y 280–1640),在 360 px 宽的画面上仍清晰可读,不要让字幕盖住标题(第一行字幕从 0.2 秒后开始),并将这一帧保存为 cover.jpg,供各平台上传封面。
  • 草稿中要有创作者本人。 如果创作者脸部所在位置是空的,就无法评判短视频;在每种镜头布局中加入背光剪影,草稿才看起来像完成版,每段拍摄内容都用 replace 插入。
  • 在画面中注明他人的作品。 引用了帖子、链接到仓库或提到某人的技能时,应在观众能看到的位置注明对方的姓名和账号,也要在旁白中提及。如果把这些作品说成自己的,就会在评论区被指出。
  • 演示就是画面;每 2–4 秒切换一次构图。 换一段内容、裁切细节、插入标题卡都可以。如果画面始终只有一个不变的方框,看起来就像带字幕的屏幕录制。快速念出清单(“灯、门、空调、机器人”)是个例外:每项对应一个片段,并在念到该词时出现,哪怕只停留很短时间。
  • 在据此制作内容之前,先核对配音实际说了什么。 克隆语音会把“5.0”读成“five”,把名字读成另一个词,也会把首字母大写的词逐个字母读出来。对照脚本核对配音中的每个词(查看 Fil 的字幕或使用 whisper);如果等场景都按配音节奏定好后才修正词语,就得重新渲染。
  • 留意来源本身的瑕疵。 演示视频可能会掩盖掉帧或页面切换时的闪烁。read-source 会列出场景切换点(cuts),但不会标出镜头内部的短暂故障或扫描线(Anatomy 在 15.8 秒处以及 20.6 秒后都出现了);保留片段前,以 0.1 秒的间隔查看每段的首尾,并以 0.25 秒的间隔检查片段内容。
  • 从帖子视频中去掉光标。 帖子屏幕录制中的光标,是盲评者最先指出的问题:在两条根据 Meng 的帖子制作的短视频草稿中(Opus 5.5 发布内容和山谷中的船只场景),四位评审都先指出了 macOS 手形光标,之后才注意到文字、布局或号召语。scripts/decursor.py 在 854 帧和 1,138 帧中找到了光标,并用其柔和阴影一并擦除。清理前先查看检测结果图。另一种带深色描边的白色光标(指向的手)要先从同一段录屏的一帧中裁出模板(template),绝不能使用 Apple 自带的光标文件。它无法找到箭头光标(黑色、白色描边)。
  • 按词剪辑,绝不凭猜测。 第一版按阅读速度计时,每个节拍都早了或晚了;第二版按照试录配音的词语时间戳剪辑,所有节拍都准确对上了。用对应的词命名每个时间点(T.zoom、T.html),让脚本读起来像旁白。
  • 场景只根据 t 绘制。 画布上不得使用 CSS 动画、过渡、计时器或 Math.random:如果场景在其他地方计时,每次渲染的结果都会不同,也无法重新定时。reel-clock.css 会关闭 #stage 上的动画和过渡。
  • 根据锚点调整时间,不要整体拉伸。 把整个场景拉伸到新的时长,会让每个节拍产生不同的偏差。词语锚点(8.6 秒钩子中有 24 个)将每个节拍固定在对应的词上,只有词与词之间的间隔会被拉伸。保持映射单调;如果创作者改写了某一行(“happens”“jumps”“demos”“fil”),就添加手动配对。
  • 变速会改变时长。 一段 3.853 秒的屏幕录制,速度设为 1.471 后,在时间线上会持续 2.619 秒。根据事件(滚动、每次步骤跳转)拆分录屏,并调整每个片段的速度,让事件落在对应的词上;速度保持在 0.5 到 2.2 之间,否则动作看起来会像快进。
  • 在布局变化处衔接不同拍摄段落。 在全屏人脸镜头中间直接跳切会很明显;如果切点藏在气泡缩小或分屏翻转的过程中,就不会明显。
  • 字幕使用单条轨道,根据拉伸调整位置。 整条短视频中的字幕都位于分屏接缝处(position: "middle"、offset: 0),因此要为每段全屏真人镜头单独设置字幕范围:{"op":"captions","ranges":[{"start":6.23,"end":7.33,"position":"bottom","offset":-380}]} 会将一行 78 px 字幕的中心放在 y 1332,即比例为 1 的绘图中人物下巴下方(鼻子在 y 960);该镜头结束后,字幕会回到接缝处(Fil 0.433.0)。每条命令都会替换所有范围,因此要一次性发送全部范围,并在 get_video 中读回检查。保持人脸在原拍摄构图中的位置(scale: 1、y: 0),不要把人脸重新构图到接缝上方(scale 1.3,y −290);保留该镜头的字幕,不要移除。大字已经显示相同内容时(钩子、署名、号召语),应移除其下方重复的字幕行({"op":"caption","caption":…,"remove":true}):大字本身就是文字,而最终发布的短视频中,钩子下方没有字幕。
  • 别让文字挡住人脸。 字幕应位于画面中部的分屏接缝处(y ≈ 960),或全屏真人镜头中人物下巴下方(底部范围,offset −380:y ≈ 1332),绝不能挡住人脸或窗口控件;钩子和尾声的标题应限制在 y 280–1640 之间,避免被应用按钮或 3:4 裁切切掉。
  • 号召越强,人物画面越大。 钩子中不出现人脸,展示证明时用气泡,演示时占半屏,提出方案和号召时占全屏。人脸出现得太早会削弱钩子;号召语时还用气泡则会削弱信任感。
  • 音效要低于人声: 音量设为 0.1 到 0.2,只用于真实事件(按下按钮、揭晓内容、卡片落下),并在最后按绝对时间点放置。
  • Fil 中的叠加内容应保持为叠加内容。 添加摄像头占位内容、气泡和卡片时使用 overlay: true:这样它们就会叠加在故事之上,修剪、替换或移除它们都不会移动场景(Fil 0.424.0;在此之前,replace 会把图片叠加内容变成故事场景,而对视频叠加内容使用 trim from 会把场景压缩到 0.1 秒)。不过,合并空隙仍会移动其后所有内容,包括音效:移除内容时使用 close_gap: false,否则之后要把音效移回原位。
  • 圆角气泡只需一个设置。 在 Fil 中对视频或图片设置 set: { corner_radius: 30 },即可将其放入带柔和阴影的圆角框中;方形裁切时若圆角半径为宽度的一半,就会变成圆形。在 0.424.0 之前,气泡必须在本地合成。
  • 图片在缩放比例为 1 时会铺满画面。 在 Fil 编辑器中,图片的 scale: 1 会铺满画面;卡片或气泡 PNG 需要设置 fit: "fit"(这样 scale 设为 1 时就能完整显示)。
  • 在新窗口中导出。 export_video 会在打开了画布的 Fil 窗口中渲染。若上传文件前就打开了窗口,该窗口可能会接手任务并报错:“This file isn't available”。请关闭该窗口,或在新标签页中打开剪辑并使用 Export › Save to canvas,然后通过 get_video 读取链接。
  • 以图片形式交付手机链接。 链接只会在首次打开它的设备上生效。如果在 Agent 的浏览器面板中点击链接,链接就会在该处被占用,而且无法使用摄像头。请将二维码作为图片发送,绝不要打开链接来测试。
  • 设置保存在云端的节点上。 提词器的脚本、提词器本身以及跟随我的语音功能都属于录制节点(使用 update_node 的 script_doc),并且在每个窗口和手机上相同。绝不要把短视频设置保存在某个窗口的本地存储中。
  • 渲染需要几分钟,机器繁忙时更久。 每一帧都要通过浏览器截图或 ffmpeg 处理:负载平均值为 350 时,一层包含 1,017 帧的字幕花了 9 分钟。使用 nice -n 10 降低进程优先级,在后台逐个运行;完整影片渲染前,先用 --test 静帧和联系表评估效果。
  • 检查导出文件,而不是时间线。 下载 MP4,以每 0.5 秒一帧的频率拼接成图,测量响度(ebur128),在爆破音处检查口型同步,并将人声高频段与原始录音对比,确认其中包含 Studio Sound。文档中读取的位置有两次出错;帧才是准的。

三条帖子的数字(带占位符的草稿)

项目数值
时长29.5–33.9 s,1080 × 1920,30 fps,−14.4 至 −14.7 LUFS
配音每条各录制一次 ElevenLabs 配音,约 400 个字符;每秒 2.2–2.4 个词;其中一条从 31.8 s 精简至 29.5 s
镜头开场(3–6 s)不露脸;全画面 0.9–2.7 s;气泡 3–7.5 s;半屏 9–22 s;提问时用上半屏,持续 3.7–4.1 s
片段每条短视频 7–19 个片段,速度从 0.26(一帧静止画面)到 2.02,每隔几个片段就裁切放大细节
标题引入部分在 540 舞台上使用 52 px,点题部分使用 100–104 px;提问中的关键词适配 492 px(七个字母:96–112 px)
字幕Inter Tight 78 px,800 字重,使用 Look.md 中的墨色和强调色,5 px 描边,放在分界线上;20–29 行,在大字或全屏人脸下方删去 3–5 行(字幕时间范围生成前)
音效每条 4 个,音量 0.10–0.16,用于揭示内容、卡片和关键词
封面取开场在 2.8–3.6 s 的画面(标题已完整显示),停留 0 → 0.2 s;标题位于 y 900–1300 之间,处于 3:4 裁剪范围内

已发布的数字(HTML Demo 短视频)

项目数值
时长37.5 s,1080 × 1920,30 fps,−14 LUFS
段落开场 0–5.12 · 转折 –8.53 · 证明 –12.50 · 演示 –18.72 · 优点 –25.24 · 提供内容 –28.97 · 价值组合 –35.08 · CTA –37.50
节奏每秒约 2.6 个词;草稿配音 37.8 s,正式录音剪至 33.4 s
录音两段竖屏手机录制;剪掉超过 0.45 s 的停顿;淡入淡出 15 ms;在 “it's HTML” 后留 0.8 s 的节拍
舞台540 × 960 CSS,2×;安全区域为 1920 高度中的 y 280–1640
标题Instrument Serif 52 px,接着是全大写的 Anton 100 px,带 0.17 em 强调色圆点;蒙版内边距为 0.14 em / 0.2 em
气泡268 × 375,位于 x 721、y 1072,圆角 30 px,边框 2 px、白色不透明度 55%;在 0.35 s 内从全画面缩小
分屏在 y 960 处硬切;镜头使用中间的 1080 × 960 区域,在 0.35 s 内从 0.86 → 1 缩放;在 0.32 s 内翻转至上半屏,缓动为 cubic in-out
字幕Inter Tight 78 px,字重 800,白色,正在说的词使用 #efb36c,深色 5 px 描边,居中,每行最多 3 个词
音效音量 0.1–0.2:切换时轻柔呼啸声,按下时咔嗒声,卡片出现时啵声,打字时加入打字声,CTA 处加入撞击声
锚点开场 24 个,单调递增,4 对手动调整
屏幕片段速度为 1.13–2.07,让拖动和逐步跳转在对应词语处落点
评审两位盲测绝对评分评审(数量较少)+ 一位成对评审;开场评分从 6.5 → 6.0 → 7.3 → 7.0,最终持平

验证

  • 第一帧就是封面:开场最佳画面上显示完整标题,位于 3:4 裁剪范围内,在 360 px 宽度下清晰可读,且没有字幕。
  • 导出视频中的每个节拍都与对应词语对齐(打开声音,以 0.25× 速度抽查几处)。
  • 每隔 0.5 s 检查一帧:标题没有超出 y 280–1640 的范围,也没有距两侧不足 16 px;人脸上没有字幕,视频展示内容上没有字幕;气泡没有遮住窗口控件;演示片段中没有光标。
  • 屏幕上的每个名称、数字和账号名都与 Source.md 一致,并注明其他所有人的作品来源。
  • 在相同 t 渲染两次,画面应完全相同。
  • 检查开头、中间和结尾处的口型同步(爆破音:p、b、m)。
  • 综合响度为 −14 LUFS ± 1,真峰值低于 −1 dBTP;配音的高频段低于原始录音(使用清理后的配音)。
  • 字幕与实际说出的内容逐字一致,名称拼写正确。
  • 章节标题标明各个节拍(宣传视频为 8 个,作品展示或“发现了这个”为 5–7 个)。

文件

  • scripts/read-source.mjs:将推文、网页、YouTube 视频或文件读入文字、媒体、帧、测量得到的视觉风格、Source.md 和 Look.md。
  • scripts/reel-clock.js、scripts/reel-clock.css:场景引擎:HTMLReel.scene({ dur, draw, anchors, shape })、变形、四种形状的舞台、通过变量定义的三种类型角色、用于适配未知长度单行文字的 fit、用于首帧的 cover,以及控件。
  • scripts/frame-video.mjs:将演示视频置于卷轴形状的画框中,背景叠加模糊副本;将视频片段切分到词语;在上方添加标题图层;以封面开场(--cover)。
  • scripts/decursor.py、scripts/cursors/:识别屏幕录制中的 macOS 手形光标(从录制中截取的抓取和张开手形模板),并将其擦除,生成 src-clean.mp4。
  • scripts/render-frames.mjs:逐帧将 __frame 页面渲染为 MP4(或透明标题图层,--alpha),支持变形或不变形,并检查安全区域。
  • scripts/timemap.py:将草稿和实际词语时间转换为锚点、映射 W 和场景的局部锚点。
  • scripts/vo-words.py:生成带词语时间戳的 ElevenLabs 旁白,保存其回复并打印语速。
  • scripts/tighten-voice.py:缩短语音中的长停顿,并同步调整词语时间。
  • scripts/named-times.py:为场景和片段中的每个词命名(T.zoom、T.skill2、T.htmlEnd)。
  • scripts/fil-words.py:从 Fil 的字幕列表提取词语时间。
  • scripts/join-takes.py:将手机录制片段拼接成一条口播音轨,并生成剪辑列表。
  • scripts/record-window.mjs、scripts/choreo-example.mjs、scripts/flash-crop.mjs:通过 playwright 驱动 DreamCut 录制,并根据闪光进行裁剪和修剪。
  • scripts/bubble.mjs、scripts/split-flip.mjs:在本地合成摄像头画面,制成圆角气泡或翻转的半屏画面。
  • scripts/preview-reel.mjs:在本地预览 Fil 将要排布的内容:画面、按编辑器设定值排列的摄像头图层、电影式字幕、旁白和音效。
  • scripts/verify-export.mjs:检查导出文件的尺寸、响度、画面表和纯净语音。
  • references/source.md:将源内容读入 Source.md(文字)和 Look.md(视觉风格)。
  • references/structures.md:结构(宣传片、展示、发现分享、讲解、前后对比)和布局库,涵盖无露脸和出镜形式。
  • references/formula.md:宣传片的 8 个部分和 6 种摄像头布局,以及如何研究参考卷轴视频。
  • references/fil-editor.md:通过 MCP 在 Fil 的视频编辑器中组装内容,包括手机录制片段和导出。
  • references/retime.md:拼接录制片段,并根据实际词语为每个部分重新定时。
  • references/judging.md:评估标准、盲测评审,以及何时停止。
  • demo/index.html:一个使用时钟的钩子场景,可播放草稿旁白,也可根据实际录制重新定时。

评论

支持 Markdown