#!/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"