68 lines
1.3 KiB
Bash
Executable File
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"
|