singe/util/demoCapture.sh
2026-10-05 22:12:53 -05:00

45 lines
2.1 KiB
Bash
Executable file

#!/bin/bash
# Captures a stretch of one of the demos headless, frame by frame, and puts the music under it:
#
# util/demoCapture.sh neonCoast 0 30 [every] [out.mp4]
#
# The demos folder is copied to a scratch folder and run from there with a wrapper that sets
# DEMO_CAPTURE (demos/kit.lua), so the clock moves exactly one 20 ms step a frame and every frame
# (or every "every"th) is saved. With every = 1 the frames become out.mp4 at 50 frames a second
# with the same stretch of the demo's music. Nothing appears on screen. The frames are left in
# $SCRATCH/frames for looking at; SCRATCH defaults to a folder under /tmp. A whole demo to MP4 is
# far quicker with util/demoRecord.sh, which uses Singe's own recorder.
set -euo pipefail
DEMO=$1
FROM=$2
TO=$3
EVERY=${4:-1}
OUT=${5:-}
# The run changes folder, so a relative output path is made absolute first.
if [ -n "$OUT" ]; then
OUT=$(realpath -m "$OUT")
fi
STEP=20
REPO=$(cd "$(dirname "$0")/.." && pwd)
BIN=$(ls "$REPO"/.builddir/Singe-v*-Linux-x86_64 | head -1)
SCRATCH=${SCRATCH:-/tmp/demoCapture-$DEMO}
rm -rf "$SCRATCH"
mkdir -p "$SCRATCH/run" "$SCRATCH/frames"
cp -r "$REPO/demos/." "$SCRATCH/run/"
cat > "$SCRATCH/run/$DEMO/capture.singe" <<LUA
DEMO_CAPTURE = { from = $FROM, to = $TO, every = $EVERY }
dofile(singeGetScriptPath():match("(.*[/\\\\])") .. "$DEMO.singe")
LUA
cd "$SCRATCH/run"
SDL_VIDEODRIVER=offscreen SDL_AUDIO_DRIVER=dummy timeout -k 10 7200 "$BIN" -k -s -w -C 640x480 -x 640 -y 480 --deterministic=$STEP -d "$SCRATCH/data" "$DEMO/capture.singe" > "$SCRATCH/run.log" 2>&1 || true
grep -E "DEMO|rror" "$SCRATCH/run.log" || true
find "$SCRATCH/data" -name "frame*.png" -exec mv {} "$SCRATCH/frames/" \;
echo "$(ls "$SCRATCH/frames" | wc -l) frames in $SCRATCH/frames"
if [ -n "$OUT" ] && [ "$EVERY" = "1" ]; then
ffmpeg -hide_banner -loglevel error -y -framerate $((1000 / STEP)) -pattern_type glob -i "$SCRATCH/frames/frame*.png" \
-ss "$FROM" -t "$(echo "$TO - $FROM" | bc)" -i "$REPO/demos/$DEMO/music.mp3" \
-map 0:v -map 1:a -c:v libx264 -preset medium -crf 18 -pix_fmt yuv420p -c:a aac -b:a 256k -shortest "$OUT"
echo "wrote $OUT"
fi