adnaan-reel
Adnaan 的素材 → 一个与已批准参考编辑稿完全一致的短视频。在一切开始之前,请先查看 assets/style/v8_contact_sheet.jpg——经批准的 reel-08 风格测试的 v7 “MINT” 风格,这是自 2026-10-17 起的主视觉默认风格(场景在 examples/reel-08-v7/ 中):TALK 节拍:他全屏 + 我们的动态文字;VISUAL 节拍:灰色板上的图标圆盘、圆盘链条和移动相机、标志性缩小效果。请先阅读 references/style.md “v7”——它会在与旧版冲突的地方覆盖旧版;v6 的声音规则、安全区、可读性规则和运动原理仍然适用。艺术指导具有约束力,存在于 references/style.md 中;场景语法(如何将短视频拆分为场景以及存在哪些场景类型)存在于 references/scenes.md 中。外观即代码:共享运行时 templates/runtime/paper.css + paper.js(世界、动态文字、原语、基于 Lasseter 原则的运动)+ v7.css + v7.js(v7:图标圆盘、圆盘链条、缩小/放大到圆盘或卡片、相机、区域遮罩),以及每种场景类型在 templates/scenes/ 中的一个启动器(v7:talk、talk_depth、visual、chain、card);slots.py prepare 将它们安装到每个场景中,因此每个场景大约 150 行复制、定位和一个定制对象。
传统的 PAPER 风格(红纸 + 手绘标记层 marker.css/marker.js、分隔带、reel-06/07——assets/style/v6_contact_sheet.jpg、v7_contact_sheet.jpg、examples/reel-06/、reel-07/)是在 init-brand --look paper 时使用的,只有当他要求时才使用。较旧的创意库:examples/reel-04/、reel-05/ 和 references/motion-ideas.md(衬线编辑风格:examples/reel-03/、init-brand --type editorial)。
你永远不看视频——你读它:按词级的脚本、在决策点的电影胶片、以及验证剪辑连接的工具。
原则
- 每个节拍都是一个场景,属于两种模式之一(v7)。 整个短视频由 8–18 个全屏 HyperFrames 场景在锁定剪辑上背靠背拼接而成,每个节拍在节拍表中选择一种模式:TALK(他全屏,我们的动态文字在他身上——钩子、过渡、观点、回报、行动号召;
talk,或者当有东西坐在他身后时使用talk_depth)和 VISUAL(没有讲话者;板子、图标圆盘、平面矢量道具、真实页面、移动相机——每个解释、列表项、例子;visual)。他在屏幕上的时间约占短视频的 50%;没有他的 VISUAL 连续镜头不超过约 8 秒。标志性缩小效果(每个短视频 1–3 次:他的镜头缩小到当前链盘或左侧小卡片中,chain/card;V.grow将他带回来以呈现回报)连接了这两种模式。小卡片出现 0–2 次。列表短视频的地图是链盘(V.chain)。长时间的屏幕录制是demo类型。 - 文字就是字幕。 没有副标题。动态的 Inter Tight 900 短语落在其口头单词上,很大(主要字 170–270 px 设计尺寸,乘以 0.94 宅
--type-scale;按颜色加重,无斜体;v7:炭灰色带柔和他镜头上的发光,ONE 个薄荷色主要字,薄荷色仅用于主要尺寸)。屏幕上的文字只能是他实际说出的词(ASR 拼写的名字已修正)——再加上一个可选的文字钩子(第 0 帧标题)。 - 展示真实的实物,使用真实的标志。 他提到的每个产品、仓库、网站、文件或框架都必须真实出现:浏览器卡片中的捕获页面、真实的仓库片段、星标数、真实的标题和部件名称。
他提到的每个工具或公司都获得其官方标志(
fetch.py logo,记录为official),在名称旁边的标签/药片中作为<img>未经修改地显示,或显示在应用卡片上——当存在标志时,绝不重绘、重新着色或用纯文本标签替换。说明性 UI 是可以的;但虚构数字、引文或帖子则不行。 - 先批准计划,然后构建所有内容。 一个节拍表 → 批准 → 所有场景并行构建 → 组装 → 自检 → 交付。自动模式(“直接做”)跳过等待。
- 绝不乏味,始终保持动画。 每个场景都有一个核心创意,具有真实的运动(事物展开、打开、合并、堆叠、沿虚线路径移动、从灰色翻转为强调色)以及持续的生命力,并且每个动作都遵循 Lasseter 的原则(
references/animation-principles.md:预备、过冲 + 稳定、重叠、弧线、舞台布置、次要动作、一个夸张节拍、退出快于进入)。运行时默认执行此操作;定制对象也必须如此。如果一个场景可能只是一个静态幻灯片,则重做。丰富性是主视觉级别(reel-05),由 v6 调节: 一次大约两个焦点元素,网格的 35–50% 为空(基于内容指南,而非硬性限制)——一个核心对象 + 1–3 个次要微观动画,这些动画演绎句子——执行操作的光标、滚动到其值的真实数字、活过来的图标、软物理、具有个性的角色、表演的字体、落到其文字上的核心图标(references/motion-ideas.md)。 - 顶部为干净的平面矢量(v7)——薄荷色风格中没有手绘标记。 带有白色 Phosphor 字形的图标圆盘(
fetch.py icon、V.disc)、能自身绘制的干净矢量描边(连接器、下划线栏、放大镜边缘——等宽,无抖动)、具有运动个性的平面矢量核心对象、真实文本后面的薄荷色荧光笔。桃色仅用于数据。(传统的纸张风格保留红色毡尖标记 + Caveat 笔记,hf/marker.js。) - 始终可读。 确保所有内容都在安全区域内(已测量),真实页面以大横条形式呈现(≥ 0.85,~45 px 文本),后面有荧光笔突出显示口语短语,无半透明文本,他衣物上的文字清晰可读(v7:炭灰色 + 发光,主要尺寸用薄荷色;纸张风格:在实色纸张上),标签/标志/涂鸦在手机上应足够大。他明确提出了这个要求。IG 安全区域(v6): 底部 20% 内无内容,且 y 1200 以下 x 900 右侧无内容(Like/Comment/Share)——行动号召放在左下/中间位置。
- 声音支持语音——30% 规则(v6)。 无米老鼠式配乐:0:00–0:04 内 1–2 个有力的触觉声音,然后仅结构性过渡(第 1/2/3 点、模式切换、大截图滑入、行动号召落地)——70 秒内约 10–14 个提示,来自温暖低沉的 v6 素材包(
assets/sfx/v6_*:印章声、哐当声、重击声、纸张声、嗖嗖声、砰的一声),低通滤波在 5 kHz。代理将这些节拍标记为"role": "hook" | "structural"在beats.json中;scenes.py edl(默认--sfx-policy sop)保持其他所有内容静音。混音: 语音在前,SFX −16…−22 dB,ElevenLabs Music 背景音乐(器乐,与情节弧线同步)在语音下 −22…−26 dB 通过--music,最后 3 秒增加 2.5 dB。 - 展示前先验证。 每个连接点都经转录,每个场景都经过检查表核对,组装后的短视频进行快速浏览和抽检。如果你不会发布它,就不要呈现它。
硬性规则
- 节拍表在构建场景前必须获得批准(除非使用自动模式)。
- 按片段提取 → 无损拼接用于剪辑(render.py),连接点处 30 ms 音频淡入淡出,绝不在单词内部剪辑,边缘填充,仅使用按词级转录,每个源缓存。
- 每个填充剪辑和每个连接点都必须经过
verify_cuts.py验证——Whisper 会过早结束单词,并且audio_env.py tighten会吞噬软单词结尾(“code”、“immediately”、“base”、“use”在参考编辑稿中均被剪掉;在 reel-05 中“works”丢失了其“s”,而 ASR 仍然读作“works”)。读取每个连接行及其 ⚠ TAIL/HEAD 能量标志(有意填充剪辑也会标记——这是预期的);当真实单词被剪掉时,将范围结束时间扩展到建议的时间,重新探测直到干净。 - 绝不从
edit/渲染部分或测试 EDL。 render.py 在 EDL 旁边写入base.mp4和timeline.json——edit/中的测试 EDL 会覆盖真实的 base。使用scenes.py preview <id>预览单个场景;使用verify_cuts.py --probe测试剪辑。 - 场景 EDL 只能来自
scenes.py edl。 它会对每个场景进行帧快照,预卷 12 毫秒,并使每个场景比下一个场景保持 0.1 秒——没有这个,render.py 的叠加同步会在每个场景边界处泄漏一个原始素材帧。然后scenes.py flashcheck <render> --edit-dir edit:0 个意外的原始素材帧(它将每一帧与base.mp4进行比较——reel-05 的天花板是纸张色,所以旧的角落测试是盲目的;计划的fullscreen/demo窗口来自slots.json并且是可预期的)。 - 每个场景一个子代理,所有子代理在一次消息中生成。 在每个
check_sheet.jpg/motion_strip.jpg落地时进行审查;使用 SendMessage 向同一代理发送修复(它会保留上下文)。每个场景必须精确符合其 TASK.md 帧数(slots.py预设了它,并且check会强制执行)——在使用scenes.py edl之前使用 ffprobe 验证所有计数;1 帧的差异意味着剪辑处有间隙或重叠。 - 通过运行时的品牌保真度。 场景使用已安装的
paper.css/paper.js+v7.css/v7.js(薄荷色)或marker.css/marker.js(纸张)——绝不编辑,绝不按场景重新实现(带有自己的卡片或文字引擎的场景将在审查时被拒绝)。仅使用 brand.css 令牌;捆绑字体断言已加载;绝不绘制或重新着色标志(仅来自官方文件的真实标志,已记录);一个强调色。绝不克隆付费字体——如果他想使用商业字体,他会购买许可并将文件放入;在此之前使用最接近的 OFL 字体(Bootzy TM → Inter Tight 900,当前默认值)。全局更改(字体、卡片大小、缓动)在templates/runtime/中进行一次,然后使用scenes.py runtime+scenes.py rerender。 - 通过
fetch.py下载,通过capture.py捕获(两者都记录来源 + 权利);fetch.py credits→ 在交付前生成credits.md。第三方页面作为对他推荐内容的评论来展示,放在浏览器卡片中,绝不冒充为他自己的内容。 - 所有输出在
<project>/edit/中。 绝不写入技能目录内部。 - 剪辑前的镜像检查:在全分辨率静帧中放大他服装/背景上的任何文字或标志(电影胶片太小了——reel-06 的倒置“SAN DIEGO”补丁仅在场景审查时被发现,并导致每个演讲者片段的重剪)。倒置则→
"mirror": true。 - 可读性是审查关卡(style.md “Readability”):如果场景中出现区域外像素、不可读的页面、幽灵文字、深色织物上的文字或手机大小的标签/涂鸦,则返回给其代理。
- 相信时间戳,而不是报告:在代理说“已重新渲染”后,检查
render.mov是否比其输入更新(reel-06 v01 报告了从未发生的重新渲染)。
设置
与 video-edit 相同的工具链(详情见 install.md):带 libass + zscale 的 ffmpeg/ffprobe、uv(辅助脚本作为 uv run --project <skill_dir> <skill_dir>/helpers/<name>.py … 运行)、转录(ElevenLabs 密钥 → Scribe;否则为 Apple Silicon mlx 通过 uv sync --extra mlx;否则为 whisper.cpp)、用于 HyperFrames 的 Node 22+(npx --yes hyperframes …)、用于 capture.py 的 Google Chrome。<skill_dir> 是包含此文件的文件夹(~/.claude/skills/adnaan-reel)。
新鲜度(每次会话一次,在任何渲染之前): 技能调用 npx --yes hyperframes(不固定版本),它会解析到最新发布的 CLI(场景 package.json 的固定版本仅由 npm run 使用,我们从不调用)。通过 npx --yes hyperframes --version 对比 npm view hyperframes version 来确认,并在任何 HyperFrames 技能过时时运行 npx --yes hyperframes skills check → npx --yes hyperframes skills update(2026-10-14 时有 10 个落后)。在 project.md 中记录 CLI 版本;如果更新后某个渲染看起来与之前的短视频不同,请说明。
辅助脚本
| 辅助脚本 | 功能 |
|---|---|
| `scenes.py init-brand --edit-dir E [--look mint | paper] (mint = v7 主视觉默认) [--accent red |
fetch.py icon <name…> --edit-dir E [--weight fill] | v7 图标圆盘字形:Phosphor(MIT)SVG → icons/<name>.svg,记录为 open-source;将它们列出到槽位的 "assets" 中作为 icons/<name>.svg,用作 V.disc({icon: name})(名称:phosphoricons.com) |
scenes.py words --edit-dir E | 每个剪辑片段,包含输出起始时间、帧和文字——在此选择场景边界 |
scenes.py cut-speaker --edit-dir E [--only ids] | 每个场景:base.mp4 窗口 → hf/assets/speaker.mp4(静音;帧精确搜索;最后一个场景用结束保持冻结填充)+ speaker_cut.webm(他的遮罩)用于 talk_depth / cutout 场景 + 复制场景的 "assets";--only 用于中期构建剪辑修复 |
scenes.py edl --edit-dir E [--beat-gain-offset -3] | edl.json + animations/slots.json + 渲染 → edl_scenes.json(帧快照、预卷、0.1 秒保持、无字幕)+ 每个场景的 beats.json → 来自 ElevenLabs 素材包的定时 audio[] 提示 |
scenes.py preview <id> --edit-dir E | 带有语音的单个场景 → verify/<id>_preview.mp4(安全:从不触碰 base) |
scenes.py flashcheck <video> --edit-dir E [--allow] | 匹配 base.mp4(= 显示原始素材)但不在计划的 talk/talk_depth/chain/card/fullscreen/demo 窗口内的帧(必须为 0);没有 --edit-dir 则进行角落颜色测试,该测试能容忍场景自身的晕影 |
scenes.py runtime --edit-dir E / scenes.py rerender --edit-dir E [--jobs 4] [--only ids] | 将共享运行时重新安装到每个场景中 / 并行重新渲染所有场景并验证帧数——几分钟内即可完成整个短视频的重新设计(新字体、卡片大小、缓动) |
capture.py <url> --edit-dir E --name n --rea | …(截断) |