Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01A1dxvtsZx8NE9fwjXUNDBr
42 lines
2.2 KiB
Python
42 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Porta i video «Come si gioca» nel gioco (assets/video/, story.tutorials): da quando si arriva nel posto del gioco
|
|
(la prima battuta del narratore), più piccoli e compressi per il web, con una copertina.
|
|
|
|
python3 video/pubblica.py briscola tressette scopa bocce biliardo
|
|
|
|
Prima la ripresa e il montaggio (video/SCALETTA-CARTE.md): legge video/out/tutorial-<gioco>.mp4 e il cues.json della
|
|
ripresa. Il titolo del gioco all'inizio della ripresa non serve, e col ritaglio dei tavoli verrebbe tagliato ai lati.
|
|
"""
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
VIDEO = Path(__file__).resolve().parent
|
|
GIOCO = VIDEO.parent
|
|
RIPRESE = Path.home() / "Workspaces/qemu/qemu-iso-lab/artifacts/tour/out"
|
|
|
|
|
|
def durata(f: Path) -> float:
|
|
return float(subprocess.run(["ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "csv=p=0", str(f)],
|
|
capture_output=True, text=True, check=True).stdout)
|
|
|
|
|
|
for gioco in sys.argv[1:]:
|
|
ripresa = RIPRESE / f"tutorial-{gioco}"
|
|
cues = json.loads((ripresa / "cues.json").read_text())["cues"]
|
|
# Lo stesso scarto di monta.py: la ripresa parte un po' prima del copione.
|
|
scarto = max(0.0, durata(ripresa / "raw.mkv") - (cues[-1]["end"] + 1.2))
|
|
inizio = max(0.0, cues[0]["start"] + scarto - 0.4)
|
|
dentro, fuori = VIDEO / "out" / f"tutorial-{gioco}.mp4", GIOCO / "assets" / "video" / f"{gioco}.mp4"
|
|
fuori.parent.mkdir(exist_ok=True)
|
|
subprocess.run(["ffmpeg", "-loglevel", "error", "-y", "-ss", f"{inizio:.2f}", "-i", str(dentro),
|
|
"-vf", "scale=trunc(iw*0.75/2)*2:-2", "-c:v", "libx264", "-preset", "slow", "-crf", "27", "-pix_fmt", "yuv420p",
|
|
"-af", "afade=t=in:d=0.4", "-c:a", "aac", "-b:a", "96k", "-movflags", "+faststart", str(fuori)], check=True)
|
|
# La copertina: un momento al tavolo, a un terzo del video.
|
|
subprocess.run(["ffmpeg", "-loglevel", "error", "-y", "-ss", f"{durata(fuori) / 3:.1f}", "-i", str(fuori), "-frames:v", "1",
|
|
"-q:v", "4", str(fuori.with_suffix(".jpg"))], check=True)
|
|
for f in (fuori, fuori.with_suffix(".jpg")):
|
|
f.chmod(0o644)
|
|
print(f"-> {fuori} ({durata(fuori):.0f} s, {fuori.stat().st_size / 1e6:.1f} MB), da {inizio:.1f} s")
|