Edit-video 工作流
每次用户发送原始视频时,请严格遵循以下步骤。工具根目录:/home/user/video-workflow
(VW=/home/user/video-workflow)。每次在暂存区为每个视频使用新的工作目录,例如 $SCRATCH/<名称>/work。
在步骤 4 之前阅读 STYLE_GUIDE.md(风格)、EFFECTS.md(17 种特效库——每个视频必须使用多种)和
templates/STORYBOARD_REFERENCE.md(语法)。
0. 设置(每个容器仅一次)
$VW/vw.sh setup。如果提示 huggingface.co 被屏蔽,请告知用户必须在其环境网络设置中允许
huggingface.co(和 *.hf.co)才能运行转录;不要自行生成转录文本。
1. 准备 + 转录 + 提出剪切方案
$VW/vw.sh prep RAW.mp4 WORK [--language ro|en] [--model small|medium]
- “水洗”版 SDR 片段(iPhone HDR 经压缩器应用重新编码,无色调映射:黑色发灰、白色暗淡——例如 *_compressed.mp4)会被检测到(黑色点高于 Y45,或白色点低于 Y203——与同一组色调映射的 .mov 片段相比白色暗淡),并在 prepare.py 中恢复其电平(亮度拉伸至 Y34~约 215,色度 x1.08),匹配已批准的色调映射 HDR 自然外观(Mindri-Box-v3)。
- 每个片段上的批准色彩外观(用户规则——‘我们讨论过的滤镜’):在标准化之后,prepare.py 在
source.mov上运行look_match:它测量画面的上 60%(背景+人物),并应用色调曲线+饱和度,使每个片段匹配已批准的外观(Mindri-Box-v3 / Comanda-Ionut-v2/v4:深黑、鲜艳橙色、干净的白色 T 恤;目标值 p5 38, p25 52, p50 76, p95 226, 饱和度 59)。它仅加深阴影/中间调、提亮暗淡的白色并增加色彩(每点最多 35 级,饱和度最大 x1.3);已匹配外观的片段保持不变。因此多片段视频彼此匹配。上层grade保持为natural。 - 手机拍摄的 HDR 画面(iPhone:HLG/PQ,BT.2020,10 位,杜比视界)自动色调映射为 SDR BT.709(zscale + hable,100 尼特)——否则一切看起来苍白且发灰。输出标记为 BT.709。
- 标准化为 30 fps CFR,1080x1920(覆盖裁剪),检测人脸(MediaPipe 全范围)并测量标题区域亮度 →
layout.json(安全区域;明亮区域会使标题带框且玻璃文本着色)。 - 使用单词时间戳转录(保留“嗯”/重新开始) →
transcript.json。 - 自动标记填充词、口吃、截断的词和重新开始 →
edit.json+review.txt。 - 对于罗马尼亚语或嘈杂音频使用
--model medium;否则自动语言检测。 - 如果源视频是横屏(会打印警告),告知用户已将其中心裁剪。
1b. 多个原始片段(一个故事)
当用户发送多个片段时,先逐个转录每个片段,并根据说话内容确定顺序(通常是拍摄顺序)。对每个片段(WORK_k)运行步骤 1-2 和 cut,然后合并:
python3 $VW/scripts/merge_clips.py WORK WORK_1 WORK_2 … → 一条时间线;layout.json 保留每个片段自身的取景(clips[]),渲染器和特效使用当前屏幕上片段 的取景。在合并后的 words.json 中修复字幕文本,然后从步骤 4 继续操作 WORK。在每个片段边界处放置转场(zoom_through、flash、glitch)。
2. 审查编辑(判断步骤——请勿跳过)
像编辑一样从头到尾阅读 WORK/review.txt,并修复 WORK/edit.json:
- 移除:失败的拍摄/检测器遗漏的重新开始(保留最后一个好的拍摄)、念错的句子、“等等,让我重做一遍”、离题的话、乏味的开场(“嘿,各位”、“嗯,今天……”)——视频必须以吸引人的开场白开始。
- 保留(
"keep": [idx…]):检测器错误移除的词语(有意的重复、“非常非常”、列举)。 - 低置信度词语
(?):检查上下文;听错的词是字幕问题(在transcript.json中修正文本,保留时间),而不是剪切问题。 - 节奏参数:
max_gap0.20 秒(紧凑,指南风格);如果单词末尾听起来被切断,则将pad_after提高到 0.14。 然后:
$VW/vw.sh cut WORK
它必须打印 Sync check: … OK。如果 MISMATCH → 停止并调查(切勿交付)。剪切点对齐到帧并放置在静音处,因此唇形同步是精确的。重新阅读 WORK/words.json(新时间线)——所有后续时间都使用它。
3. 修正字幕文本
在 words.json 中更正拼写错误、品牌名称、数字(当阅读效果更好时“ten”→“10”),并保留用户的
语言和变音符号(ă â î ș ț)。不要更改时间。
4. 故事板(判断步骤)
编写 WORK/storyboard.json(语法:templates/STORYBOARD_REFERENCE.md,示例:templates/storyboard.example.json)。
首先编写一个简短计划作为表格(时间 · 所说内容 · 视觉 · 转场 · SFX),并在回复结束时展示给用户。来自风格指南的规则:
开场吸引点(0-3 秒) ——最强的陈述作为巨大的 title 元素,每个短语一个,3 秒内至少 3 次视觉变化
(标题切换/字体切换/闪光/拉近)。混合标题字体(衬线 → 粗体 → 斜体金色)。无开场白。
主体 ——屏幕上大约每 ~1-3 秒发生变化:
- 用视觉元素说明所说内容,时间对准提及该内容的具体单词(元素
start= 该单词的start): 工具/应用 →strike(当被拒绝时)或card;指令/提示 →prompt(打字);数字 →counter/stat; 步骤 →step徽章;列举 →list;关键短语 →title;用户提供的截图/标志 →image/card。 - 每个句子一个英雄关键词放在
captions.keywords中(能承载意思的词,而非填充词)。 - 拉近缩放(
zooms,比例 1.06-1.12,绝不超过)用于强调的行,与 1.0 交替——这样能保持 说话者处于正常取景,同时隐藏跳切。 - 仅在段落变化/关键收尾处使用风格化转场,最多每 5-10 秒一个:
flash、glitch、leak、whoosh、impact。 - 每 10-15 秒切换模式(例如,一串 UI 卡片,然后是一个大标题时刻,然后是一个统计)。
说话者始终可见:图形放在 pos: "top"(头部上方,根据 layout.json 中的可用区域自动调整)或 "lower"(胸部区域,字幕上方)。绝不对 center 覆盖脸部。标题可稍微重叠头顶(这就是外观),但绝不能覆盖眼睛/嘴巴。
“编辑”参考规则(EFFECTS.md,底部)——在每个视频中必须遵守:始终使用色彩 grade
(默认 natural 预设——画面本身的色彩,无风格化滤镜;其他外观仅在要求时使用),每 30 秒进行 1-3 次面部 tracking,为命名的具体事物使用互联网 photos
(scripts/images.py,先查看它们,在回复中注明出处),为开场吸引点和章节标题使用 combo 标题,为列举使用 numcards。
特效库(EFFECTS.md)——在每个视频中必须使用:最终视频中大约每 4-6 秒一个特效时刻
(30 秒 → 5-7 个,60 秒 → 9-12 个),每个特效与正在说的内容相匹配,约 15 秒内不重复,混合使用相机、抠图和 UI
类。在开场吸引点中放置一个。包含所有特效的示例:templates/storyboard.effects-example.json。
CTA/结尾(如果用户说了他们想要的东西):在最后 4-6 秒内使用 comment(关键词 CTA)和/或 follow 卡片。
品牌主题(用户的固定选择)——屏幕上的一切:故事板 "style": "depth", "palette": "mindricel"
→ 标题、卡片、步骤、磁贴/数字、图表、检查清单、笔记、轨道卡片、玻璃文本和产品都使用
mindricel.ro 调色板中的深度参考外观(橙色 #FF6600 渐变、墨黑色 #0A0A0A 面板、白色文本、精细的深色
轮廓)。标题行中的编辑字体名称会自动映射;使用橙色(#FF6600/#FF8533)或白色用于
涂鸦。切勿混入绿色/奶油色编辑颜色。
字幕(用户的固定选择——“锁屏”参考,完全照搬):"captions": {"style": "lockup", "palette": "scene"}(无需关键词列表;角色自动分配)。
- 每个口语短语(2-5 个词)是一个排印组合:实词 BIG 格式(Montserrat ExtraBold,约 170 px, 紧凑 -0.045em,按说话方式——大多小写),虚词 SMALL 格式(Montserrat SemiBold,1/3 大小,白色带精细 深色轮廓)塞入实词的角落——在一个实词之前:左上角,之后:右下角 (“over $10,000 a month”)。每行一个实词,行之间紧密堆叠并左右交错。
- 每个实词的填充:数字/金钱 → 绿色渐变,否定词(nu,fără,stop,greșeli,scump...) → 红色
渐变,其他 → 来自该片段画面颜色的渐变(
body_profile.py调色板)或白色;在明亮场景下自动更深/更饱和,在黑暗场景下更浅,以便始终可读。 - 位置在头部/胸部/头部/头顶上方旋转;当标题或图形占据顶部时,短语保持在胸部。前方的短语 绝不覆盖脸部(从头发到下巴):而是移到胸部或头顶上方。
- 深度(用户规则,每个视频):大约 40% 的短语(
behind_share0.4)稍微位于头部后方(后层- 抠图)。搜索范围涵盖从“下边缘掠过头发”到中脸部的高度,并横向偏移 ±240 px。一个位置有效
仅当头部确实与某个词重叠(
behind_min_overlap5%),每个实词最多隐藏 25%(短词每个字母约 4%,例如 4 个字母最多 16%),并且第一个/最后一个字母的顶部 保持可见。使用该片段上最差的轮廓(occ_max),按该时刻激活的任何缩放比例缩放。绝不会连续 3 个短语位于后方,也绝不会在图形占据顶部时使用。在 QA 中检查那些帧。
- 抠图)。搜索范围涵盖从“下边缘掠过头发”到中脸部的高度,并横向偏移 ±240 px。一个位置有效
仅当头部确实与某个词重叠(
- 可读性:每个实词都有精细轮廓(暗区用深色,亮区用浅色)+ 柔和阴影;虚词
有深色轮廓。填充颜色根据短语正下方的亮度选择(
lum地图来自 body_profile.py):暗区域用浅色调,亮区域用深色调——调色板保持画面本身的颜色。 - QA:检查没有前层短语接触脸部,并且后层短语清晰可读(在每个短语处打开帧检查)。
- 运动:短语侧向甩入,带运动模糊残影,词随着说话出现(快速模糊进入), 并在下一个短语开始时向相反方向甩出(短语之间无间隙)。
- 阅读时间:一个短语在说话前
lead0.25 秒出现(其词稍微超前于声音),短于min_phrase1.0 秒的短语与下一个/上一个合并(最多 7 个词 / 34 个字符),最后一个短语保持hold1.2 秒。视频在最后一个词之后保留tail0.8 秒的画面(edit.json参数;如果画面 提前结束,则保持最后一帧)。多片段:除最后一个片段外,其他所有片段"tail": 0。 - 混合背景(例如白色 T 恤在深色背景前,短语正下方亮度分布 > 0.17):使用视频自身颜色中鲜艳的中间色调,搭配深色轮廓(见下方“字幕颜色”)。
- 对比度保护:如果某词的颜色与其背景的亮度过于接近(
min_contrast0.42),则该颜色 会使用其最大对比度色相 + 精细轮廓——绝不变成白色(用户规则)。 - 敏感/严肃主题(葬礼、疾病、损失、道歉...):保持锁屏外观,但
"motion": "fade"(柔和的淡入,无甩动),"semantic": false(无绿色/红色单词颜色),无故障/像素/眩晕/帧断裂效果, 无冲击力音效(完全没有也可以),缓慢的推进和温和的跟踪,等级强度约 0.6,并且没有 mindricel 橙色主题,除非这是用户自己的品牌。告知用户语气已调整,并提供充满活力的版本。 - 较旧的字幕样式(
clean标题、depth、bold、editorial)仅应要求使用。
数字:tiles 现在渲染为一个深色圆角药丸形状,包含清晰的大数字计数,并可选地在橙色中包含 unit
(例如 {"type": "tiles", "text": "400-600", "unit": "cm³"});旧的方块仅在带有 "look": "classic" 时使用。
转场(房地产参考):在片段更改/部分更改处使用 flash_blur(过度曝光散焦)、
pixelate(像素溶解,也适用于元素/图像离开时)、zoom_through,以及缩放跳切(punch
在跳切上交替使用 1.0 / 1.1-1.15)。glitch 要少用。
声音(用户的 SFX 参考视频,已提取——唯一的库;旧的合成库已按要求删除):
sfx/ 中有 10 个 WAV 文件(峰值 -3 dBFS):loading(数字滴答声 0.9 秒)、click、air(短促的空音嗖声)、tap(柔和的爆音)、
marker(荧光笔划痕)、tick(微小的 UI 滴答声)、blur_hit(冲击力撞击 + 尾音)、swish、sub_boom(次低频
落下)、logo_hit(大揭秘撞击声)。自动映射(compose.py):flash_blur → blur_hit,zoom_through/leak/
whoosh/swoosh 转场 → swish,flash → air,pixelate/glitch/rewind → loading,impact → sub_boom,punch → click;
title/stat/combo → blur_hit(第一个 combo 加 sub_boom),strike/doodle/wall/accent → marker,cards/app/image/product info → tap,
products → air + swish,steps/lists/checklists/numcards → click,counters/tiles/charts → loading,glass/cover → sub_boom,
follow card → logo_hit,typing → tick。旧名称(pop、whoosh、deep_bass、ding...)仍可通过 SFX_ALIAS 工作。
SFX 密度(用户:“更频繁地使用音效”)——默认 "sfx_density": "high":在元素和
转场声音之上,compose.py 添加安静额外的声音(-15..-19 dB),用于字幕短语变化(短语在头部后方时用 air,数字/价格上用 tap,否则交替使用 swish / tick;来自 WORK/caption_events.json),每个跳切上(click),顶部图形离开时(air),以及推拉/跟踪相机移动时。每个额外声音与相邻声音保持至少 0.3 秒间隔(约每秒 1 个音效)。平静主题:"sfx_density": "normal"(当字幕 motion: "fade" 时自动使用)。
更少的字幕(用户规则,每个视频):每个短语都加字幕会让人疲劳——只有约 60% 的短语获得字幕
(captions.density 0.6 = 减少 40%)。渲染器保留最有意义的短语(实词、数字/价格、否定词、名称、问题/感叹;填充词如 bă/mă/băi/deci 得分降低),始终包含第一个和最后一个短语,并且从不会有连续 4 个短语
...