Fecha: 10-nov-2026
Resultado: out/nvidia_operacion_politica.mp4 — 63.6s, 1080x1920 (9:16), 30fps, H.264 + AAC, -14 LUFS, 3.6MB
Renderizado en: esotericwarfare@100.91.16.10 (PC con más recursos, vía SSH/Tailscale)
Copias del final: en ambas máquinas, en ~/nvidia-video/out/
La PC remota tiene una NVIDIA GeForce GTX 1050 (2GB) y su ffmpeg sí tiene compilados los encoders
h264_nvenc (verificado con ffmpeg -encoders). Pero el build codificó con libx264 puro CPU
(-c:v libx264 -preset medium -crf 18), escrito así a propósito en build.py.
La rapidez (~2 minutos de render total) vino de:
medium paraleliza solo.-f rawvideo por stdin): los ~1900 frames nunca tocan el
disco como JPEGs/PNGs intermedios, van de RAM al encoder.Si más adelante se quiere usar la GPU, el cambio es una línea en build_videos()
(libx264 → h264_nvenc + -preset p4), pero ojo: el cuello de botella real es el
render de frames en Pillow (CPU), no el encode. La ganancia sería parcial.
~/nvidia-video/
├── script.json # EL guion: narración, textos en pantalla, duraciones, config
├── build.py # pipeline completo (fotos → tts → visuales → ffmpeg)
├── rssh.sh # wrapper ssh con multiplexión (ver §7)
├── BITACORA-BUILD.md # este archivo
├── assets/
│ ├── images/ # fotos descargadas + metadatos de licencia
│ │ ├── jensen.jpg / jensen.json
│ │ ├── hotz.jpg / hotz.json
│ │ └── (alice: sin foto → tarjeta generada en runtime)
│ ├── tts/ # narraciones 00.mp3..06.mp3 (cache)
│ └── music.mp3 # OPCIONAL: si existe, se mezcla a 13% con fade out
├── work/ # escenas individuales + audio por escena + concats (cache)
└── out/
└── nvidia_operacion_politica.mp4
ffmpeg pero NO Pillow.100.91.16.10, hostname arch): Arch Linux, kernel 7.2.14, AMD FX-6300 (6 núcleos),
7.7GB RAM, GTX 1050, Python 3.14.9, ffmpeg n9.0.2, Pillow 12.3.0, edge-tts, rsync.
Ya tenía Pillow/edge-tts de trabajos anteriores (docs de Piper en ~/).login.tailscale.com, aprobado por el usuario).rssh.sh en este proyecto (idéntico al usado en /tmp/opencode/rssh).build.py (5 etapas)prop=imageinfo + extmetadata), valida que la licencia sea CC BY / CC BY-SA /
CC0 / dominio público (rechaza fair use y no-libres), baja el thumb a 1080px de ancho
y guarda artista+licencia en .json para renderizar la atribución EN PANTALLA
(abajo, gris, chico).
File:Jensen huang stanford 2026-04-30 008 (cropped).jpg — CC BY-SA 4.0File:George Hotz speaks onstage during TechCrunch Disrupt SF 2016 01.jpg — CC BY 2.0es-AR-TomasNeural, rate +30%.
assets/tts/ (con --force-tts se regenera).max(min_duration, tts + lead_in + tail).r_hero, r_dossier, r_lupa, r_list3, r_data, r_grid, r_punch):
adelay(150ms) + apad hasta la duración exacta →
AAC 48kHz estéreo 192k. Concat por demuxer. Sin música (no hay
assets/music.mp3; si se agrega, se mezcla a volumen 0.13 con fade out).loudnorm I=-14 TP=-1.5 (estándar redes),
-movflags +faststart.| Problema | Solución |
|---|---|
| Tailscale SSH pedía check por navegador | usuario aprobó el link; luego ControlMaster para no repetir |
edge-tts 7.2.8 → 403 en speech.platform.bing.com |
pip3 install --user --break-system-packages --upgrade edge-tts → 7.3.1 funcionó |
| Duración inicial 71.9s (objetivo 55-65s) | rate +15%→+30%, pausas 0.2/0.4→0.15/0.3s, min_duration por escena recalibrados → 63.56s |
| Sin foto libre de Alice Huang | tarjeta generada con silueta (§3.1) |
| (Preventivo) licencias | solo CC/dominio público; atribución renderizada en pantalla |
ffprobe: h264 1080x1920, aac, duración 63.60s video / 63.63s audio.# en la REMOTA (o local si tiene Pillow):
cd ~/nvidia-video
python3 build.py # rehace solo lo que cambió (caches por escena)
python3 build.py --tts-only # tabla de duraciones sin renderizar
python3 build.py --rate "+25%" # cambia velocidad de voz (regenera TTS)
python3 build.py --force-tts # regenera narraciones
python3 build.py --fresh # borra work/ y rehace todo
script.json (castellano, comentado por escena).build.py.assets/music.mp3 → se mezcla solo
en la etapa final (los visuales NO se re-renderizan).script.json.# wrapper ssh multiplexado (también copiado como ~/nvidia-video/rssh.sh)
cat > rssh.sh <<'EOF'
#!/bin/bash
exec ssh -o BatchMode=yes -o ControlMaster=auto \
-o ControlPath=/tmp/opencode/tssh-%r@%h-%p -o ControlPersist=86400 \
-o ServerAliveInterval=30 -o ConnectTimeout=20 "$@"
EOF
chmod +x rssh.sh
# sync del proyecto → remota
rsync -az -e "./rssh.sh" ~/nvidia-video/ esotericwarfare@100.91.16.10:nvidia-video/
# build completo en la remota
./rssh.sh esotericwarfare@100.91.16.10 'cd ~/nvidia-video && python3 build.py'
# traer el resultado a local
scp -o ControlPath=/tmp/opencode/tssh-%r@%h-%p \
esotericwarfare@100.91.16.10:nvidia-video/out/nvidia_operacion_politica.mp4 ~/nvidia-video/out/
# verlo
mpv ~/nvidia-video/out/nvidia_operacion_politica.mp4
Tiempos de render reales por escena (remota, CPU): S1 8.3s, S2 19.8s, S3 13.2s, S4 13.7s, S5 21.2s, S6 9.4s, S7 15.4s → ~101s de render total para 1907 frames.