No description
Find a file
2026-05-12 14:25:32 +02:00
.gitignore fix: Auto Pronunciation using AI and .env file with settings 2026-05-12 14:04:26 +02:00
config.py fix: Auto Pronunciation using AI and .env file with settings 2026-05-12 14:04:26 +02:00
main.py fix: Auto Pronunciation using AI and .env file with settings 2026-05-12 14:04:26 +02:00
media.py fix: Auto Pronunciation using AI and .env file with settings 2026-05-12 14:04:26 +02:00
Pipfile init 2026-05-07 15:19:44 +02:00
Pipfile.lock init 2026-05-07 15:19:44 +02:00
pronunciation.py fix: Auto Pronunciation using AI and .env file with settings 2026-05-12 14:04:26 +02:00
README.md feat: README rewrite 2026-05-12 14:25:32 +02:00
speaker.mp3 init 2026-05-07 15:19:44 +02:00
subtitle_utils.py fix: Subtitles merging 2026-05-07 17:23:03 +02:00
tts_utils.py fix: Subtitles merging 2026-05-07 17:23:03 +02:00

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
  • ffmpeg
  • ffprobe
  • model i zaleznosci Coqui TTS / XTTS
  • torch
  • pydub
  • pysrt

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:

  1. sprawdza strumienie przez ffprobe
  2. szuka napisow o wybranym jezyku
  3. wyciaga je do pliku .srt w --workdir
  4. 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 referencyjnego
  • SUBS_TO_LECTOR_WORKDIR - katalog na pliki posrednie
  • SUBS_TO_LECTOR_AUTO_PRONUNCIATION - wlacza domyslnie OpenRouter
  • SUBS_TO_LECTOR_PRONUNCIATION_MODEL - domyslny model dla OpenRouter
  • SUBS_TO_LECTOR_PRONUNCIATION_MAX_NAMES - limit nazw wysylanych do modelu
  • SUBS_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 testow
  • google/gemini-2.0-flash-lite-001 - szybki i tani wariant do regularnego uzycia
  • deepseek/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 video
  • h265 - kodowanie H.265
  • av1 - kodowanie AV1
--video-backend cpu

Backend enkodera video.

Dostepne wartosci:

  • cpu - libx265 dla H.265 albo libsvtav1 dla AV1
  • nvenc - 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.