# MoneyPrinterTurbo User Guide

## 1. Quick Start

MoneyPrinterTurbo automatically generates short-form videos from a single topic or keyword. You provide a subject, it writes a video script via an LLM, finds matching stock footage from Pexels or Pixabay, synthesizes a voiceover, burns in subtitles, adds background music, and outputs a ready-to-publish MP4.

**What you get:**

- Fully automated video pipeline: topic &rarr; script &rarr; footage &rarr; voiceover &rarr; subtitles &rarr; final video
- 14 LLM providers (OpenAI, DeepSeek, Gemini, Ollama, Moonshot, Qwen, LiteLLM, and more)
- 4 TTS engines: Azure TTS V1 (edge_tts, free), Azure TTS V2, SiliconFlow, Google Gemini TTS
- Stock footage from Pexels and Pixabay, or supply your own local files
- Streamlit WebUI with 7-language support (English, Chinese, German, Portuguese, Russian, Turkish, Vietnamese)
- REST API for headless/programmatic access
- Video transitions (fade, slide), configurable subtitles, background music from 26 bundled tracks
- Optional cross-posting to TikTok and Instagram via the Upload-Post integration
- Docker deployment with optional GPU acceleration

> [!TIP]
> The WebUI is the primary interface and the fastest way to get started. The REST API is available for automation workflows but is not required for basic video generation.

**Prerequisites:**

- Python 3.11 or later
- An API key for at least one LLM provider (OpenAI, DeepSeek, Gemini, etc.)
- A Pexels or Pixabay API key if using stock footage (or use local files instead)
- ImageMagick installed and accessible from `PATH` (required by moviepy for subtitle rendering)
- ffmpeg installed and accessible from `PATH`

**Fastest path to your first video:**

```bash
git clone https://github.com/harry0703/MoneyPrinterTurbo.git
cd MoneyPrinterTurbo
pip install -r requirements.txt
streamlit run ./webui/Main.py
```

The WebUI opens in your browser. On first launch, a `config.toml` file is auto-created from `config.example.toml`. Open the **Settings** panel in the sidebar, enter your LLM API key and a Pexels API key, click **Save**, then switch to the main panel. Type a topic, select your language and voice, and click **Generate Video**. Output appears in `storage/tasks/{task_id}/`.

> [!NOTE]
> The project is bilingual (Chinese/English). The WebUI, documentation, and most configuration comments appear in both languages. Select your preferred UI language from the sidebar dropdown.

---

## 2. Installation

### 2.1 System Requirements

| Requirement | Detail |
|---|---|
| Python | 3.11+ (the Docker image uses 3.11; 3.13 is also supported) |
| ffmpeg | Required for video/audio processing. Must be on `PATH`. |
| ImageMagick | Required by moviepy for subtitle text rendering. Must be on `PATH`. |
| OS | Windows, macOS, Linux |
| RAM | 4 GB minimum, 8 GB+ recommended for Whisper subtitle generation |
| GPU | Optional. NVIDIA GPU with CUDA speeds up Whisper; not required for anything else. |

### 2.2 Local Install (pip)

```bash
git clone https://github.com/harry0703/MoneyPrinterTurbo.git
cd MoneyPrinterTurbo
pip install -r requirements.txt
```

> [!IMPORTANT]
> Install ImageMagick before running. On Ubuntu/Debian: `sudo apt install imagemagick`. On macOS: `brew install imagemagick`. On Windows, download the installer from the ImageMagick website and ensure "Install legacy utilities" is checked. MoviePy will fail to render subtitles without it.

Verify your install:

```bash
python -c "import moviepy; print(moviepy.__version__)"
ffmpeg -version
magick --version
```

### 2.3 Docker Install

**Standard (CPU only):**

```bash
git clone https://github.com/harry0703/MoneyPrinterTurbo.git
cd MoneyPrinterTurbo
docker compose up -d
```

This builds from `Dockerfile` (based on `python:3.11-slim-bullseye`), installs all dependencies, and exposes the API on port 8080 and the WebUI on port 8501.

**With GPU acceleration (NVIDIA):**

```bash
docker compose -f docker-compose.yml -f docker-compose.gpu.yml up -d
```

> [!WARNING]
> GPU mode requires the NVIDIA Container Toolkit installed on the host. Without it, the container will fail to start. GPU acceleration only benefits the Whisper subtitle provider — all other operations run on CPU.

The Docker container runs as a non-root user (`appuser`). If you encounter permission errors on bind-mounted volumes (see GitHub issue #885), ensure the `storage/` directory is writable by UID 1000:

```bash
sudo chown -R 1000:1000 storage/
```

### 2.4 Installing ffmpeg

| Platform | Command |
|---|---|
| Ubuntu/Debian | `sudo apt install ffmpeg` |
| macOS | `brew install ffmpeg` |
| Windows (Chocolatey) | `choco install ffmpeg` |
| Windows (manual) | Download from https://ffmpeg.org/download.html, extract, add `bin/` to `PATH` |

You can also set a custom ffmpeg path via the `IMAGEIO_FFMPEG_EXE` environment variable instead of adding it to `PATH`.

### 2.5 Post-Install Verification

After installation, start the WebUI:

```bash
streamlit run ./webui/Main.py
```

Or use the helper scripts:

| Platform | Script |
|---|---|
| Linux/macOS | `bash webui.sh` |
| Windows | `webui.bat` |

The WebUI should open at `http://localhost:8501`. If you see the settings panel with fields for API keys, the installation is working.

---

## 3. Configuration

### 3.1 Configuration File

All settings live in `config.toml` at the project root. On first run, this file is auto-created from `config.example.toml`. You can edit it directly or use the WebUI Settings panel (which writes back to `config.toml` on save).

The file uses TOML format with these sections:

| Section | Purpose |
|---|---|
| `[app]` | LLM provider, API keys, video defaults, Redis, proxy, TLS |
| `[whisper]` | Whisper model size and Hugging Face endpoint |
| `[proxy]` | HTTP/HTTPS proxy settings |
| `[azure]` | Azure Speech API credentials (for TTS V2) |
| `[siliconflow]` | SiliconFlow API key (for SiliconFlow TTS) |
| `[ui]` | UI language, hide settings panel |

See the Admin Guide for complete configuration reference.

### 3.2 LLM Provider Setup

MoneyPrinterTurbo supports 14 LLM providers. You need at least one configured to generate video scripts.

| Provider | Config Key (`llm_provider`) | Required Keys |
|---|---|---|
| OpenAI | `openai` | `openai_api_key`, `openai_base_url`, `openai_model_name` |
| Moonshot | `moonshot` | `moonshot_api_key`, `moonshot_base_url`, `moonshot_model_name` |
| Azure OpenAI | `azure` | `azure_api_key`, `azure_base_url`, `azure_model_name`, `azure_api_version` |
| Qwen (通义千问) | `qwen` | `qwen_api_key` |
| DeepSeek | `deepseek` | `deepseek_api_key`, `deepseek_base_url`, `deepseek_model_name` |
| ModelScope | `modelscope` | `modelscope_api_key`, `modelscope_model_name` |
| Gemini | `gemini` | `gemini_api_key`, `gemini_model_name` |
| Ollama | `ollama` | `ollama_base_url`, `ollama_model_name` |
| OneAPI | `oneapi` | `oneapi_api_key`, `oneapi_base_url`, `oneapi_model_name` |
| Cloudflare | `cloudflare` | `cloudflare_api_key`, `cloudflare_account_id`, `cloudflare_model_name` |
| ERNIE (百度文心一言) | `ernie` | `ernie_api_key`, `ernie_secret_key`, `ernie_model_name` |
| Pollinations | `pollinations` | `pollinations_model_name` |
| LiteLLM | `litellm` | `litellm_model_name`, `litellm_api_key`, `litellm_base_url` |
| g4f | `g4f` | None (free, no API key) |

> [!CAUTION]
> **g4f is disabled by default** and must be explicitly enabled by setting `enable_g4f = true` in `config.toml`. The g4f library carries supply-chain risks (see GitHub issue #883) and uses third-party LLM endpoints without guarantees. Use it only if you understand and accept these risks.

**Example: Configuring OpenAI**

In `config.toml`:

```toml
[app]
llm_provider = "openai"
openai_api_key = "sk-your-key-here"
openai_model_name = "gpt-4o"
openai_base_url = "https://api.openai.com/v1"
```

**Example: Configuring Ollama (local, no API key needed)**

```toml
[app]
llm_provider = "ollama"
ollama_base_url = "http://localhost:11434/v1"
ollama_model_name = "llama3"
```

### 3.3 Video Source API Keys

To use stock footage, configure at least one video source:

```toml
[app]
pexels_api_keys = ["your-pexels-key"]    # array, supports multiple keys for rotation
pixabay_api_keys = ["your-pixabay-key"]  # array, supports multiple keys for rotation
```

Get a free Pexels API key at https://www.pexels.com/api/ and a Pixabay key at https://pixabay.com/api/docs/.

If you only plan to use local video files, you can skip this step entirely.

### 3.4 TTS Provider Setup

| Provider | Config | Cost |
|---|---|---|
| Azure TTS V1 (edge_tts) | No configuration needed | Free |
| Azure TTS V2 | `azure_speech_key` + `azure_speech_region` in `[azure]` | Paid (Azure pricing) |
| SiliconFlow TTS | `api_key` in `[siliconflow]` | Paid (SiliconFlow pricing) |
| Google Gemini TTS | Uses `gemini_api_key` from `[app]` | Paid (Google pricing) |

Azure TTS V1 (edge_tts) is the default and requires no API key. It provides high-quality voices in dozens of languages at no cost.

The edge_tts timeout is configurable (default 30 seconds):

```toml
[app]
edge_tts_timeout = 30
```

Increase this value if you experience timeouts on slow connections.

### 3.5 Proxy Configuration

If you are behind a proxy:

```toml
[proxy]
http_proxy = "http://proxy.example.com:8080"
https_proxy = "http://proxy.example.com:8080"
```

TLS certificate verification is enabled by default. If your proxy uses a self-signed certificate, you can disable TLS verification:

```toml
[app]
tls_verify = false
```

> [!WARNING]
> Disabling TLS verification weakens security. Only use this in trusted proxy environments where certificate issues cannot be resolved.

### 3.6 Environment Variables

These environment variables override `config.toml` settings:

| Variable | Purpose |
|---|---|
| `MPT_APP_REDIS_HOST` or `REDIS_HOST` | Override Redis host |
| `CORS_ALLOWED_ORIGINS` | Comma-separated list of allowed CORS origins for the API |
| `IMAGEIO_FFMPEG_EXE` | Path to a custom ffmpeg binary |
| `HF_ENDPOINT` | Hugging Face mirror URL for downloading Whisper models |

### 3.7 Redis (Optional)

By default, task state is stored in memory. For persistence across restarts, enable Redis:

```toml
[app]
enable_redis = true
redis_host = "127.0.0.1"
redis_port = 6379
redis_db = 0
redis_password = ""
```

---

## 4. Core Usage

### 4.1 The WebUI Workflow

The Streamlit WebUI is the primary way to use MoneyPrinterTurbo. Start it with:

```bash
streamlit run ./webui/Main.py
```

The interface has three main areas:

1. **Sidebar** — Language selection, Settings panel (API keys, defaults)
2. **Main panel** — Video generation form
3. **Output area** — Generated video previews and download links

**Step-by-step video generation:**

1. Open the WebUI at `http://localhost:8501`
2. In the sidebar, click **Settings** and enter your LLM API key and at least one video source API key (Pexels or Pixabay). Click **Save**.
3. In the main panel, enter a **Video Subject** (topic or keyword, e.g., "benefits of morning exercise")
4. Select the **Video Language** — this determines the script language and voice language
5. Choose **Video Aspect Ratio**: Portrait (9:16) for mobile/TikTok, Landscape (16:9) for YouTube
6. Select a **Voice Name** from the dropdown (varies by language)
7. Set the number of videos to generate simultaneously (1-5)
8. Optionally expand **Advanced Settings** to configure subtitles, transitions, clip duration, and background music
9. Click **Generate Video**
10. Wait for processing (typically 2-5 minutes depending on video length and provider speed)
11. Preview and download the generated video(s)

> [!TIP]
> Generate multiple videos at once (up to 5) from the same topic. Each video uses different footage clips, giving you variety to choose from.

> [!NOTE]
> The WebUI writes your settings back to `config.toml` when you click Save, so they persist across restarts.

### 4.2 Video Settings Reference

| Setting | Options | Default | Notes |
|---|---|---|---|
| Aspect Ratio | Portrait (9:16), Landscape (16:9) | Portrait | Square (1:1) exists in the schema but is not exposed in the WebUI |
| Video Concat Mode | Random, Sequential | Random | Random picks clips in random order; Sequential uses them in search-result order |
| Transition | None, Shuffle, FadeIn, FadeOut, SlideIn, SlideOut | None | Shuffle randomly applies one of the transition types per cut |
| Clip Duration | 2-10 seconds | 5 | Duration of each individual stock footage clip |
| Video Count | 1-5 | 1 | Number of video variants to generate simultaneously |

### 4.3 Subtitle Settings

| Setting | Options | Default |
|---|---|---|
| Subtitle Provider | edge (uses edge_tts word boundaries), whisper (faster-whisper) | edge |
| Font | Dropdown from `resource/fonts/` (includes Charm-Bold, Charm-Regular, MicrosoftYaHeiBold, etc.) | Varies |
| Font Size | 30-100 | 60 |
| Font Color | Color picker | White |
| Stroke Color | Color picker (text outline) | Black |
| Stroke Width | Numeric | 1.5 |
| Position | Top, Center, Bottom, Custom (% from top) | Bottom |

The "edge" subtitle provider is faster because it uses word-boundary data from edge_tts to align text without running a speech recognition model. The "whisper" provider uses faster-whisper for more precise alignment but requires downloading a Whisper model on first use (and benefits from a GPU).

### 4.4 Audio Settings

| Setting | Range | Default |
|---|---|---|
| Voice Volume | 0.6-5.0 | 1.0 |
| Voice Rate | 0.8-2.0 | 1.0 |
| Background Music | None, Random, Custom path | Random |
| BGM Volume | 0.0-1.0 | 0.2 |

**Custom audio narration:** You can upload your own audio file (mp3, wav, m4a, aac, flac, ogg) instead of using TTS. When a custom audio file is provided, TTS is skipped entirely and your audio is used as the narration track.

**Background music:** The "Random" option selects from 26 bundled tracks in `resource/songs/`. You can also provide a path to your own music file.

### 4.5 Using Local Video Files

Instead of downloading stock footage, you can supply your own video or image files:

1. In the WebUI, select **Local Files** as the video source
2. Upload files via the upload widget (supported formats: mp4, mov, avi, flv, mkv, jpg, jpeg, png)
3. Uploaded files are stored in `storage/local_videos/`

Local files are used as the visual layer instead of Pexels/Pixabay clips. The tool still generates the script, voiceover, subtitles, and background music as usual.

> [!TIP]
> Mixing video and image files works. Images are displayed for the configured clip duration with a Ken Burns (pan/zoom) effect applied automatically.

### 4.6 Using the REST API

The FastAPI server provides headless access to all generation features. Start it with:

```bash
python main.py
```

This launches uvicorn on `0.0.0.0:8080` by default. Interactive API documentation is available at `http://localhost:8080/docs` (Swagger UI).

**Health check:**

```bash
curl http://localhost:8080/api/v1/ping
```

**Generate a video (API):**

```bash
curl -X POST http://localhost:8080/api/v1/videos \
  -H "Content-Type: application/json" \
  -d '{
    "video_subject": "benefits of morning exercise",
    "video_language": "en",
    "video_aspect": "9:16",
    "voice_name": "en-US-AriaNeural",
    "voice_volume": 1.0,
    "voice_rate": 1.0,
    "bgm_type": "random",
    "bgm_volume": 0.2,
    "subtitle_enabled": true,
    "font_name": "Charm-Bold.ttf",
    "text_fore_color": "#FFFFFF",
    "text_background_color": "#000000",
    "font_size": 60,
    "stroke_color": "#000000",
    "stroke_width": 1.5,
    "subtitle_position": "bottom",
    "video_clip_duration": 5,
    "video_count": 1,
    "video_source": "pexels",
    "video_concat_mode": "random"
  }'
```

The API returns a task ID. Use it to check status and retrieve the generated video. See the Admin Guide for the complete API endpoint reference, request/response schemas, and authentication details.

### 4.7 Output Files

Each video generation task creates a directory under `storage/tasks/{task_id}/` containing:

| File | Content |
|---|---|
| `script.json` | The LLM-generated video script (narration text + search terms) |
| `audio.mp3` | Synthesized voiceover |
| `subtitle.srt` | Generated subtitle file |
| `combined-N.mp4` | Intermediate video (footage + transitions, no audio) |
| `final-N.mp4` | Final output with voiceover, subtitles, and background music |

Where `N` is the video variant number (1 through your configured video count).

Downloaded stock footage is cached in `storage/cache_videos/` to avoid re-downloading identical clips across tasks.

---

## 5. Common Tasks

### 5.1 Create a TikTok-Ready Vertical Video

1. Set **Aspect Ratio** to Portrait (9:16)
2. Set **Clip Duration** to 3-4 seconds (fast cuts work well for short-form)
3. Enable a transition like **FadeIn** or **Shuffle** for visual polish
4. Set **Background Music** to Random
5. Generate 3-5 variants and pick the best one

### 5.2 Create a YouTube Landscape Video

1. Set **Aspect Ratio** to Landscape (16:9)
2. Increase **Clip Duration** to 5-7 seconds for a slower pace
3. Use Sequential concat mode if you want footage to follow your script order more closely
4. Choose a professional-sounding voice (e.g., `en-US-GuyNeural`)

### 5.3 Generate a Video in a Non-English Language

1. Set the **Video Language** to your target language (e.g., Chinese, German, Portuguese)
2. Select a matching voice from the Voice Name dropdown (voices are filtered by language)
3. Ensure your LLM provider supports generating text in that language
4. Change the UI language in the sidebar dropdown if desired (7 languages available)

### 5.4 Use Your Own Voiceover

1. Record your narration as an audio file (mp3, wav, m4a, aac, flac, or ogg)
2. In the WebUI, upload the file via the **Custom Audio** upload widget
3. TTS is automatically skipped when a custom audio file is provided
4. The tool will still generate subtitles from your audio using the configured subtitle provider

### 5.5 Use Local Footage Instead of Stock Video

1. Select **Local Files** as the video source
2. Upload your mp4, mov, avi, flv, mkv, jpg, jpeg, or png files
3. Set concat mode to **Sequential** if the order of your files matters
4. The tool handles cutting, transitions, and overlay of narration/subtitles

### 5.6 Batch Generate Videos via the API

Use the REST API to submit multiple generation requests programmatically:

```python
import requests

topics = [
    "morning exercise benefits",
    "healthy breakfast ideas",
    "productivity tips for remote workers"
]

for topic in topics:
    resp = requests.post("http://localhost:8080/api/v1/videos", json={
        "video_subject": topic,
        "video_language": "en",
        "video_aspect": "9:16",
        "voice_name": "en-US-AriaNeural",
        "video_source": "pexels",
        "video_count": 1
    })
    print(f"Task for '{topic}': {resp.json()}")
```

### 5.7 Change Subtitle Appearance

For white text with a black outline on a dark background:

```toml
# In config.toml or via WebUI Settings
font_name = "Charm-Bold.ttf"
font_size = 70
text_fore_color = "#FFFFFF"
stroke_color = "#000000"
stroke_width = 2.0
subtitle_position = "bottom"
```

For a centered, large-text "meme" style:

- Font size: 90-100
- Position: Center
- Stroke width: 3.0
- Choose a bold font

### 5.8 Use Whisper for Precise Subtitle Timing

If the default edge_tts subtitle alignment is not precise enough:

1. Set **Subtitle Provider** to `whisper`
2. On first use, the Whisper model downloads automatically from Hugging Face
3. If you are in China or behind a firewall, set the `HF_ENDPOINT` environment variable to a mirror:

```bash
export HF_ENDPOINT=https://hf-mirror.com
```

4. GPU acceleration is strongly recommended for Whisper; CPU inference is slow for longer videos

Configure the Whisper model size in `config.toml`:

```toml
[whisper]
model_size = "base"  # tiny, base, small, medium, large-v3
```

### 5.9 Auto-Post Generated Videos to Social Media

MoneyPrinterTurbo integrates with upload-post.com for cross-posting to TikTok and Instagram:

1. Sign up at upload-post.com and get an API key
2. Configure in `config.toml`:

```toml
[app]
upload_post_enabled = true
upload_post_api_key = "your-upload-post-key"
upload_post_username = "your-upload-post-username"
upload_post_platforms = ["tiktok", "instagram"]
upload_post_auto_upload = true
```

3. When `upload_post_auto_upload` is `true`, videos are automatically posted after generation

> [!NOTE]
> The Upload-Post integration is disabled by default. You must explicitly enable it and provide credentials.

### 5.10 Use Ollama for Free Local LLM Script Generation

To avoid LLM API costs entirely, use Ollama:

1. Install Ollama from https://ollama.ai
2. Pull a model: `ollama pull llama3`
3. Configure `config.toml`:

```toml
[app]
llm_provider = "ollama"
ollama_base_url = "http://localhost:11434/v1"
ollama_model_name = "llama3"
```

4. Pair with edge_tts (free TTS) and local video files for a completely free setup

### 5.11 Run in Docker with Persistent Storage

Mount a host directory for persistent output:

```yaml
# In docker-compose.yml, the storage volume is already mapped:
volumes:
  - ./storage:/app/storage
```

This ensures generated videos survive container restarts. If you modify `config.toml` on the host, the container picks up changes on next task submission.

### 5.12 Switch Between Multiple LLM Providers

You can configure API keys for multiple providers in `config.toml` simultaneously and switch between them by changing `llm_provider`:

```toml
[app]
llm_provider = "deepseek"   # Change this to switch providers

# All keys can coexist:
openai_api_key = "sk-..."
deepseek_api_key = "sk-..."
gemini_api_key = "AIza..."
```

Only the provider named in `llm_provider` is used at runtime.

---

## 6. Troubleshooting

### Error: ImageMagick not found

**Cause:** MoviePy requires ImageMagick for subtitle text rendering but cannot locate the binary.

**Solution:**

1. Install ImageMagick for your platform (see Section 2.2)
2. Verify it is on `PATH`: run `magick --version` (or `convert --version` on older versions)
3. On Windows, if you installed ImageMagick but it is not found, ensure the install directory is in your system `PATH`

**Prevention:** Always install ImageMagick before running MoneyPrinterTurbo.

### Error: ffmpeg not found

**Cause:** MoviePy and pydub require ffmpeg for all audio/video processing.

**Solution:**

1. Install ffmpeg (see Section 2.4)
2. Verify: `ffmpeg -version`
3. Alternatively, set the `IMAGEIO_FFMPEG_EXE` environment variable to point to your ffmpeg binary

### Error: TTS service timeout or failure

**Cause:** The edge_tts service is rate-limited or the network connection is slow. Related to GitHub issues #875 and #869.

**Solution:**

1. Increase the edge_tts timeout in `config.toml`:

```toml
[app]
edge_tts_timeout = 60
```

2. If using a proxy, ensure `http_proxy`/`https_proxy` are correctly configured
3. Try a different TTS provider (Azure TTS V2 or SiliconFlow) as a fallback
4. Check your internet connection — edge_tts requires access to Microsoft's TTS service

### Error: Storage permission denied (Docker)

**Cause:** The Docker container runs as `appuser` (UID 1000), but the bind-mounted `storage/` directory is owned by root or another user. See GitHub issue #885.

**Solution:**

```bash
sudo chown -R 1000:1000 storage/
```

Or set the correct permissions before starting:

```bash
mkdir -p storage && chmod 777 storage
```

### Error: Cannot generate videos / empty output

**Cause:** Multiple possible causes. Related to GitHub issue #888.

**Solution:**

1. Check the terminal/console output for the actual error message
2. Verify your LLM API key is valid and has available quota
3. Verify your Pexels/Pixabay API key is valid
4. Check that the video source has footage matching your topic (try a more generic topic)
5. Ensure `storage/` directory is writable

### Error: File not found on Windows

**Cause:** Path length limitations or special characters in the file path. Related to GitHub issue #877.

**Solution:**

1. Clone the repository to a short path (e.g., `C:\MPT\`)
2. Avoid special characters and spaces in the project path
3. On Windows 10/11, enable long path support: set `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled` to `1`

### Error: docker-compose build fails with EOF

**Cause:** Network issues pulling the base Python image. Related to GitHub issue #867.

**Solution:**

1. Retry the build (transient network issue):

```bash
docker compose build --no-cache
```

2. If behind a proxy, configure Docker daemon proxy settings
3. Try pulling the base image separately: `docker pull python:3.11-slim-bullseye`

### Error: Gemini TTS fails to generate audio

**Cause:** Gemini TTS configuration or API key issue. Related to GitHub issue #864.

**Solution:**

1. Verify your `gemini_api_key` is valid and has the Gemini TTS API enabled
2. Check that `gemini_model_name` is set to a model that supports TTS
3. Fall back to edge_tts (free, no API key needed) while debugging

### Error: Whisper model download fails

**Cause:** Cannot reach Hugging Face to download the faster-whisper model, common in China or behind firewalls.

**Solution:**

Set the Hugging Face mirror endpoint:

```bash
export HF_ENDPOINT=https://hf-mirror.com
```

Or in `config.toml`:

```toml
[whisper]
# Ensure model_size is valid: tiny, base, small, medium, large-v3
model_size = "base"
```

### Error: Video generation is very slow

**Cause:** Several factors can slow down generation.

**Solution:**

1. **LLM response time:** Switch to a faster provider (DeepSeek and Ollama local are typically fast)
2. **Stock footage download:** Pexels/Pixabay downloads depend on network speed; cached videos (in `storage/cache_videos/`) are reused automatically
3. **Whisper processing:** Use the "edge" subtitle provider instead of "whisper" — it is significantly faster
4. **Video encoding:** Reduce video count, shorten clip duration, or use a machine with more CPU cores

> [!TIP]
> The `storage/cache_videos/` directory caches downloaded stock footage. Do not delete it between runs if you want faster subsequent generations.

### Error: Subtitles not appearing in output video

**Cause:** ImageMagick is either not installed or not configured correctly for MoviePy.

**Solution:**

1. Verify ImageMagick installation (see Section 2.2)
2. On Windows, check that the ImageMagick `magick.exe` path is in your system `PATH`
3. Restart the WebUI/API server after installing ImageMagick

> [!CAUTION]
> Some Linux distributions package an older ImageMagick version with a restrictive security policy that blocks text rendering. If you see a "not authorized" error, edit `/etc/ImageMagick-6/policy.xml` (or `-7`) and change the PDF/text policies to allow read/write.

### Error: Redis connection refused

**Cause:** Redis is enabled in `config.toml` but the Redis server is not running.

**Solution:**

1. If you don't need persistence, set `enable_redis = false` in `config.toml`
2. If you need Redis, start it: `redis-server` or `docker run -d -p 6379:6379 redis`
3. Verify the `redis_host`, `redis_port`, and `redis_password` values in `config.toml`

---

## 7. FAQ

**Q: Which LLM provider should I choose?**
A: For best results, use OpenAI (GPT-4o) or DeepSeek. For a free option, use Ollama with a local model like Llama 3. The LLM only generates the video script and search terms — even smaller models produce acceptable results.

**Q: Is MoneyPrinterTurbo free to use?**
A: The software itself is free and open source. Costs depend on your provider choices. A completely free setup is possible using Ollama (free local LLM) + edge_tts (free TTS) + local video files. Using cloud LLM providers and Pexels/Pixabay incurs their respective API costs.

**Q: What video lengths can I generate?**
A: Video length is determined by the script length, which depends on the LLM output. Typical generated videos are 30-90 seconds. You can influence length by adjusting your topic prompt (e.g., "give a detailed explanation of..." for longer scripts).

**Q: Can I use this for languages other than English?**
A: Yes. MoneyPrinterTurbo supports script generation in any language your LLM provider supports, and edge_tts offers voices in dozens of languages. The WebUI itself supports 7 languages: English, Chinese, German, Portuguese, Russian, Turkish, and Vietnamese.

**Q: What about TikTok, Bilibili, and Xiaohongshu as video sources?**
A: These appear in the UI dropdown but are not yet functional. They are listed as "coming soon." Currently only Pexels, Pixabay, and local file uploads work as video sources.

**Q: Does the g4f (free GPT) provider work?**
A: g4f is disabled by default for security reasons. To enable it, set `enable_g4f = true` in `config.toml`. Be aware that g4f relies on third-party endpoints that may be unreliable or carry security risks (see GitHub issue #883).

**Q: Can I run MoneyPrinterTurbo on a server without a display?**
A: Yes. Use the REST API (`python main.py`) for headless operation. The Streamlit WebUI also works over the network — access it from any browser at `http://your-server-ip:8501`.

**Q: How do I update to a newer version?**
A: Pull the latest code and reinstall dependencies:

```bash
cd MoneyPrinterTurbo
git pull
pip install -r requirements.txt
```

Your `config.toml` is preserved across updates. If new configuration keys are added, they use defaults until you set them.

**Q: Where are my generated videos stored?**
A: In `storage/tasks/{task_id}/`. Each task gets its own directory with the script, audio, subtitles, and final video files. Cached stock footage is stored in `storage/cache_videos/`.

**Q: Can I customize the video script instead of having the LLM generate one?**
A: The WebUI includes a text area where you can edit the LLM-generated script before proceeding with video generation. You can also replace it entirely with your own text.

**Q: How do I use multiple Pexels/Pixabay API keys?**
A: Both `pexels_api_keys` and `pixabay_api_keys` accept arrays. Provide multiple keys and the tool rotates between them to avoid rate limits:

```toml
pexels_api_keys = ["key1", "key2", "key3"]
```

**Q: What is the difference between the WebUI and the API?**
A: The WebUI (Streamlit) is a visual interface for interactive use — you see previews, adjust settings with sliders, and download results directly. The API (FastAPI on port 8080) is for programmatic access, automation, and integration with other tools. Both use the same generation engine.

**Q: Can I use MoneyPrinterTurbo behind a corporate proxy?**
A: Yes. Set `http_proxy` and `https_proxy` in the `[proxy]` section of `config.toml`. If your proxy uses a self-signed certificate, set `tls_verify = false` in `[app]` (use with caution).

**Q: How much disk space does it use?**
A: Each generated video is typically 20-100 MB depending on resolution and length. The `storage/cache_videos/` directory grows over time as stock footage is cached. Periodically clean this directory if disk space is a concern.

---

_Generated May 2026 from harry0703/MoneyPrinterTurbo at 46ba578. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
