# MoneyPrinterTurbo Video Generation Pipeline: 6-Stage Modular Architecture Explained

> Explore the MoneyPrinterTurbo video generation pipeline. Discover its 6-stage modular architecture, from LLM script creation to final clip composition with transitions.

- Repository: [Harry/MoneyPrinterTurbo](https://github.com/harry0703/MoneyPrinterTurbo)
- Tags: architecture
- Published: 2026-03-23

---

**MoneyPrinterTurbo uses a deterministic six-stage pipeline orchestrated by [`app/services/task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/task.py) that progresses from LLM script generation through keyword extraction, TTS audio synthesis, subtitle creation, stock video acquisition, and final clip composition with transitions.**

MoneyPrinterTurbo is an open-source automated video creation tool that transforms text subjects into short-form videos through a modular Python-based workflow. The entire process is defined in the `harry0703/MoneyPrinterTurbo` repository and centers on the [`task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/task.py) orchestrator, which chains discrete processing stages into a single cohesive rendering pipeline.

## The Six Stages of the Video Generation Pipeline

The pipeline executes sequentially within `task.start()`, with each stage calling specialized service modules. Every function is a pure-Python implementation that can be invoked independently or as part of the end-to-end workflow.

### Stage 1: Script Generation

The pipeline begins at [`app/services/task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/task.py) lines 16-34 with the `generate_script` function. This stage invokes the LLM service ([`app/services/llm.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/llm.py)) to create a video script based on the user-provided **subject**, optionally respecting parameters for **language** and **paragraph count**. The generated text serves as the narrative foundation for all subsequent stages.

### Stage 2: Keyword Extraction

Immediately following script creation, `generate_terms` (lines 36-58 in [`task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/task.py)) processes the script to extract search terms and keywords. These terms drive the visual material search in Stage 5, ensuring the downloaded footage semantically aligns with the narration content.

### Stage 3: Audio Synthesis

The `generate_audio` function (lines 73-122 in [`task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/task.py)) handles text-to-speech conversion via the `voice` service module. If no custom audio file is provided, the system synthesizes narration using supported providers such as Azure or ElevenLabs. This stage returns a `sub_maker` object—an internal data structure used later for subtitle timing—and calculates the total **audio duration** required for video timing synchronization.

### Stage 4: Subtitle Creation

Subtitles are generated in `generate_subtitle` (lines 124-161 in [`task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/task.py)) through two possible paths: the Edge-API (using the TTS result from Stage 3) or a fallback to Whisper for transcription. The resulting subtitle file undergoes cleaning and correction against the original script to ensure accuracy before overlay rendering.

### Stage 5: Visual Material Acquisition

The `get_video_materials` function (lines 162-192 in [`task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/task.py)) acquires footage through two distinct paths:

- **Remote sources**: `material.download_videos` (from [`app/services/material.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/material.py)) pulls short clips from **Pexels**, **Pixabay**, **Douyin**, **Bilibili**, and **Xiaohongshu**, filtered by the requested **aspect ratio** and constrained to match the total audio duration.
- **Local sources**: `video.preprocess_video` converts user-uploaded images into short zoom-in video clips for custom visuals.

### Stage 6: Clip Composition and Final Rendering

The final stage splits into two operations within [`app/services/video.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/video.py):

1. **Clip chopping and shuffling**: `combine_videos` (lines 17-130) segments source clips into pieces of `max_clip_duration` or less, optionally shuffles their order, resizes them to the target aspect ratio, and applies the selected **transition effect** (fade, slide, or shuffle modes).
2. **Final assembly**: `generate_video` (lines 363-426) loads the combined clip sequence, overlays the narration audio (with optional background music), burns in the subtitle clips, and writes the finalized MP4 to disk.

## Pipeline Orchestration and Entry Points

The [`task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/task.py) module exposes multiple interfaces for executing the pipeline, ranging from high-level automation to granular debugging.

### High-Level API: End-to-End Execution

For standard usage, the `start` function in [`app/services/task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/task.py) provides a single entry point that accepts a `VideoParams` configuration object and a `stop_at` parameter for partial execution.

```python
from app.services.task import start
from app.models.schema import VideoParams

# Configure generation parameters

params = VideoParams(
    video_subject="The impact of money",
    voice_name="zh-CN-XiaoyiNeural-Female",
    voice_rate=1.0,
)

# Execute full pipeline; stop_at can be "script", "terms", "audio", etc.

task_id = "my-task-001"
result = start(task_id, params, stop_at="video")
print(result["videos"][0])  # Final MP4 path

```

The `stop_at` parameter enables partial pipeline execution for debugging or iterative content creation, terminating after the specified stage.

### Manual Step-by-Step Execution

For development or custom workflows, individual service functions can be invoked directly without the orchestrator:

```python
from app.services import task, video, voice, subtitle, material, llm

# 1. Generate content

script = llm.generate_script(video_subject="Future of finance", language="en")
terms = llm.generate_terms(video_subject="Future of finance", video_script=script)

# 2. Create audio and subtitles

audio_file, audio_dur, sub_maker = voice.tts(
    text=script,
    voice_name="en-US-JennyNeural",
    voice_rate=1.0,
)
subtitle_path = subtitle.create(audio_file=audio_file, subtitle_file="sub.srt")
subtitle.correct(subtitle_path, script)

# 3. Download stock footage

materials = material.download_videos(
    task_id="debug",
    search_terms=terms,
    source="pexels",
    video_aspect="portrait",
    video_contact_mode="random",
    audio_duration=audio_dur,
    max_clip_duration=4,
)

# 4. Combine clips with transitions

video.combine_videos(
    combined_video_path="combined.mp4",
    video_paths=materials,
    audio_file=audio_file,
    video_aspect="portrait",
    video_concat_mode="random",
    video_transition_mode="fade_in",
    max_clip_duration=4,
)

# 5. Render final video with overlays

video.generate_video(
    video_path="combined.mp4",
    audio_path=audio_file,
    subtitle_path=subtitle_path,
    output_file="final.mp4",
    params=VideoParams(),
)

```

### Web UI Integration

The Streamlit interface in [`webui/Main.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/webui/Main.py) (around lines 500-540) wraps the high-level API for end-user interaction:

```python
if st.button("Generate Video", key="run_video"):
    with st.spinner("Generating video..."):
        task_id = utils.random_id()
        params = VideoParams(
            video_subject=user_subject,
            video_script=user_script,
            # ... additional UI parameters

        )
        result = task.start(task_id, params, stop_at="video")
        st.video(result["videos"][0])

```

## Core Service Architecture

The pipeline relies on six primary service modules, each isolated to a specific domain:

- **[`app/services/task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/task.py)**: Central orchestrator implementing `start()` and the six-stage coordination logic.
- **[`app/services/video.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/video.py)**: Low-level video manipulation including `combine_videos` for clip assembly and `generate_video` for final rendering with subtitle/BGM overlay.
- **[`app/services/material.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/material.py)**: Stock footage acquisition via `download_videos`, supporting Pexels, Pixabay, and Chinese platforms (Douyin, Bilibili, Xiaohongshu).
- **[`app/services/voice.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/voice.py)**: TTS provider abstraction and audio duration calculations.
- **[`app/services/llm.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/llm.py)**: LLM API wrapper (OpenAI, Claude, DeepSeek) for script and keyword generation.
- **[`app/models/schema.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/models/schema.py)**: Data models including `VideoParams`, aspect ratio enums, and transition mode definitions shared across the pipeline.

## Summary

- **MoneyPrinterTurbo implements a six-stage linear pipeline** orchestrated by [`app/services/task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/task.py): Script → Keywords → Audio → Subtitles → Visuals → Composition.
- **Each stage is modular and independently callable**, allowing partial execution via the `stop_at` parameter or direct service function invocation.
- **Visual sourcing is multi-platform**, supporting both international stock libraries (Pexels, Pixabay) and Chinese social platforms (Douyin, Bilibili, Xiaohongshu).
- **Rendering supports configurable transitions** (fade, slide, shuffle) and automatic subtitle burning via `video.combine_videos` and `video.generate_video`.
- **The entry point `task.start()`** accepts a `VideoParams` schema object, making the pipeline compatible with both API integrations and the provided Streamlit web interface.

## Frequently Asked Questions

### Can I execute individual pipeline stages without running the full workflow?

Yes. The `start()` function accepts a `stop_at` parameter that accepts stage names including `"script"`, `"terms"`, `"audio"`, `"subtitle"`, `"material"`, or `"video"`. Alternatively, you can import individual functions from [`app/services/llm.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/llm.py), [`voice.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/voice.py), or [`video.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/video.py) to execute specific stages manually for debugging or custom workflows.

### What video sources does MoneyPrinterTurbo use for stock footage?

According to [`app/services/material.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/material.py), the system downloads clips from **Pexels**, **Pixabay**, **Douyin**, **Bilibili**, and **Xiaohongshu**. The `download_videos` function filters results by aspect ratio and ensures the total downloaded duration matches the audio length. For custom content, `video.preprocess_video` converts local images into animated clips.

### How does the subtitle generation handle different languages?

The `generate_subtitle` function in [`task.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/task.py) (lines 124-161) prioritizes the **Edge-API** when using Azure TTS voices, deriving timing directly from the `sub_maker` object returned during audio synthesis. If this fails or for non-Azure voices, it falls back to **Whisper** for transcription. The `subtitle.correct()` function then aligns the generated text against the original script to fix transcription errors.

### What transition effects are available during clip composition?

The `combine_videos` function in [`app/services/video.py`](https://github.com/harry0703/MoneyPrinterTurbo/blob/main/app/services/video.py) supports multiple **video_transition_mode** values including `"fade_in"`, slide transitions, and shuffle modes. The `max_clip_duration` parameter controls segment length, while `video_concat_mode` (set to `"random"` or sequential) determines clip ordering before transitions are applied.