Files
pivoine.art/scripts/compress-videos.sh
T
valknar 1f24ee8276 feat: compress MP4 videos at Docker build time via FFmpeg
Hugo has no video processing, so FFmpeg runs in the builder stage
before hugo builds, compressing every content/**/*.mp4 in-place.

scripts/compress-videos.sh:
  - H.264 CRF 28 + preset slow (good web compression)
  - faststart for progressive streaming
  - AAC 64k audio
  - Only replaces source if output is actually smaller, so
    already-lean videos are skipped

Dockerfile:
  - apk adds ffmpeg alongside hugo in the builder stage
  - RUN compress-videos.sh runs after COPY . . before pnpm build
    (compressed files land in public/ via Hugo's copy of page bundles)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 18:42:57 +02:00

48 lines
1.3 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/sh
# Compress MP4 page-bundle videos with FFmpeg before Hugo builds.
#
# Usage: sh scripts/compress-videos.sh [content-dir]
#
# Encoding choices:
# H.264 CRF 28 — good web quality, ~60-80% smaller than camera/AI originals
# preset slow — best compression for a given CRF (fine in CI/Docker)
# faststart — moov atom moved to front for progressive streaming
# aac 64k — low-bitrate audio (videos are muted in-player by default)
#
# The script replaces each source file in-place only when the compressed
# output is actually smaller, so already-lean videos are left untouched.
set -e
CONTENT_DIR="${1:-content}"
find "$CONTENT_DIR" -name "*.mp4" | while IFS= read -r src; do
tmp="${src%.mp4}.__tmp.mp4"
echo "$src"
ffmpeg -i "$src" \
-c:v libx264 \
-crf 28 \
-preset slow \
-movflags +faststart \
-c:a aac \
-b:a 64k \
-loglevel error \
-y "$tmp"
src_size=$(stat -c%s "$src" 2>/dev/null || stat -f%z "$src")
tmp_size=$(stat -c%s "$tmp" 2>/dev/null || stat -f%z "$tmp")
if [ "$tmp_size" -lt "$src_size" ]; then
mv "$tmp" "$src"
saved=$(( (src_size - tmp_size) / 1024 ))
echo "${src_size}${tmp_size} bytes (${saved} KB)"
else
rm -f "$tmp"
echo " — already optimal, skipped"
fi
done
echo "Done."