ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

AI短剧生产流水线:从剧本解析到角色一致性管理

2026/9/26 2:55:19 拓冰建站 浏览量
AI短剧生产流水线:从剧本解析到角色一致性管理 简介这款一站式AI短剧生产工具面向短视频创作者、直播运营者以及有二次开发需求的程序员输入剧本后即可自动完成智能分镜、角色/场景/道具一致性管理并延伸支持自动剪辑、标题封面生成与多平台发布帮助用户从创意输入直达成品输出大幅降低视频内容生产门槛。压缩包共777个文件以Python脚本、TypeScript/TSX前端代码和Markdown文档为主体辅以CSS样式、CSV配置、SQL数据及Docker、GitHub Actions等工程化配置既覆盖后端算法、前端交互也提供了完善的部署与协作支撑整体大小仅2.93MB。目前已有237人学习下载。借助源码、配置与文档可深入理解分镜生成、素材一致性控制、平台热门监控等核心模块的实现思路清晰的目录结构与插件机制也便于开发者快速定位关键代码、按需进行DIY扩展或将其整合进自己的AI剪辑与发布系统中。1. AI 短剧生产的第一道坎不是生成模型是镜头间的一致性一批做竖屏短剧、微短剧的创作者正在把同一件事变成日常剧本写完丢给大模型出分镜、出画面。真正把人卡住的不是生成模型而是角色、场景、道具在镜头之间说变就变。这套打包好的生产工具 A.zip就是把「剧本输入 → 智能分镜 → 角色_场景_道具一致性管理」串成一条可重复跑的流水线。拆完之后我的感受是它不是一个一键出片的魔法盒而是一套把 AI 短剧从依赖运气变成可复现工程的操作规范。它能解决的痛点是同一张脸、同一件外套、同一把道具刀在第 3 集还能对得上。适合已经会跑 AI 绘画或视频模型、但被多镜头一致性反复折磨的剪辑、编剧和独立开发者。2. 剧本输入到智能分镜解析器与镜头规则怎么搭2.1 剧本输入层先把自然语言改造成结构化文本很多人在试过 AI 短剧工具后都会说“提示词越写越玄学”核心原因其实是剧本格式太自由。大模型读散文没问题但分镜脚本需要稳定字段哪一场、谁出场、做什么动作、说什么台词。A.zip 里的解析器默认吃的不是纯散文而是一种轻标记剧本看起来像这样场景夜市大排档 角色张强小芸 动作张强把烤串放到铁盘上抬头看向小芸。 台词张强“你今天怎么跑这来了” 动作小芸低头不接话把手机屏幕转向张强。这套标记结构一共就四类场景、角色、动作、台词。好处是任何编剧都能在十分钟里改完不需要学 XML 或 YAML。解析器会按行读取遇到“场景”就开新场遇到“动作”就把下一句台词挂到当前场景下。你要是愿意也可以把它理解成一种极简的 DSL只服务于分镜这个场景。import json def parse_script(text): scenes [] current None for line in text.splitlines(): line line.strip() if not line: continue if line.startswith(场景): current {scene: line[2:].strip(), shots: []} scenes.append(current) elif line.startswith(角色) and current is not None: current.setdefault(roles, []).append(line[2:].strip()) elif line.startswith(动作) and current is not None: current[shots].append({action: line[2:].strip(), line: }) elif line.startswith(台词) and current is not None: speaker, content line[2:].split(, 1) current[shots][-1][line] f{speaker}: {content} return scenes这段代码的逻辑很直白按行扫描用行首关键字做分支台词行里用中文冒号切出说话人和内容。这里有两个值得留意的细节。第一“动作”和“台词”是一对多的关系所以把台词挂到最近一个“动作”上连续两段台词也只更新同一镜头的台词字段第二角色列表用setdefault收集避免同一场戏里重复列表。如果你的剧本还会用到画外音、闪回、梦境这类元素在解析器里加分支也不复杂后续分镜规则会读取同样的字段不会破坏整条链路。2.2 智能分镜规则景别、时长和镜头逻辑解析出场景和动作之后下一步是把一场戏拆成可生成的镜头。A.zip 里的分镜脚本采用了一套短视频节奏规则每秒 24 帧固定每个镜头时长按台词字数估算景别则由动作类型推导。动作越碎镜头越短说话越多镜头越长。竖屏短剧和横屏长剧最大的差异就在这里——竖屏更依赖近景和特写全景太多会让手机屏幕显得空。动作类型默认景别建议时长对话中景3 ~ 5 秒情绪反应低头、沉默近景特写2 ~ 3 秒走位、进场、出场全景3 ~ 4 秒打斗、追逐等强动作中近景切换1 ~ 2 秒分镜脚本对这些默认参数开放。比如把max_dialogue_duration改成 6长台词镜头就会被再拆一次避免一个镜头里嘴型和语音对不上。计算时长时按中文语速每分钟 240 字左右估算一句话 30 字原本大约 7.5 秒但竖屏短剧对节奏要求更紧脚本里默认再乘 0.8 的压缩系数。DEFAULT_FPS 24 # 竖屏输出统一用 24 帧 def estimate_duration(line: str) - float: if not line: return 2.0 content line.split(: , 1)[-1] words len(content) raw words / 240 * 60 # 每秒 4 字 return round(min(max(raw * 0.8, 1.0), 5.0), 1) def split_into_shots(scene) - list: shots [] for idx, item in enumerate(scene[shots]): d estimate_duration(item[line]) if d 4.0: left { order: idx * 2, action: item[action], line: item[line], duration: round(d / 2, 1), } right { order: idx * 2 1, action: item[action], line: , duration: round(d / 2, 1), } shots.extend([left, right]) else: item[order] idx item[duration] d shots.append(item) return shots这段脚本的意义在于让每个镜头都带一个可计算的时长字段。你后面接 AI 视频生成时把duration乘以 24就知道需要生成多少帧如果模型一次只能生成 4 秒那 7 秒的镜头就必须拆成两段再进剪辑台拼接。参数 0.8 是给竖屏短剧的节奏压缩系数做横屏长剧的人可以改回 1.0。另外duration带小数是为了后面拼接时间线方便不是笔误。2.3 把分镜表输出成 JSON给生成端定数据接口分镜规则确定之后脚本会把整个剧本输出成一份storyboard.json。这个文件是 A.zip 里所有一致性管理模块的数据源头。它的格式有点像剪辑软件的时间线雏形每个镜头固定一个order后续角色卡、场景库、道具列表都会拿scene_id和order做外键关联。{ project: 夜排档, fps: 24, aspect: 9:16, scenes: [ { scene_id: 1, scene: 夜市大排档, roles: [张强, 小芸], shots: [ { order: 1, action: 张强把烤串放到铁盘上抬头看向小芸。, line: 张强: 你今天怎么跑这来了, duration: 1.8, camera: 中景, camera_move: 固定, transition: cut } ] } ] }和 2.1 里那张解析表相比这版 JSON 多加了camera、camera_move、transition三个字段。camera是景别camera_move表示固定镜头还是缓慢推进transition是切镜方式默认cut情绪转折时可以用overlap或shake。这些字段不是给分镜脚本看的是给下游绘图和剪辑阶段用的。AI 剪辑拿到这份 JSON可以直接按order排序生成时间线和字幕轨。你手动改 JSON 也可以但我更推荐直接改 md 源文件再重新运行脚本。因为手动改 JSON 容易改着改着就跟角色卡里的场景名对不上回头排查又是一轮折腾。保持“源文件 → 生成 JSON”的单向数据流能少踩很多坑。2.4 智能分镜的边界哪些必须人工复核这里要泼一盆冷水这套智能分镜本质是机械规则不对“叙事情绪”负责。动作密集的场景它会把镜头拆得很碎但一个关键反转镜头比如女主发现自己被骗时那个停顿规则可能只给一个 2 秒中景。编剧的直觉在这里比算法可靠。我习惯的做法是生成storyboard.json后先做一次“抚摸式审查”只看镜头拆得够不够、情绪重场有没有被切碎。重点检查duration小于 1.2 秒的镜头太短的镜头塞进 AI 视频模型通常会被拒绝生成。分镜脚本里一般会有--min-duration这类参数但人工调整后的 JSON 一定要回写不要下次重新生成又覆盖掉。3. 角色、场景、道具一致性管理用 token、seed 和配置模板锁住画面3.1 一致性管理为什么不能只靠提示词生成式 AI 的文本提示词本身就不稳定同一句“穿黑色皮衣的年轻男人”不同步数、不同模型版本生成出来的脸完全不一样。短剧是一集一集生产的只靠文字描述约束角色等于让演员每场戏换个头。A.zip 的一致性管理拆成三层角色卡负责脸和体型场景库负责环境底色道具清单负责关键物品。底层逻辑是把“高变化的文本描述”换成“低变化的结构化标识”。角色脸上的特征会被压缩到 token 和 LoRA 里环境信息会被压缩到场景 seed 和参考图里道具则是通过引用固定图像来约束。这三层互相独立又通过scene_id关联到分镜 JSON。改一层不会影响另外两层这就是它比单条长提示词更可控的原因。3.2 角色卡配置seed、LoRA 与触发器怎么配合A.zip 的configs/characters目录下默认放了角色卡模板。把一张卡拆开看长这样{ id: zhang_qiang, name: 张强, trigger: zhangqiang, lora: models/lora/zhangqiang_v1.safetensors, base_seed: 20240813, init_image: assets/zhang_qiang_face.png, template_prompt: 1man, solo, looking at viewer, upper body, wearing black leather jacket, negative_prompt: blurry, bad face, deformed hands, multiple people, wardrobe: { scene_1: [black leather jacket, jeans], scene_2: [white tshirt, jeans] } }trigger是给模型的身份词lora指向角色专用的低秩微调文件base_seed是生成首张定妆照时用的随机数种子init_image是人工挑选的正面参考图用于后续 IP-Adapter 或 reference-only 控制。wardrobe按场景区分服装等于把服装从角色外貌里单独摘出来了。拼提示词时脚本会把 trigger、场景描述、道具描述按固定顺序拼成一个长句。顺序错了很容易出问题因为模型会优先响应靠前的 token。实际实现如下def build_prompt(role_card, scene, props, wardrobe_keyscene_1): base role_card[template_prompt] outfit role_card[wardrobe].get(wardrobe_key, ) scene_text scene.get(base_prompt, ) prop_text , .join(props) return f{role_card[trigger]}, {outfit}, {scene_text}, {prop_text}, {base}这个拼接函数最大的价值是让“人和场景”分开控制。trigger永远放在第一位模型优先匹配角色身份场景只是背景道具放中间重要性高于 base 里的笼统描述。如果某一场景里角色服装变化过大优先检查wardrobe_key有没有传对而不是去调 LoRA 权重。LoRA 权重一般压在 0.6 到 0.9 之间太低脸没特征太高动态和姿势会僵硬。3.3 场景库与道具清单把容易漂移的视觉元素外部化场景和道具如果都写进角色 prompt角色卡会被撑爆。这个资源包里把场景拆分成了scene_library.json和props.json。每个场景有一条base_prompt和一个base_seed每次生成同一场景时复用同一个 seed环境构图就能稳定住。道具则按场景分组只保留剧情上必须出现且不能变样的物品比如定情信物、凶器、招牌。{ scene_library: { 夜市大排档: { base_prompt: night market, steam, warm neon lights, outdoor stalls, depth of field, base_seed: 555111, ref_image: assets/scene_night_market.png } }, props: { 夜市大排档: [ { name: 不锈钢烤盘, ref_image: assets/prop_tray.png, mandatory: true }, { name: 手机屏幕, ref_image: assets/prop_phone_screen.png, mandatory: true } ] } }注意mandatory字段。普通水杯、雨伞这类装饰性道具不需要进列表但剧情反转里那个手机屏幕必须进去。我一般会把所有关键道具单独生成一张参考图再用 IP-Adapter 或 ControlNet 把它塞进画面。不加参考图的话镜头 A 里的手机是贴了钢化膜的镜头 B 里可能就变成新款折叠屏观众一眼就能看出来。3.4 跨模型迁移时的一致性策略开源模型生态更新很快上个月还在用 SD 1.5下个月就可能切到 SDXL 或新的视频模型。token 和 LoRA 不一定能跨模型直接用。我见过的稳妥做法是先找出角色卡里的init_image用目标模型跑一次定妆照再把新出的定妆照作为下一阶段的参考图。这样既保留原角色特征又适应新模型的画风。另一个技巧是用首帧做镜头间校准。同一场戏里先把第一个镜头的生成结果第一帧存下来传进下一个镜头当 reference能明显减少动作捕捉的漂移。但这个方法有副作用如果前面镜头已经是糊的后面会一路糊下去。所以做批量生成时基线镜头必须人工确认清晰才允许作为后续 reference。4. 把 A.zip 跑起来目录结构、依赖安装与首个测试案例4.1 解压之后先看什么下载 A.zip 后第一件事不是双击运行而是先确认目录。这个压缩包内部组织和常见开源工程一致scripts 放解析和拼接脚本configs 放角色和场景配置workflow 放 ComfyUI 或类似图形工作流的导出文件docs 放使用说明。我建议解压后先翻一遍docs/quickstart.md因为不同版本对 Python 版本的要求有差异。目录/文件作用常见坑scripts/storyboard.py剧本解析与分镜输出依赖 openpyxl 时需先安装scripts/prompt_builder.py按 JSON 配置拼生成提示词读不到 configs 路径会报错configs/characters/角色卡一人一个 JSON文件名不要带中文configs/scene_library.json场景底图和固定 seed修改后要重新生成 storyboardworkflow/图形化工作流文件版本不同可能导入失败docs/参数说明和排错手册优先看这一份还有一个容易忽略的点解压后不要直接把 scripts 目录单独拷出去用。脚本里通常用了相对路径读取configs/脱离顶层目录会立刻报FileNotFoundError。我基本都会把整个包留在一个固定工作目录再用cd进根目录执行不搞散装。4.2 依赖安装不同系统的差异cd A.zip 的展开目录 python -m venv .venv source .venv/bin/activate # Windows 下是 .venv\Scripts\activate pip install -r requirements.txt先用虚拟环境隔离依赖是避免污染系统 Python 的习惯。requirements.txt 里一般只有 json、Pillow、numpy 这类基础库安装很快。Windows 上如果python -m venv后激活失败检查是不是用了 Windows Store 的 python 别名macOS 的 Apple Silicon 机器如果跑模型需要给 PyTorch 设置PYTORCH_ENABLE_MPS_FALLBACK1否则某些算子在 MPS 后端会直接崩。Linux 服务器则要留意显卡驱动驱动不对时pip install成功也没用。4.3 从剧本到首版分镜命令与预期输出我在自己的目录里建了一个test/文件夹放了一个三行剧本然后跑脚本验证整条链路。下面这个命令串就是最基础的操作流。python scripts/storyboard.py --input test/script.md --output test/storyboard.json python scripts/prompt_builder.py --storyboard test/storyboard.json --out test/prompts.txtstoryboard.py输出的是结构化 JSONprompt_builder.py再把角色卡、场景库、道具清单合并成每个镜头的完整英文提示词。跑完之后prompts.txt里大约是这样一个行zhangqiang, black leather jacket, night market, steam, warm neon lights, stainless steel tray, mobile phone screen, 1man, solo, looking at viewer...这一行会被直接喂给生成模型。注意 prompt 的第一个词是zhangqiang而不是场景这是角色优先级的设计。如果两个脚本都能正常退出说明 A.zip 在你机器上的链路是通的。之后你只需要改剧本和配置不再需要碰这段流程。4.4 参数怎么调分辨率、帧率、镜头数量、采样步数跑通首版之后就需要开始调参了。竖屏短剧输出端最常见的分辨率是 720×1280 和 1080×1920。分辨率太高视频生成模型一次推理的时间和显存占用都会翻倍太低转场后细节会糊。A.zip 默认配置是 720×1280对大多数开源视频模型是安全值。参数默认值建议范围影响resolution720x1280720x1280 ~ 1080x1920显存不足时先降这里fps2416 / 24部分模型只用 24 训练sample_steps2020 ~ 30过高会放大角色特征偏差cfg_scale5.05.0 ~ 7.0过高表情僵硬过低画面发灰max_shot_duration4.02.0 ~ 5.0限制单镜头秒数采样步数和一致性强相关。Stable Diffusion 系列一般 20 步出图30 步细节好但容易把角色特征带偏视频模型里 CFG 通常建议 5 到 7数值太大会让角色表情僵硬太小画质发灰。调整时每次只动一个变量不要同时改步数和 CFG否则翻车了不知道是该怪哪边。5. 常见问题排查AI 短剧生产中最容易翻车的五个细节5.1 同一角色换个场景就换脸现象第一集男主的脸还能认第二集同一角色五官完全变了一个人。更隐蔽的情况是单独看每个镜头都正常但两个镜头放一起对比就不像同一个人。原因角色卡里的 base_seed 没被固定或者生成时随机数被重置。很多 AI 视频工具如果不显式传 seed每次调用都会起一个随机 seed人脸的细节就被随机数带着跑。解决把所有镜头的生成请求统一强制传递角色卡里的 base_seed。如果用 ComfyUI把 seed 节点接成固定值如果自己的脚本调用模型也要在参数里显式传。遇到必须换 seed 的场景至少保留 LoRA 和 trigger 不变并把新 seed 写回角色卡的 sample 字段方便回溯。5.2 人没走衣服走了现象长镜头里人物上半身保持稳定但外套颜色从黑色慢慢变成深蓝下一个镜头直接变成夹克。这个问题在 AI 短剧里比脸崩还常见因为服装在 prompt 里的权重太靠后了。原因生成视频模型对短镜头窗口内的语义保持较好但跨越多个镜头时服装描述在长提示词里被稀释。角色 trigger 是合成词权重集中在脸部服装只是笼统的文本标签。解决把 wardrobe 从角色卡里单独拿出来作为每个镜头的固定前缀。我还会先用 ControlNet 的 openpose 约束身体姿态再让局部重绘只处理脸部区域这样衣服不会跟着表情一起变。关键场次的服装可以先单独生成一张平铺图通过 IP-Adapter 塞进画面的参考通道。5.3 智能分镜把关键动作漏掉现象剧本里写了“从兜里掏出手机”分镜表里只有“抬头看向小芸”手机道具直接消失后面的反转戏根本没素材可用。原因解析器只认“动作”关键字。如果剧本作者把动作写进了台词描述里例如“小芸低头将手机屏幕转过来”写在台词行里没有单独写“动作小芸把手机屏幕转向张强”解析器就会忽略。解决写剧本时把所有视觉信息都放到动作行。我一般会让编剧先过一遍标记规范分镜脚本跑完后再逐场看 JSON 里 shots 的数量。如果某个情节节点在分镜里找不到对应镜头就去改源剧本不要直接往 JSON 里硬插。5.4 zip 里的脚本在别人机器上报错现象在自己电脑上跑得好好的发给同事解压后直接报ModuleNotFoundError: No module named openpyxl或者报FileNotFoundError: configs/characters/xxx.json。原因第一压缩包里的 requirements.txt 没有把环境锁全第二对方用系统 Python 直接跑没进虚拟环境第三对方从 zip 解压后只在子目录里执行脚本相对路径找不到 configs。解决接收方先执行 4.2 的虚拟环境命令再跑pip install -r requirements.txt。路径问题则统一从根目录进不要直接双击单个 py 文件。如果包作者没提供 requirements.txt就用pip install openpyxl补上但要把这行注释掉再提交避免别人每次都重装。5.5 生成的成片时长对不上平台规格现象单镜头生成 6 秒拼接后一条短剧总时长过长发出去因为时长问题被平台限流或者是镜头之间出现明显跳跃动作中断。原因分镜时长估算用了台词字数但 AI 视频模型一次只能生成 3 到 4 秒。硬拼时长会让动作在中间出现跳跃平台侧的节奏要求也没被考虑进去。解决给storyboard.json里的 duration 字段设上限 4 秒超过的镜头拆两段。竖屏短剧的切镜本来就频繁观众对 1 到 2 秒的跳切接受度很高。拆完镜头后在剪辑台用叠化或变速接一下比强行让模型生成 6 秒要稳定得多。6. 进阶用法给角色做“配方”再批量验证一致性6.1 把单集剧本变成系列“配方”微短剧真正的常量是一致性所以我会在 A.zip 基础上再建一个series_recipe.json把每一集需要的角色状态、场景变化、道具位置都记录进去。第一集定妆后固定角色 token LoRA 基础 seed第二集只改 trigger 和服装其他全部继承。这样跨集生成时角色底子不会漂。6.2 用批量图像相似度脚本验证输出人眼检查几十张定妆图太慢我一般跑一遍相似度脚本把同角色在不同场景下的定妆图两两比较输出平均差异分。低于阈值直接判为存疑再人工复查。下面这段代码是从包里常用做法摘出来的import os import numpy as np from PIL import Image def compare_dir(role_dir, threshold0.2): imgs sorted(os.listdir(role_dir)) scores [] for i in range(len(imgs) - 1): path_a os.path.join(role_dir, imgs[i]) path_b os.path.join(role_dir, imgs[i 1]) a np.array(Image.open(path_a).convert(RGB).resize((256, 256)), dtypenp.float32) b np.array(Image.open(path_b).convert(RGB).resize((256, 256)), dtypenp.float32) diff np.mean(np.abs(a - b)) / 255.0 scores.append(diff) return scores这个脚本把相邻镜头定妆图缩到 256×256再计算像素平均绝对差。差异值小于 0.1 说明画面非常接近0.1 到 0.2 算正常范围超过 0.2 就需要重新生成或排查是不是场景光线干扰过大。它不能替代肉眼但能快速筛出明显翻车的镜头。肉眼复查时只看超阈值的那几张图精力就能集中在最要命的地方。6.3 我的收工习惯现在我每次做完一集都会把角色卡、场景库、storyboard.json 三件套打包回一个 zip文件名带集数和日期。遇到某张图特别满意就把那次的 seed、CFG、采样器写进角色卡的 sample 字段当作下一集的对齐基准。这个习惯救了我好几次尤其隔两周再继续做同一部短剧模型版本都更新了没有基准参数就只能从头试错。从那以后我每次开新集都强制走一遍“解析剧本 → 生成 storyboard → 对比定妆图 → 锁定参数”的流程。希望帮到你。本文还有配套的精品资源点击获取