Vite + React + Tailwind site with a scroll-scrubbed drone fly-through, services, projects, company, team and contact sections, plus a Dockerfile + nginx config for Coolify deployment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
30 lines
1.5 KiB
Bash
Executable file
30 lines
1.5 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Turns any fly-through clip into the WebP frame sequences the scroll scene scrubs through.
|
|
# Desktop: 16:9 1280x720. Mobile: centre-cropped 9:16 480x854 (portrait phones).
|
|
#
|
|
# Usage: scripts/make-frames.sh <video.mp4> [frame-count=120]
|
|
# Then commit public/frames/**. The site reads public/frames/manifest.json.
|
|
set -euo pipefail
|
|
IN=${1:?video file}
|
|
COUNT=${2:-120}
|
|
OUT="$(cd "$(dirname "$0")/.." && pwd)/public/frames"
|
|
|
|
DUR=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$IN")
|
|
FPS=$(echo "$COUNT / $DUR" | bc -l)
|
|
|
|
mkdir -p "$OUT/desktop" "$OUT/mobile"
|
|
find "$OUT/desktop" "$OUT/mobile" -name '*.webp' -delete
|
|
|
|
TMP=$(mktemp -d)
|
|
ffmpeg -loglevel error -y -i "$IN" -vf "fps=$FPS,scale=1280:720:force_original_aspect_ratio=increase,crop=1280:720" \
|
|
-frames:v "$COUNT" "$TMP/d%04d.png"
|
|
ffmpeg -loglevel error -y -i "$IN" -vf "fps=$FPS,crop=ih*9/16:ih,scale=480:854" \
|
|
-frames:v "$COUNT" "$TMP/m%04d.png"
|
|
# cwebp (brew install webp) — encode in parallel
|
|
ls "$TMP"/d*.png | xargs -P 8 -I{} sh -c 'f={}; n=$(basename "$f" .png); cwebp -quiet -q 60 -m 6 "$f" -o "'"$OUT"'/desktop/${n#d}.webp"'
|
|
ls "$TMP"/m*.png | xargs -P 8 -I{} sh -c 'f={}; n=$(basename "$f" .png); cwebp -quiet -q 58 -m 6 "$f" -o "'"$OUT"'/mobile/${n#m}.webp"'
|
|
rm -r "$TMP"
|
|
|
|
N=$(ls "$OUT/desktop" | wc -l | tr -d ' ')
|
|
printf '{ "count": %s, "desktop": "/frames/desktop/", "mobile": "/frames/mobile/" }\n' "$N" > "$OUT/manifest.json"
|
|
echo "wrote $N frames -> $OUT ($(du -sh "$OUT/desktop" | cut -f1) desktop, $(du -sh "$OUT/mobile" | cut -f1) mobile)"
|