【免费下载链接】MoneyPrinter
Automate Creation of YouTube Shorts using MoviePy.
本文以 MoneyPrinter 项目为核心,系统讲解「输入一个视频主题 → 自动产出 YouTube Shorts 短视频」的完整技术链路:全本地 Ollama 驱动的脚本与元数据生成、API + Worker + Postgres 的数据库任务队列架构、.env 全量配置、本地与 Docker 两种部署方式,以及任务生命周期 API 与常见故障排查。读者读完可独立完成从环境搭建、配置调优到排队生成视频的完整实战。
1. 项目定位:给一个主题,自动产出 YouTube Shorts
MoneyPrinter 的核心能力用一句话概括(见 README.md):Automate the creation of YouTube Shorts by providing a video topic —— 你只需要提供一个视频主题,系统会自动完成脚本撰写、语音合成、素材匹配、字幕生成与视频合成,最终产出可直接发布的竖屏短视频。
它在技术选型上有两个显著特征:
- Ollama-first:脚本生成与视频元数据(标题、描述、标签等)完全由本地 Ollama 模型驱动,不依赖任何云端 LLM 服务,数据与推理均在本地完成;
- 数据库任务队列架构:当前版本已重构为 DB-backed generation queue(API + Worker + Postgres in Docker),具备可靠、重启安全(restart-safe)、面向未来扩展的设计目标,取代了早期"请求即同步处理"的简单模式。
整个系统由以下几个仓库文件构成主链路:
| 组件 | 文件 | 职责 |
|---|---|---|
| 前端 | Frontend/index.html、Frontend/app.js | 提交生成请求、轮询任务状态与事件 |
| API | Backend/main.py | Flask 服务,校验入参、入队任务、暴露状态查询 |
| Worker | Backend/worker.py | 认领排队任务并执行生成流水线 |
| 流水线 | Backend/pipeline.py | 视频生成核心步骤编排 |
| 数据层 | Backend/db.py、Backend/repository.py、Backend/models.py | 任务状态、事件、脚本与产物的持久化 |
| 编排 | docker-compose.yml | 一键拉起前端、后端、Worker 与 Postgres |
2. 架构解析:数据库任务队列如何工作
2.1 四类角色与职责划分
根据 docs/architecture.md,系统由四个角色协作:
- Frontend:提交生成请求,并通过轮询获取任务状态与事件流;
- API(Flask):校验输入并往 Postgres 写入排队任务(enqueue);
- Worker:认领排队任务(claim),运行生成流水线,并回写日志事件与最终状态;
- Postgres:作为任务状态、进度事件与产物记录的唯一事实来源(source of truth)。
整体请求流如下(Mermaid 流程源自 architecture.md 原文):
2.2 任务生命周期状态机
一个任务从创建到终结,只会在以下状态间流转(状态图同样来自 architecture.md):
从源码看,Backend/worker.py 的 process_next_job() 正是这套状态机的执行者:它通过 claim_next_queued_job() 认领一个 queued 任务,随即调用 run_generation_pipeline() 执行流水线;成功时 mark_completed,流水线主动取消(PipelineCancelled)时 mark_cancelled,其余异常则 mark_failed。每次处理前还会清理 TEMP_DIR 与 SUBTITLES_DIR 临时目录。
2.3 核心数据模型
任务持久化围绕三个核心表展开(ER 图见 architecture.md):generation_jobs 记录任务本体(状态 status、请求载荷 payload、cancel_requested 取消标记、attempt_count/max_attempts 重试字段、result_path 产物路径、error_message 错误信息及各类时间戳);generation_events 以追加方式记录任务日志事件(event_type、level、message、payload),支持前端增量轮询;scripts 与 artifacts 分别保存生成的脚本与视频产物记录。
2.4 当前保证与规划中的硬化
architecture.md 明确列出的当前设计保证包括:
- API 对生成请求快速且非阻塞(入队即返回
jobId); - 任务状态与日志在 API/Worker 重启后依然存活;
- 取消是任务级的(
cancel_requested标记),并在流水线执行过程中被持续检查; - 前端刷新后可通过轮询持久化事件恢复进度。
同时文档也披露了后续硬化方向:引入 Alembic 迁移工具做 schema 版本管理、以 next_retry_at 实现重试/退避与死信语义、补充产物元数据与校验和跟踪、以及 Worker 并发控制与队列指标端点——这些目前仍是规划项而非既有能力。
3. 本地快速上手:从零跑通一次视频生成
完整步骤详见 docs/quickstart.md,以下为可执行的完整路径。
3.1 环境前提
本地运行需要:Python 3.11+、uv 包管理器、FFmpeg、ImageMagick、Ollama。其中 Ollama 负责模型推理,FFmpeg 与 ImageMagick 负责视频/字幕合成。
3.2 方式 A:交互式安装脚本(推荐)
git clone https://gitcode.com/gh_mirrors/mo/MoneyPrinter.git
cd MoneyPrinter
./setup.sh
setup.sh 会依次完成:检查依赖、生成 .env、用 uv 安装 Python 包,并可选地拉取 Ollama 模型。
3.3 方式 B:手动安装
uv sync
cp .env.example .env
Windows PowerShell 对应:
Copy-Item .env.example .env
3.4 配置必需环境变量
编辑 .env,至少设置两个必需项(模板见 .env.example):
TIKTOK_SESSION_ID:TikTok 的sessionidcookie,用于 TTS 语音接口;PEXELS_API_KEY:Pexels API Key,用于拉取视频素材片段。
其余变量均可选,完整说明见下一节。
3.5 启动 Ollama 并拉取模型
ollama serve
ollama pull llama3.1:8b
如果 Ollama 运行在其他机器或端口,在 .env 中设置 OLLAMA_BASE_URL 即可。
3.6 启动三个进程
后端(终端 1):
uv run python Backend/main.py
Worker(终端 2):
uv run python Backend/worker.py
前端(终端 3):
cd Frontend
python3 -m http.server 3000
随后浏览器打开 http://localhost:3000。
3.7 生成第一个视频
- 输入视频主题;
- 展开高级选项(Advanced Options);
- 从模型下拉框选择 Ollama 模型——该列表由后端
/api/models动态从 Ollama 加载; - 点击 Generate。
生成的视频输出为项目根目录下的 output.mp4。
补充源码细节:
/api/models端点(Backend/main.py)在无法连接 Ollama 时会优雅降级,返回OLLAMA_MODEL环境变量(默认llama3.1:8b)作为兜底模型列表,因此即使 Ollama 短暂不可用,前端下拉框也不会空转报错。
4. .env 配置全量详解
MoneyPrinter 从项目根目录的 .env 读取配置(见 docs/configuration.md),以 .env.example 为模板。后端在启动时通过 load_dotenv(ENV_FILE) 加载(Backend/main.py),并在 check_env_vars() 中校验必需变量。
4.1 必需变量
| 变量 | 说明 |
|---|---|
TIKTOK_SESSION_ID | TikTok 会话 cookie(sessionid),用于 TTS 语音接口调用 |
PEXELS_API_KEY | 用于拉取视频素材片段的 API Key |
4.2 可选变量
| 变量 | 说明 | 默认值 |
|---|---|---|
IMAGEMAGICK_BINARY | ImageMagick 可执行文件绝对路径;为空时从 PATH 自动检测 | 自动检测 |
OLLAMA_BASE_URL | Ollama 服务地址,用于模型列表与 chat 生成 | http://localhost:11434 |
OLLAMA_MODEL | 前端未传模型值时的兜底模型 | llama3.1:8b |
ASSEMBLY_AI_API_KEY | 若设置,字幕由 AssemblyAI 生成;否则走本地字幕生成 | 空 |
POSTGRES_DB | Docker Postgres 服务数据库名 | moneyprinter |
POSTGRES_USER | Docker Postgres 服务用户名 | moneyprinter |
POSTGRES_PASSWORD | Docker Postgres 服务密码 | moneyprinter |
DATABASE_URL | SQLAlchemy DSN(postgresql+psycopg://... 或 sqlite:///...),供 API 与 Worker 共用 | sqlite:///moneyprinter.db |
4.3 关键行为说明
- 模型列表来源:前端展示的 Ollama 模型由后端
/api/models端点提供,该端点查询OLLAMA_BASE_URL/api/tags获取可用模型。使用前需先ollama pull llama3.1:8b。 - ImageMagick 找不到:自动检测失败时,在
.env中显式设置IMAGEMAGICK_BINARY,Windows 路径请使用双反斜杠,例如IMAGEMAGICK_BINARY="C:\\Program Files\\ImageMagick-7.1.0-Q16\\magick.exe"。 - 数据库选型:新架构使用数据库承载任务队列。本地运行默认走 SQLite(
.env.example中DATABASE_URL留空即本地 SQLite 默认值);Docker 环境通过DATABASE_URL指向 Postgres。SQLAlchemy DSN 与repository.py中的队列操作(create/claim/cancel/completion)由 API 与 Worker 两端共用,因此二者的状态读写天然一致。
5. 任务队列 API 与作业生命周期实操
5.1 API 端点一览
以下端点均定义于 Backend/main.py:
| 方法 | 路径 | 说明 | 源码位置 |
|---|---|---|---|
| GET | /api/models | 获取 Ollama 可用模型与默认模型 | L26-L46 |
| POST | /api/generate | 提交生成任务,入队后立即返回 jobId(缺 videoSubject 返回 400) | L49-L64 |
| GET | /api/jobs/<job_id> | 查询任务状态(state、cancelRequested、resultPath、errorMessage、时间戳) | L67-L90 |
| GET | /api/jobs/<job_id>/events?after=n | 增量拉取事件流(after 为事件自增 ID 游标) | L93-L120 |
| POST | /api/jobs/<job_id>/cancel | 请求取消任务(设置 cancel_requested=true) | L123-L130 |
| POST | /api/cancel | 取消当前最新一个 running/queued 任务 | L158-L184 |
| POST | /api/upload-songs | 上传自定义 MP3 背景音乐(会清空原 songs 目录) | L133-L155 |
5.2 用 curl 走通一次完整任务
提交一个生成任务(请求体字段与 Docker 文档一致):
curl -X POST http://localhost:8080/api/generate \
-H "Content-Type: application/json" \
-d '{"videoSubject":"AI business ideas","aiModel":"llama3.1:8b","voice":"en_us_001","paragraphNumber":1,"customPrompt":""}'
响应会返回 jobId,随后轮询状态与事件:
curl http://localhost:8080/api/jobs/<jobId>
curl "http://localhost:8080/api/jobs/<jobId>/events?after=0"
5.3 前后端协作时序
前端采用轮询而非 WebSocket/SSE 获取进度(时序逻辑见 architecture.md):POST /api/generate 入队拿到 jobId 后,进入轮询循环——反复 GET /api/jobs/:id 读取状态、GET /api/jobs/:id/events?after=n 按游标增量拉取事件;与此同时 Worker 认领任务、写入 running 状态与日志事件、执行流水线,最终写入终态事件;取消则通过 POST /api/jobs/:id/cancel 置位 cancel_requested,Worker 在流水线执行中观测到该标记后中止并标记 cancelled。这种设计让前端在刷新页面后也能依据持久化事件恢复进度显示。
6. Docker Compose 一键部署
若希望以容器方式运行完整四件套(前端 + API + Worker + Postgres),参考 docs/docker.md。
6.1 准备环境
cp .env.example .env
在 .env 中设置 TIKTOK_SESSION_ID 与 PEXELS_API_KEY。数据库默认值已内置在 .env.example:
POSTGRES_DB=moneyprinter
POSTGRES_USER=moneyprinter
POSTGRES_PASSWORD=moneyprinter
DATABASE_URL=postgresql+psycopg://moneyprinter:moneyprinter@postgres:5432/moneyprinter
6.2 打通宿主机 Ollama
Docker 后端的默认配置是访问宿主机上的 Ollama:
OLLAMA_BASE_URL=http://host.docker.internal:11434
Linux 平台通过 compose 的 extra_hosts host-gateway 映射提供支持(见 docker-compose.yml)。若 Ollama 运行在其他容器或机器,按实际情况修改 OLLAMA_BASE_URL。
6.3 启动与访问
docker compose up --build
服务端口映射:
- 前端:
http://localhost:8001 - 后端 API:
http://localhost:8080 - Postgres:
localhost:5432
6.4 验证模型列表并提交任务
curl http://localhost:8080/api/models
正常返回包含 models 与 default 字段的 JSON。随后即可用 5.2 节的 curl 命令向容器内 API 提交生成任务。
7. FAQ 实战解答
以下内容继承自 README.md 的 FAQ 小节,覆盖使用中最常遇到的问题。
7.1 MoneyPrinter 使用哪家 AI 提供商?
完全基于 Ollama。 启动 Ollama、拉取模型,然后在 UI 中选择模型即可:
ollama serve
ollama pull llama3.1:8b
脚本生成与视频元数据均由此本地模型完成,无需任何云端 LLM Key。
7.2 如何获取 TikTok Session ID?
在浏览器中登录 TikTok,打开开发者工具,复制名为 sessionid 的 Cookie 值即可。该值用于 TTS 语音接口的鉴权调用。
7.3 ImageMagick 二进制检测不到怎么办?
MoneyPrinter 会在 Linux、macOS、Windows 上从 PATH 自动检测 ImageMagick。若自动检测失败,可在 .env 中手动指定可执行文件路径,例如 Windows:
IMAGEMAGICK_BINARY="C:\\Program Files\\ImageMagick-7.1.0-Q16\\magick.exe"
注意路径中必须使用双反斜杠(\\),而非单个反斜杠。
7.4 playsound 安装失败(Wheel failed to build)怎么办?
可先升级 wheel 再重试安装:
uv pip install -U wheel
uv pip install -U playsound
仍未解决时,可查阅 docs/troubleshooting.md 或在社区反馈问题。
8. 测试与故障排查
8.1 运行测试
MoneyPrinter 使用 pytest 进行后端测试(见 docs/testing.md):
uv sync --group dev # 安装开发依赖(含 pytest)
uv run pytest # 运行全部测试
可按文件或按单个用例运行:
uv run pytest tests/test_repository.py
uv run pytest tests/test_repository.py::test_create_job_persists_payload_and_queued_event
当前测试覆盖范围:
- tests/test_api_jobs.py:API 队列、任务状态/事件与取消端点;
- tests/test_api_misc.py:模型列表兜底与歌曲上传行为;
- tests/test_repository.py:create/claim/cancel/完成事件的队列行为;
- tests/test_worker.py:Worker 循环的成功、取消、失败与空队列路径;
- tests/test_utils.py:文件系统清理、歌曲选择与 ImageMagick 二进制解析;
- tests/conftest.py:每个测试使用隔离的 SQLite session 夹具。
8.2 常见故障速查
以下要点提炼自 docs/troubleshooting.md:
- 模型下拉框为空:确认
ollama serve已运行、ollama list至少有一个模型(必要时ollama pull llama3.1:8b),并核对.env中OLLAMA_BASE_URL。 - 前端连不上后端:确认后端运行在
8080端口、前端通过本地 HTTP 服务(如python3 -m http.server)打开,并检查浏览器控制台/网络面板中/api/generate、/api/models的请求。 - ImageMagick 未检测到:安装并确保可执行文件在
PATH中,或显式设置IMAGEMAGICK_BINARY。 - 找不到素材视频:核对
PEXELS_API_KEY有效性,尝试更宽泛的主题词,并重试(素材结果随查询词变化)。 - 字幕失败:使用 AssemblyAI 时核对
ASSEMBLY_AI_API_KEY;不使用 AssemblyAI 时,本地字幕生成仍应可用。 - YouTube 上传被跳过:将
client_secret.json放入Backend/目录,并在 Google Cloud 控制台开启所需 YouTube scope 与 OAuth 同意配置。
9. 许可与贡献
按 README.md 的说明,项目现阶段暂不接受 Pull Request。代码许可信息见仓库根目录 LICENSE 文件。更多文档统一收录于 docs/README.md,推荐的阅读顺序为:Quickstart → Configuration → Docker(容器场景)→ Testing → Troubleshooting(遇到问题时)。
【免费下载链接】MoneyPrinter
Automate Creation of YouTube Shorts using MoviePy.
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



