Files
dotfiles/scripts/shell/ffmpeg-join-videos.sh
2025-12-25 18:51:45 -03:00

68 lines
1.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# Usage example:
# ./ffmpeg-join-videos.sh -i vid1.mp4 vid2.mp4 vid3.mp4 -o output_name
# Exit on error
set -e
# Parse arguments
videos=()
output_filename=""
while [[ $# -gt 0 ]]; do
case "$1" in
-i | --input-list)
shift
# Collect all filenames until another option appears or args end
while [[ $# -gt 0 && "$1" != -* ]]; do
videos+=("$1")
shift
done
;;
-o | --output-filename)
output_filename="$2"
shift 2
;;
-h | --help)
echo "Usage: $0 -i file1 file2 [file3 ...] -o output_name"
exit 0
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
# Validate args
if [[ ${#videos[@]} -lt 2 ]]; then
echo "Error: You must provide at least two input files with -i"
exit 1
fi
if [[ -z "$output_filename" ]]; then
echo "Error: You must provide an output filename with -o"
exit 1
fi
# Number of videos
n=${#videos[@]}
# Build input args for ffmpeg
inputs=()
for vid in "${videos[@]}"; do
inputs+=("-i" "$vid")
done
# Build the concat filter
filter=""
for i in "${!videos[@]}"; do
filter+="[$i:v] [$i:a] "
done
filter_complex="${filter}concat=n=$n:v=1:a=1 [v] [a]"
# Run ffmpeg
ffmpeg "${inputs[@]}" -filter_complex "$filter_complex" -map "[v]" -map "[a]" "${output_filename}.mp4"