AI漫剧全流程生产:从剧本分析到Seedance视频生成的工作流
发布时间:2026/10/2 9:09:34来源:尧图网络
简介一个本地化部署的AI漫剧/短剧创作工具包面向内容创作者、短视频团队与AI绘画/视频爱好者解决从剧本分析、分镜设计到视频生成全流程依赖云端、数据外泄与工具分散的问题。压缩包内含1175个文件以webp图片资产为主1125个另有前端JavaScript、配置JSON、Docker部署文件及说明文档等整体19.84MB便于快速启动工作流。已有50人学习下载适合希望自主掌控创作管线、探索Seedance视频生成接入的初级至中级用户。工具整合了剧本分析、AI分镜、图片资产管理与火山方舟Seedance视频生成模型并配套Dockerfile与nginx配置可实现一键容器化部署通过本地运行保障数据不出本机结合丰富的webp分镜素材与接口调用示例使用者可直观理解漫剧生产链路并二次开发形成从故事到成片的高灵活度本地工具链。1. AI漫剧全流程工具在解什么题一集短剧产线的四个工位正在做 AI 漫剧 / AI 短剧的人多数卡在同一个地方单条视频能出整集出不动。这套全流程创作工具把工作流拆成四个工位——剧本分析负责把文本剧本读成结构化数据AI 分镜把每一个场景拆成镜头语言图片资产统一管理角色和场景参考图最后由 Seedance 和火山方舟的视频生成工作流出片。它不是某个在线网站而是一个能跑在本地、参数全开的产线方案。适合已经被 AI 视频生成折腾过、手里攒过零星片段、但想批量出整集短剧的个人创作者和小团队。2. 全流程拆解剧本分析、AI分镜、图片资产与视频生成怎么咬合2.1 四个模块的分工与数据流把一集短剧的生产拆成四个工位依赖关系是固定的基本跑不出下面这条链路剧本文本 → 剧本分析 → scenes.json → AI分镜 → storyboard.json → 图片资产生成 → assets/ → Seedance视频生成 → video_clips/ → 剪辑合成 → 成片.mp4四个工位的输入输出我整理成一张表后面所有脚本和配置都围绕这张表来写工位输入输出关键产物剧本分析剧本 txt / docx场景结构化 JSONscenes.jsonAI 分镜scenes.json带镜头语言的 JSONstoryboard.json图片资产storyboard.json角色、背景参考图assets/*.png视频生成storyboard.json assets/镜头短视频video_clips/*.mp4要理解这套工具先得理解中间为什么要有两层 JSON。常见误用是直接把剧本丢给视频生成模型让它“看着办”。这在单条样片里可行在整集短剧里不可行视频生成模型每次只处理一个镜头它不知道上一镜的人物长什么样、背景是哪个房间也没法在几十次调用之间保持记忆。scenes.json 和 storyboard.json 就是用来做这个记忆的——剧本分析把“故事”变成表AI 分镜把“表”变成镜头图片资产把“镜头”变成可复用的形象视频生成只干一件事把形象变成动起来的画面。数据流里还藏着一个工程点断点续跑。如果视频生成阶段某一镜失败只需要从该镜头重跑不必把剧本重新解析一遍。这也是我坚持把中间结果落成独立 JSON 文件、而不是在内存里直接传递的原因。跑挂的时候你能清楚地看到是哪个工位出的问题也能看到生成任务到底烧掉了多少钱。2.2 为什么是 Seedance 和火山方舟选型做错的代价视频生成环节是整条工作流最容易被带偏的点。很多团队最初会选本地 ComfyUI 工作流下载一个满血版整合包导入别人分享的动画工作流 JSON加载模型、调插件、跑出一段段动画。ComfyUI 的价值在可控性节点化之后能控制每一帧的生成逻辑配合 ControlNet 还能约束姿态但短板也恰恰来自这种自由节点生态碎片化插件版本冲突是家常便饭一个工作流 JSON 拿到手不花半小时排查连报错位置都找不到。在漫剧这种需要几十个镜头连续产出的场景里ComfyUI 更适合做单镜头风格测试或镜头语言实验不太适合直接铺成整集产线。Seedance 走的是火山方舟 API 路线。Seedance 长在镜头感上一个 5 秒镜头里能承担推、拉、摇、移这类运镜对漫剧尤其关键。漫剧的画面信息密度比真人短剧低一旦镜头全程定死整集观感立刻变成 PPT 翻页。方舟的优势则是统一接入一个 API Key 既用来调大模型做剧本分析和分镜又用来调 Seedance 生成视频鉴权只有一套脚本里的配置项不会爆炸。也有人在 Coze 工作流或 n8n 工作流里搭动画工作流把剧本、分镜、视频生成全部做成平台节点。Coze 适合快速验证概念给合作方演示流程但跑整集时有两个硬伤一是视频生成节点的参数窗口小图片资产往往只接受公网 URL没法与本地文件一一绑定二是节点失败的重试逻辑是平台封装好的你很难在“烧钱”和“出片”之间做精细权衡。所以我会把核心产线留在本地脚本Coze、n8n、Dify 这类工具只在外围做进度通知和结果推送别让黑匣子嵌进产线主链路。至于本地部署 Seedance 的念头也建议放下——它的模型规模早超出消费级显卡能扛的范围即使在本地拷贝了权重也很难跑出可用帧最现实的接入方式还是方舟 API。2.3 给四个工位先立一份数据契约自动化程度取决于 JSON 字段的约束程度。我搭这套工具时第一件事不是写代码而是先定一份契约四个工位只认这些字段字段类型说明shot_idstring全局唯一例如 scene_001_shot_002scene_idstring所属场景 IDshot_typestring枚举远景/全景/中景/近景/特写movementstring枚举固定/推/拉/摇/跟随durationint生成时长Seedance 建议 5~10 秒visualstring画面内容描述给图片资产生成器读promptstring视频生成提示词含动作与氛围dialoguestring/null本镜头台词无台词则为 null这份契约的价值在排障。穿帮镜头出现时先看 visual 字段和图片资产对得上对不上再看 prompt 是不是把角色特征写没了最后查视频生成参数——能一步步把锅甩到具体工位上。如果分镜输出很自由字段名五花八门后面的脚本只能靠正则去猜自动化立刻退回手工作坊。3. 从剧本到分镜结构化抽取与提示词工程3.1 剧本分析把文本剧本转成 JSON 场景表剧本分析是第一个工位目标是把编剧写的自然语言剧本转成机器能读的 scenes.json。我一般把剧本按集拆成一个 txt 文件格式不做强制要求对话和场景描述能区分就行剩下的交给大模型抽取。用下面的函数调火山方舟上的大模型import json import requests def clean_json_fence(text: str) - str: 剥掉大模型输出里多余的 markdown 围栏。 text text.strip() if text.startswith(): text text.split(, 2)[1] if text.startswith(json): text text[4:] return text.strip() def parse_script_to_scenes(script_text: str, api_key: str, endpoint: str) - dict: 把剧本文本转成结构化 scenes JSON。 prompt f你是短剧编剧助手。把下面的文本剧本拆成 JSON字段如下 - project: 剧名 - scenes: 数组每项包含 - id: 场景编号如 scene_001 - location: 场点描述 - time: 白天/夜晚/黄昏 - characters: 出场角色名数组 - action: 这个场景的关键动作一句话 - dialogues: 数组每项含 role 和 text 只输出 JSON不要任何解释。 剧本如下 {script_text} resp requests.post( endpoint, headers{Authorization: fBearer {api_key}}, json{ model: doubao-seed-1-6, # 以方舟控制台开通的服务名为准 messages: [{role: user, content: prompt}], temperature: 0.3, }, timeout60, ) resp.raise_for_status() msg resp.json()[choices][0][message] content msg.get(content) if isinstance(content, list): content .join(item.get(text, ) for item in content) return json.loads(clean_json_fence(content))抽取逻辑不复杂关键在参数。temperature 压到 0.3抽取不是创作温度越低输出越可控同一个剧本不会两次解析出不同数量的场景。endpoint 是方舟控制台生成的服务地址不同账号和区域会不一样不要在代码里写死。timeout 设 60 秒整集剧本的 prompt 很长模型要读完再输出太短会直接超时。拿到返回后还要做一道校验不通过就抛异常避免脏数据一路传到后面烧钱。我的校验逻辑scenes 不为空每个 scene 的 id 以 scene_ 开头dialogues 字段存在所有角色名在同一集里保持前后一致。如果出现同一角色两个名字多半是模型把别名当成了新角色这时我会在 prompt 里加一句“同一角色使用同一名字禁止用昵称替换”再重跑一次。3.2 AI 分镜把场景转成可执行的镜头表scenes.json 是剧本维度AI 分镜要把它拆成镜头维度。常见做法是逐场景调用大模型既避免整集剧本一次性塞进去导致输出超长被截断也方便某个场景分镜不满意时单独重跑。每次调用输入一个 scene JSON输出镜头数组def scene_to_storyboard(scene: dict, api_key: str, endpoint: str) - list: 单个场景转成镜头列表。 scene_json json.dumps(scene, ensure_asciiFalse) prompt f把下面的短剧场景拆成 3~6 个镜头按 JSON 数组输出。每个镜头包含 - shot_id: 由场景id加_shot_序号组成如 scene_001_shot_001 - shot_type: 远景/全景/中景/近景/特写 - movement: 固定/推/拉/摇/跟随 - duration: 5~10 的整数 - visual: 画面内容描述中文给图片生成用 - prompt: 视频生成的提示词描述画面中的动作、运镜、氛围 - dialogue: 台词字符串无台词为 null 只输出 JSON 数组。 场景 {scene_json} resp requests.post( endpoint, headers{Authorization: fBearer {api_key}}, json{ model: doubao-seed-1-6, messages: [{role: user, content: prompt}], temperature: 0.4, max_tokens: 2000, }, timeout90, ) resp.raise_for_status() msg resp.json()[choices][0][message] content msg.get(content) if isinstance(content, list): content .join(item.get(text, ) for item in content) shots json.loads(clean_json_fence(content)) for shot in shots: shot[scene_id] scene[id] return shotstemperature 提到 0.4分镜需要一点创造性但不能放开否则会出现一个场景被拆出十几个镜头的情况。max_tokens 设 2000 是防截断的关键参数场景里有大段对白时模型输出可能超长被截断的 JSON 无法解析脚本白跑一次。这里的 clean_json_fence 和 3.1 是同一个函数建议封装成公共工具两处共用。我在分镜 prompt 里加了镜头数上限“3~6 个”这是跑下来比较平衡的区间。少于 3 个镜头画面太干多于 6 个成本扛不住。如果做的是单集 60 秒的短剧建议把单镜头时长拉到 6~10 秒、镜头数压到 4 个以内。短剧用户跳着看镜头切太碎反而增加理解负担。3.3 让分镜 JSON 每次都能被解析三个边界参数分镜阶段踩过的坑基本都在输出格式不稳定。三个参数建议固定下来temperature、max_tokens、是否开启 JSON Mode。方舟服务支持 response_format 指定 json_object 时务必开启否则模型可能在数组前面输出一句“好的以下是分镜”json.loads 直接爆炸。不支持 json_object 的版本就用上面的剥围栏函数兜底。另一个坑是字段值的一致性。shot_type 和 movement 必须在 prompt 里用枚举写死不能给模型自由发挥空间。我见过模型输出“镜头缓缓推近”而不是“推”这种值一旦落进 JSON后面所有基于枚举的校验全部失效。解决办法是 prompt 里明确写“你只能从以下值中选择禁止编造新词”做完解析再加一道枚举校验非法值直接把该场景标红重跑不要静默放过。提示分镜 JSON 的字段名一旦定了就不要轻易改。后面图片资产模块、视频生成模块、字幕模块全按这份契约读字段改一个字段名等于全线返工。4. 图片资产生成与 Seedance 视频生成工作流接入4.1 图片资产角色一致性靠什么保底第三个工位是图片资产。很多做 AI 短剧的新手会跳过这个工位直接在视频生成提示词里写“一个女人站在街头”结果每一镜都生成一个全新的女人穿帮穿到没法看。正确做法是先做角色设定图把每一镜要用到的形象固定下来视频生成时以图片为第一帧输入或者把图片 URL 作为参考图传给模型。我习惯的目录结构是这样assets/ ├── char/ │ ├── 林月/ │ │ ├── default.png # 正面全身基准形象 │ │ ├── portrait.png # 脸部特写用于近景/特写 │ │ └── pose_a.png # 常用站姿用于全景/中景 │ └── 陆沉/ │ ├── default.png │ └── portrait.png └── bg/ ├── scene_001_bg.png └── scene_002_bg.png角色设定图的生成有几个硬要求。分辨率至少要 1024x1792 或 1152x2048低于这个值视频模型拉高后脸容易糊保持 9:16 比例和成片比例一致避免送进视频模型后做无谓裁切同一个角色的设定图建议生成 3 张以上正面、半侧、特写各一张分镜用哪个景别就引用对应的图而不是一张图走天下。图片资产这个工位不要追求每张都好看要追求每张都是同一个人。实现方式上我为每个角色写一段固定的特征描述块放在生成设定图的提示词里生成新角度时直接复用。特征描述块只写永久特征脸型、发色、瞳色、标志性服装配色和配饰。情绪、动作这些可变因素留给分镜里的 visual 字段不要把“微笑”写进角色固定描述否则下一个镜头需要面无表情时模型仍会默认带上笑意。4.2 调 Seedance 视频生成接口建任务、轮询、收片视频生成是第四个工位。Seedance 通过火山方舟接入时走的是异步任务模式先提交任务拿到 task_id再轮询查询任务状态成功后拿视频 URL。直接同步等待不可行单个镜头生成时间太长HTTP 连接根本扛不住。下面这个函数是整条工作流的核心import requests import time def seedance_generate_video( api_key: str, model: str, image_url: str, prompt: str, duration: int 5, resolution: str 1080p, ) - str: 用 Seedance 从首帧图片 提示词生成视频返回视频 URL。 # 具体路径以前缀为准这里写的是 cn-beijing 常见接入方式 create_url https://ark.cn-beijing.volces.com/api/v3/contents/generations/tasks headers {Authorization: fBearer {api_key}, Content-Type: application/json} payload { model: model, content: [ {type: image_url, image_url: {url: image_url}}, {type: text, text: prompt}, ], parameters: { duration: duration, resolution: resolution, fps: 24, }, } # 1) 创建任务 r requests.post(create_url, headersheaders, jsonpayload, timeout30) r.raise_for_status() task_id r.json()[data][id] # 2) 轮询任务状态 query_url f{create_url}/{task_id} for _ in range(180): # 最多等 15 分钟 time.sleep(5) resp requests.get(query_url, headersheaders, timeout15).json() data resp.get(data, {}) if data.get(status) succeeded: return data[content][video_url] if data.get(status) failed: err data.get(error, unknown) raise RuntimeError(fSeedance task failed: {err}) raise TimeoutError(Seedance task 15min timeout)代码里有三个细节需要解释。第一是 URL 的区域前缀cn-beijing 是火山方舟最常见的接入区域其他区域整套前缀都要换不然拿到 404。第二是 content 数组首帧图片和提示词是并列关系图片一栏放角色或背景图的 URL提示词文案从 storyboard.json 的 prompt 字段取。第三是轮询策略5 秒一次、最多 15 分钟是我压出来的折中值Seedance 的 5 秒 1080p 任务正常 2~4 分钟出高峰期排队可能拖到 10 分钟15 分钟上限不会白等太久也不会在排队时误判超时。注意sleep(5) 的轮询粒度不要改成 1 秒。视频生成任务不是即时任务频繁轮询只会给自己加限流风险不会让任务提前完成。参数上duration 建议控制在 5~8 秒。Seedance 支持更长但时长越长画面漂移和角色崩坏的概率会明显上升整集拼接时 8 秒以内的镜头调整余地更大。fps 用 24 就够除非分发渠道明确要求 30 帧再改。4.3 串成一条命令本地目录到成片的完整工作流四个工位单独能跑只是第一步产线意味着一条命令出成片。我会把逻辑收进一个 pipeline.py入口大致是这个流程def run_pipeline(): script load_script(input/script.txt) scenes parse_script_to_scenes(script, ARK_KEY, LLM_ENDPOINT) save_json(scenes, output/scenes.json) storyboard [] for scene in scenes[scenes]: storyboard.extend(scene_to_storyboard(scene, ARK_KEY, LLM_ENDPOINT)) save_json(storyboard, output/storyboard.json) generate_assets(storyboard) # 调用文生图产出 assets/ 下的参考图 for shot in storyboard: video_url seedance_generate_video( ARK_KEY, SEEDANCE_MODEL, pick_asset(shot), shot[prompt], duration5 ) download_video(video_url, fvideo_clips/{shot[shot_id]}.mp4) concat_videos(video_clips, output/final.mp4)download_video 很简单requests.get 后写文件就行。concat_videos 才是踩坑的地方。多个镜头视频的分辨率、帧率必须完全一致否则 concat 会花屏或错位。我的做法是先把所有片段统一规格再拼接# 统一规格1080x192025fpsh264yuv420p静音 for f in video_clips/*.mp4; do ffmpeg -y -i $f -vf scale1080:1920:force_original_aspect_ratiodecrease,pad1080:1920:(ow-iw)/2:(oh-ih)/2,fps25 \ -c:v libx264 -pix_fmt yuv420p -an ${f%.mp4}_norm.mp4 done # 按镜头顺序拼接 ffmpeg -y -f concat -safe 0 -i (for f in video_clips/*_norm.mp4; do echo file $PWD/$f; done) \ -c copy output/final.mp4拼接命令里有个容易被忽略的参数-pix_fmt yuv420p。视频生成接口返回的片段编码偶尔不是 420 色彩采样不统一的话拼接后的成片在部分播放器上会偏色出绿屏。这属于那种不踩一次不会记住的玄学问题我每次换模型版本都会先抽查返回片段的编码参数再批量拼接省得整集都拼完才发现只有第一镜能看。5. 避坑指南全流程里最容易翻车的六个点5.1 角色穿帮换个镜头脸就变了现象漫剧角色在一镜里是黑发高马尾下一镜变成棕色卷发一集上线后被观众截图挂出来。原因图片资产里没有角色基准图每个镜头都在“凭空生成”模型只在提示词里看到名字视觉细节全靠随机。解决建角色基准图全剧所有镜头共享。分镜里凡是出现林月图片资产模块必须返回 assets/char/林月/default.png 或分镜指定的角度图视频生成的 prompt 里不写外貌外貌统一以图片资产为准。这是唯一能长期生效的解法。5.2 Seedance 任务卡在排队或直接失败现象任务创建成功轮询 5 分钟状态还是 queued或者中途 status 变成 failed。原因常见三个。一是并发配额超限整集工作流一次性提交了几十个任务二是 prompt 触发了内容审核拒绝三是 model 参数写错方舟返回 model not found。解决整集跑的时候把并发控制在 3~5 个任务以内别一口气全提交。failed 先看 error 字段区分内容审核和参数不合法——审核拒绝要改 prompt参数不合法要查 model 名和 content 格式。轮询上限按 4.2 的建议设 15 分钟别用 60 秒的短超时去赌运气。5.3 分镜数量失控成本直接爆掉现象一个普通对话场景被分镜模块拆出 12 个镜头一集 20 个场景视频生成任务数直接翻倍账单跟着爆。原因分镜 prompt 没加镜头数约束或者 temperature 开太高模型进入创作状态一个点头动作被拆成三个机位。解决分镜 prompt 里固定“本场景最多 6 个镜头”temperature 踩在 0.3~0.4storyboard 生成后跑一个汇总模块单集总时长超过设定值时自动合并同场景、同景别的相邻镜头合并规则是保留开头景别和结尾运镜中间全部裁掉。既压成本又不破坏节奏。5.4 成片发糊分辨率参数没对齐现象生成的视频在手机全屏播放时脸部边缘发虚线条像水彩洇开。原因输入图片资产分辨率低于视频模型下限模型把低清图拉伸后再生成伪影被当成细节画出来。常见于 512x912 的角色图直接丢给 Seedance。解决角色图和背景图统一出 1024x1792 以上视频生成参数里的 resolution 要和输入图比例对齐竖屏输出 1080p 时输入图不能是横构图模型会先裁掉构图再生成。出片后抽检三个镜头用 ffprobe 看实际分辨率别只看文件名。5.5 台词与画面错位字幕总是慢半拍现象角色讲台词的镜头和字幕完全对不上人还没张嘴字幕已经跳了两行。原因分镜 JSON 里 dialogue 字段没绑定时间轴视频生成只管画面字幕文件是后面人工粗排的时间对不准。解决生成字幕时以 storyboard 里每个镜头的顺序和 duration 为准先累加每个镜头的全局时间窗口再把该镜头的 dialogue 写进那一帧区间。核心逻辑是timeline 0 for shot in storyboard: if shot[dialogue]: srt_entries.append(build_srt(timeline, timeline shot[duration], shot[dialogue])) timeline shot[duration]如果对白过长一个镜头装不下就在分镜阶段强制拆分凡是对白超过 60 字的镜头AI 分镜自动拆成两个镜头档位前一个镜头只讲上半句。短剧观众能接受的单镜头信息量有限这是从漫画叙事节奏里抄来的处理方式。5.6 模型名和 Endpoint 写死换个账号全挂现象脚本在本地跑得好好的换个账号或换个区域突然全部 404查配置发现模型名还是旧服务的。原因火山方舟的模型服务名和 endpoint 不是全局一致的每个账号开通的服务、区域、模型版本都不一样。把 model 名写死在 pipeline.py 里等于把产线焊死在单一账号上。解决把 model、endpoint、api_key 全部挪进 settings.yamlpipeline.py 只读配置不写死。迁移账号时只改配置不碰代码。我还会在代码里加一个启动自检加载配置后先调用一次方舟的模型列表接口校验 model 名存在再进主流程宁可慢十秒也不白跑一轮。6. 进阶把整集短剧的成品率抬上去的三个验证手法6.1 用相似度计算拦下角色穿帮角色基准图生成后不要用肉眼判断“像不像”用 CLIP 特征向量把每一张图与基准图做余弦相似度计算低于阈值的直接重生成。我的参考阈值是 0.85算出来的相似度在 0.8 到 0.85 之间就要人工复核低于 0.8 基本是换人了。这套校验放在图片资产工位之后、视频生成之前能拦掉不少肉眼在缩略图里看不出来、但视频生成会放大的细节漂移。6.2 用 ffprobe 批量抓规格异常视频生成接口偶尔会返回非标准帧率或分辨率单独看每个文件没问题拼进成片就花屏。批量扫一遍所有片段for f in video_clips/*.mp4; do ffprobe -v error -select_streams v:0 \ -show_entries streamwidth,height,r_frame_rate -of csvp0 $f done发现分辨率或帧率不一致的片段立刻标记重跑而不是等最后 concat 时对着花屏发呆。这个检查我放在每批任务结束后的收尾脚本里一条命令扫完不占用人力。6.3 用字幕时间轴验证分镜节奏分镜生成的 SRT 可以反查镜头节奏。检查每一条字幕的时间戳是否落在对应镜头的区间内偏差超过 0.5 秒的输出 warning 列表。我的习惯是看 warning 列表再决定是否返工镜头内说话、字幕晚半拍进场的情况微调字幕延迟参数就能解决不值得为一个镜头重跑一次视频生成只有台词张冠李戴、时间戳完全不在镜头区间时才回到分镜阶段修正 dialogue 的归属。这三步做到位之后整集短剧的成品率能抬到七成以上。我自己跑每一集都会把 storyboard.json 存档标记哪些镜头沿用了历史分镜模板、哪些是新写的。下一集开拍时会先找出相似场景的模板做基线再针对新剧本的差异做增量分镜而不是让模型每次从零写一遍。这比调任何参数都省成本。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网