Standalone chunked TTS voiceover + Whisper timing CLI
Project description
Voiceover Pipeline
Standalone CLI для генерации озвучки + Whisper timing из Markdown-сценариев.
Четыре TTS-провайдера: Polza GPT Audio, Polza TTS, OpenRouter TTS, Qwen3-TTS (GPU).
Whisper CPU small — точные тайминги для Remotion-анимаций и субтитров.
Agent-grade JSON-контракт: --json, semantic exit codes, manifest.json.
Сценарии могут быть plain Markdown или Markdown с frontmatter metadata для provider/model/voice.
Install
Console scripts: voiceover and voiceover-pipeline (both work).
| Manager | Base | + Whisper | + Qwen GPU | + All extras |
|---|---|---|---|---|
| uvx (no install) | uvx voiceover-pipeline doctor |
uvx --from "voiceover-pipeline[timing-whisper]" voiceover-pipeline generate --with-timings ... |
uvx --from "voiceover-pipeline[voiceover-qwen]" voiceover-pipeline generate --provider qwen-local ... |
uvx --from "voiceover-pipeline[timing-whisper,voiceover-qwen,cuda]" ... |
| pipx | pipx install voiceover-pipeline |
pipx install "voiceover-pipeline[timing-whisper]" |
pipx install "voiceover-pipeline[voiceover-qwen]" |
pipx install "voiceover-pipeline[timing-whisper,voiceover-qwen,cuda]" |
| pip | pip install voiceover-pipeline |
pip install "voiceover-pipeline[timing-whisper]" |
pip install "voiceover-pipeline[voiceover-qwen]" |
pip install "voiceover-pipeline[timing-whisper,voiceover-qwen,cuda]" |
| uv pip | uv pip install voiceover-pipeline |
uv pip install "voiceover-pipeline[timing-whisper]" |
uv pip install "voiceover-pipeline[voiceover-qwen]" |
uv pip install "voiceover-pipeline[timing-whisper,voiceover-qwen,cuda]" |
From source
git clone https://github.com/VladimirMonin/voiceover-pipeline
cd voiceover-pipeline
uv sync --group dev --extra timing-whisper
uv run voiceover doctor
First run
.envis searched in CWD and upwards through parent directories.- Whisper model (~486 MB) auto-downloads from HuggingFace on first
--with-timings. Subsequent runs use cache. - Qwen-local requires NVIDIA GPU + CUDA drivers (~4 GB VRAM).
API Keys
Create .env in your working directory (CWD or any parent directory — searched upwards):
POLZA_API_KEY=pza_...
OPENROUTER_API_KEY=sk-or-v1-...
Never commit .env.
Golden Command
voiceover generate `
--provider polza-chat-audio `
--model "openai/gpt-audio-mini" `
--script "script.md" `
--run-id "prod" `
--json `
--resume
Recommended production flow: generate paid audio first, then run voiceover timings
as a separate step. If you still use --with-timings, Whisper dependencies are
checked before the first paid TTS request.
Metadata script
---
format: voiceover
provider: polza-tts
model: openai/gpt-4o-mini-tts
voice: ash
max_chunk_chars: 2000
---
Первый фрагмент озвучки.
******
Второй фрагмент озвучки.
Для Gemini 3.1 Flash TTS podcasts доступен format: gemini-dialogue с двумя
спикерами, voice map и inline tags вроде [laughs], [serious], [short pause].
Gemini prompting quick guide
Gemini TTS works best as a directed voice performer, not as plain text-to-speech.
Keep instructions separate from spoken transcript: AUDIO PROFILE, SCENE,
PERFORMANCE, CONTEXT, then #### TRANSCRIPT.
Synthesize speech for the performance defined below.
The profile, scene, performance notes, and context are direction only.
Do NOT speak them.
Speak ONLY the lines under #### TRANSCRIPT.
### PERFORMANCE
Style: Warm, thoughtful, conversational, emotionally alive.
Pace: Natural podcast pace with small pauses after important ideas.
Accent: Natural Russian speech.
#### TRANSCRIPT
[thoughtfully] Сегодня разберём Gemini TTS, [short pause] и почему хороший голос начинается с режиссуры.
Use English service directions and English audio tags; keep the transcript in the
target language. Use PERFORMANCE for global emotion and inline tags such as
[thoughtfully], [sighs], [laughs], [gasp], [medium pause] for local
delivery changes. For long podcasts, prefer semantic chunks of roughly 250-450
Russian words, or 180-350 words for emotional material.
Do not paste the whole prompt skeleton into the script body. In this project,
put direction into style_prompt, vibe, and speaker profile; keep body text
as spoken transcript only. See the full guides:
docs/skills/voiceover-pipeline/docs/11-gemini-prompting.md and
docs/skills/voiceover-pipeline/docs/12-gemini-prompting-templates.md.
Результат (JSON stdout):
{"status": "success", "provider": "polza-chat-audio", "run_id": "prod",
"duration_ms": 25520, "segment_count": 8, "cost": {"total": 0.0146, "currency": "RUB"}}
Что на выходе
out/<run-id>/
├── manifest.json ← entry-point для агентов
├── run_state.json ← resumable state after each chunk
├── generation.log ← human-readable generation log
├── <run-id>-voiceover-<model>.mp3 ← полный MP3
├── <run-id>-voiceover-<model>.json ← run-манифест
├── <run-id>.timings.json ← Whisper-сегменты (ms)
├── <run-id>.srt ← субтитры SRT
└── chunks/
├── chunk_01.mp3 ... chunk_NN.mp3
└── chunks.json
Команды
| Команда | Зачем |
|---|---|
doctor |
Проверить окружение |
validate --script X |
Проверить сценарий |
list providers/voices/timing-models |
Доступные модели |
split --script X |
Чанки сценария |
generate |
Генерация аудио с resume/retry/state/log |
timings --audio X |
Тайминги из готового MP3 |
status --run-id X |
Статус partial/resumable run |
concat --run-id X --format ogg |
Склеить существующие chunks в partial/full файл |
Все команды поддерживают --json; generate также поддерживает --json-events.
Модели и цены
| Провайдер | Модель | Цена минуты |
|---|---|---|
| Polza | openai/gpt-audio-mini |
~0.004 ₽/мин (anomalous 200s smoke — model added speech, needs rerun) |
| Polza | openai/gpt-audio |
~7.00 ₽/мин |
| Polza | openai/gpt-4o-mini-tts |
~1.07 ₽/мин |
| Polza | elevenlabs/text-to-speech-turbo-2-5 |
~3.51 ₽/мин |
| Polza | elevenlabs/text-to-speech-multilingual-v2 |
~7.57 ₽/мин |
| OpenRouter | google/gemini-3.1-flash-tts-preview |
~$0.030/мин |
| OpenRouter | openai/gpt-4o-mini-tts-2025-12-15 |
~$0.00041/мин |
| Qwen3-TTS | CustomVoice (preset/clone) | Бесплатно (GPU) |
Тестирование
uv sync --group dev --extra timing-whisper
uv run pytest
118 тестов: JSON-контракт, exit codes, валидация, output policy, providers, prompt modes, script metadata, resume/retry/state/log/status/concat safety, Gemini safe tags.
Agent Skill
OpenCode agent skill — устанавливает pipeline, выбирает провайдера, генерирует озвучку:
- Source: https://github.com/VladimirMonin/voiceover-pipeline/tree/v0.4.5/docs/skills/voiceover-pipeline
- Download: https://github.com/VladimirMonin/voiceover-pipeline/releases/tag/v0.4.5
Legal / Provider Notes
This project is an independent CLI wrapper around third-party providers. It is not affiliated with OpenAI, Google, OpenRouter, Polza.ai, Qwen, or CTranslate2 / faster-whisper. Provider names and model names are used solely for integration and documentation purposes. Generated audio usage is subject to the selected provider's terms of service. Do not upload private voice samples or generated speech without permission.
License
MIT. See LICENSE.
Документация
- Agent CLI Contract — JSON-контракт, exit codes, stdout/stderr, safety rules
- Remotion Workflow — как агент Remotion использует pipeline
- Artifacts & Analysis — JSON-схемы, обработка аудио, сравнение моделей
- Whisper Timing — модель, device, compute, word timestamps
- Troubleshooting — типовые ошибки и их коды
- Polza Models — голоса, цены, особенности
- Polza TTS Models — OpenAI TTS, ElevenLabs через Polza AI
- OpenRouter TTS — Gemini, OpenAI TTS через OpenRouter
- OpenCode Skill — Agent skill для установки и озвучки
- Gemini Prompting Skill Guide — режиссура Gemini TTS, эмоции, теги, chunk limits
- Gemini Prompting Templates — project-native examples, шаблоны, QA checklist
- Qwen Local — preset-голоса, клонирование, GPU
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file voiceover_pipeline-0.4.5.tar.gz.
File metadata
- Download URL: voiceover_pipeline-0.4.5.tar.gz
- Upload date:
- Size: 1.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d79314bd2ff98e5d8baf546b0047908286426166be03374eadc8307f25bd4aec
|
|
| MD5 |
a7e92a359837490ce1c52aca923d5489
|
|
| BLAKE2b-256 |
6638cb3f29aab0b261d3fda9a919eac8802cf0b119951b9a252d83877ab12786
|
File details
Details for the file voiceover_pipeline-0.4.5-py3-none-any.whl.
File metadata
- Download URL: voiceover_pipeline-0.4.5-py3-none-any.whl
- Upload date:
- Size: 49.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c8c1c988293349edb0b327106cd83fe1c9bfb6b92c971649c4101556b0406e4
|
|
| MD5 |
43ebbd318c68523c44d0d0fb43f07e77
|
|
| BLAKE2b-256 |
0a09096eb6410d60d33947ce47c36d2fd9f03be7726f9e05fd0df12a1af55f06
|