Uses ffmpeg to generate an H.264/AAC video from an MP3 file with a centred title overlay. Supports optional background image (title at bottom) or solid colour (title centred). Includes spec, dryrun support, and 10 tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
137 lines
4.0 KiB
Bash
Executable File
137 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -uo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
SCRIPT="$SCRIPT_DIR/../scripts/mp3-to-mp4"
|
|
PASS=0
|
|
FAIL=0
|
|
GREEN='\033[0;32m'
|
|
RED='\033[0;31m'
|
|
RESET='\033[0m'
|
|
|
|
pass() { echo -e "${GREEN}PASS${RESET}: $1"; ((PASS++)); }
|
|
fail() { echo -e "${RED}FAIL${RESET}: $1 — $2"; ((FAIL++)); }
|
|
|
|
# Create a short test mp3 using ffmpeg (1 second of silence)
|
|
TMPDIR=$(mktemp -d)
|
|
trap 'rm -rf "$TMPDIR"' EXIT
|
|
|
|
TEST_MP3="$TMPDIR/test.mp3"
|
|
TEST_IMG="$TMPDIR/test.png"
|
|
ffmpeg -y -f lavfi -i anullsrc=r=44100:cl=mono -t 1 -q:a 9 "$TEST_MP3" 2>/dev/null
|
|
ffmpeg -y -f lavfi -i "color=c=blue:s=320x240:d=1" -frames:v 1 "$TEST_IMG" 2>/dev/null
|
|
|
|
# --- Tests ---
|
|
|
|
# Help flag
|
|
desc="--help exits 0 and shows usage"
|
|
out=$("$SCRIPT" --help 2>&1)
|
|
if [[ $? -eq 0 ]] && echo "$out" | grep -q "Usage:"; then
|
|
pass "$desc"
|
|
else
|
|
fail "$desc" "exit code or output unexpected"
|
|
fi
|
|
|
|
# Missing input file
|
|
desc="missing input exits 1"
|
|
out=$("$SCRIPT" -t "Test" 2>&1)
|
|
if [[ $? -ne 0 ]] && echo "$out" | grep -qi "error"; then
|
|
pass "$desc"
|
|
else
|
|
fail "$desc" "expected error exit"
|
|
fi
|
|
|
|
# Missing title
|
|
desc="missing --title exits 1"
|
|
out=$("$SCRIPT" "$TEST_MP3" 2>&1)
|
|
if [[ $? -ne 0 ]] && echo "$out" | grep -qi "title"; then
|
|
pass "$desc"
|
|
else
|
|
fail "$desc" "expected error about title"
|
|
fi
|
|
|
|
# File not found
|
|
desc="non-existent file exits 1"
|
|
out=$("$SCRIPT" -t "Test" /tmp/nonexistent_audio_12345.mp3 2>&1)
|
|
if [[ $? -ne 0 ]] && echo "$out" | grep -qi "not found"; then
|
|
pass "$desc"
|
|
else
|
|
fail "$desc" "expected file not found error"
|
|
fi
|
|
|
|
# Dryrun shows expected fields
|
|
desc="--dryrun shows all expected fields"
|
|
out=$("$SCRIPT" --dryrun -t "My Title" "$TEST_MP3" 2>&1)
|
|
if [[ $? -eq 0 ]] \
|
|
&& echo "$out" | grep -q "\[dryrun\] Input:" \
|
|
&& echo "$out" | grep -q "\[dryrun\] Output:" \
|
|
&& echo "$out" | grep -q "\[dryrun\] Title:.*My Title" \
|
|
&& echo "$out" | grep -q "\[dryrun\] Duration:" \
|
|
&& echo "$out" | grep -q "\[dryrun\] Resolution:.*1920x1080" \
|
|
&& echo "$out" | grep -q "\[dryrun\] Font size:.*72" \
|
|
&& echo "$out" | grep -q "\[dryrun\] Would generate"; then
|
|
pass "$desc"
|
|
else
|
|
fail "$desc" "missing expected dryrun fields"
|
|
echo " Output was:"
|
|
echo "$out" | sed 's/^/ /'
|
|
fi
|
|
|
|
# Dryrun with custom options
|
|
desc="--dryrun respects custom options"
|
|
out=$("$SCRIPT" --dryrun -t "Custom" -r 1280x720 --font-size 48 --font-color yellow --bg-color blue "$TEST_MP3" 2>&1)
|
|
if [[ $? -eq 0 ]] \
|
|
&& echo "$out" | grep -q "Resolution:.*1280x720" \
|
|
&& echo "$out" | grep -q "Font size:.*48" \
|
|
&& echo "$out" | grep -q "Font color:.*yellow" \
|
|
&& echo "$out" | grep -q "Background:.*blue"; then
|
|
pass "$desc"
|
|
else
|
|
fail "$desc" "custom options not reflected"
|
|
echo " Output was:"
|
|
echo "$out" | sed 's/^/ /'
|
|
fi
|
|
|
|
# Dryrun with custom output
|
|
desc="--dryrun respects -o output path"
|
|
out=$("$SCRIPT" --dryrun -t "Test" -o /tmp/custom.mp4 "$TEST_MP3" 2>&1)
|
|
if [[ $? -eq 0 ]] && echo "$out" | grep -q "Output:.*custom.mp4"; then
|
|
pass "$desc"
|
|
else
|
|
fail "$desc" "custom output not shown"
|
|
fi
|
|
|
|
# Dryrun with --image shows image as background
|
|
desc="--dryrun with --image shows image path"
|
|
out=$("$SCRIPT" --dryrun -t "Test" -i "$TEST_IMG" "$TEST_MP3" 2>&1)
|
|
if [[ $? -eq 0 ]] && echo "$out" | grep -q "Background:.*test.png.*(image)"; then
|
|
pass "$desc"
|
|
else
|
|
fail "$desc" "expected image path in background"
|
|
echo " Output was:"
|
|
echo "$out" | sed 's/^/ /'
|
|
fi
|
|
|
|
# Image not found
|
|
desc="--image with non-existent file exits 1"
|
|
out=$("$SCRIPT" -t "Test" -i /tmp/nonexistent_img_12345.png "$TEST_MP3" 2>&1)
|
|
if [[ $? -ne 0 ]] && echo "$out" | grep -qi "image not found"; then
|
|
pass "$desc"
|
|
else
|
|
fail "$desc" "expected image not found error"
|
|
fi
|
|
|
|
# Default output replaces .mp3 with .mp4
|
|
desc="default output replaces .mp3 with .mp4"
|
|
out=$("$SCRIPT" --dryrun -t "Test" "$TEST_MP3" 2>&1)
|
|
if echo "$out" | grep -q "Output:.*test.mp4"; then
|
|
pass "$desc"
|
|
else
|
|
fail "$desc" "expected test.mp4 in output"
|
|
fi
|
|
|
|
# --- Summary ---
|
|
echo ""
|
|
echo "Results: $PASS passed, $FAIL failed"
|
|
[[ $FAIL -eq 0 ]] && exit 0 || exit 1
|