#!/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. 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" < "$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