Nombre: Sincro
Lema: Subtítulos y traducción en vivo, abiertos y a escala.
Demo en vivo: https://sincro.gscod.com
Repositorio: https://github.com/GastonSch/singro
Licencia: MIT (OSI)

Cómo lo construí

Pipeline en Python asíncrono con piezas desacopladas:

Audio en vivo desde micrófono, archivo o stream (RTSP/HTTP/HLS) e incluso charlas de YouTube (vía yt-dlp), normalizado a PCM 16 kHz mono con ffmpeg.
Motor intercambiable: gemini_live (Live API en streaming, traducción nativa con translation_config), gemini_chunk (REST), local (faster-whisper int8 + argostranslate) y mock (demos sin credenciales).
SessionManager: cada escenario es una tarea asyncio; motor compartido.
EventBus + WebSocket que difunde cada subtítulo a la vista de audiencia, al overlay de OBS y al monitor de producción.
UI de audiencia con video embebido + botón Ejecutar (sin autostart), export SRT/VTT/TXT/JSON, glosario de términos técnicos y Docker/systemd.

Qué aprendí

La Live API de Gemini permite transcripción de entrada e interpretación en un mismo stream (input_audio_transcription + traducción nativa).
En tiempo real la segmentación pesa más que el modelo: con VAD a 500 ms el primer subtítulo pasó de ~27 s a ~5–7 s.
Escalar es desacoplar captura, inferencia y difusión: pasar de 2 a 30 sesiones es sumar tareas/réplicas, no reescribir.
Un motor mock determinista permite desarrollar y testear sin credenciales ni GPU.

Desafíos

Hardware hostil (sin GPU, 8 núcleos, ~7 GB RAM): inviable correr 10 sesiones Whisper locales → diseño híbrido (Gemini para escala, local como fallback).
Reconexión de la Live API: pump de audio persistente + backoff para que una charla larga no pierda subtítulos.
Deltas de transcripción: el texto llega fragmentado; hubo que acumular y finalizar por pausa/fin de oración para exportar bloques coherentes.
REST en 503 y renombres de modelos (gemini-2.5-flash → gemini-3.8-flash); se resolvió usando el modelo Live de traducción.
Ritmo real del audio: pacing manual de ffmpeg con loop para las demos.

Built With

Share this project:

Updates

Submission history