一、流水线拆解:八个环节
一部 AI 漫剧的生产,可以拆成下面这条链:
- 剧本:把小说或创意扩写成带台词、带情绪提示的剧本;
- 分镜表(Storyboard) :把剧本拆成一个个镜头,每个镜头要有画面描述、台词、时长、运镜;
- 角色设定:为主角生成正面/侧面/表情参考图,锁定形象;
- 画面生成:文生图逐镜出图,靠角色一致性手段锁定人物;
- 动态化:图生视频或分层动效,让静帧动起来;
- 配音:TTS 按角色音色合成台词,控制情绪与语速;
- 配乐音效:背景音乐、转场音效;
- 合成剪辑:按时长对齐画面与音轨,加字幕,输出成片。
八个环节里,1、2、8 是纯软件逻辑,最容易自动化;3、4、5 是效果瓶颈;6、7 已经相当成熟。所以一个务实的做法是:把软件逻辑部分写死成流水线,把效果瓶颈部分保留人工审核和重试。
二、真正的难点:一致性
如果用一句话总结 AI 漫剧的技术难点,那就是——跨镜头的角色一致性。
观众能容忍画风粗糙,但绝不能容忍"第二集主角换了张脸"。而扩散模型的默认行为恰恰是每次生成都随机。业界主流的三种解法:
- 角色 LoRA:用 15~30 张同一角色的图训练一个小模型,绑定到角色 ID。效果最稳,但每个角色都要训,冷启动慢;
- 参考图注入(IP-Adapter / Reference Only) :不训练,直接把角色参考图作为条件注入,成本低、上手快,适合角色多但戏份少的剧;
- 固定种子 + 精细提示词:最土但最实用。同一个角色在所有镜头里用同一 seed,配合固定的外貌描述模板(发型、瞳色、服装、体型),能兜住大部分场景。
工程上通常是三者叠加:LoRA 打底保证核心角色,参考图处理配角,种子和模板兜底。
第二个隐性难点是镜头语言的连贯。分镜之间要有景别变化(远景交代环境、中景推进对话、特写给情绪),机位不能乱跳(越轴会让观众迷失方向)。这部分目前 AI 还不能自己做好,必须在分镜表阶段由人把控——分镜表是整个项目的"施工图",值得花最多时间打磨。
三、少量代码:从分镜表到成片
流水线的核心不是生成模型本身(那些都是 API 调用),而是编排:如何让分镜表驱动批量生成,再把碎片自动拼成成片。
3.1 分镜表就是一份结构化数据
把分镜写成 JSON,是整个自动化流程的地基。字段不需要多,但每个都要能被程序消费。
import json
SHOTS = [
{"id": 1, "shot": "远景", "desc": "雨夜霓虹街道,主角撑伞独行",
"line": "这座城市,从不为谁停留。", "speaker": "男主", "dur": 4.0},
{"id": 2, "shot": "特写", "desc": "男主眼神,雨水顺着伞骨滴落",
"line": "但我偏要试试。", "speaker": "男主", "dur": 3.0},
]
desc 决定画面,line 决定配音,dur 决定镜头时长。这三个字段齐了,剩下全是机械劳动。
3.2 批量生成:调用层封装
生成环节的代码几乎全是胶水——把分镜字段翻译成各家 API 的入参。关键是统一错误处理和重试,因为生成模型失败率不低。
def gen_assets(shots, image_api, tts_api, retries=3):
out = []
for s in shots:
img = tts = None
for _ in range(retries): # 生成失败自动重试
try:
img = image_api(prompt=build_prompt(s), seed=CHAR_SEED[s["speaker"]])
tts = tts_api(text=s["line"], voice=VOICE[s["speaker"]])
break
except Exception:
continue
if img is None or tts is None:
raise RuntimeError(f"镜头 {s['id']} 生成失败,转人工")
out.append({**s, "img": img, "audio": tts})
return out
注意 CHAR_SEED 和 VOICE 两个字典——它们就是"角色一致性"在代码里的落点。角色的脸和声音,本质都是被固定下来的两个映射。
3.3 合成:让 ffmpeg 干重活
合成是最容易写砸的部分。一个常见错误是先定镜头时长再配音,导致音画对不齐。正确顺序是反的:先出配音,用音频时长决定镜头时长,dur 只作为最小值和参考。
import subprocess, os
def build_shot(s, idx, fps=30):
"""静帧 + 轻微缩放(Ken Burns)+ 音轨 -> 单个镜头视频"""
dur = audio_duration(s["audio"]) or s["dur"]
cmd = [
"ffmpeg", "-y", "-loop", "1", "-i", s["img"], "-i", s["audio"],
# 从 1.0 缓慢放大到 1.08,制造运镜感
"-vf", f"scale=1280:720,zoompan=z='min(zoom+0.0005,1.08)':d={int(dur*fps)}:s=1280x720,fps={fps}",
"-t", f"{dur:.2f}",
"-c:v", "libx264", "-pix_fmt", "yuv420p", "-c:a", "aac",
f"shot_{idx:03d}.mp4",
]
subprocess.run(cmd, check=True)
return f"shot_{idx:03d}.mp4"
def assemble(files, out="final.mp4"):
with open("list.txt", "w") as f:
f.writelines(f"file '{p}'\n" for p in files)
subprocess.run(["ffmpeg", "-y", "-f", "concat", "-safe", "0",
"-i", "list.txt", "-c", "copy", out], check=True)
zoompan 那一行就是"让静帧活起来"的最低成本方案:缓慢推近,配合音效和转场,观感远好于完全静止的画面。真正上量之后,可以把这一步替换成图生视频模型,其余代码不变。
至此,从分镜 JSON 到 final.mp4,全链路不到五十行。
四、几个几乎必踩的坑
1. 单镜头好看,连起来难看。
这是新手最常犯的错。每个镜头独立看都精美,剪在一起却像幻灯片。原因通常是没有统一色调和转场节奏。解法是在合成阶段加统一 LUT 调色,并让转场音效承担节奏衔接。
2. 配音和口型对不上。
如果画面上有角色说话,嘴型不动会非常出戏。低成本方案是避开正面大特写,多用侧脸、背影、过肩镜头,或者加轻微的头部动效掩盖。要正面说话,就得接口型同步工具。
3. 提示词里塞太多东西。
一个 prompt 同时描述场景、人物、光线、构图、情绪、画风,模型顾此失彼。实践中最稳的做法是分层提示词:固定的角色模板 + 可变的场景描述 + 固定的画风后缀,三段拼接。
4. 时长失控。
一集 3 分钟、每镜 3 秒,就是 60 个镜头,每个镜头平均重试 3 次,生成次数直接上到两百次。算力和时间成本会远超预期。先做一集 60 秒的样片跑通全链路,再考虑量产。
5. 版权与合规。
角色形象、配音音色、背景音乐,每一环都可能踩线。尤其音色克隆,必须取得授权。这不是技术问题,但翻车代价最大。
五、什么时候不该做 AI 漫剧
有两个判断值得记住。
第一,故事不行,技术救不了。 AI 能解决画面,解决不了"这个故事为什么值得看"。大量 AI 漫剧折在剧本平淡,而不是画面拉胯。分镜表和剧本该花的功夫,一点都省不掉。
第二,动作戏和复杂运镜目前仍是短板。 图生视频模型在人物剧烈动作、多人交互、镜头大幅运动时依然容易崩(肢体扭曲、物体穿模)。如果剧本核心是打斗,要么大幅简化动作设计,要么接受较高的重试率。擅长的是情绪、对话、氛围,不擅长的是打斗、追逐、群戏——按这个特点选题材,成功率会高很多。
结语
AI 漫剧的本质,是把一个依赖大量人工的创意生产过程,改造成一条可编排、可重试、可批量的流水线。技术门槛比想象中低——核心代码不到五十行;但工程门槛在别处:角色一致性怎么锁、分镜表怎么打磨、生成失败怎么兜底、题材怎么选。
如果你准备动手,建议的路径是:先写一个 60 秒、五个镜头的迷你剧,把分镜 JSON、生成、配音、合成整条链路跑通,看一遍成片。你会立刻发现哪里最出戏——是角色的脸、是配音的情绪、还是镜头的节奏。然后针对那一处死磕,比一上来就规划二十集要高效得多。