- Python 100%
| .gitignore | ||
| config.py | ||
| main.py | ||
| media.py | ||
| Pipfile | ||
| Pipfile.lock | ||
| pronunciation.py | ||
| README.md | ||
| speaker.mp3 | ||
| subtitle_utils.py | ||
| tts_utils.py | ||
Subs to Lector
Skrypt generuje polskiego lektora TTS na podstawie napisow, miksuje go z
oryginalnym audio filmu i zapisuje wynikowy plik MKV z dodatkowa sciezka audio
Polski AI Lektor.
Obslugiwane sa dwa tryby:
- osobny plik napisow
.srt - napisy tekstowe osadzone w pliku video, np. w
.mkv
Wymagania
W systemie musza byc dostepne:
- Python 3.11
ffmpegffprobe- model i zaleznosci Coqui TTS / XTTS
torchpydubpysrt
Skrypt uzywa modelu:
tts_models/multilingual/multi-dataset/xtts_v2
Do klonowania glosu potrzebny jest plik referencyjny z glosem lektora, np.
speaker.mp3.
Instalacja
Instalacja zaleznosci Python przez uv:
uv venv --python 3.11
uv pip install pysrt pydub TTS torch
ffmpeg i ffprobe musza byc zainstalowane w systemie.
Sposob uruchomienia
Tryb z osobnym plikiem napisow:
python main.py video subtitles output [opcje]
Tryb z napisami osadzonymi w filmie:
python main.py video output [opcje]
W trybie z osadzonymi napisami skrypt:
- sprawdza strumienie przez
ffprobe - szuka napisow o wybranym jezyku
- wyciaga je do pliku
.srtw--workdir - uzywa wyciagnietego pliku do generowania lektora
Konfiguracja .env
Skrypt czyta lokalny plik .env w katalogu projektu. Mozesz tam trzymac
zarowno OPENROUTER_API_KEY, jak i domyslne ustawienia CLI.
Przyklad:
OPENROUTER_API_KEY=sk-or-...
SUBS_TO_LECTOR_SPEAKER_WAV=speaker.mp3
SUBS_TO_LECTOR_WORKDIR=subs
SUBS_TO_LECTOR_AUTO_PRONUNCIATION=true
SUBS_TO_LECTOR_PRONUNCIATION_MODEL=google/gemini-2.0-flash-lite-001
SUBS_TO_LECTOR_PRONUNCIATION_MAX_NAMES=120
SUBS_TO_LECTOR_PRONUNCIATION_TIMEOUT=120
Najwazniejsze klucze:
SUBS_TO_LECTOR_SPEAKER_WAV- domyslny plik glosu referencyjnegoSUBS_TO_LECTOR_WORKDIR- katalog na pliki posrednieSUBS_TO_LECTOR_AUTO_PRONUNCIATION- wlacza domyslnie OpenRouterSUBS_TO_LECTOR_PRONUNCIATION_MODEL- domyslny model dla OpenRouterSUBS_TO_LECTOR_PRONUNCIATION_MAX_NAMES- limit nazw wysylanych do modeluSUBS_TO_LECTOR_PRONUNCIATION_TIMEOUT- timeout requestu do OpenRouter
Biezace ustawienia z linii polecen mozesz zapisac do .env przez:
--save-settings
Opcje
Podstawowe
--speaker-wav PATH
Plik referencyjny glosu dla XTTS. Wymagany, jesli nie ustawisz
SUBS_TO_LECTOR_SPEAKER_WAV w .env.
--workdir DIR
Katalog na pliki posrednie.
--keep-temp
Zostawia pliki tymczasowe *.lektor.wav i *.lektor-final.opus.
Napisy
--subtitle-language pol
Preferowany jezyk osadzonych napisow przy automatycznym wyciaganiu.
--subtitle-track 0
Wybiera konkretna sciezke napisow. Numeracja liczy tylko strumienie napisow, nie wszystkie strumienie w pliku.
--normalize-subtitles
--no-normalize-subtitles
Wlacza albo wylacza lokalna normalizacje tekstu przed TTS. Bez wylaczania
skrypt poprawia proste skroty pod lektora, np. np. -> na przyklad,
itd. -> i tak dalej, m.in. -> miedzy innymi.
Auto pronunciation
--auto-pronunciation
--no-auto-pronunciation
Wlacza albo wylacza automatyczne przygotowanie polskiej wymowy nazw wlasnych przez OpenRouter.
--auto-pronunciation-review
Generuje cache wymowy i wypisuje zmiany, ale zatrzymuje skrypt przed TTS, zeby dac czas na reczna korekte.
--pronunciation-model MODEL
Model OpenRouter uzywany przez --auto-pronunciation. Domyslnie:
openrouter/free
Przykladowe modele:
openrouter/free- darmowy wariant do testowgoogle/gemini-2.0-flash-lite-001- szybki i tani wariant do regularnego uzyciadeepseek/deepseek-v3.2- mocniejszy fallback, gdy tansze modele daja slabe wyniki
--pronunciation-cache PATH
Sciezka do pliku JSON z cache wymowy. Domyslnie:
workdir/nazwa-wyjscia.pronunciation.json
--pronunciation-max-names 120
Maksymalna liczba wykrytych nazw wysylanych do modelu w jednym przebiegu.
--pronunciation-timeout 120
Timeout requestu do OpenRouter w sekundach.
Do --auto-pronunciation potrzebny jest klucz:
export OPENROUTER_API_KEY="sk-or-..."
albo wpis w .env:
OPENROUTER_API_KEY=sk-or-...
Audio i TTS
--audio-track 0
Wybiera oryginalna sciezke audio z filmu, ktora bedzie miksowana z lektorem.
--original-volume 0.20
Glosnosc oryginalnego audio podczas miksowania.
--lector-volume 1.0
Glosnosc wygenerowanego lektora podczas miksowania.
--volume 0.0
Dodatkowa zmiana glosnosci pojedynczych fragmentow TTS w dB.
--pause-ms 150
Dodatkowa pauza po kazdym wygenerowanym fragmencie.
--tail-ms 2000
Dodatkowy zapas ciszy na koncu wygenerowanej sciezki lektora.
--max-chars 160
Maksymalna dlugosc tekstu wysylanego jednorazowo do TTS.
Video
--video-codec copy
Kodek video w pliku wynikowym.
Dostepne wartosci:
copy- bez rekompresji videoh265- kodowanie H.265av1- kodowanie AV1
--video-backend cpu
Backend enkodera video.
Dostepne wartosci:
cpu-libx265dla H.265 albolibsvtav1dla AV1nvenc- enkodery NVIDIA dla H.265 albo AV1
--video-crf N
Jakosc kodowania dla h265 albo av1. Nizsza wartosc oznacza lepsza jakosc i
wiekszy plik.
--video-preset VALUE
Preset enkodera. Dla H.265 przy CPU typowe wartosci to medium, slow,
slower. Dla AV1/libsvtav1 zwykle 4, 6, 8. Dla nvenc typowe sa
presety p1 do p7.
Przyklady
Osobny plik SRT
.venv/bin/python main.py \
original/film.mkv \
subs/film.pl.srt \
compiled/film-lektor.mkv \
--speaker-wav speaker.mp3
Napisy osadzone w MKV
.venv/bin/python main.py \
original/film.mkv \
compiled/film-lektor.mkv \
--speaker-wav speaker.mp3 \
--workdir subs
Inny jezyk napisow osadzonych
.venv/bin/python main.py \
original/film.mkv \
compiled/film-lektor.mkv \
--speaker-wav speaker.mp3 \
--subtitle-language eng
Konkretna sciezka napisow
.venv/bin/python main.py \
original/film.mkv \
compiled/film-lektor.mkv \
--speaker-wav speaker.mp3 \
--subtitle-track 0
Auto pronunciation z konkretnym modelem
.venv/bin/python main.py \
original/film.mkv \
compiled/film-lektor.mkv \
--speaker-wav speaker.mp3 \
--workdir subs \
--auto-pronunciation \
--pronunciation-model google/gemini-2.0-flash-lite-001
Auto pronunciation w trybie review
.venv/bin/python main.py \
original/film.mkv \
compiled/film-lektor.mkv \
--speaker-wav speaker.mp3 \
--workdir subs \
--auto-pronunciation \
--auto-pronunciation-review
Po sprawdzeniu cache uruchom ponownie bez --auto-pronunciation-review.
Wspolny cache wymowy dla serialu
.venv/bin/python main.py \
original/episode-02.mkv \
compiled/episode-02-lektor.mkv \
--speaker-wav speaker.mp3 \
--workdir subs \
--auto-pronunciation \
--pronunciation-cache subs/sopranos.pronunciation.json
Zapis aktualnych ustawien do .env
.venv/bin/python main.py \
original/film.mkv \
compiled/film-lektor.mkv \
--speaker-wav speaker.mp3 \
--workdir subs \
--auto-pronunciation \
--pronunciation-model google/gemini-2.0-flash-lite-001 \
--pronunciation-max-names 120 \
--save-settings
Konwersja video do H.265
.venv/bin/python main.py \
original/film.mkv \
compiled/film-lektor-h265.mkv \
--speaker-wav speaker.mp3 \
--workdir subs \
--video-codec h265 \
--video-crf 24 \
--video-preset medium
Konwersja video do AV1
.venv/bin/python main.py \
original/film.mkv \
compiled/film-lektor-av1.mkv \
--speaker-wav speaker.mp3 \
--workdir subs \
--video-codec av1 \
--video-crf 32 \
--video-preset 6
Przyklad dla serialu z polskimi napisami w MKV
.venv/bin/python main.py \
"original/The.Sopranos.S01E01.Pilot.1080p.MAX.WEB-DL.DD+5.1.H.264-playWEB.mkv" \
"compiled/The.Sopranos.S01E01.Pilot.PL-Lektor.mkv" \
--speaker-wav speaker.mp3 \
--workdir subs
Ograniczenia
Automatyczne wyciaganie napisow dziala dla napisow tekstowych, np. subrip
/ SRT.
Jesli napisy w filmie sa obrazkowe, np. PGS albo VobSub, ffmpeg nie zamieni
ich automatycznie na tekst. Wtedy najpierw trzeba zrobic OCR do pliku .srt,
a dopiero potem uruchomic skrypt w trybie z osobnym plikiem napisow.
Sprawdzenie dostepnych napisow
Mozesz sprawdzic strumienie w pliku:
ffprobe -v error \
-show_entries stream=index,codec_type,codec_name:stream_tags=language,title \
-of table \
original/film.mkv
Jesli widzisz strumien subtitle z language=pol i kodekiem tekstowym,
skrypt powinien umiec go wyciagnac automatycznie.