
简介这是一套面向AI漫剧与短剧创作者、视频内容开发者的本地化全流程创作工具核心解决从故事到成片的高效产出难题。资源整合剧本分析、AI分镜、图片资产与Seedance火山方舟视频生成支持AI真人剧与AI漫剧在本地完成制作数据不出本机即可完成短剧工作流管理。压缩包共1175个文件以1125个webp图片资产为主辅以js/json配置、Docker/nginx等部署配置以及png/jpg/svg图形资源整体仅19.84MB轻量便于部署。已有50人学习适合想深度定制AI视频生成流程、搭建自有短剧创作平台的中高级创作者。从这套工程中可获得可直接运行的前后端框架、容器编排与反向代理配置、浏览器端交互页面能够快速复现本地化AI漫剧生产流水线显著降低从剧本分析到视频合成的试错成本。1. AI 短剧全流程创作工具把从剧本到 Seedance 成片的脏活一次串完做 AI 短剧的同行应该都有同感真正卡住进度的不是最后那一下视频生成而是生成前没人替你收拾的结构化工作。剧本停在口头创意、分镜靠手感、角色图和场景图各存各的真到 Seedance 上生成时才发现提示词、首帧、时长根本没对齐。这套 AI 漫剧 / AI 短剧全流程创作工具就是把剧本分析、AI 分镜、图片资产、Seedance×火山方舟视频生成的链路完整串起来的一套工程包。适合自己攒短剧的个人创作者也适合做漫剧分镜设计的动画工作者跟着章节走一遍你能拿到一份可以直接替换成自己内容的分镜脚本 JSON、一份角色一致性的素材库方案以及一套跑通视频生成的调用骨架。下文所有操作都按我实际跑过的顺序来写参数给到可直接抄的程度。2. 剧本分析把文案拆成可执行的分镜脚本拆错等于全盘重来2.1 为什么要先做「结构化拆解」而不是直接去生成分镜短剧剧本本质是叙事文本里面是故事线、对白和情绪模型读不懂「运镜」和「景别」。如果你把一段三百字的故事直接丢给图生视频模型它只会按自己的理解自由发挥出来的画面大概率跟你的预期两不相干。我见过太多人在这里翻车剧本写得热血沸腾生成出来的视频像新闻播报原因是模型没拿到任何镜头信息全靠猜。所以必须先有一个中间格式分镜脚本。它把每一段文字对应到「什么场景、什么角色、什么动作、什么景别、镜头怎么动、大概几秒」。这一步做完后面 AI 分镜和视频生成才有依据。常见做法是让大模型比如豆包、GPT或你在 Coze 里接的 LLM先把剧本清洗成结构化文本再交给脚本做场景切分如果你剧本本身格式规整直接跑解析脚本也行。这套工具包里的剧本分析模块走的就是「LLM 清洗 脚本切分」的组合路子清洗这一步可以手动做重点是输出格式要统一。2.2 一份可直接抄的分镜脚本 JSON 结构分镜脚本的格式决定了后面所有环节能不能自动衔接。我用的结构是把「场景 scene」作为第一层每个场景下面挂「分镜 shot」。一个 shot 将来就对应一张分镜底图、一条 Seedance 生成任务这个对应关系是整条工作流的锚点。{ story_title: 老街的猫, scenes: [ { scene_no: 1, location: 老街巷口, time: 黄昏, shots: [ { shot_no: S1-01, shot_type: 全景, camera_move: 缓推, content: 猫蹲在屋檐上看着远处亮灯的小卖部, dialog: , sound: 巷子里的风声, duration: 3 }, { shot_no: S1-02, shot_type: 中景, camera_move: 固定, content: 猫站起身尾巴轻轻扫过瓦片, dialog: 阿桔今晚该去讨点鱼干了。, sound: 环境音, duration: 4 } ] } ] }各字段的作用我在下表里说明后面脚本和 Seedance 调用都会引用这些字段名所以命名务必统一。字段类型说明story_titlestring故事名用于命名输出文件夹scene_noint场景序号决定文件分组locationstring场景地点必须和图片资产库里的场景名一致timestring时间段影响灯光描述词shot_nostring镜头编号全局唯一建议「S场景-序号」格式shot_typestring景别远景/全景/中景/近景/特写camera_movestring运镜固定/缓推/拉远/横移/跟随contentstring画面内容中文描述动作与主体dialogstring对白留空表示无对白durationint预估时长秒后续视频生成直接使用这套结构里一个 shot 对应一条生成任务shot_no 会成为所有中间文件的命名前缀。你拿到工具包后不需要改结构只替换内容字段即可。2.3 一段能把剧本切成场景的解析脚本我一般会把剧本按「空行分场景、非对白首行写环境、对白行写台词」的约定整理好再跑下面这个脚本产物就是标准的 storyboard.json。这个约定看着简单但能让解析逻辑稳定下来比让模型自由发挥可靠得多。import re import json raw open(script.txt, encodingutf-8).read() # 按空行拆分得到一个个场景块 blocks [b.strip() for b in raw.split(\n\n) if b.strip()] # 匹配 角色名台词 行冒号中英文都兼容 line_re re.compile(r^(?Prole[\u4e00-\u9fa5A-Za-z])\s*[:]\s*(?Ptext.)$) scenes [] for idx, block in enumerate(blocks, 1): scene {scene_no: idx, location: , shots: []} for line in block.split(\n): m line_re.match(line.strip()) if m: # 每个对白行先当做一个潜在镜头后续可再拆 scene[shots].append({ shot_no: fS{idx}-{len(scene[shots]) 1:02d}, role: m.group(role), dialog: m.group(text).strip(), }) elif line.strip(): # 非对白的首行文本作为场景描述 scene[location] line.strip() scenes.append(scene) with open(storyboard.json, w, encodingutf-8) as fp: json.dump(scenes, fp, ensure_asciiFalse, indent2) print(f解析完成共 {len(scenes)} 个场景)逻辑说明脚本先按空行把剧本拆成场景块这是基于「一段一场景」的写作约定接着逐行匹配「角色名台词」格式基于它生成 shot 雏形非对白行则作为 location 字段。这样生成的 JSON 会和 2.2 节的结构基本一致只是每个 shot 还缺少 shot_type、camera_move 这些信息需要在下一步由人来补或者用 LLM 批量补齐。参数说明line_re的正则里\s*用来兼容中英文冒号前后的空格[\u4e00-\u9fa5A-Za-z]只匹配中英文角色名避免把场景描述误判成对白。如果你的剧本里角色名带数字或符号把字符集扩一下就行。脚本输出的storyboard.json就是后面分镜、资产、Seedance 调用共同读取的唯一数据源所以这一步跑完先打开 JSON 目检一遍确认 location 没被对白行污染再继续。3. AI 分镜生成从分镜脚本到分镜底图提示词该怎么拼3.1 分镜提示词的模板化拼接角色库 / 场景库 / 运镜库分镜底图的质量直接决定最终视频的上限而提示词是最容易失控的环节。我的习惯是按「角色库 场景库 运镜库」三块词表拼提示词每块词表固定写法这样同一个角色在不同镜头里描述才能保持一致。角色库管谁在画面里场景库管背景和光影运镜库管镜头语言。def build_prompt(character, action, location, shot_type, camera_move, style赛璐璐动画高饱和配色黄昏暖光电影感): template ( {style}{shot_type}{camera_move} 画面主体是{character}{action}背景是{location} ) return template.format( stylestyle, shot_typeshot_type, camera_movecamera_move, charactercharacter, actionaction, locationlocation, ) # 示例调用 prompt build_prompt( character一只橘白相间的胖猫耳朵有缺口眼睛是琥珀色, action蹲在屋檐上尾巴轻轻扫过瓦片看向远处小卖部, location老街巷口的瓦房屋顶远处有亮灯的小卖部招牌, shot_type中景, camera_move缓推, ) print(prompt)逻辑说明style是全局风格锚点同一部剧从头到尾固定这一句不要每张图换风格描述否则分镜之间像两部片子。character来自角色资产库里的固定描述词action则来自 storyboard.json 里的 content 字段。模板的价值在于把变量隔离角色和场景的描述词各自维护、独立迭代。参数说明style 里我强烈建议带上「赛璐璐、厚涂、写实、水墨」这种一级风格词再补一个「黄昏暖光」这种光效词。光效词决定整组底图的色调统一度这是漫剧和短剧最容易出彩也最容易翻车的点。action 字段只写一个主动作 一个次要动作别把「站起来、伸懒腰、跳向招牌」三个动作挤在一起后面视频生成会乱。3.2 参数怎么设步数、CFG、分辨率与长宽比分镜底图我一般走 ComfyUI 批量出图这样可以把 3.1 的提示词函数接到工作流里按 storyboard.json 自动跑。漫剧场景下画面构图比细节纹理重要参数不必往极致里调够用就行。下面是我验证过的一组起点参数不同渲染器比如 SD1.5 和 SDXL取值会略有浮动但大方向一致。参数建议值说明采样步数 steps25~30漫剧不需要堆到 40 步收益很小CFG4.5~7越高越贴提示词但容易脏角色一致性场景建议偏低采样器DPM 2M Karras出图稳定动画风格友好分辨率1088x1920竖版 9:16短剧必须竖版直接用方舟支持的档位种子 seed固定同一角色/场景复用同一个 seed能显著减少变脸批量大小4~8ComfyUI 里一次跑多个 shot注意显存上限为什么 CFG 是关键参数分镜阶段我们追求的是「同一角色不同镜头长得像」CFG 拉到 7 以上时模型会过度响应提示词里的细碎描述反而把角色特征画飞。我一般控制在 6 附近配合固定 seed 使用。分辨率直接对齐火山方舟 Seedance 支持的档位免得后面生成视频时还要二次裁剪。3.3 保证分镜底图「一个角色一张脸」的做法角色一致性是漫剧分镜里最玄学的一环。你生成十张图同一个角色可能出现五张不同的脸这不是模型笨是提示词和参数没有约束住它。我常用的方案是「固定 seed 低 CFG 参考图引导」三者叠加。ComfyUI 里把第一张满意的角色正脸图作为参考图接入 ControlNet用 IPAdapter 或 reference-only 模式后续所有分镜在这个参考约束下生成脸型、瞳色、毛色基本不会跑偏。负面提示词也值得单独维护一份我固定在用的一组是模糊低质量多余的肢体变形的脸夸张的阴影文字水印logo。其中「文字水印」必须常驻漫剧画面里一旦出现乱码文字后面对齐首帧时会非常显眼。这套工具包里的 ComfyUI 工作流 json 已经把这些节点接好了你只需要把 3.1 的 build_prompt 输出接到工作流的文本输入框再替换角色参考图即可。批量出图完成后按 shot_no 编号归档下一步图片资产整理才能对得上。4. 图片资产把一次性的图变成可复用的素材库4.1 资产目录与命名规范分镜底图只是中间产物你真正需要沉淀的是可复用的角色图、场景图和道具图。很多教程教你先出图再想名字结果素材库十天就乱成一锅粥。我这边固定用下面这套目录结构命名规则是「对象_视角_版本」所有文件放进 assets 根目录后面脚本校验时直接按这个规则查。assets/ ├── characters/ │ ├── 阿桔_正面_竖版_v1.png │ ├── 阿桔_侧面_竖版_v1.png │ └── 阿桔_半身_竖版_v1.png ├── scenes/ │ └── 老街巷口_黄昏_v1.png ├── props/ │ └── 小卖部招牌_特写_v1.png └── styles/ └── 赛璐璐_风格参考_v1.png命名规范的三个约定第一段是资产主人角色、场景、道具各归各的文件夹第二段是视角或时间同一个场景的白天/黄昏版本必须分文件因为光照会直接影响视频生成的调色第三段是版本号改版只加版本号不覆盖旧文件方便回溯。这套约定成本极低但能让你在跑完五十个镜头后还找得着每一张图的出处。4.2 角色一致性的三个常用方案对比图片资产的核心价值就是喂给后续视频生成角色一致性靠的不只是提示词而是资产方案本身。我把常见的三个方案列个对比你按项目体量选方案做法优点代价固定角色描述词资产库里只维护一段文本零成本改词方便一致性最弱不同分镜还得碰运气参考图 IPAdapter选一张正脸图每次生成都带参考一致性较强动画风格够用需要熟悉 ComfyUI 节点跑批略慢多视图角色卡生成正面/侧面/背面三张组合成角色卡一致性最强适合多集连续剧建卡成本高每集要做二次校验漫剧这种单集时长短、角色数量少的场景我建议直接上方案二「参考图 IPAdapter」性价比最高。如果你的项目是几十集的连续漫剧主角出场频次极高才值得为方案三花时间。方案一的坑在于提示词写「琥珀色眼睛、缺口耳朵」写得再细模型出五张图大概率还是五张脸。4.3 批量整理素材的脚本思路分镜多了以后手动检查每个镜头缺哪张图会疯。我写了个小脚本直接读 storyboard.json自动比对 assets 目录输出一张「待补齐清单」。这样在进入 Seedance 生成之前你能一眼看到哪些镜头缺角色图、哪些场景没对应资产而不是等生成完才发现某张首帧是坏的。import json import os from pathlib import Path storyboard json.load(open(storyboard.json, encodingutf-8)) assets_root Path(assets) missing [] for scene in storyboard[scenes]: location scene.get(location, ) # 场景图检查注意 assets 里用下划线剧本里可能是中文逗号 scene_file assets_root / scenes / f{location.replace(, _)}_黄昏_v1.png if not scene_file.exists(): missing.append(f场景图缺失: {location}) for shot in scene[shots]: shot_no shot.get(shot_no, ) if not (assets_root / characters).glob(*): missing.append(f角色资产目录为空无法匹配 {shot_no}) break report \n.join(missing) if missing else 资产齐全可以进入视频生成阶段 print(report) with open(asset_check_report.txt, w, encodingutf-8) as fp: fp.write(report)逻辑说明脚本遍历 storyboard 里的每个场景和镜头按命名规范拼出预期文件名用exists()检查资产是否存在。location 里如果带中文逗号先替换成下划线再拼接这是命名规范里最容易踩的细节。最后把缺失项写成文本报告而不是直接抛异常方便你批量补齐后重跑。参数说明assets_root指向你的资产根目录如果你改了目录结构改这一行就能适配。replace(, _)是必要的脏数据兜底因为剧本里写「老街巷口黄昏」和资产文件名里的下划线永远对不上这类问题在脚本里静默处理比回头人工排查效率高。这个检查脚本跑完asset_check_report.txt 里没有内容我再放心进 Seedance。5. Seedance × 火山方舟 视频生成工作流搭建步骤与避坑要点5.1 工作流的整体形态分镜图作为首帧视频生成只做「动起来」到了这一步前面所有工作的目标都是让 Seedance 把分镜底图「动起来」。Seedance 是火山方舟上以模型服务方式提供的视频生成能力刚才的静态分镜图会作为 first_frame 首帧输入模型基于它和 prompt 生成后续视频帧。这里的关键认知是视频生成阶段不要再试图改变画面内容它只负责运动、镜头和时序。你在 prompt 里写新的角色描述、场景描述都会和首帧打架出来的画面不是鬼畜就是突变。所以我建议完整链路是分镜底图 → base64 编码 → 作为 first_frame 提交 → Seedance 根据 motion prompt 生成视频 → 下载成片。这也意味着分镜底图的质量就是视频质量的上限第 3 章的工作在这里兑现。motion prompt 只写「动作 运镜」不写任何外观描述词。5.2 调 Seedance 的代码骨架请求参数与轮询状态调用火山方舟 Seedance 的方式和大多数模型服务类似提交生成任务后轮询状态。下面这版代码我加了完整的注释和 base64 处理你把它里的 API Key 和接入点地址替换成自己在火山方舟控制台申请到的值就能跑。import base64 import time import requests API_KEY 你的火山方舟 API Key ENDPOINT 你在方舟控制台创建的接入点地址 # 开通 Seedance 后自动生成 headers { Authorization: fBearer {API_KEY}, Content-Type: application/json, } # 读分镜底图并编码 with open(S1-01.png, rb) as fp: img_b64 base64.b64encode(fp.read()).decode() payload { model: seedance 系列模型标识以你控制台开通的服务名为准, content: [ { type: video_generation, video_generation: { prompt: 猫站起身缓推镜头尾巴扫过瓦片跳向亮灯的小卖部招牌, first_frame: fdata:image/png;base64,{img_b64}, resolution: 1080x1920, duration: 5, fps: 30, seed: 20240601, }, } ], } resp requests.post(ENDPOINT, jsonpayload, headersheaders) task resp.json() task_id task.get(id) or task.get(task_id) print(任务 ID:, task_id) # 任务提交后异步执行轮询结果 while True: detail requests.get(f{ENDPOINT}/{task_id}, headersheaders).json() status detail.get(status) print(当前状态:, status) if status in (succeed, failed): break time.sleep(3) if status succeed: video_url detail.get(video_url) or detail[output][video_url] print(成片地址:, video_url) else: print(生成失败错误信息:, detail.get(error) or detail)逻辑说明提交阶段把任务id拿到然后每隔 3 秒轮询一次状态直到 succeed 或 failed。长视频生成要几十秒轮询间隔太短会平白增加请求次数和费用3 秒是平衡值。status和返回内容的字段名在不同版本接口里略有差异所以代码里给了or的兜底写法。参数说明first_frame我用了data:image/png;base64,{img_b64}前缀这是图生视频常见的传输格式少了前缀会被当成纯文本解析而报错。duration注意别超过模型上限Seedance 单次生成时长受分辨率档位限制5 秒是稳妥值。seed固定能降低同一组镜头间的随机性但不同任务的 seed 不必连续用一个有意义的种子号即可。resolution对齐 1080x1920 竖版档位和第 3 章分镜底图保持一致避免首帧拉伸。5.3 高频翻车点排查现象、原因、解决视频生成阶段的问题不像代码报错那么直接很多是画面层面的只能靠经验判断。我把自己踩过的坑整理成下面五条按「现象 → 原因 → 解决」的结构写每条都是真实发生过、改完再跑就正常的。坑一首帧失效角色突然变脸现象明明提交了分镜底图生成出来的第一秒角色脸型、发色和底图不一致。 原因first_frame 字段名传错或者 base64 前缀缺了服务端没解析到图片等于跑了文生视频。 解决先打印提交给服务端的 payload确认 first_frame 以data:image/png;base64,开头若没有就是 encode 环节丢了前缀。代码里我已写好完整写法直接对照排查。坑二镜头运动像幻灯片画面几乎不动现象视频能出但主体只平移了一下就定住没有自然的动作变化。 原因motion prompt 里塞了太多动作「起跳、扑向、回头看」全挤在一起模型只能挑一个完成。 解决一个镜头只写一个主动作加一个简单运镜。比如「猫从蹲姿缓缓站起来镜头缓慢推进」。粗糙的动作描述远胜于堆砌因为模型分不清动作优先级。坑三任务报错提示参数非法现象提交后立刻返回 4xx 错误提示 duration、resolution 或 model 字段有问题。 原因多数是对齐问题——duration 超过了当前档位上限或分辨率不是模型支持的档位或 model 标识复制错了。 解决打开火山方舟控制台对照你开通的服务说明逐项核对字段取值。别自作聪明传 8 秒时长或 2K 分辨率只有文档里明确列出的档位才合法。不同模型比如 Minimax 或可灵参数不通用换模型必须重新核对。坑四画面里出现乱码文字现象生成结果里招牌、海报上的文字全是变形乱码特别显眼。 原因分镜底图本身带了小字视频生成时模型尝试重建文字但失败了。 解决在分镜阶段就处理掉文字内容把招牌改成纯色图案或者把文字移出画面。这个坑在后期几乎没法修只能重做首帧返工成本极高。坑五耗时长、费用超出预期现象同一批镜头反复重试跑的时长和费用比预算翻了一倍。 原因没有先在低分辨率档位上试跑 motion prompt直接上 1080x1920 终份档失败一次就烧一次钱。 解决先拿 1~2 个镜头用最低档分辨率跑通 motion prompt确认动作自然、首帧对齐后再批量提交终档。这套工具包的工作流里也内置了「草稿档验证」这一步别跳过。这些坑的共同点在于问题大多出在提交前的数据准备而不是模型本身。5.2 的代码骨架和 5.3 的排查表搭配使用能覆盖九成以上的失败场景。6. 进阶技巧成本核算、批量输出与成片一致性校验6.1 成本怎么算按秒计费与前期的「钞能力」控制Seedance 这类视频模型的计费逻辑是按生成时长和分辨率档位算的同一段 5 秒视频1080p 的单价明显高于低档位。我现在的习惯是任何新项目先做两件事一是估算总时长二是把批量提交前需要验证的镜头控制在两三个以内。总成本的大头从来不是正常生成而是失败重试——首帧不对、动作鬼畜、时长超限每失败一次烧掉的时间和费用都白费。所以「草稿档验证 参数核对 资产检查」这三步前置工作做扎实省下来的费用远大于多做几分钟测试。控制台里的用量统计记得定时看我见过到了月底才发现超支的例子不止一个。6.2 成片一致性校验抽帧比对 场景打点视频批量跑完不能直接发至少做一次成片与分镜的一致性抽检。我的做法是从每段成片里抽首帧和中段帧和分镜底图做一次相似度粗筛把偏差大的标出来人工复核。脚本逻辑很简单但能筛掉大部分首帧错位的漏网之鱼。import cv2 video cv2.VideoCapture(S1-01.mp4) ok, frame video.read() # 第一帧 storyboard cv2.imread(S1-01.png) # 统一尺寸后做直方图比较 frame_small cv2.resize(frame, (256, 256)) board_small cv2.resize(storyboard, (256, 256)) score cv2.compareHist( cv2.calcHist([frame_small], [0], None, [256], [0, 256]), cv2.calcHist([board_small], [0], None, [256], [0, 256]), cv2.HISTCMP_CORREL, ) print(首帧相似度:, score) # score 低于 0.6 的镜头标记复查 if score 0.6: print(S1-01 首帧偏差较大需人工复核)逻辑说明compareHist算的是两帧直方图的相似度对色调和整体构图变化敏感对局部细节变化不敏感。这正好适合做粗筛——首帧如果完全对不上分数会非常低画面构图相同但颜色有轻微漂移分数会正常。细看阶段的镜头按 shot_no 找到对应的 storyboard 手动比对即可。这个校验脚本看着简单但它挡住的都是发布后才发现的大问题。从那以后我每次批量生成完都强制走一遍抽帧比对阈值卡在 0.6宁可多花十分钟筛出有问题的镜头重新补一条也不愿整批项目交付后才发现首帧崩了。这套工具包把第 2 到第 5 章说的完整流程收成了开箱即用的工程文件你拿自己的剧本替换输入按序跑一遍就能复现整个链路希望帮到你。本文还有配套的精品资源点击获取