submaster/whisper_project/srt_to_kokoro.py

124 lines
4.8 KiB
Python

"""Funciones helper para sintetizar desde SRT.
Este módulo mantiene compatibilidad con la antigua utilidad `srt_to_kokoro.py`.
Contiene `parse_srt_file` y `synth_chunk` delegando a infra.kokoro_utils.
Se incluye una función `synthesize_from_srt` que documenta la compatibilidad
con `KokoroHttpClient` (nombre esperado por otros módulos).
"""
from __future__ import annotations
from typing import Any
from whisper_project.infra.kokoro_utils import parse_srt_file as _parse_srt_file, synth_chunk as _synth_chunk
def parse_srt_file(path: str):
"""Parsea un .srt y devuelve la lista de subtítulos.
Delegado a `whisper_project.infra.kokoro_utils.parse_srt_file`.
"""
return _parse_srt_file(path)
def synth_chunk(endpoint: str, text: str, headers: dict, payload_template: Any, timeout: int = 60) -> bytes:
"""Envía texto al endpoint y devuelve bytes de audio.
Delegado a `whisper_project.infra.kokoro_utils.synth_chunk`.
"""
return _synth_chunk(endpoint, text, headers, payload_template, timeout=timeout)
def synthesize_from_srt(srt_path: str, out_wav: str, endpoint: str = "", api_key: str = ""):
"""Compat layer: función con el nombre esperado por scripts legacy.
Nota: la implementación completa se encuentra ahora en `KokoroHttpClient`.
Esta función delega a `parse_srt_file` y `synth_chunk` si se necesita.
"""
raise NotImplementedError("Use KokoroHttpClient.synthesize_from_srt or the infra adapter instead")
__all__ = ["parse_srt_file", "synth_chunk", "synthesize_from_srt"]
#!/usr/bin/env python3
"""
srt_to_kokoro.py
Leer un archivo .srt y sintetizar cada subtítulo usando una API OpenAPI-compatible (p. ej. Kokoro).
- Intenta autodetectar un endpoint de síntesis en `--openapi` (URL JSON) buscando paths que contengan 'synth'|'tts'|'text' y que acepten POST.
- Alternativamente usa `--endpoint` y un `--payload-template` con {text} como placeholder.
- Guarda fragmentos temporales y los concatena con ffmpeg en un único WAV de salida.
Dependencias: requests, srt (pip install requests srt)
Requiere ffmpeg en PATH.
Ejemplos:
python srt_to_kokoro.py --srt subs.srt --openapi "https://kokoro.../openapi.json" --voice "alloy" --out out.wav --api-key "TOKEN"
python srt_to_kokoro.py --srt subs.srt --endpoint "https://kokoro.../v1/synthesize" --payload-template '{"text": "{text}", "voice": "alloy"}' --out out.wav
"""
import argparse
import os
import shutil
import subprocess
import sys
import tempfile
from typing import Optional
"""
Thin wrapper CLI que delega en `KokoroHttpClient.synthesize_from_srt`.
Conserva la interfaz CLI previa para compatibilidad, pero internamente usa
el cliente HTTP nativo definido en `whisper_project.infra.kokoro_adapter`.
"""
import argparse
import os
import sys
import tempfile
from whisper_project.infra.kokoro_adapter import KokoroHttpClient
def main():
p = argparse.ArgumentParser()
p.add_argument("--srt", required=True, help="Ruta al archivo .srt traducido")
p.add_argument("--endpoint", required=False, help="URL directa del endpoint de síntesis (opcional)")
p.add_argument("--api-key", required=False, help="Valor para autorización (se envía como header Authorization: Bearer <key>)")
p.add_argument("--voice", default="em_alex")
p.add_argument("--model", default="model")
p.add_argument("--out", required=True, help="Ruta de salida WAV final")
p.add_argument("--video", required=False, help="Ruta al vídeo original (opcional)")
p.add_argument("--align", action="store_true", help="Alinear segmentos con timestamps del SRT")
p.add_argument("--keep-chunks", action="store_true")
p.add_argument("--mix-with-original", action="store_true")
p.add_argument("--mix-background-volume", type=float, default=0.2)
p.add_argument("--replace-original", action="store_true")
args = p.parse_args()
# Construir cliente Kokoro HTTP y delegar la síntesis completa
endpoint = args.endpoint or os.environ.get("KOKORO_ENDPOINT")
api_key = args.api_key or os.environ.get("KOKORO_API_KEY")
if not endpoint:
print("Debe proporcionar --endpoint o la variable de entorno KOKORO_ENDPOINT", file=sys.stderr)
sys.exit(2)
client = KokoroHttpClient(endpoint, api_key=api_key, voice=args.voice, model=args.model)
try:
client.synthesize_from_srt(
srt_path=args.srt,
out_wav=args.out,
video=args.video,
align=args.align,
keep_chunks=args.keep_chunks,
mix_with_original=args.mix_with_original,
mix_background_volume=args.mix_background_volume,
)
print(f"Archivo final generado en: {args.out}")
except Exception as e:
print(f"Error durante la síntesis desde SRT: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == '__main__':
main()