Skip to main content

CLI to download and sync subtitles for video files using semantic embeddings + DTW

Project description

subs_down_n_sync

CI PyPI version Python versions License

CLI Python para baixar e sincronizar legendas para arquivos de vídeo. Idioma padrão: pt-BR, configurável via flag --lang (qualquer tag BCP 47).

A sincronização usa embeddings semânticos multilíngues (sentence-transformers, modelo paraphrase-multilingual-MiniLM-L12-v2) combinados com DTW: baixa uma legenda de referência no idioma original (padrão: EN, configurável via --ref-lang) e alinha os cues da legenda alvo aos timestamps da referência por similaridade semântica. Legendas com match exato (hash ou release group) são usadas sem sincronização.

Instalação

Recomendado: pipx

pipx instala ferramentas CLI em ambientes isolados e adiciona automaticamente ao PATH:

pipx install subs-down-n-sync

Alternativa: pip

pip install subs-down-n-sync

Se aparecer o aviso WARNING: The script subs-down-n-sync is installed in '...' which is not on PATH, adicione o diretório ao PATH:

# Linux/macOS — adicione ao ~/.bashrc ou ~/.zshrc
export PATH="$HOME/.local/bin:$PATH"
# Windows (PowerShell) — adicione ao seu $PROFILE
$env:PATH += ";$env:APPDATA\Python\Scripts"

Após editar o arquivo de perfil, reinicie o terminal ou rode source ~/.bashrc (Linux/macOS).

Instale também o ffmpeg:

sudo apt install ffmpeg    # Debian/Ubuntu
brew install ffmpeg        # macOS
winget install Gyan.FFmpeg # Windows

Configure as credenciais do OpenSubtitles:

export OPENSUBTITLES_USERNAME="seu_usuario"
export OPENSUBTITLES_PASSWORD="sua_senha"

OPENSUBTITLES_USERNAME e OPENSUBTITLES_PASSWORD são opcionais se as credenciais já estiverem salvas em ~/.config/subs-down-n-sync/credentials.enc (criptografado com AES-128). No primeiro uso sem env vars, o CLI solicita interativamente e salva o arquivo. Env vars têm prioridade sobre o arquivo salvo.

Para desenvolvimento, veja Setup.

Setup

Linux/macOS:

python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

Windows (PowerShell):

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e ".[dev]"

Windows (cmd.exe):

python -m venv .venv
.venv\Scripts\activate.bat
pip install -e ".[dev]"

Instale também o ffmpeg no sistema:

sudo apt install ffmpeg    # Debian/Ubuntu
brew install ffmpeg        # macOS
winget install Gyan.FFmpeg          # Windows (winget)
choco install ffmpeg                # Windows (Chocolatey)
scoop install ffmpeg                # Windows (Scoop)

Confirme que ffmpeg está no PATH rodando ffmpeg -version em novo terminal.

Configuração (uma única vez)

Linux/macOS:

export OPENSUBTITLES_USERNAME="seu_usuario"
export OPENSUBTITLES_PASSWORD="sua_senha"

Windows (PowerShell, sessão atual):

$env:OPENSUBTITLES_USERNAME = "seu_usuario"
$env:OPENSUBTITLES_PASSWORD = "sua_senha"

Windows (persistente, próximas sessões):

setx OPENSUBTITLES_USERNAME "seu_usuario"
setx OPENSUBTITLES_PASSWORD "sua_senha"

OPENSUBTITLES_USERNAME e OPENSUBTITLES_PASSWORD são opcionais se as credenciais já estiverem salvas em ~/.config/subs-down-n-sync/credentials.enc (criptografado com AES-128). No primeiro uso sem env vars, o CLI solicita interativamente e salva o arquivo. Env vars têm prioridade sobre o arquivo salvo.

Uso

# Default: pt-BR
subs-down-n-sync /caminho/para/filme.mkv

# Outro idioma (BCP 47: 'en', 'pt-BR', 'en-US', 'es', 'ja', ...)
subs-down-n-sync /caminho/para/filme.mkv --lang en
subs-down-n-sync /caminho/para/filme.mkv -l es

# Processar diretório inteiro (busca vídeos recursivamente)
subs-down-n-sync /caminho/para/pasta/
subs-down-n-sync /caminho/para/pasta/ --lang en
subs-down-n-sync /caminho/para/pasta/ --overwrite   # sobrescreve legendas existentes (baixa da API)
subs-down-n-sync /caminho/para/pasta/ --resync      # sincroniza legenda existente sem API
subs-down-n-sync /caminho/para/pasta/ --parallel    # processa até 2 vídeos simultâneos

# Audio sync com modelo Whisper maior (mais preciso, mais lento)
subs-down-n-sync /caminho/para/filme.mkv --whisper-model base

# Idioma original diferente de EN (ex.: conteúdo espanhol)
subs-down-n-sync /caminho/para/filme.mkv --ref-lang es

# Ou via módulo Python
python -m subs_down_n_sync /caminho/para/filme.mkv

Ao passar um diretório, vídeos que já têm legenda (<video>.<lang>.srt) são pulados por padrão. Use --overwrite / -o para baixar novamente da API. Use --resync / -r para sincronizar a legenda existente sem bater na API (útil quando a legenda já está correta mas fora de sincronia). Use --parallel / -p para processar até 2 vídeos em paralelo.

Saída: /caminho/para/filme.<lang>.srt (ex.: filme.pt-BR.srt, filme.en.srt). Isso permite manter legendas do mesmo vídeo em idiomas diferentes sem sobrescrever.

Desenvolvimento

pip install -e ".[dev]"
pytest

Os testes unitários rodam com gate de cobertura de 90% (configurado em pyproject.toml). O CI falha se a cobertura cair abaixo disso.

Para rodar sem o gate (útil ao explorar com -k ou --collect-only):

pytest --no-cov

Lint e formatação

O projeto usa Ruff para formatação e lint.

ruff format .           # aplica formatação
ruff format --check .   # verifica sem escrever (usado no CI)
ruff check .            # roda lint
ruff check --fix .      # aplica fixes automáticos

O CI falha se ruff format --check ou ruff check encontrarem problemas.

Testes de integração

O projeto tem duas camadas de testes:

  • Testes unitários (padrão, pytest) — rápidos, mockam subliminal e sentence_transformers. Não precisam de rede nem de binários externos além do Python.
  • Testes de integração (pytest -m integration) — exercitam o pipeline real de alinhamento semântico (download do modelo sentence-transformers + DTW) sobre legendas reais. Requer acesso à internet no primeiro run para baixar o modelo (~120 MB), cacheado pelo Hugging Face em ~/.cache/huggingface/.

Como rodar cada camada:

pytest                    # só unit (rápido)
pytest -m integration     # só integração (baixa modelo de embeddings, roda DTW real)
pytest -m ""              # tudo (unit + integração)

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

subs_down_n_sync-1.4.1.tar.gz (46.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

subs_down_n_sync-1.4.1-py3-none-any.whl (31.4 kB view details)

Uploaded Python 3

File details

Details for the file subs_down_n_sync-1.4.1.tar.gz.

File metadata

  • Download URL: subs_down_n_sync-1.4.1.tar.gz
  • Upload date:
  • Size: 46.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for subs_down_n_sync-1.4.1.tar.gz
Algorithm Hash digest
SHA256 84c24d6506c5a31d97cf61be7a069531fb7f58dbab4e08559c3fad9800255289
MD5 14e23018c9b5ac1cd5cf738368f2856e
BLAKE2b-256 0addd10177c05e4a97db213ad627a15e2b38a03b1a39c9b7cbf7e4990af507b9

See more details on using hashes here.

Provenance

The following attestation bundles were made for subs_down_n_sync-1.4.1.tar.gz:

Publisher: release.yml on airton-soares/subs_down_n_sync

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file subs_down_n_sync-1.4.1-py3-none-any.whl.

File metadata

File hashes

Hashes for subs_down_n_sync-1.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 77cb1074828130ed4fc89f4d5d499451f8a33e127eb0f5bbbe20aecad367304d
MD5 49decbc9c491792cf362e50f1b10114b
BLAKE2b-256 c25d57a60bff7f24bf8c6d0acea9aa75d4cbe8a81e94acbe2ccc65528b6b28cf

See more details on using hashes here.

Provenance

The following attestation bundles were made for subs_down_n_sync-1.4.1-py3-none-any.whl:

Publisher: release.yml on airton-soares/subs_down_n_sync

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page