PTENES
CLI · Python · ffmpeg

30 minutos se convierten en 2 — y el modelo nunca elige dónde cortar

O otv transcribe, divide el habla en unidades numeradas y solo le pide al modelo una nota de 0 a 10 por id. El código es el que convierte el id en segundos y corta; por eso el corte nunca cae en medio de una palabra y ejecutar dos veces da el mismo resultado.

Portada del proyecto otimizevideo
Qué es

Un cortador de video cuyas decisiones son auditables

Una clase, un podcast o una conferencia de 20 a 30 minutos entran; sale un output.mp4 de unos dos minutos con el mejor contenido. Cada fase guarda un JSON que puedes leer, editar y volver a renderizar sin gastar nada.

🎯 El modelo puntúa, no corta

Ve [042] 4.2s talking_head "texto" y devuelve una puntuación. El tiempo se obtiene de la transcripción con marcas de tiempo por palabra, así que el límite del corte coincide con el límite de una palabra real: nunca es una marca de tiempo inventada.

🔁 Determinista y barato de rehacer

La selección (mochila por nota, cuota por tema, anclas de gancho y cierre, cohesión) es código. Incluso notas.json, incluso plan.json. Editar el plan a mano y volver a renderizar no cuesta ninguna llamada al modelo.

🔌 Proveedor intercambiable por fase

Transcripción con Groq o Whisper local; puntuación con GLM, Gemini, Ollama o el propio Claude Code; TTS con inemavox o ElevenLabs; imagen con flux-2-klein. Una línea en el config.yaml o un flag.

Cómo funciona

Nueve fases, un JSON entre cada una

Cada fase lee el artefacto de la anterior y guarda el suyo. Volver a ejecutar una fase no repite las demás, y se reutiliza lo que ya existe, a menos que pidas --forcar.

ingest→ transcribir→ escenas→ clasificar→ unidades→ puntuar→ seleccionar→ narrar→ renderizar

Modo A — condensado

El estándar. Mantiene al presentador y corta solo lo que funciona. Variante A+ (--substituir gerado) cambia los segmentos del presentador por ilustraciones generadas y conserva el audio original.

Modo B — sin presentador

Se queda solo con las diapositivas, la demo de pantalla y los gráficos; el modelo redacta un guion en PT-BR y lo narra con TTS, mientras el audio original queda como fondo a −18 dB.

Modo C — solo visual

La misma selección del B, sin la capa de narración, para cuando el material visual ya se explica por sí solo.

Requisitos previos

Lo que necesitas en la máquina

Nada de contenedores ni builds. Python 3.12, ffmpeg y las claves en los .env de siempre.

ffmpeg y ffprobe

Se encargan de todo el corte, la mezcla de audio y el titular. El render se ejecuta dentro de un scope con un límite de memoria.

# Debian/Ubuntu
sudo apt install ffmpeg

Dependencias de Python

yt-dlp para descargar, PySceneDetect para encontrar los cortes, mediapipe y OpenCV para detectar rostros.

# en la raíz del proyecto
pip install -r requirements.txt

Claves de API

Leídas en runtime de ~/projetos/openpcbotv2/.env e ~/projetos/wifi/.env. Ninguna clave se copia al proyecto.

# lo que se usa
GROQ_API_KEY
OPENROUTER_API_KEY
FAL_KEY  # solo en el modo A+
Guía de uso · paso a paso

Del enlace al corte de dos minutos

Todos los comandos de abajo son reales y se ejecutaron durante la validación integral. El <id> es el nombre de la carpeta creada en trabalho/.

1

Ejecuta todo el pipeline

Una línea lo hace todo: descarga, transcribe, detecta escenas, puntúa, selecciona y renderiza. El resultado se copia a ~/projetos/output/otimizevideo/<id>/.

python3 otv.py run "https://www.youtube.com/watch?v=..." --modo A --alvo 120
2

Mira qué se eligió

O status enumera los artefactos, el titular y cada segmento con tiempo, duración y clasificación visual.

python3 otv.py status <id>  # plan: modo A · 136.6s en 18 segmentos
3

Revisa el gasto

Cada fase registra el tiempo y el costo en trabalho/<id>/custos.json. Una condensación típica cuesta unos centavos de dólar.

python3 otv.py custo <id>  # total US$0.0023
4

¿No te gustó un fragmento? Edita el plan

Abre el plan.json, elimina o ajusta un segmento y vuelve a renderizar. No se realiza ninguna llamada a modelos — el corte manual es gratis.

$EDITOR trabalho/<id>/plan.json
python3 otv.py render <id>
5

Cambia el proveedor de una sola fase

Las fases son independientes: volver a puntuar con otro modelo no repite la transcripción ni la descarga.

python3 otv.py pontuar <id> --provedor gemini --forcar
python3 otv.py selecionar <id> && python3 otv.py render <id>
6

Modo B — video sin presentador, con narración

Se queda solo con las diapositivas, la demo y los gráficos. Necesita la clasificación visual del modelo, así que pasa --visual.

python3 otv.py run "<url>" --modo B --visual glm  # roteiro.md + narracao/*.wav
7

Modo A+ — el presentador se convierte en ilustración

Cada segmento con un rostro se reemplaza por una imagen generada con un efecto Ken Burns lento. El audio sigue siendo el original, así que el habla no cambia.

python3 otv.py run "<url>" --modo A --visual glm --substituir gerado
Ejemplos

Ejecutado en un video real de 20 minutos

Fuente de 1206 s en inglés sobre longevidad e IA, condensada a 136,6 s en 18 segmentos por US$0,0023 de modelo. El render tarda 21 segundos.

Fotograma de un fragmento reemplazado por una ilustración en el modo A+
Modo A+: el segmento del presentador se convirtió en una naturaleza muerta conceptual generada por IA; el audio sigue siendo el original.
Fotograma de un fragmento conservado del video original
Un segmento conservado de la fuente: corte con precisión de fotograma, que empieza y termina en el límite de una palabra.
Hoja de ruta

Dónde está el proyecto

El pipeline está implementado y validado de principio a fin. Lo que sigue es escalar y definir el formato.

Listo
Pipeline completo, modos A, A+, B y CNueve fases, CLI con fase individual, 110 pruebas, validación integral documentada en la spec.
Listo
Robustez del renderizadoUna entrada de ffmpeg por segmento y un límite de memoria: antes, un único filtergraph llegaba a 60,9 GB y bloqueaba la máquina.
Siguiente
Salida 9:16 y por lotesCorte vertical para Reels y Shorts, y una playlist entera con un solo comando.
Idea
Modo A+ con b-roll realReemplazar al presentador por un video de archivo en lugar de una imagen estática.