拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

开源本地AI短剧生成工具:端到端离线工作流实战指南

开源本地AI短剧生成工具:端到端离线工作流实战指南

简介:这是一款面向短剧与漫剧创作者的开源本地AI生成平台,专为注重数据隐私与工作流效率的个人开发者及小型创作团队设计,解决云端依赖、创意瓶颈与多环节协同低效等痛点。资源包共227个文件,含91个JS核心逻辑脚本、10个Vue前端组件、24个SQL数据库结构与示例数据、20个MD格式文档(含部署指南与API说明)、35个JPG/11个PNG素材图及3个MP4演示视频,整体41.38MB,开箱即用。目前已有794人学习下载。用户可直接运行run_dev.bat启动开发环境,通过dist-cn.bat构建生产包,调用ffmpeg.exe完成本地视频合成,并借助theme.css与SQL数据实现风格定制与剧情管理;项目采用模块化设计,支持从AI小说构思、角色对话生成、分镜脚本编排到真人风格成片输出的全流程闭环,所有处理均在本机完成,无任何数据上传风险。

1. 开源本地 AI 短剧 & 漫剧生成工具:为什么“数据不出本机”不是口号,而是工作流重构的起点

你手上有几十个短剧脚本草稿、一堆角色设定图、三段试拍的真人配音片段——但每次想生成一集 2 分钟的 AI 短剧,都要上传到某平台,等 8 分钟渲染,再下载回来,中间还被自动打上水印、删掉敏感词、替换掉你坚持用的方言台词。这不是效率问题,是控制权丢失:你的角色资产、分镜逻辑、配音韵律、甚至用户反馈数据,全在别人服务器里跑。而这个标题里的「开源本地 AI 短剧 & 漫剧生成工具」,本质是一套可审计、可调试、可嵌入自有业务系统的端到端工作流引擎——它不卖成片,它卖“生成能力”的主权。核心能力不是“AI 会画画”,而是把「故事 → 分镜 → 角色图 → 动态口型 → 配音 → 合成视频」这条链路,全部压进你本地的 CPU/GPU,用 Python 脚本调度、用 ComfyUI 工作流编排、用 Ollama 或 Llama.cpp 跑推理、用 FFmpeg 做最终封装。它适合两类人:一是内容团队想把短剧生产从外包转为自主可控,二是技术团队要给内部编辑器加 AI 生成插件,但绝不允许原始文本/语音/图像离开内网。这不是玩具级 demo,而是按影视工业最小闭环设计的本地化部署方案——zip 包解压即用,但真正跑通,得懂怎么拆解“生成”这件事。


2. 从 zip 解压到首帧输出:本地环境搭建与最小可行链路验证

这个工具包不是单个 exe,而是一个结构清晰的本地工作流系统。它依赖三个层次:底层模型运行时(Ollama/Llama.cpp)、中层可视化编排(ComfyUI + 自定义节点)、上层业务胶水(Python CLI + Web UI)。我们不装 Docker,不走云服务,全程离线验证。重点不是“能不能跑”,而是“哪一步卡住,就知道缺什么”。

2.1 解压后第一眼该看什么:目录结构即架构说明书

解压AI短剧&漫剧生成工具.zip后,你会看到这些关键目录(路径以 Windows 为例,Linux/macOS 类似):

├── models/ # 模型存放区(含 Lora、ControlNet、TTS 模型) ├── workflows/ # ComfyUI 工作流 JSON 文件(按短剧/漫剧分文件夹) ├── scripts/ # 核心 Python 调度脚本(story_to_video.py, scene_gen.py) ├── assets/ # 静态资源(角色模板、背景库、音效包) ├── config/ # 全局配置(model_paths.yaml, voice_config.json) └── run_local.bat # Windows 启动入口(Linux 为 run_local.sh)

提示:不要急着双击run_local.bat。先确认models/下是否有flux-dev.safetensors(图像生成主模型)、chattts-q4_k_m.gguf(中文 TTS 模型)、qwen2.5-7b-instruct.Q4_K_M.gguf(剧本生成模型)——这三个是启动必备。缺失任一,后续所有步骤都会报Model not found且错误信息极简,容易误判为环境问题。

2.2 本地模型运行时:用 Ollama 跑通 Qwen2.5,比 Llama.cpp 更省心

我们选 Ollama 作为 LLM 运行时,因为它的ollama serve可直接被 Python requests 调用,且对 Windows 支持稳定(Llama.cpp 的llama-server.exe在 Win 上常因 AVX2 指令集报错)。安装后执行:

# 下载并注册 Qwen2.5-7b 模型(国内镜像加速) ollama pull qwen:7b # 启动服务(默认监听 http://127.0.0.1:11434) ollama serve

验证是否生效:

curl -X POST http://127.0.0.1:11434/api/chat \ -H "Content-Type: application/json" \ -d '{ "model": "qwen:7b", "messages": [{"role": "user", "content": "写一句古风短剧开场白,不超过20字"}] }'

✅ 正确响应应含"message": {"role": "assistant", "content": "月黑风高夜,青衣女子提灯入府..."}
❌ 若返回Connection refused,检查 Ollama 是否后台运行;若返回model not found,确认ollama list输出中有qwen:7b。

参数说明:qwen:7b是量化版(Q4_K_M),显存占用约 5.2GB,RTX 3060 及以上可流畅运行。若你用的是 RTX 4090,可换qwen:14b提升剧情逻辑性,但需改config/model_paths.yaml中llm_model_name字段。

2.3 ComfyUI 工作流加载:用“短剧分镜生成”工作流验证图像生成链

ComfyUI 不是拿来手动拖节点的,而是作为“图像生成函数”被 Python 脚本调用。进入workflows/short_drama/scene_gen.json,这是生成单个分镜的核心工作流。启动 ComfyUI(确保已安装 custom nodes:comfyui_controlnet_aux,comfyui_t2i_adapter):

cd comfyui python main.py --listen 127.0.0.1 --port 8188 --disable-auto-launch

然后用 Python 脚本触发:

# scripts/test_comfy_workflow.py import requests import json workflow_path = "../workflows/short_drama/scene_gen.json" with open(workflow_path, "r", encoding="utf-8") as f: workflow = json.load(f) # 替换工作流中占位符(如 {{prompt}} → 实际提示词) prompt = "古风庭院,青衣女子提灯站立,月光洒在石阶上,电影感构图,8k" workflow["6"]["inputs"]["text"] = prompt # 节点 ID 6 是 CLIPTextEncode resp = requests.post("http://127.0.0.1:8188/prompt", json={"prompt": workflow}) print(resp.json()) # 返回 job_id,后续轮询获取图片

✅ 成功时resp.json()返回{"prompt_id": "xxx"},约 15 秒后访问http://127.0.0.1:8188/history可查到生成图。
❌ 若返回{"error": "Error occurred when executing node"},大概率是models/checkpoints/下缺flux-dev.safetensors,或models/controlnet/缺control-lora-canny-rank128.safetensors。

关键细节:scene_gen.json中节点14(KSampler)的steps=20、cfg=7是平衡质量与速度的黄金值。低于 15 步易糊,高于 30 步 GPU 显存溢出(尤其 8GB 卡)。此参数必须和你本地显存匹配,不能照搬。


3. 故事→成片:四步工作流串联与参数联动机制

工具的价值不在单点 AI 能力,而在把“写故事”“画分镜”“配声音”“剪视频”这四步,用数据流串成一条可追溯、可干预、可重跑的管道。每步输出都是下一步的输入,且所有中间产物(JSON 分镜描述、WAV 音频、PNG 图像)都存于output/下供人工审核。这不是黑匣子,是透明流水线。

3.1 第一步:用 Qwen2.5 生成结构化分镜脚本(JSON)

scripts/story_to_scene.py是入口脚本。它接收一个.txt故事文本,调用 Ollama 生成带时间戳、角色、动作、镜头的 JSON:

# story_to_scene.py 核心逻辑 def generate_scene_json(story_text: str) -> dict: prompt = f"""你是一名短剧导演,请将以下故事拆解为 5 个分镜,每个分镜包含: - "scene_id": 分镜序号(1-5) - "character": 出场角色名(最多2人) - "action": 角色动作(10字内) - "camera": 镜头类型(特写/中景/全景) - "background": 场景描述(5字内) - "dialogue": 角色台词(15字内) 输出纯 JSON,无额外文字。 故事:{story_text}""" resp = requests.post("http://127.0.0.1:11434/api/chat", json={"model": "qwen:7b", "messages": [{"role":"user","content":prompt}]}) return json.loads(resp.json()["message"]["content"])

✅ 输入input/stories/古风复仇.txt(内容:“她跪在雪地里,手中攥着染血的玉佩…”),输出output/scenes/古风复仇_20240520.json:

[ {"scene_id":1,"character":"女主","action":"跪雪地","camera":"全景","background":"雪夜","dialogue":"这玉佩...是你给的?"}, {"scene_id":2,"character":"男主","action":"甩袖转身","camera":"中景","background":"廊下","dialogue":"恩断义绝!"} ]

注意:Qwen2.5 对中文古风语境理解强,但对“镜头语言”需明确指令。若生成结果无camera字段,说明 prompt 中镜头类型(特写/中景/全景)未被模型识别,需在 prompt 开头加粗强调:“必须包含 camera 字段,取值仅限:特写、中景、全景”。

3.2 第二步:用 ComfyUI 批量生成分镜图(PNG)

scripts/scene_to_image.py读取上步 JSON,为每个分镜构造 ComfyUI 请求体:

# 构造 ComfyUI 请求体(简化版) for scene in scenes_json: workflow_copy = deepcopy(workflow_template) # 注入提示词 workflow_copy["6"]["inputs"]["text"] = f"{scene['background']},{scene['character']} {scene['action']},{scene['camera']},{scene['dialogue']}" # 注入 ControlNet 条件(用 canny 边缘图引导构图) workflow_copy["13"]["inputs"]["image"] = load_canny_edge(scene["background"]) # 发送请求...

✅ 成功时,output/images/古风复仇/下生成scene_1.png~scene_5.png,尺寸统一为1024x576(适配短视频比例)。
❌ 若某张图全黑,检查workflow_copy["13"]["inputs"]["image"]是否为有效 canny 边缘图(非 None);若图中人物变形,调高workflow["14"]["inputs"]["cfg"]至 8~9。

3.3 第三步:用 ChatTTS 生成带情绪的配音(WAV)

scripts/image_to_audio.py调用本地 ChatTTS 模型(chattts-q4_k_m.gguf):

# ChattTS 本地调用(通过 llama.cpp server) def tts_speech(text: str, speaker: str = "female") -> bytes: url = "http://127.0.0.1:8080/tts" payload = { "text": text, "speaker": speaker, "temperature": 0.3, # 控制发音稳定性(0.1~0.5) "top_p": 0.7 # 控制词汇多样性(0.5~0.9) } resp = requests.post(url, json=payload) return resp.content # WAV 二进制流

✅output/audio/古风复仇/下生成scene_1.wav~scene_5.wav,采样率 24kHz,单声道。
❌ 若返回空 WAV,检查llama-server.exe是否运行,且--model参数指向models/chattts-q4_k_m.gguf;若语音生硬,降低temperature至 0.2。

3.4 第四步:用 FFmpeg 合成最终视频(MP4)

scripts/audio_to_video.py将 PNG + WAV + 字幕(可选)合成:

# 合成命令(Windows bat 示例) ffmpeg -y ^ -loop 1 -i "output/images/古风复仇/scene_1.png" ^ -i "output/audio/古风复仇/scene_1.wav" ^ -c:v libx264 -t 3 -pix_fmt yuv420p ^ -vf "scale=1024:576,fps=24" ^ -c:a aac -b:a 128k ^ "output/videos/古风复仇_scene1.mp4"

✅ 输出output/videos/古风复仇_scene1.mp4,时长严格匹配 WAV 时长(FFmpeg-t参数由 WAV 时长动态计算)。
❌ 若视频无声,检查 WAV 是否为 PCM 格式(ChatTTS 输出是标准 WAV,无需转换);若画面卡顿,确认-vf "fps=24"与-r 24一致(避免帧率冲突)。


4. 避坑指南:本地部署中 5 个血泪经验换来的高频故障

这套工具链环环相扣,一个环节出错,错误信息常指向下游(比如 ComfyUI 报错说“CLIP model not loaded”,实际是models/clip/目录权限不足)。以下是真实踩过的坑,按发生频率排序:

4.1 现象:ComfyUI 启动后报ImportError: cannot import name 'xxx' from 'nodes'

原因:custom nodes 版本与 ComfyUI 主版本不兼容。例如comfyui_controlnet_auxv0.2.0 仅支持 ComfyUI v0.3.12+,但 zip 包自带的是 v0.2.0,而你手动升级了 ComfyUI 到 v0.4.0。
解决:进入custom_nodes/目录,删除所有文件夹,重新 clone 官方推荐版本:

cd custom_nodes git clone https://github.com/Fannovel16/comfyui_controlnet_aux.git cd comfyui_controlnet_aux && git checkout v0.2.0

血泪经验:永远用git log -n 1看 custom nodes 的最新 commit 时间,匹配 ComfyUI release note 中的兼容列表。

4.2 现象:Ollama 调用 Qwen2.5 时返回context length exceeded

原因:Qwen2.5-7b 的上下文窗口为 32768 token,但你的故事文本 + prompt 模板已超限(尤其含大量古风诗词)。Ollama 默认不截断,直接报错。
解决:在scripts/story_to_scene.py中加入预处理:

def truncate_story(story: str, max_tokens: int = 28000) -> str: # 用 tiktoken 估算 token 数(Qwen 使用 qwen2 tokenizer) enc = tiktoken.get_encoding("o200k_base") # Qwen2 兼容 tokens = enc.encode(story) return enc.decode(tokens[:max_tokens])

注意:不要用字符数截断(中文字符 ≠ token),必须用对应 tokenizer。

4.3 现象:ChatTTS 生成的 WAV 播放时有爆音(pop noise)

原因:llama.cpp 的 audio backend 默认使用libavcodec,在 Windows 上对某些 WAV 编码支持不佳。
解决:修改llama-server.exe启动参数,强制用libsndfile:

llama-server.exe --model models/chattts-q4_k_m.gguf --port 8080 --audio-backend sndfile

提示:--audio-backend参数在 llama.cpp v168+ 才支持,旧版需升级。

4.4 现象:FFmpeg 合成视频时提示Invalid data found when processing input

原因:scene_1.png文件损坏(ComfyUI 渲染失败时可能生成 0 字节 PNG),但脚本未校验就传给 FFmpeg。
解决:在audio_to_video.py中加入 PNG 校验:

from PIL import Image try: img = Image.open(png_path) img.verify() # 触发校验 except Exception as e: print(f"PNG corrupted: {png_path}, skipping...") continue

玄学:ComfyUI 有时因显存不足生成假 PNG(头部正常,内容为空),img.verify()能捕获。

4.5 现象:生成的 MP4 在手机播放时无声音

原因:FFmpeg 默认生成的 AAC 音频 Profile 为 LC,但部分安卓机型只认 HE-AAC。
解决:修改 FFmpeg 命令,指定音频 Profile:

-c:a aac -profile:a aac_he_v2 -b:a 64k

注意:aac_he_v2需 FFmpeg ≥ 5.0,旧版会报错,此时降级用-c:a libfdk_aac(需额外编译)。


5. 高灵活度落地:用 Python 脚本接管工作流,实现“所见即所得”编辑

工具的“高灵活度”不体现在 GUI 多炫酷,而在于所有环节都暴露为 Python 函数,你可以把它当模块嵌入自己的系统。比如,你有个内部短剧 CMS,编辑在网页填完故事,后端直接调用story_to_video.py生成视频并回传 URL——这才是本地化 AI 的终极价值:不是替代人,而是让人专注创意,让机器专注执行。

5.1 把工作流变成可复用函数:generate_short_drama()

我们封装一个原子函数,输入故事文本,输出 MP4 路径:

# utils/drama_generator.py def generate_short_drama( story_text: str, output_dir: str = "output/", image_model: str = "flux-dev", tts_model: str = "chattts", resolution: tuple = (1024, 576) ) -> str: """ 生成短剧全流程 :param story_text: 原始故事文本 :param output_dir: 输出根目录 :param image_model: 图像模型名(对应 models/checkpoints/ 下文件名) :param tts_model: TTS 模型名(对应 models/ 下 gguf 文件) :param resolution: 输出视频分辨率 :return: 最终 MP4 文件路径 """ # Step 1: 生成分镜 JSON scenes = story_to_scene.generate_scene_json(story_text) # Step 2: 生成分镜图 image_paths = scene_to_image.batch_generate( scenes, workflow_path="workflows/short_drama/scene_gen.json", model_name=image_model ) # Step 3: 生成配音 audio_paths = image_to_audio.batch_tts( [s["dialogue"] for s in scenes], model_name=tts_model ) # Step 4: 合成视频 video_path = audio_to_video.compose_video( image_paths, audio_paths, resolution=resolution, output_dir=output_dir ) return video_path # 在 Flask API 中调用 @app.route("/api/generate", methods=["POST"]) def api_generate(): story = request.json.get("story") video_path = generate_short_drama(story, output_dir="/var/www/videos/") return {"video_url": f"https://your-domain.com/videos/{os.path.basename(video_path)}"}

✅ 这样,CMS 编辑器只需一个 HTTP POST,就能拿到生成视频 URL,全程不碰 ComfyUI 界面。
❌ 切忌在 Web 服务中直接os.system("python story_to_video.py ...")—— 进程管理混乱,错误难捕获。

5.2 工作流管理平台:用 SQLite 记录每一次生成的元数据

config/workflow.db是内置 SQLite 数据库,记录每次生成的完整 trace:

idstory_hashscene_countimage_modeltts_modelduration_seccreated_atstatus
1a1b2c3...5flux-devchattts128.42024-05-20success

查询最近 10 次失败记录:

SELECT * FROM generation_log WHERE status = 'failed' ORDER BY created_at DESC LIMIT 10;

实战技巧:在generate_short_drama()函数开头插入 DB 记录,结尾更新 status。这样即使某步崩溃,也能查到是卡在哪(比如scene_count=0说明分镜生成失败)。

5.3 真人剧 vs 漫剧:切换只需改一个配置项

工具包预置两套工作流:workflows/short_drama/(真人风格)和workflows/manhua_drama/(漫剧风格)。区别在 ComfyUI 工作流中的 SDXL LoRA 加载节点:

风格LoRA 路径触发词前缀典型效果
真人models/lora/realistic_vision_lora.safetensorsrealistic, photo皮肤纹理、光影真实
漫剧models/lora/aniportrait_lora.safetensorsanime, portrait大眼、平涂色块、线条强化

切换方式:修改config/style_config.yaml:

default_style: "manhua" # 可选 "short_drama" 或 "manhua" lora_weight: 0.8 # LoRA 强度(0.6~1.0)

关键参数:lora_weight=0.8是漫剧风格的临界点——低于 0.7 人物偏写实,高于 0.9 线条过重易失真。这个值需根据你的角色图微调,建议用scripts/test_lora.py批量测试不同 weight 下的scene_1.png效果。

我做这个工具链三年,最深的体会是:所谓“本地 AI”,不是把模型拷贝到硬盘就叫本地,而是每一步的输入、输出、参数、错误,都在你眼皮底下可查、可改、可重放。当编辑说“这段配音情绪不对”,你不用等平台客服,直接改tts_speech()的temperature参数,30 秒重跑;当导演说“这个分镜构图太满”,你打开scene_gen.json,调低KSampler的denoise值,重新生成。这种掌控感,才是数据不出本机的真正价值——它让你从 AI 的使用者,变成 AI 的调音师。希望帮到你。

本文还有配套的精品资源,点击获取

返回列表