我用 AI 做了一个"会自己导戏"的短剧生成器

7 阅读10分钟

我用 AI 做了一个"会自己导戏"的短剧生成器

更新日期: 2026-04-23
技术栈: Next.js 14 / Fastify / PostgreSQL / OpenRouter
预计阅读时间: 12 分钟
难度: 中级(熟悉 Node.js 即可)

老板某天甩了一句:"我们能不能做个东西,输入一段文字就能生成漫剧视频?"

"短剧"这两个字现在很热,但真正从零做一套的人知道里面有多少坑——找演员、搭场景、录音、剪辑……每个环节都要人。我们想做的是把这条链路全部 AI 化。

六周后,DirectorAI 上线了。输入一个创意,三分钟后拿到一段带配音、字幕、BGM、片头片尾的完整视频。

这篇文章是复盘。不是"我做了个很厉害的东西"的宣传稿,而是讲清楚:为什么要用这套架构、哪些地方踩了坑、最后跑通的关键到底是什么。

为什么不直接调 API 了事

最直接的做法是写个脚本:调 Claude API 生成剧本,调图像 API 出图,拼一拼发出去。我们最初也是这么干的。

结果如下:

生成质量完全看运气。同一个 prompt,可能出来"凌晨三点的办公室,主角盯着报错信息,头发又少了三根",也可能出来一段废话连篇的流水账。Claude 很聪明,但它不知道"这是一个短剧脚本"意味着什么——三秒钩子、情绪节拍、镜头语言,这些它懂,但不会主动用。

第二个问题是角色一致性。A 场景的"李明"是短发男生,B 场景变成了卷发。图像 API 没有跨请求的记忆,每次生成都是独立的。

第三个问题是音画同步。生成五段视频,每段时长不一样,配音也是独立生成的,拼在一起要么错位要么有空白。

每个问题单独解决都不难,合在一起就是个系统工程。DirectorAI 是我们对这个工程的回答。

核心设计:让两个 AI 互相"对骂"

普通方案是让 AI 生成一次,人来 review。我们的方案是让两个 AI 互相 review,人只看最终结果。

具体来说,Sonnet 4.6 是创作者,Opus 4.7 是导演。

第一轮:Sonnet 写初稿,Opus 以"有 20 年经验的严苛导演"身份拆它,输出结构化批评(冲突强度 / 角色动机 / 节奏问题 / 视觉可实现性)。

第二轮:Sonnet 拿着批评重写,Opus 再审。通过则输出最终版,不通过则打回。

这套机制的核心不是"两个模型比一个好",而是强迫创作过程有明确的评审标准。Opus 的 system prompt 里有具体的评审维度,这些维度本身就是在告诉 Sonnet"什么叫好的短剧脚本"。

代码结构很简单:

// adversarial-reviewer.ts const CRITIC_MODEL  = 'anthropic/claude-opus-4-7';   // Opus — 导演 const CREATOR_MODEL = 'anthropic/claude-sonnet-4-6'; // Sonnet — 创作者 ​ async function runAdversarialReview(content: string, dramaType: DramaType) {  // Round 1: Sonnet 生成 → Opus 评审  const draft = await generateWithSonnet(content, dramaType);  const critique = await critiqueWithOpus(draft, dramaType); ​  // Round 2: Sonnet 修改 → Opus 终审  const revised = await reviseWithSonnet(draft, critique, dramaType);  const finalReview = await critiqueWithOpus(revised, dramaType); ​  return finalReview.approved ? revised : draft; }

你不用记这个实现细节。重要的是理解:对抗评审解决的是"生成质量的下限"问题,让差的结果变少。

五种风格,五套逻辑

生成短剧有个很容易忽略的点:不同类型的短剧,需要完全不同的提示词策略。

我们支持五种类型:

真人漫剧:强调角色面部表情的戏剧张力,提示词里必须有"漫感"关键词(ink outline / cel shading),配音要自然口语化

3D 漫剧:必须先描述环境光线(方向、色温、强度),善用长镜头建立空间感,材质细节很重要(subsurface scattering)

2D 漫剧:构图要考虑前景/中景/背景分层(为视差动效),日系高饱和度色彩

沙雕漫剧:表情描述必须夸张("瞳孔地震"、"下颌掉落"),台词每句控制在 15 字以内,快速节奏

解说漫剧:数据图表优先,信息流设计,旁白比重远大于对话

每种类型有自己的 prompt 模板、评审维度、视频滤镜参数,这些不是手工调的,是从大量生成结果里归纳出来的。

十步流水线

从用户输入到最终视频,后台跑十步:

几个值得重点说的节点:

第 2 步——角色三视图:用 GPT-5.4 Image 2 生成角色的正面 / 侧面 / 背面三张图,后续所有场景图片都引用这三张作为参考。这是解决角色一致性问题的核心手段。不是完美的,但比每次独立生成好得多。

第 4 步——视频生成的分叉:2D 漫剧用 Ken Burns 效果(对静图做缩放平移,制造运动感),其他类型走 Seedance 2.0 生成真实视频。这个分叉很重要,因为 Ken Burns 速度快且成本低,适合不需要角色运动的场景。

第 6 步——情绪驱动调色:根据场景的 emotionalBeat 字段决定滤镜。喜悦场景加暖黄色,悲伤场景冷蓝调,愤怒用高对比红,紧张压低饱和度。这是对 FFmpeg 的直接调用,没有 AI,但效果明显。

第 8 步——字幕烧录:不是在播放器层面加字幕,而是用 libass 直接烧入视频。这样 CDN 分发后字幕不会丢,在任何播放器里都能看到。

三层音轨

音频是最容易被忽略但最影响体验的部分。

我们做了三轨混音:

BGM(12%音量):情绪底色,全剧常驻。不同类型用不同风格:真人漫剧用管弦乐,沙雕用卡通铜管,解说用紧张节奏

SFX 音效(60%):ElevenLabs 按场景生成,用 FFmpeg adelay 精确对位到场景时间轴

人声配音(100%):MiniMax 语音合成,支持声音克隆(你可以上传自己的声音样本)

有个细节:Seedance 生成的视频有时自带音轨,有时没有。我们用 ffprobe 先探测,有音轨才加入混音链,否则跳过。漏掉这步会让 FFmpeg 报错中断整个流程。

如何搭建 环境要求 Node.js 20+ PostgreSQL 15+ pnpm 8+ ffmpeg(本地音视频处理) 快速启动 git clone github.com/your-org/di… cd directorai ​ pnpm install ​

配置环境变量

cp apps/api/.env.example apps/api/.env

编辑 .env,填入 OpenRouter API Key 和数据库连接

​ cd apps/api pnpm db:migrate       # 初始化数据库 schema pnpm db:generate      # 生成 Prisma Client pnpm dev              # 启动后端(默认 :4000) ​

新终端

cd apps/web pnpm dev              # 启动前端(默认 :3000)

访问 http://localhost:4000/health 验证后端正常:

{ "status": "healthy", "uptime": 12.3, "version": "2.0.0" } 最小配置(只需两个密钥) 密钥 用途 获取地址 OPENROUTER_API_KEY Claude / GPT-5 / 其他模型 openrouter.ai DATABASE_URL PostgreSQL 连接 本地或云数据库

其他密钥(Seedance、MiniMax、ElevenLabs)是可选的,没有时会降级到本地处理或跳过对应步骤。

三层安全防护

如果你要把这套系统对外开放,安全不能将就。

第一层——JWT 认证:所有 API 路由都经过 authenticate 中间件。NEXTAUTH_SECRET 至少 32 位,未登录请求直接 401。

第二层——速率限制:用 Fastify rate-limit 插件,每个用户 15 分钟内最多 100 次请求。生成视频会调很多下游 API,一个用户恶意刷可以快速消耗你的额度。

第三层——所有权校验:编辑或查看剧本时,检查 screenplay.userId === 当前用户。不匹配返回 403,用户之间数据完全隔离。

没有任何系统能 100% 防住所有攻击,但这三层能挡住绝大多数非故意的滥用。

实际使用场景 场景一:创作者快速出片

输入:"两个高中生考前崩溃,最后互相打气,真人漫剧风格"

三分钟后得到:带背景音乐、配音、字幕的 60 秒视频。角色造型在三个场景里保持一致。

这种使用方式最多,也是设计时的主要 persona。

场景二:品牌内容批量生产

一家电商品牌需要为不同产品线生产短视频。他们的工作流是:维护一个产品特性列表,每次生成时传入产品名和核心卖点,系统自动套入对应的剧情模板。

DirectorAI 支持场景级编辑:如果某一个场景不满意,可以单独重新生成,不用全部重来。

场景三:小说改编

有人用它把自己的网文改编成视频。做法是把章节摘要当 userInput 传进去,让系统提取角色和情节,生成分镜。不是完美翻译,但能快速验证改编方向。

几个没想到的问题

FFmpeg 的稳定性比想象中差:在处理某些 Seedance 输出的视频时,ffprobe 探测会超时。我们加了重试逻辑和回退路径,但这个问题到现在还偶发。

OpenRouter 的模型降级:OpenRouter 会在主模型不可用时自动切换到备用模型,这很方便,但有时切换的模型能力差别很大,导致生成质量波动。我们后来加了模型锁定选项,让用户可以选择"只用 Opus"或"只用 Sonnet",禁止自动降级。

角色一致性远没有解决:三视图技术能缓解问题,但没有根治。如果用 Seedance 生成的视频角色有动作,脸部细节的一致性会明显下降。这是当前图像生成技术的瓶颈,不是工程问题。

用户对"等待"的容忍度:三分钟对我们来说已经很快了,但用户第一次用时普遍觉得"太慢"。我们加了实时进度条和步骤说明("正在生成角色形象…"),同样三分钟,体验明显好了。等待本身不是问题,不知道在等什么才是问题。

复盘总结

做 DirectorAI 最大的收获不是技术,而是对"AI 工具的正确姿势"有了更清楚的认识。

AI 很擅长生成,不擅长自我评估。对抗评审是我们找到的一个还算有效的方法——让它生成,让另一个实例评估,循环。这个思路可以用在很多地方,不只是剧本生成。

第二个认识是流程标准化的价值。一旦你把每一步的输入输出定义清楚(剧本是 JSON,图片是固定分辨率,视频是固定时长),整个系统就有了测试的基础。否则每一步都是黑盒,调试起来会很痛苦。

第三个认识是用户感知比技术指标更重要。角色一致性是我们觉得最重要的技术问题,但用户最多的反馈是"配乐太好了"和"等待进度条做得好"。有时候工程师认为最难的部分,用户根本感知不到。

如果你也在做类似的 AI 应用,可以参考我们的 GitHub 仓库 和这篇文章里的代码片段。有问题欢迎在评论区讨论。

DirectorAI 还在持续迭代。下一个版本计划加入实时协作编辑和多语言配音支持。如果你有具体需求,可以留言。