MoneyPrinterTurbo视频生成流程简介
MoneyPrinterTurbo视频生成流程简介
MoneyPrinterTurbo 是一款开源(MIT)的 Python 短视频自动化工具:用户提供一个主题或关键词,系统可自动完成文案撰写、素材检索、配音合成、字幕生成、背景音乐混音与成片导出。本文梳理其任务编排流水线、各阶段能力依赖,并与基于 HTML 模板录屏的 html-video 路线对比「文案如何进入画面」。内容基于公开仓库与源码阅读归纳,非官方使用手册。
参考与延伸阅读:
- MoneyPrinterTurbo:https://github.com/harry0703/MoneyPrinterTurbo
- 流水线核心:
app/services/task.py - html-video(对比参照):https://github.com/nexu-io/html-video
目录
- 1. 项目概述与入口
- 2. 核心结论:剪辑拼接而非文生视频
- 3. 视频生成全流程
- 4. 阶段中断点 stop_at
- 5. 各阶段 AI 与能力依赖
- 6. 文生视频大模型依赖说明
- 7. 主要模块对照
- 8. 与 html-video 的文案填充模型对比
- 9. 输出规格
- 10. 小结
- 11. 参考与来源
1. 项目概述与入口
MoneyPrinterTurbo 架构采用 MVC,对外提供两种入口:
| 入口 | 说明 |
|---|---|
| Streamlit WebUI | 交互式使用 |
| FastAPI REST API / cli.py | 程序化调用与命令行 |
任务由 TaskService(app/services/task.py)编排,状态可存于内存或 Redis。
2. 核心结论:剪辑拼接而非文生视频
MoneyPrinterTurbo 不需要、也不内置「文生视频」大模型(如 Sora、Kling、Seedance、Runway 等)。
成片方式为:
1
文本 LLM 写文案 → TTS 配音 → 下载/本地 B-roll 素材 → MoviePy + FFmpeg 剪辑合成
README 中的「AI 大模型」主要指 文本 LLM(生成脚本与检索关键词),而非逐帧生成视频画面。
配置项 max_concurrent_tasks 旁注释中的「文生视频」泛指 视频生成任务的并发上限,并非调用文生视频 API。
3. 视频生成全流程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
┌─────────────────────────────────────────────────────────────────┐
│ 入口层 │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Streamlit │ │ FastAPI │ │ cli.py │ │
│ │ WebUI │ │ /api/v1/... │ │ 命令行 │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ └─────────────────┴─────────────────┘ │
│ │ │
│ VideoParams + task_id │
│ ▼ │
│ TaskManager(内存 / Redis 队列) │
│ ▼ │
│ app/services/task.py :: start() │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 阶段 1:生成文案(stop_at = "script" 可在此结束) │
│ │
│ 用户输入 video_subject / 自定义 video_script │
│ │ │
│ ├─ 有自定义文案? ──是──► 直接使用 │
│ │ │
│ └─ 否 ──► llm.generate_script() │
│ (OpenAI / DeepSeek / Ollama / 通义 / Gemini 等)│
│ │ │
│ ▼ │
│ 输出:video_script(旁白全文) │
│ 保存:tasks/{id}/script.json │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 阶段 2:生成素材搜索词(stop_at = "terms";local 素材可跳过) │
│ │
│ 用户自定义 video_terms? │
│ ├─ 是 ──► 解析为关键词列表 │
│ └─ 否 ──► llm.generate_terms() │
│ (根据主题 + 脚本生成 5~8 个检索词) │
│ │ │
│ ▼(可选) │
│ TwelveLabs Marengo 语义重排关键词 │
│ (需 API Key;仅优化检索顺序,不生成画面) │
│ │ │
│ ▼ │
│ 输出:search_terms[] │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 阶段 3:生成配音(stop_at = "audio") │
│ │
│ 有 custom_audio_file? │
│ ├─ 是 ──► 直接用本地音频(无 TTS 时间轴) │
│ └─ 否 ──► voice.tts() │
│ ├─ Edge TTS(免费,默认) │
│ ├─ Azure Speech V2(付费) │
│ └─ SiliconFlow 等 │
│ │ │
│ ▼ │
│ 输出:audio.mp3 + audio_duration + sub_maker(TTS 时间戳对象) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 阶段 4:生成字幕(stop_at = "subtitle") │
│ │
│ subtitle_enabled = false? ──是──► 跳过 │
│ │ │
│ ▼ │
│ subtitle_provider: │
│ ├─ edge:用 TTS 返回的 sub_maker 对齐生成 .srt(快) │
│ └─ whisper:faster-whisper 转写音频(慢但更准) │
│ │ │
│ ▼ │
│ subtitle.correct() 用脚本校正字幕文本 │
│ │ │
│ ▼ │
│ 输出:subtitle.srt │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 阶段 5:获取画面素材(stop_at = "materials") │
│ │
│ video_source? │
│ ├─ local ──► 用户本地 mp4 列表,预处理切片 │
│ ├─ pexels ──► Pexels API 搜索 + 下载 │
│ ├─ pixabay ──► Pixabay API 搜索 + 下载 │
│ └─ coverr ──► Coverr API 搜索 + 下载 │
│ │ │
│ ▼ │
│ 按关键词检索 → 下载到 cache / task 目录 │
│ 累计时长 ≥ 配音时长(可循环使用多段素材) │
│ │ │
│ ▼ │
│ 输出:downloaded_videos[](库存实拍短片,非 AI 生成) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 阶段 6:合成成片(stop_at = "video",默认跑完全程) │
│ │
│ 6a. video.combine_videos() │
│ ├─ 按配音时长裁剪/拼接多段 B-roll │
│ ├─ 缩放 + 黑边/居中适配 9:16 或 16:9 │
│ ├─ 可选转场(fade / slide / shuffle) │
│ └─ 输出 combined-{n}.mp4(仅画面轨) │
│ │ │
│ ▼ │
│ 6b. video.generate_video() │
│ ├─ 叠加配音音轨 │
│ ├─ 混入背景音乐(resource/songs,可调音量) │
│ ├─ Pillow 渲染字幕烧录(字体/颜色/描边/位置) │
│ └─ FFmpeg 编码输出 final-{n}.mp4 │
│ │ │
│ ▼ │
│ 可批量生成 video_count 个不同随机组合版本 │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 阶段 7(可选):跨平台发布 │
│ │
│ Upload-Post 配置开启时 │
│ ├─ llm.generate_social_metadata() 生成标题/标签 │
│ └─ 上传 TikTok / Instagram / YouTube Shorts │
└─────────────────────────────────────────────────────────────────┘
│
▼
任务完成,返回 final-*.mp4
4. 阶段中断点 stop_at
流水线支持在任意阶段提前结束,便于调试或分步调用:
stop_at 值 | 结束时机 |
|---|---|
script | 文案生成后 |
terms | 关键词生成后 |
audio | 配音生成后 |
subtitle | 字幕生成后 |
materials | 素材下载后 |
video | 完整成片(默认) |
5. 各阶段 AI 与能力依赖
| 环节 | 是否必须 | 技术类型 | 说明 |
|---|---|---|---|
| 写脚本 / 关键词 | 可跳过(手写文案/关键词) | 文本 LLM | 非视频生成模型 |
| 配音 | 可跳过(上传音频) | TTS | Edge TTS 免费可用 |
| 字幕 | 可关闭 | Edge 时间轴 / Whisper ASR | 本地或云端 |
| 画面素材 | 必须(本地或在线) | 素材库 API / 本地文件 | 库存实拍,非 AI 生成 |
| 成片合成 | 必须 | MoviePy + FFmpeg | 传统剪辑合成 |
| TwelveLabs(可选) | 否 | 视频理解 / 嵌入 | Marengo 重排关键词;Pegasus 做素材 QA,不生成视频 |
| 文生视频大模型 | 无 | — | 代码库未集成 Sora / Kling / Seedance 等 |
6. 文生视频大模型依赖说明
该项目从设计上 不走文生视频路线。
最小可运行组合示例:
1
2
主题或自定义文案 + 本地 mp4 素材 + Edge TTS(免费)+ FFmpeg
→ 无需任何文生视频 API
若追求更高离线程度,还可使用:自定义文案 + 本地素材 + 本地音频 + 关闭字幕,同样不依赖文生视频能力。
7. 主要模块对照
| 模块 | 路径 | 职责 |
|---|---|---|
| 任务编排 | app/services/task.py | 串联全流程、进度与状态 |
| 文案 LLM | app/services/llm.py | 脚本、关键词、社媒文案 |
| 素材获取 | app/services/material.py | Pexels / Pixabay / Coverr 检索与下载 |
| 配音 | app/services/voice.py | TTS 与音频时长 |
| 字幕 | app/services/subtitle.py | Whisper 转写与校正 |
| 视频合成 | app/services/video.py | 拼接、混音、字幕烧录、编码 |
| 可选增强 | app/services/twelvelabs.py | 关键词语义重排(非画面生成) |
| 可选发布 | app/services/upload_post.py | 跨平台上传 |
8. 与 html-video 的文案填充模型对比
两条路线都能用 LLM 写带货/种草文案,但 「文案怎样填进视频」 的模型完全不同:MoneyPrinterTurbo 是 剪辑拼接型;html-video 是 模板槽位填充型。
8.1 MoneyPrinterTurbo:文案进入成片的三个通道
LLM 产出在流水线里分成 三条弱耦合通道,没有「第 N 句旁白 → 第 N 个画面版式块」的一一映射。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
LLM 产出
│
┌───────────────┼───────────────┐
▼ ▼ ▼
口播全文 检索关键词 (可选)社媒元数据
video_script video_terms
│ │
▼ ▼
TTS 配音 Pexels/Pixabay 等
│ 或本地图/视频
│ │
▼ ▼
音轨 audio.mp3 多段 B-roll 片段
│ │
└───────┬───────┘
▼
combine_videos() 按配音时长裁剪/拼接
▼
generate_video() 叠配音 + BGM + 烧录字幕
(1)口播:全文灌进音频
llm.generate_script()输出 自由文本(段落数、语言由 prompt 约束,无 JSON schema)。- TTS 将全文读成一条音轨;画面中没有由脚本字段单独控制的「标题区 / 卖点区」。
(2)画面:关键词检索,而非文案填充
llm.generate_terms()根据主题与脚本生成 5~8 个检索词。- 素材库按词搜片、下载;
combine_videos()按时长裁剪拼接。 - 默认
random模式会 打乱片段顺序;sequential仅保证按关键词轮询,仍是「词 → 库存镜头」,不是「句子 → 版式」。 - 本地模式(
video_source=local)可将图片转为带缓推效果的短视频再拼接,但 LLM 文案不会填入图片上的标题/价签等区域(价签等只能依赖字幕层)。
(3)字幕:文案在画面上的主要载体
- 口播 → TTS 时间轴或 Whisper →
.srt。 generate_video()用 MoviePy/Pillow 在 固定区域(通常底部居中)烧录字幕。- 可调字体、颜色、描边、背景等,属于 全局字幕样式,不是模板分区的主标题/CTA。
随机性与难预料的来源
| 来源 | 表现 |
|---|---|
| 素材库 API 每次返回不同 | 同关键词搜到的镜头变化 |
video_concat_mode=random | 片段顺序随机 |
video_count > 1 | 一次生成多个随机组合版本 |
转场 shuffle | 随机 slide 方向 |
| LLM 重写脚本/关键词 | 文案与检索词每次略变 |
因此成片 「能听、能读字幕,但画面与卖点结构的对应关系弱」,同参数下复现性较低。
8.2 html-video:模板 schema 与变量注入
html-video 走 「模板契约 + 结构化变量 + 录制前注入」:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
用户主题 / 意图
│
▼
LLM 输出(约定 JSON)
├─ narration(旁白全文)
└─ variables(对齐 template.yaml 中的 schema)
headline / subheadline / cta / duration_sec …
│
▼
变量归一化、写入 HTML 槽位
(patchHtmlVariables、DOM 兜底脚本等)
│
▼
Playwright 按模板时间轴录屏
│
▼
(可选)配音 + 字幕 + 混流
精准控制体现在:
- 模板 YAML 定义 schema — 每个模板在
template.html-video.yaml声明字段(如headlinemaxLength、ctamaxLength);LLM 按 schema 填 JSON。 - 变量 → DOM 槽位 — 如
headline→main h1,cta→.chip;版式、动效、字号由模板作者固定,LLM 只改字。 - 时长可控 —
duration_sec写入 variables,渲染可按 explicit 模式录满指定秒数(受模板 min/max 限制)。 - 生成前可预览 — Studio /
project-preview可在浏览器查看注入变量后的 HTML;同一模板 + 同一 variables 画面可预期。 - 多分镜 — 每镜可指定不同
template_id与variables,便于「钩子镜 → 卖点镜 → 催单镜」结构。
字幕层仍多为旁白全文烧录,可能与模板主标题重复;但 画面主文案落在哪、长什么样 由模板锁定,可控性高于剪辑拼接路线。
8.3 「填充」填到哪里:对照表
| 维度 | MoneyPrinterTurbo | html-video |
|---|---|---|
| LLM 输出形态 | 自由文本 + 关键词列表 | JSON:narration + variables |
| 画面主文案 | 无版式槽位;主要靠字幕条 | headline / caption / cta 等进模板 |
| 画面视觉内容 | 库存视频 / 本地素材拼接 | 预定 HTML/CSS 动效 |
| 文案与画面对齐 | 弱(词搜片 + 随机/顺序拼接) | 较强(模板叙事结构固定) |
| 版式 / 动效 | 不控制(沿用素材自带画面) | 模板完全控制 |
| 生成前预览 | 基本无(生成后才知道) | 模板预览、变量预览 |
| 同参数复现 | 低 | 高(同模板 + 同 variables) |
| 改一个字 | 改 script 后重跑全流程 | 可只改变量/旁白再渲染 |
填充模型简图:
1
2
3
4
5
6
7
MoneyPrinterTurbo:
文案 ──► 配音 + 字幕(画面上的字)
文案 ──► 关键词 ──► 素材库(画面里的镜头,弱关联)
html-video:
文案 ──► narration ──► 配音 + 字幕
文案 ──► variables ──► 模板槽位(主标题 / 副标题 / CTA …)
8.4 方案选型对照
| 关注点 | 更适合的方案 |
|---|---|
| 口播 + 库存 B-roll + BGM,快速出片 | MoneyPrinterTurbo |
| 文案精准落入固定版式、动效可预期、生成前预览 | html-video |
| 具体商品与画面语义严格对应(无用户素材时) | 两者均弱;MPT 依赖关键词碰运气,html-video 依赖模板文字动效 |
| 用户自备商品图/视频 | MPT local 模式已支持图转视频拼接;html-video 需在模板 schema 中扩展图片字段 |
若核心需求是 「大模型文案如何精准、可预期地出现在画面版式里」,html-video 的模板路线在架构上更匹配;MoneyPrinterTurbo 的优势在于 成熟的剪辑链、BGM、素材下载与批量随机成片,而非版式级填充控制。
9. 输出规格
| 项目 | 常见配置 |
|---|---|
| 画幅 | 竖屏 9:16(1080×1920)、横屏 16:9(1920×1080) |
| 素材源 | Pexels、Pixabay、Coverr,或本地文件 |
| 默认 TTS | Edge TTS(免费,WebUI 中显示为「Azure TTS V1」) |
| 字幕 | edge(快)或 whisper(准,需本地模型) |
10. 小结
| 要点 | 结论 |
|---|---|
| 成片路线 | LLM 文案 + TTS + 库存/本地 B-roll + MoviePy/FFmpeg 剪辑,非文生视频 |
| 流水线编排 | task.py 串联七阶段,支持 stop_at 分步调试 |
| 画面与文案 | 弱耦合:关键词搜片 + 字幕承载口播,无版式槽位 |
| 与 html-video | 剪辑拼接型 vs 模板填充型;前者快、后者可控可预览 |
| 最小依赖 | 自定义文案 + 本地素材 + Edge TTS 即可,无需文生视频 API |
11. 参考与来源
- harry0703, MoneyPrinterTurbo:https://github.com/harry0703/MoneyPrinterTurbo
- nexu-io, html-video:https://github.com/nexu-io/html-video
