You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
7.2 KiB
7.2 KiB
hilo-promo · 规范速查与文件结构
详细技术规范与文件组织,供阶段六合成时参考。
关键规范速查
字幕规范
📸 视觉参考:
assets/subtitle_style_ref.jpg(实拍样式图,收录于 skill assets)
| 项目 | 规范 |
|---|---|
| 渲染方式 | PIL 生成全帧 RGBA 透明 MOV,再用 ffmpeg overlay 叠加(本环境无 drawtext/ass filter) |
| 字体 | Arial Black,全大写(text.upper()) |
| 颜色 | 白色填充 (255,255,255),橙红色描边 (210,70,10),stroke_width=4 |
| 自适应字号 | 从 56pt 开始逐步缩小(52→48→44→40→36→32→28→24),直到文字宽度 ≤ 756px(画面宽 70%) |
| 左右边距 | 每侧留白 15-20%;最大文字宽度 = 1080 × 0.70 = 756px |
| 竖向位置 | 文字底边在 y = 1344(画面高度 70%,位于数字人 PiP 上方) |
| 显示方式 | 逐句单行:一次只显示一句话,句与句之间无重叠;长句拆成短语分时段显示 |
| 时间戳来源 | 先用 audio_transcribe_lyrics 获取句级时间戳,再按自然语义拆成 5-7 词的短语,时长按字符数比例分配 |
| 无背景条 | 文字直接叠加在视频画面上,不加半透明底条 |
PIL 渲染核心代码:
font, tw, fs = fit_font(text, max_w=756) # 自适应字号
x = (1080 - tw) // 2 # 水平居中
y = 1344 - fs # 底边对齐 y=1344
draw.text((x, y), text.upper(), font=font,
fill=(255,255,255,255),
stroke_width=4, stroke_fill=(210,70,10,255))
数字人 PiP 规范
⚠️
pip_clean.mov易过度抠像(alpha 全零),阶段七合成时改用talking_head_green.mp4+ ffmpegchromakey实时抠像,更可靠。
| 项目 | 规范 |
|---|---|
| 抠像方式 | ffmpeg chromakey 实时抠绿幕(阶段七合成时内联,无需预处理) |
| 绿幕颜色 | 采样视频角落像素确定实际颜色(AI 生成绿幕通常为 RGB≈56,138,61 = 0x388A3D) |
| ⚠️ similarity | 必须 ≤ 0.10(深色皮肤角色 YUV 距离仅 0.25,similarity=0.15 即开始抠掉人物;切勿使用 0.2 以上) |
| blend | 0.02(边缘锐利,减少半透明残边) |
| 缩放 | scale=400:-2(宽 400px = 画面宽 37%,高度保持比例,约 541px) |
| 位置 | overlay=x=0:y=H-h(左对齐,底部与视频底边齐平) |
| 起始时间 | enable='lte(t\,{voiceover_end})'(第 0s 出场,口播结束即消失) |
| 图层顺序 | 数字人必须在最上层(覆盖字幕层之上) |
| 幕色选择 | 默认绿幕 #00FF00;角色服装含绿色调时改用蓝幕 #0000FF |
阶段七 filter_complex 片段:
[2:v]chromakey=0x388A3D:0.10:0.02,scale=400:-2[pip_keyed];
[v_sub][pip_keyed]overlay=x=0:y=H-h:enable='lte(t\,13.735)':format=auto[v_out]
similarity 诊断方法:
# 提取单帧检查抠像结果
ffmpeg -ss 3 -i talking_head_green.mp4 -frames:v 1 -vf "chromakey=COLOR:SIM:0.02" test.png
# 用 PIL 检查 non-zero alpha 像素数
# 正常:~55-65% 像素可见(人物占画面大部分区域)
# 过度抠像:< 5% 像素可见 → 降低 similarity
教程段规范
| 项目 | 规范 |
|---|---|
| tut_002 时长 | 1-1.5s,严禁超过 2s |
| tut_004 | 不展示静态原图;上传动画结束即为确认状态 |
| 教程 overlay | 必须预拼接为单一 tut_combined.mp4,禁止分段 overlay |
| 教程结束衔接 | 教程段结束后立即切回写真照片,无缝衔接 |
音频规范
| 项目 | 规范 |
|---|---|
| 语音收尾 | 截断而非 fade out:尾板开始时直接截断口播,禁止 fade out |
| BGM 音量 | volume=0.15,不可盖过口播 |
| voice_id | 根据角色性别,调用声音列表工具(如 get_voice_id)选择合适的声音 |
| 尾板音频 | 用 amix 混合,保留尾板自身声音 |
| 音效保留 | 原 skill 中的所有音效必须保留(如闪光灯音效、转场音效等) |
口播超过 6s 时的画面循环处理(数字人视频生成上限 ~5.88s):
ffmpeg -stream_loop N -i talking_head_green.mp4 -i voiceover.mp3 \
-map 0:v -map 1:a -c:v libx264 -c:a aac -shortest -t {实际音频时长} output.mp4
图片转场规范
- 写真图之间必须使用 xfade 转场(
slideleft/slideright/fadeblack) - 禁止硬切
文件组织总览
{project_name}/
├── fonts/
├── brief.md # 需求摘要
├── character.jpg # 角色形象图
├── character_prompt.txt # 生图提示词
├── digital_person/
│ ├── green_screen.jpg # 绿幕肖像(Step 1)
│ ├── talking_head_green.mp4 # official 图音视频(口型同步,Step 2)
│ ├── pip_clean.mov # 抠像后透明视频(Step 3)
│ └── talking_head_preview.mp4 # 5s demo 预览
├── photos/ # 换脸写真
│ ├── photo_01.jpg
│ ├── photo_02.jpg
│ └── photo_03.jpg
├── voiceover.mp3 # 口播语音
├── voiceover_script.txt # 口播文案
├── voiceover_subtitle.json # 字幕时间戳
├── final.mp4 # 最终视频
└── final_4x5.mp4 # 4:5 裁切版
⚠️ 合成时音频处理:数字人视频(talking_head_green.mp4)自带音频,合成时直接使用该音频,不要分离音频再混合,避免口型错位。
导出剪映/CapCut
使用 clip-export skill 与 scripts/export_to_jianying.py 导出工程到剪映/CapCut 进行精细调整。
脚本已内置多路径自动查找 jy_wrapper(同级 ../clip-export/scripts/、~/.claude/skills/clip-export/scripts/ 等),无需手动指定路径。
使用方式
python scripts/export_to_jianying.py \
--project-name "my_promo" \
--photos photos/photo_01.jpg photos/photo_02.jpg photos/photo_03.jpg \
--digital-person digital_person/talking_head_green.mp4 \
--voiceover voiceover.mp3 \
--bgm bgm.mp3 \
--subtitles voiceover_subtitle.json
若找不到
jy_wrapper,脚本会打印安装提示;也可通过JY_WRAPPER_PATH环境变量手动指定clip-export/scripts/目录路径。
合成命令参数
动作模板合成
python scripts/composite.py action \
--dance ./dance_video.mp4 \
--tutorial ./tutorial_segment.mp4 \
--voiceover ./voiceover.mp3 \
--bgm ./bgm.mp3 \
--subtitle-json ./voiceover_subtitle.json \
--endcard ./assets/endcard_en.mp4 \
--output ./final.mp4
图片模板合成
python scripts/composite.py image \
--photos ./photos/photo_01.jpg ./photos/photo_02.jpg ./photos/photo_03.jpg \
--tutorial ./tut_combined.mp4 \
--pip ./digital_person/pip_clean.mov \
--voiceover ./voiceover.mp3 \
--bgm ./bgm.mp3 \
--subtitle-json ./voiceover_subtitle.json \
--endcard ./assets/endcard_en.mp4 \
--output ./final.mp4
所有路径均相对于
{project_name}/项目目录。--photos传入所有写真图,顺序即展示顺序;--pip仅图片模板需要传入。