90 lines
1.8 KiB
Bash
Executable File
90 lines
1.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
die() {
|
|
echo "$*" >&2
|
|
exit 1
|
|
}
|
|
|
|
usage() {
|
|
cat <<'EOF' >&2
|
|
Usage: convert-to-video.sh /path/to/audio.file
|
|
Creates a slideshow video from stormux images and the provided audio.
|
|
EOF
|
|
exit 1
|
|
}
|
|
|
|
require_commands() {
|
|
for cmd in "$@"; do
|
|
command -v "$cmd" >/dev/null 2>&1 || die "Missing dependency: $cmd"
|
|
done
|
|
}
|
|
|
|
locate_images() {
|
|
local candidate="."
|
|
local have_all=true
|
|
|
|
for i in 1 2 3 4 5; do
|
|
[ -f "$candidate/stormux${i}.png" ] || have_all=false
|
|
done
|
|
|
|
if [ "$have_all" = true ]; then
|
|
printf '%s\n' "$candidate"
|
|
return
|
|
fi
|
|
|
|
candidate="/usr/share/stormux/slideshow"
|
|
for i in 1 2 3 4 5; do
|
|
[ -f "$candidate/stormux${i}.png" ] || die "Missing image: $candidate/stormux${i}.png"
|
|
done
|
|
|
|
printf '%s\n' "$candidate"
|
|
}
|
|
|
|
detect_container() {
|
|
local audio_file="$1"
|
|
local codec
|
|
|
|
codec="$(ffprobe -v error -select_streams a:0 -show_entries stream=codec_name -of csv=p=0 "$audio_file" || true)"
|
|
case "$codec" in
|
|
aac|mp3) echo "mp4" ;;
|
|
*) echo "mkv" ;;
|
|
esac
|
|
}
|
|
|
|
build_video() {
|
|
local audio_file="$1"
|
|
local image_dir="$2"
|
|
local container="$3"
|
|
local output_filename="$4"
|
|
local output_dir="$HOME/Videos"
|
|
|
|
mkdir -p "$output_dir"
|
|
|
|
ffmpeg -y \
|
|
-stream_loop -1 -framerate 1/35 -start_number 1 -i "$image_dir/stormux%d.png" \
|
|
-i "$audio_file" \
|
|
-map 0:v:0 -map 1:a:0 \
|
|
-c:v libx264 -crf 18 -preset veryfast -r 30 -pix_fmt yuv420p \
|
|
-c:a copy \
|
|
-shortest \
|
|
"$output_dir/${output_filename##*/}"
|
|
}
|
|
|
|
[ "$#" -eq 1 ] || usage
|
|
|
|
audio="$1"
|
|
[ -f "$audio" ] || die "Audio file not found: $audio"
|
|
|
|
require_commands ffmpeg ffprobe
|
|
|
|
image_dir="$(locate_images)"
|
|
container="$(detect_container "$audio")"
|
|
base="$(basename "$audio")"
|
|
name="${base%.*}"
|
|
output="${name}.${container}"
|
|
|
|
build_video "$audio" "$image_dir" "$container" "$output"
|
|
|
|
echo "Wrote $HOME/Videos/$output"
|