AI 短剧制作(横屏/竖屏微短剧,多集)
SkillDev toolsProduce multi-episode AI micro-dramas: create a series bible and character references, complete episode scripts, shot-by-shot I2V, dialogue auditing, dubbed voiceover, subtitles, BGM, and final cuts, maintaining consistency across shots and episodes. Use when the user says "AI/landscape/portrait/mic
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the AI 短剧制作(横屏/竖屏微短剧,多集) skill
What this skill tells your AI
The instructions your AI receives, as published by zju-real/easel in skills/openclaw/short-drama/SKILL.md and read by ahel’s review.
配置检查路径铁律:整条流水线开始前先
cd到AGENTS.md末尾给出的 Easel 项目根,确认.env与skills/shared/scripts/存在。生图、视频、配音配置必须从这里运行注册表/check;不得在 OpenClaw workspace 使用./shared/scripts/...,不得用env/printenv判定缺少IMG_BASE_URL、VOICE_BASE_URL或 Key。发现缺项先核对pwd,回项目根并显式传--env-file .env重查。
⛔ 三条铁律(最容易翻车,动手前先记死)
- 每镜必须「图生视频」成动态片段——绝不能拿静态图冒充。 关键帧图(frame)只是 I2V 的首帧,必须再用 ai-video-gen
image2video驱动成会动的clip。跳过这步 = 一堆静态图配音,垃圾。合成前storyboard会硬拦只有 frame 没 clip 的镜头。 - 配音必须闭源云 provider(有情感、像真人)——绝不用 edge(AI 味平读)。 先
.env配VOICE_PROVIDER+voice_clone.py check验 key;配了 key 后dubbing align/dub合成前就硬拦 edge,任何角色(含旁白)想落到 edge 直接失败。只有完全没 key 才--allow-edge兜底。 - 原生音频优先、环境音每镜必留、台词务必喂给模型。 视频模型原生音频(环境音/脚步/物理音效)质量好,环境音默认整轨全用。头号要点:生视频必须把台词写进
generation_prompt(prepare生成)喂给模型,否则模型不知说啥、台词全错。默认 native-first(让模型逐字说、能说就用、不默认丢 TTS)→audit逐镜 ASR 核验:对上用原生对白(常态)、说错转dub换 TTS、旁白/动作镜走 TTS/环境音。决策与探针细节见步骤 16/18 及references/native-audio-workflow.md。 - 画面/声音/字幕按时间线对齐,自然播放。 画面用真实片段全长(台词只占其中一段,按实际说话时间放置),绝不慢放/循环/冻结;片段盖不住台词就重生成/拆镜(
align硬拦)。
⚠️ 不许抄近路(执行纪律,最常翻车):
prepare → drama_ops.py generate(生视频) → audit → align是不可跳的链,脚本已加链式硬门:① 生视频必须走drama_ops.py generate(它逐镜读generation_prompt自己调视频模型,agent 无从传成只有画面的 prompt)——别再逐镜手调 ai-video-gen;②generate/audit见有台词的镜缺generation_prompt→ 判定「没跑 prepare」直接失败;③align见缺clip-audit.json→ 判定「没跑 audit」直接失败(不再静默把全部对白降级成 TTS)。「手调生视频只传画面 prompt + 直接 TTS」这条错误捷径会被拦回来——才有「台词喂给模型 + 用视频原声」。
编排层 SKILL:创意(圣经/剧本/分镜/lines)你 LLM 写,生成动作全委派已有 SKILL(ai-image-gen/ai-video-gen/ai-music),确定性 IO 走
scripts/drama_ops.py+scripts/dubbing.py;角色一致性靠「先定参考图再 I2V」+ 剧集圣经锁成同一部剧。
输入
| 字段 | 必填 | 说明 |
|---|---|---|
| 题材/梗概 | 是 | 一句话剧情或改编源(没给就问) |
| 集数 | 否 | 由题材/需求定,不强制(微短剧常 10–30 集只是常见值;起号测试可先 1–3 集验证链路) |
| 单集时长 | 否 | 不强制固定分钟数——由题材/平台/剧情节奏定,几十秒到数分钟皆可;成片总时长 = 各镜片段时长之和(脚本不设上限,用户说多长就多长) |
| 画幅 | 是 | 用户或上游任务未明确横版/竖版(或 16:9/9:16/具体分辨率)时,制作前必须追问并等确认;不得按平台、Profile 或默认值静默推断,已明确则不重复问 |
| 视觉风格 | 否 | 都市港风/古装/校园/悬疑…(定统一风格前缀) |
产物结构(outputs/剧名/)
series-bible.md 剧集圣经(戏剧承诺+角色表【行动模型+want/need/wound/flaw+可跟随四问+音色档案】+剧情线+情绪曲线/爽点节奏+反派阶梯+分集反转+钩子+风格前缀)
cast.json 选角表(角色→音色:edge 音色 + pitch/rate,或克隆音色)
ref_index.json 参考图索引(C 角色 / S 场景 / P 道具,跨镜跨集复用)
refs/ 参考图(C01_林策.png ...)
episodes/ep01/
script.md 本集剧本(因果节拍四幕 + 对白 + 集末钩子)
lines.json 本集逐行对白({speaker,text,emotion,shot,at?},shot=所属镜头、at=镜内起始秒/对齐说话时刻,喂时间线配音)
shots.json 本集分镜(逐镜:时间轴 prompt + @参考 + 尾帧描述 + 可选 sfx[定时音效];align 回写每镜 duration)
shots/ 逐镜关键帧图 + 生成的片段
voice.mp3 / voice.srt 多角色配音(每角色独立声线、镜对齐)+ 同轴字幕
timing.json 逐镜时长 + 逐行起止(align 产出,留档/校验)
clip-audit.json 原生音轨、ASR、语言、说话时间与 native/dub/regenerate 决策
final.mp4 本集成片
progress.json 逐集/逐镜生成进度(控费、断点续跑)
脚本(相对项目根):skills/openclaw/short-drama/scripts/drama_ops.py(资产/分镜/进度)、
skills/openclaw/short-drama/scripts/dubbing.py(多角色配音);
合成器复用:skills/openclaw/auto-short-video/scripts/assemble.py。
执行步骤
⚠️ 生图/生视频/配音是异步 + 按量计费。先出 Plan(几集、每集几镜、调哪些付费 API、 大致耗时/花费),确认后再跑。起号测试建议先跑 1 集 验证全链路再放量。
0. 剧集策划(新脑子,必做)
- 选题材 + 定爽点:先读
references/genre-hooks-handbook.md选一个主题材(逆袭/战神/重生复仇/甜宠/马甲…)+ 其核心爽点,避免「剧情太简单/太散」。 - 搭骨架:
python skills/openclaw/short-drama/scripts/drama_ops.py scaffold --series "<剧名>"。 - 过故事引擎(治「剧情简单/人物扁平」,写 bible 前必做):读
references/story-engine.md——- 写戏剧承诺一句话并过其自检(主体/追求/昂贵阻力/反复回报,换名不失独特、阻力有筹码、主角有能动性、中段有回报);
- 每个主要角色建 8 字段行动模型 + want/need/wound/flaw/弧光 + 可跟随四问(ep1 可见其一);
- 反派按
references/satisfaction-and-villain.md排 4 层阶梯(治工具人/爽点通胀)。
- 写
series-bible.md(读references/series-bible-schema.md,已含上述深度字段):一句话卖点、戏剧承诺、世界观、角色表(行动模型+深度)、剧情主线、情绪曲线 + 爽点节奏表 + 反派阶梯、分集大纲(每集:剧情 + 因果反转点 + 集末悬念)、统一视觉风格前缀。 - 过 A/B 门:按
references/drama-review-rubric.md的 A(故事引擎门)+ B(人物可跟随门)逐项引证自评,任一 ⛔ 硬伤必修再往下。
1. 分集剧本(因果节拍 + 台词功底,别写流水账)
- 每集读
references/four-act-drama.md、references/causal-beats.md、references/vertical-pacing.md和references/dialogue-craft.md,按因果节拍写episodes/epNN/script.md: 目标(3秒钩)→阻碍→转折(爽/虐爆点)→集末钩子,相邻节拍用「因为/所以」串;爽点密度每 15–30s 一个情绪事件。- 反转按因果生成:每个反转过
genre-hooks-handbook.md的「因果反转一句话测试」+ 公平揭示 5 问,填不出=空降反转,重做。 - 台词按
dialogue-craft.md:禁直给/禁全员一个腔(过 swap-test)/曝光转冲突/每人有想要+想藏/每集 ≥1 金句/单行 ≤15 字。 - 每句台词必须标清说话人:剧本里对白一律写成
角色名:台词(角色名用 cast/bible 里的准确名字,别用「他/她/众人」)——后续抽 lines.json 时 speaker 直接照抄,避免配音配错角色。
- 反转按因果生成:每个反转过
- 写完过 C/D/E 门:按
references/drama-review-rubric.md的 C(反转揭示)+ D(节奏)+ E(台词)逐项引具体节拍/台词自评,任一 ⛔ 硬伤(无 ep1 钩/腔调雷同/空降反转)必修,别凑合。
2. 角色 / 场景定妆(一致性地基)
- 用 ai-image-gen 为每个角色生成定妆参考图(正面/多角度,喂角色外貌关键词 + 统一风格前缀);关键场景/道具同理。
- 逐个登记进索引(自动分配 C/S/P 编号):
读python skills/openclaw/short-drama/scripts/drama_ops.py ref add --series "<剧名>" \ --kind character --name 林策 --image refs/C01_林策.png --desc "男主,冷峻西装" --style "都市港风"references/character-consistency.md了解为什么必须先定参考图。 9.5 ⛔ 定妆图必须肉眼复核(做完图绝不跳过):用图片工具逐张看每个角色定妆图,确认发型/年龄/服装/气质符合角色设定,逐个记录:
形象跑偏(如男主长成大叔、萝莉长成成年)→ 重生成定妆图再复核,别拿跑偏形象往下生视频(跨镜长相全崩)。角色定妆图没复核,后面python skills/openclaw/short-drama/scripts/drama_ops.py ref review --series "<剧名>" \ --code C01 --observation "看到:冷峻短发西装男,符合男主设定"generate会硬拦。
2.5 选角(角色→音色,多声线关键,闭源优先 + 音色贴角色)
- 读
skills/shared/references/voice-casting.md。音色由角色的真实定妆参考图形象决定——先看 §2 生成出来的定妆图长什么样,按 voice-casting.md〇.6「形象原型 → 音色速查」对号入座:图里是萝莉就配萝莉音(女童声/高而快)、御姐配成熟音、大叔配低沉老成音、霸总配浑厚音…绝不能形象与音色错位(女主配大妈音、小孩配成年音 = 出戏)。每个角色用--archetype写形象原型、--ref绑定其定妆图 C 编号(cast check会核对:ref_index 里每个有定妆图的角色都必须被配音,漏配直接拦)。旁白单列且与所有角色不同。
- 闭源强制优先(铁律②,含旁白/普通配音):先
.env配VOICE_PROVIDER+python skills/shared/scripts/voice_clone.py check --provider <..> --env-file .env验 key 能用;cast init旁白与cast add都默认clone并自动取VOICE_PROVIDER。配了 key 后:cast check拦静态配置里的 edge,align/dub合成前再拦一道——任何角色(含旁白)想落到 edge 直接失败(clone 缺 voice_id / clone 调用失败都算),逼你修好闭源再出片。只有完全没 key 才--allow-edge兜底。预置音色见 voice-casting.md〇.5。
python skills/openclaw/short-drama/scripts/dubbing.py cast init --series "<剧名>" # 建模板(旁白默认闭源)
# 按角色定妆图形象挑贴合的闭源预置音色,并标注 archetype/ref
python skills/openclaw/short-drama/scripts/dubbing.py cast add --series "剧名" --name 林策 --role male_lead \
--engine clone --provider openai-compatible --voice-id FunAudioLLM/CosyVoice2-0.5B:benjamin \
--archetype "冷峻男主" --ref C01 --note "低沉磁性,贴 C01 定妆图"
python skills/openclaw/short-drama/scripts/dubbing.py cast add --series "剧名" --name 朵朵 --role child \
--engine clone --provider openai-compatible --voice-id FunAudioLLM/CosyVoice2-0.5B:bella \
--pitch=+6Hz --rate=+5% --archetype "萝莉/小女孩" --ref C03 --note "童声,贴 C03 幼态定妆图"
python skills/openclaw/short-drama/scripts/dubbing.py cast check --series "剧名"
需要专属克隆嗓音(非预置)→ --provider minimax/dashscope + 先 voice_clone.py enroll 拿 --voice-id。
完全没配任何闭源 key 时才回退 edge(cast check 出 💡 提醒升级)。分层与配置见 voice-casting.md〇 与 multi-voice-dubbing SKILL。
3. 分镜脚本 + 逐行对白 + 时长规划(自然的关键:先定好每镜停留多久,再去生视频)
- 按本集时长与节奏拆镜(镜数不强制——时长短几个镜、时长长就多几个镜,跟着剧情走),写
episodes/epNN/shots.json(格式见references/shot-prompt-format.md): 每镜含idx / desc / prompt(风格头+逐秒画面节拍+【声音】) / refs(引用 C/S/P) / tail(尾帧描述)。 - 同时抽本集逐行对白
episodes/epNN/lines.json(有序[{speaker, text, emotion, shot}];字段规则见步骤 17)——在生视频之前就写好,因为每镜停留多久由它的台词决定。 - 规划每镜时长 + 检查能否塞进片段(治「画面停住/太赶」的根本):
python skills/openclaw/short-drama/scripts/dubbing.py plan --series "<剧名>" --episode N
⚠️ 现实约束:AI 视频只能生成固定档位(多为 5s,部分 5/10s),不能按任意秒数出片。 所以 plan 的作用是:① 估出每镜台词时长(= 最终画面应停留的时间,写回 target_duration)② 检查每镜台词能否塞进一个片段档——塞不下(台词 > ~5s)就拆成多镜或精简台词(plan 会 ⚠️ 标出来),别硬生成再靠后期拉伸 ③ 给出每镜建议生成的片段档位 gen_duration(5 或 10)。把每镜台词控制在一个片段档内,是画面自然的关键。
14. 校验分镜:drama_ops.py shots validate --series "<剧名>" --episode N(风格前缀/引用参考图/编号已登记/idx 连续)。
4. 关键帧生成(只是 I2V 的首帧,不是成片)
- 用 ai-image-gen 按每镜 prompt 生成首帧图(图生图并引用该镜 refs 的参考图,保角色一致),落
episodes/epNN/shots/,路径写回 shots.json 的frame。⚠️ 到此还只是静态图,下一步必须驱动成视频。
5. 逐镜生视频(I2V,铁律①:每镜必做,绝不跳过)
- 生成音频契约和 prompt(把台词喂给模型):先跑
model_registry.py configured --group video --env-file .env;多个可用且用户没点名时先询问,本集选定后全链路锁定。python skills/openclaw/short-drama/scripts/dubbing.py prepare --series "<剧名>" --episode N --language zh-CN --provider "$VIDEO_PROVIDER"prepare读lines.json把台词契约写进每镜generation_prompt:默认 native-first(要求模型逐字说台词、成片用原生对白);旁白/纯动作镜不给台词。- 一镜可有多句画内对白:视频模型能连着说,
prepare会把该镜多句按时间顺序全写进generation_prompt(各句按at定位、缺则顺排,累计须塞进片段档)。不必为「多句」硬拆成一句一镜——只有旁白与画内对白仍不同镜(避免原生人声与旁白重叠)。 - 别用 dub 躲避 native-first:
prepare --dialogue-mode dub(全剧不给台词、后期全 TTS)已加硬门——没有ai_video.py probe-dialogue实测模型不忠实、也没显式--force-dub时会被拒绝。撞到多句/一句约束不是改 dub 的理由(多句直接一起塞进 prompt)。默认让模型试原生、audit只对真说错的镜逐镜换 TTS。
- 一镜可有多句画内对白:视频模型能连着说,
- 逐镜生视频(脚本驱动,强制把台词喂给模型):
python skills/openclaw/short-drama/scripts/drama_ops.py generate --series "<剧名>" --episode N --ratio "<9:16或16:9>"prepare会把最终 provider/model 锁进 shots.json;generate必须复用,显式传入冲突值会硬拦。它过 prompt 硬门后逐镜调 ai-video-gen(自动带--audio auto --ratio <已确认画幅> --duration gen_duration),clip 写回并记进度;已有 clip 自动跳过,--dry-run看计划、--only 1,3单镜重生、--force强制重生。- 片段档必须 ≥ 该镜台词时长(步骤 13
plan已选档、超长镜已拆):画面时长由真实片段主导,成片只做自然裁剪,绝不慢放/循环/冻结。片段比台词还短 →align硬失败,重生成/拆镜。 - 跨镜/跨集连贯用
references/character-consistency.md「尾帧→下一镜首帧」(--only单镜重生成时把上一镜尾帧填进该镜 frame)。
- 片段档必须 ≥ 该镜台词时长(步骤 13
6. 多角色配音 + 字幕 + 音效 + BGM(时间线对齐)
lines.json 已在步骤 12 写好;这里做实际配音并按时间线对齐。 核心模型(时间线/轨道式):每镜 = 一条完整片段的时间线,台词只占其中一段,其余时间是 动作/停顿/音效——片段时长通常 > 台词总长。配音不是把台词首尾相接填满片段,而是把每行 按
at偏移放到片段时间线上(对齐说话/嘴动时刻),空白留给动作与音效。
- 审计每个生成片段的原生音轨(环境音优先,决策见
references/native-audio-workflow.md):
输出python skills/openclaw/short-drama/scripts/dubbing.py audit --series "<剧名>" --episode Nclip-audit.json,逐镜决策native / dub / regenerate:native=有对白(可多句)+语言对+整段 ASR 相似度≥阈值(默认 0.6)或纯动作镜无意外语音 → 整轨原音直通+字幕不配音;dub=人声真坏了(语言/内容不符)或完全无原音 → 换 TTS,该镜原生轨丢弃(无人声分离时保留会与配音重复);regenerate=片段缺失/ASR 读不出/动作镜意外语音 → 带反馈重生成、拿到好原声转native(优先,既用模型原声又保环境音),最多两次。语言正确为强制前置门;阈值用--threshold调;嘴型/人物明显不符时视觉复核重生成。 - 逐行对白
lines.json字段规则(步骤 12 写、此处复核)——有序[{speaker, text, emotion, shot, at?}]:speaker必须精确等于 cast.json 里的角色名(照抄剧本「角色名:」,别写「他/她」泛称)——align会严格校验,speaker 不在 cast 直接拦截报错(治「配音配错角色」),不再静默用旁白音色顶替。emotion是给配音引擎的情感通道(不是让角色把情绪念出来),写具体:愤怒/冷笑/隐忍/崩溃大哭/颤抖/惊恐/得意/温柔/失望/嘲讽/急切/沉痛/撒娇 等——闭源云 provider 转成「用<情绪>的语气说」驱动演绎。⚠️ 音色不随情绪改变:emotion只调语调/语速/情感(emotion_prosody叠加 rate/pitch/volume 增量),角色音色身份始终是 cast.json 里绑定的那一个voice_id——同一角色跨镜跨集音色恒定,只有情绪语调在变。shot= 这句台词所属的镜头 idx(必填):让每句配音/字幕落到对应画面片段上;一镜可多句;纯动作镜无台词就不出现在 lines 里。at= 这句台词在本镜片段内的起始秒(可选,秒):对齐画面里角色开始说话/嘴动的时刻(如角色前 1.5s 在走动、之后才开口 →at: 1.5)。不写则从头顺序排。这是「说话时刻对得上画面」的关键;台词之间的空白就是动作/停顿/音效的时间。
- 时间线对齐配音(必须在每镜生成并审计后运行):
读python skills/openclaw/short-drama/scripts/dubbing.py align --series "<剧名>" --episode Nclip-audit.json后,native画内对白不合成 TTS、直接用模型原声,原生 ASR 起止时间写入字幕;旁白和dub对白进入独立配音轨(dub镜原生轨在合成时丢弃、纯 TTS,避免双重人声)。产出voice.mp3、同轴voice.srt、timing.json,并把真实片段时长写回 shots.json。- 画面时长 = 真实片段时长(铁律③):
align探测每镜真实 clip 时长作画面时长,台词按at叠在其上、其余留给动作/停顿/音效——成片就是片段原样播放、绝不冻结/拉伸/循环。 - 时间线硬拦:有台词镜缺 clip、
at为负、同镜台词重叠、或at+真实配音时长超出片段,任一情况均失败;必须重生成、拆镜、精简台词或修正at,禁止让字幕/声音拖到下一镜。 - lines 没标
shot或 speaker 配错 →align拦截/告警,按提示修 lines.json 重跑。
- 画面时长 = 真实片段时长(铁律③):
- 音效 + BGM(占用非台词时间,让画面有声音层次):
- 音效(枪声/椅子移动/脚步/开门/耳光…):在
shots.json该镜加sfx数组[{"file": "sfx/gun.wav", "at": 1.2, "volume": 0.9}](at=镜内秒)。音效文件可用 ai-music 生成短音(或素材库),把路径填进file。storyboard会把镜内at换算成全局时间、assemble定点叠进成片音轨。 - BGM:ai-music 按剧情氛围生成(紧张/甜/悬疑),落
episodes/epNN/bgm.mp3(assemble 混音时自动对旁白闪避压低)。 (字幕已由align产出voice.srt,无需再单独跑 auto-subtitle。)
- 音效(枪声/椅子移动/脚步/开门/耳光…):在
7. 逐集合成 + 交付
- 把本集分镜转成合成输入并合成。
storyboard自动读取审计结果:native镜整轨原音(模型原声+环境音)直通;dub镜原生轨丢弃、改用独立 TTS 配音(无人声分离时保留会与配音双重人声);完全无原音的镜补等长静音;侧链闪避仅让旁白/配音干净盖在 native 镜环境音上;合成器统一 AAC 48 kHz stereo 后拼接:
字幕由 assemble 自动烧成底部居中、字号合适的样式(默认按分辨率,可用python skills/openclaw/short-drama/scripts/drama_ops.py storyboard --series "<剧名>" --episode N --size "<1080x1920或1920x1080>" \ -o episodes/epNN/storyboard.json --narration episodes/epNN/voice.mp3 --bgm episodes/epNN/bgm.mp3 --subtitle episodes/epNN/voice.srt python skills/openclaw/auto-short-video/scripts/assemble.py assemble \ --storyboard episodes/epNN/storyboard.json -o episodes/epNN/final.mp4--sub-size/--sub-margin-v/--sub-font微调)。 - 每集结尾可加「下集预告/钩子卡」提升追剧。成片后过
references/drama-review-rubric.md「配音/选角」「成片」评审(尤其确认不是全剧一个声音、声线贴人物、字幕/配音与画面对齐)。多集每集重复步骤 6–22(剧本→分镜→生视频→配音→合成);用progress show看整部进度。 - 发布:按已确认画幅/平台交对应发布层 SKILL(如竖屏抖音/快手,横屏 B站)。
编排原则(承 auto-short-video)
- 降级是例外、不是默认(对齐三条铁律):视频每镜必做 I2V、配音默认硬拦 edge,成片默认硬拦静态图;只有用户明确要静态图短剧才
storyboard --allow-static、完全没闭源 key 才--allow-edge;任何降级都如实、显式告知用户降了什么、为什么。中间产物留档+断点续跑:参考图/分镜/片段/进度都落文件,某镜不满意可单独重生成,progress 防重复烧钱。
Profile 感知
- 有 Profile:
platforms.md只用于给出画幅建议,仍须用户确认;style.md融进统一视觉风格前缀与配色;identity.md定题材调性;preferences.md红线过滤(暴力/软色情/价值观)。 - 无 Profile:先问横版/竖版、题材/集数/单集时长与风格偏好;时长不预设固定值(用户不指定就按题材节奏定,别硬套某个分钟数)。
开源方法论溯源见
EASEL-META.md。
Signals
- GitHub stars
- 1k
- Forks
- 143
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
short-drama-zju-real- Source
- github.com/zju-real/easel