aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/build_blender.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/build_blender.py')
-rw-r--r--scripts/build_blender.py58
1 files changed, 58 insertions, 0 deletions
diff --git a/scripts/build_blender.py b/scripts/build_blender.py
new file mode 100644
index 0000000..41731cf
--- /dev/null
+++ b/scripts/build_blender.py
@@ -0,0 +1,58 @@
+# -*- coding: utf-8 -*-
+"""Arma el video final de las escenas hechas en Blender.
+
+Compone en una sola pasada de ffmpeg:
+ fondo punteado + secuencia PNG con alfa (3D) + overlay de Manim + audio
+El overlay trae chip, barra de progreso y subtitulos, o sea que el estilo sale
+del mismo codigo que los videos de Manim.
+"""
+import glob, os, subprocess, sys
+
+ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+sys.path.insert(0, os.path.join(ROOT, "scripts"))
+import build_video
+
+FPS = 30
+
+
+def componer(name, con_musica=True):
+ fondo = os.path.join(ROOT, "media", "images", "overlay", "fondo.png")
+ carpeta = os.path.join(ROOT, "render", name)
+ seq = os.path.join(carpeta, "f%04d.png")
+ overlay = os.path.join(ROOT, "media", "videos", "overlay", "1920p30", f"{name}.mov")
+ for p in (fondo, overlay):
+ if not os.path.exists(p):
+ raise SystemExit(f"falta {p}")
+ n = len(glob.glob(os.path.join(carpeta, "f*.png")))
+ if n < 30:
+ raise SystemExit(f"[{name}] solo hay {n} frames renderizados")
+
+ wav = build_video.build_track(name, con_musica)
+ out = os.path.join(ROOT, "out", f"{name}.mp4")
+ cmd = [
+ "ffmpeg", "-v", "error", "-y",
+ "-loop", "1", "-framerate", str(FPS), "-i", fondo,
+ "-framerate", str(FPS), "-start_number", "1", "-i", seq,
+ "-i", overlay,
+ "-i", wav,
+ "-filter_complex",
+ "[0:v][1:v]overlay=format=auto[a];[a][2:v]overlay=format=auto,format=yuv420p[v]",
+ "-map", "[v]", "-map", "3:a",
+ "-filter:a", "loudnorm=I=-14:TP=-1.5:LRA=11,aresample=48000",
+ "-frames:v", str(n),
+ "-c:v", "libx264", "-profile:v", "high", "-pix_fmt", "yuv420p",
+ "-preset", "slow", "-crf", "20", "-r", str(FPS),
+ "-c:a", "aac", "-b:a", "192k", "-ac", "2",
+ "-movflags", "+faststart", "-shortest", out,
+ ]
+ subprocess.run(cmd, check=True)
+ d = subprocess.run(["ffprobe", "-v", "error", "-show_entries", "format=duration",
+ "-of", "csv=p=0", out], capture_output=True, text=True).stdout.strip()
+ print(f"[{name}] {out} {float(d):.1f}s {os.path.getsize(out)/1e6:.1f} MB "
+ f"({n} frames 3D)", flush=True)
+ return out
+
+
+if __name__ == "__main__":
+ for n in (sys.argv[1:] or ["bolapeluda", "caos", "diferencial"]):
+ componer(n)