Install
openclaw skills install @hitjcl/ai-short-film-finalizationFinalize an AI-generated short film using the free Route C pipeline (Google Flow Omni Flash text-to-video, Nano Banana 2 image generation, edge-tts narration, Chrome CDP automation). Covers shot generation, consistency checks, 1080p composition with subtitles/BGM, director review console, and highlight trailer.
openclaw skills install @hitjcl/ai-short-film-finalization本 Skill 覆盖 零成本 AI 短片全链路,采用 路线 C:
| 环节 | 工具 | 成本 |
|---|---|---|
| 文生图 | Google Flow Nano Banana 2 | 免费(Google Labs 积分) |
| 图生视频 / 文生视频 | Google Flow Omni Flash | 免费(Google Labs 积分) |
| 配音 | edge-tts | ¥0 |
| 浏览器自动化 | Chrome CDP + Playwright | ¥0 |
| 合成 / 字幕 / 审片 | FFmpeg + PIL + Python | ¥0 |
适用场景:用户已有分镜脚本,需要批量生成画面、配音、字幕,并输出带导演审片功能的 1080p 成片。
两大阶段:
核心模式:Chrome DevTools Protocol (CDP) + Playwright 人类化操作。
--remote-debugging-port=9222。chromium.connectOverCDP('http://127.0.0.1:9222') 连接。humanMove / humanClick / humanScroll / humanType 等随机延迟/抖动操作,降低被检测风险。启动 Chrome(macOS 示例):
pkill -9 "Google Chrome"; sleep 2
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--remote-debugging-port=9222 \
--user-data-dir="$HOME/Library/Application Support/Google/Chrome/Default" \
"https://labs.google/fx/tools/flow" &
sleep 5
Node 依赖:
cd /Users/zzhwj2026/.workbuddy/binaries/node/workspace
/Users/zzhwj2026/.workbuddy/binaries/node/versions/22.12.0/bin/npm install playwright-core
运行时设置:
export NODE_PATH=/Users/zzhwj2026/.workbuddy/binaries/node/workspace/node_modules
Python 依赖(TTS / 字幕 / 合成):
/Users/zzhwj2026/.workbuddy/binaries/python/versions/3.13.12/bin/python3 -m venv /Users/zzhwj2026/.workbuddy/binaries/python/envs/default
/Users/zzhwj2026/.workbuddy/binaries/python/envs/default/bin/pip install edge-tts pillow
验证 CDP:
curl -s http://127.0.0.1:9222/json/version | head -3
用于生成关键帧、参考图、角色肖像、fallback 静态图。
示例:
node generate-image.js \
--prompt "Cinematic portrait of a young Chinese woman soldier, round face, short black hair, wearing grey cotton Eighth Route Army uniform, flat-topped cloth cap with two plain front buttons, red scarf, determined expression, 1940 northern China, soft daylight" \
--aspect 16:9 \
--count x2 \
--output ./images
参数:
| 参数 | 说明 | 默认值 |
|---|---|---|
--prompt | 英文提示词 | 必填 |
--aspect | 16:9 / 9:16 / 4:3 / 1:1 / 3:4 | 16:9 |
--count | 1x / x2 / x3 / x4 | x2 |
--model | Nano Banana 2 / Nano Banana Pro | Nano Banana 2 |
--output | 输出目录 | /tmp/flow-images |
文生视频:
node generate-one.js \
--prompt "Video of a young Chinese woman soldier riding a black horse across a dusty mountain valley, 1940 northern China, grey cotton uniform, flat-topped cloth cap, red scarf, modern rifle, cinematic lighting" \
--output ./videos
⚠️ Omni Flash 提示词必须以 Video of 开头,否则模型会出图。脚本应自动补前缀。
图生视频(推荐,一致性更强):
node generate-img2video.js \
--image ./images/01-李林肖像.jpg \
--prompt "Slow camera push in, gentle ambient motion, cinematic lighting" \
--duration x2 \
--output ./videos
参数:
| 参数 | 说明 | 默认值 |
|---|---|---|
--image | 参考图路径 | 图生视频必填 |
--prompt | 视频运动/镜头描述 | 自动生成 |
--duration | x2(10s) / x3(15s) / x4(20s) | x2 |
--aspect | 16:9 / 9:16 | 16:9 |
standard-portrait-v2.jpg。generate-img2video.js 图生视频。分镜脚本格式:
{
"project": "li-lin",
"episodes": [{
"id": "E01",
"shots": [
{
"id": "S01",
"type": "narration",
"prompt_image": "英文图片提示词,用于 Nano Banana 2",
"prompt_video": "Video of ... 英文视频提示词,用于 Omni Flash",
"duration": "x2"
}
]
}]
}
运行:
node flow-workflow.js --script storyboard.json --mode full --output ./output
模式:
| 模式 | 行为 | 适用场景 |
|---|---|---|
full | 文生图 → 图生视频 | 默认,一致性最好 |
image-only | 只出图 | 需要人工挑选关键帧 |
video-only | 直接文生视频 | 快速出片,一致性略弱 |
输出结构:
output/项目名称/
├── images/ # 生成的参考图
├── videos/ # 生成的视频片段
├── workflow-results.json # 制作报告
└── debug-*.png # 调试截图
Video of 开头,否则 Omni Flash 会生成图片。/project/,应检测页面元素。finally 块末尾必须调用 process.exit(0);CDP WebSocket 会保持事件循环活跃,导致 Node 不退出。不要调用 browser.close(),否则会关闭用户 Chrome。<video src>,用 page.request.get() 复用 cookie/CORS 下载。正面描述(八路军 / 抗战题材):
young Chinese woman commander, round face, short black hair,
grey cotton Chinese Communist Eighth Route Army uniform,
flat-topped cloth cap with two plain front buttons,
red scarf around neck, no cap badge, no insignia,
holding a modern rifle, 1940 northern China
负面提示词(每条生成必须带):
no ancient armor, no spears, no longbows, no crossbows,
no Japanese uniforms on Chinese soldiers,
no peaked caps, no cap badges, no visors, no samurai helmets,
no modern clothing, no suits, no ties, no dresses,
no smartphones, no cars, no electric lights, no concrete buildings,
no feudal castles, no palaces, no ancient Chinese architecture unless scripted
合成前对 每个镜头 运行以下检查。任一失败 = 重制该镜头。
| 检查 | 通过标准 | 失败示例 |
|---|---|---|
| 面容 / 身份 | 主角在所有镜头中为同一人 | 镜头 06 换了演员 |
| 发型 | 长度、颜色、样式一致 | 镜头 01 短发,镜头 05 长发 |
| 性别 | 每镜性别正确 | 女主角被画成男性士兵 |
| 年龄 | 表观年龄一致(±5 岁) | 闪回童年却像成人 |
| 标准像匹配 | resembles standard-portrait-v2.jpg | 生成的脸与参考图无关 |
| 服装连续性 | 同一场景内服装不变 | 连续镜头中外套变了 |
| 检查 | 通过标准 | 失败示例 |
|---|---|---|
| 服装年代 | 服饰符合所述历史时期 | 1940 年抗战场景出现清朝长袍 |
| 武器年代 | 武器符合同期技术 | 1940 年出现火绳枪或 AK-47 |
| 建筑 | 建筑符合时期与地域 | 1940 年村庄出现混凝土高楼 |
| 交通 | 无时代错乱载具 | 1940 年中国农村出现汽车(除非剧本需要) |
| 电子设备 | 无时代错乱设备 | 1950 年前场景出现智能手机、电灯 |
| 文字 | 使用正确的文字体系 | 1956 年前出现简化字 |
| 检查 | 通过标准 | 失败示例 |
|---|---|---|
| 制服颜色 | 派系颜色正确 | 八路军穿蓝色制服(应为灰色) |
| 帽型 | 帽型正确 | 平顶布帽被画成大檐帽 |
| 帽饰 | 无禁用元素 | 帽徽、帽檐、帽舌出现在八路军帽上 |
| 徽章 | 符合时代或不存在 | 国民党标志出现在共军士兵身上 |
| 武器类型 | 符合军队与时代 | 正规军主力武器是长矛 |
| 敌人形象 | 敌人不得穿中国军装 | 日军穿着八路军制服 |
| 检查 | 通过标准 | 失败示例 |
|---|---|---|
| 季节 | 同一场景内季节一致 | 镜头 03 下雪,镜头 04 绿叶(同一天) |
| 时间 | 光照方向一致 | 同一场景广角是晨光,特写是正午 |
| 地形 | 地点符合剧本 | 北方战场出现热带丛林 |
| 天空 | 阴晴符合场景天气 | 剧本写“阴天硝烟”却出现蓝天 |
| 道具连续性 | 重复出现的道具一致 | 连续骑兵镜头马匹颜色不同 |
no ancient armor, no spears, no longbows, no crossbows,
no Japanese uniforms on Chinese soldiers,
no peaked caps, no cap badges, no visors, no samurai helmets,
no modern clothing, no suits, no ties, no dresses,
no smartphones, no cars, no electric lights, no concrete buildings,
no feudal castles, no palaces, no ancient Chinese architecture unless scripted
| 场景类型 | useRef | 原因 |
|---|---|---|
| 军装 / 制服镜头 | true | 需要与制服保持角色一致 |
| 平民 / 学生 / 童年 | false | 参考图含军装,会污染平民服装 |
| 群像镜头(多人) | false | 参考图会让所有人长得像主角 |
| 风景 / 无角色 | false | 没有角色需要保持一致 |
首次成片渲染后,生成一个自包含的导演审片控制台,让人类导演独立检查每一镜的画面、音频、字幕,对每一部分决定是否重制,填写修改意见后自动生成可执行提示词,并支持在镜头之间插入或删除镜头。
| 能力 | 说明 |
|---|---|
| 审片粒度 | 按组件:画面 / 音频 / 字幕 各自独立通过/待定/重制 |
| 重制表单 | 每个组件有独立表单:问题类型、导演意见、自动提示词、工具选择、参考图开关 |
| 镜头管理 | 可在任意两镜之间插入新镜头;可删除任意镜头并撤销 |
| 新增镜头 | 默认所有组件为“重制”,填写标题/旁白/字幕/视频提示词即可 |
| 导出格式 | director-fix-pack.json,含 fix_list + insert_list + delete_list |
| 执行命令 | 每个 fix 条目生成对应的 execution_cmd |
每个镜头 / 段落包含:
start_ts、end_ts 在成片中的位置).mp4 片段 → 截图 → 通过/待定/重制开关 → 重制表单.mp3 片段 → 通过/待定/重制开关 → 重制表单cd /path/to/project
python3 review-final-v4.py --project-root . \
--output review-v4/ \
--template-html review-director-template.html
该脚本会:
storyboard-v2.json 并计算每镜时间戳review-v4/clips/review-v4/audio/review-v4/frames/review-v4/manifest.jsonreview-director-template.html 并替换 __MANIFEST_DATA__ 和 __PROJECT_NAME__review-v4/review.html,数据内联,无需服务器/CORSreview.htmldirector-fix-pack.jsondirector-fix-pack.json{
"project": "li-lin",
"summary": {
"total_shots": 12,
"fix_items": 3,
"new_shots": 1,
"deleted_shots": 1
},
"fix_list": [
{
"uid": "shot-06",
"shot_id": 6,
"title": "抗日烽火",
"component": "video",
"director_note": "李林的脸不像参考图",
"prompt": "Cinematic wide shot... [导演修改要求] 在提示词中强化角色外貌描述...",
"tool": "flow-img2video",
"use_ref": true,
"problem_type": "角色不一致",
"execution_cmd": "node generate-img2video.js --image images/06-抗日烽火.jpg --prompt '...' --output videos/06-抗日烽火.mp4",
"start_ts": 34.9,
"end_ts": 43.1
}
],
"insert_list": [
{
"uid": "new-1719312000000",
"title": "过渡镜头",
"position": 6,
"narration": "旁白文本...",
"video_prompt": "Video of ...",
"video_tool": "flow-img2video",
"use_ref": false,
"voice": "zh-CN-XiaoxiaoNeural",
"rate": "+0%"
}
],
"delete_list": [
{ "uid": "shot-07", "id": 7, "title": "军民情深" }
]
}
director-fix-pack.jsonexecution_cmdstoryboard-v2.jsoncompose-final-v4.py 合成成片review-final-v4.py 生成新的审片包compose-final-v4.py 生成 TTS、ASS 字幕、1080p 成片(含 hook/CTA/BGM)。review-final-v4.py 输出自包含导演控制台。humanMove / humanClick / humanScroll / humanType 复用。process.exit(0);绝不能调用 browser.close() 关闭用户 Chrome。page.request.get() 下载生成结果。自动携带 cookie 和 CORS 上下文。Video of 开头。否则模型出图。edge-tts 的 SentenceBoundary 偏移依赖 rate;rate 不同会导致字幕漂移数秒。target_dur = audio_dur + 0.5s,视频够长则裁剪,稍短则轻微慢放(≤15%)。tpad=stop_mode=clone 会让影片像幻灯片。edge-tts 输出 24000 Hz 单声道;在 filter_complex 中 aresample=44100,最终 concat 用 -c:a aac -ar 44100 重编码。-c copy 混音会导致几乎静音。overlay + enable='between(t\,start,end)' 烧录字幕。/Users/zzhwj2026/.workbuddy/binaries/node/versions/22.12.0/bin/node 与隔离的 playwright-core。| 脚本 | 用途 |
|---|---|
generate-image.js | Nano Banana 2 文生图 |
generate-one.js | Omni Flash 文生视频 |
generate-img2video.js | Omni Flash 图生视频 |
flow-workflow.js | 短剧全流程编排:按 storyboard.json 批量出图/视频 |
compose-final-v4.py | 导演级最终合成:TTS、ASS→PNG 字幕、节奏同步、BGM、hook/CTA |
review-final-v4.py | v4 导演控制台生成器:拆分片段、提取音画、输出自包含 HTML |
review-director-template.html | v4 导演控制台 HTML 模板,含 __MANIFEST_DATA__ 占位符 |
generate-trailer-v4.py | 基于 FFmpeg 的高光预告片 |
references/consistency_checklist.md — 逐镜检查清单。references/fallback_prompts.md — 常见问题镜头的收紧提示词。li-lin/videos/、li-lin/audio/、li-lin/subtitles/、li-lin/final/。/opt/homebrew/bin/ffmpeg。/Users/zzhwj2026/.workbuddy/binaries/python/envs/default/bin/python3。/Users/zzhwj2026/.workbuddy/binaries/node/versions/22.12.0/bin/node。http://127.0.0.1:9222(要求 Chrome 以 --remote-debugging-port=9222 启动)。https://labs.google/fx/tools/flow。