Skip to content

Instantly share code, notes, and snippets.

@lucasnegrao
Last active September 23, 2024 05:33
Show Gist options
  • Select an option

  • Save lucasnegrao/90edae82fb3ce898d73e4d2976842a4e to your computer and use it in GitHub Desktop.

Select an option

Save lucasnegrao/90edae82fb3ce898d73e4d2976842a4e to your computer and use it in GitHub Desktop.
Using FFMPEG to concat videos
#!/bin/bash
# Check if directory is provided as an argument
if [ -z "$1" ]; then
echo "Usage: $0 /path/to/video/files"
exit 1
fi
# Set desired output resolution and frame rate
output_width=1280
output_height=720
output_fps="10"
clip_duration=2 # Clip duration in seconds
# Set the directory to search for video files
input_dir="$1"
# Create a text file to list clips for concatenation
concat_list="concat_list.txt"
> "$concat_list"
# Loop through all video files in the specified directory
for file in "$input_dir"/*.{avi,mpg,mkv,wmv,mp4}; do
if [ -f "$file" ]; then
# Get video duration in seconds using ffprobe
duration=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$file")
total_seconds=$(printf "%.0f\n" "$duration")
# Random start time, ensuring there's enough room for a full clip
max_start=$((total_seconds - clip_duration))
if [ $max_start -le 0 ]; then
start_time=0
else
start_time=$((RANDOM % max_start))
fi
# Generate the caption text from the file name (without extension)
filename=$(basename "$file")
caption="${filename%.*}"
# Proportional scaling using scale filter while maintaining aspect ratio
scale_filter="scale='if(gt(a,${output_width}/${output_height}),${output_width},-1)':'if(gt(a,${output_width}/${output_height}),-1,${output_height})'"
# Extract a random clip, ignore audio, and apply a text overlay for the file name
output_clip="clip_$caption.mp4"
ffmpeg -ss "$start_time" -i "$file" -t "$clip_duration" \
-vf "$scale_filter,fps=$output_fps,drawtext=text='$caption':fontcolor=white:fontsize=24:x=(w-text_w)/2:y=h-50" \
-c:v libx264 -preset medium -crf 23 -tune film -an "$output_clip"
# Check if the clip was created and add to the concat list
if [ -f "$output_clip" ]; then
echo "file '$output_clip'" >> "$concat_list"
fi
fi
done
# Concatenate all the clips into one video if any clips were created
if [ -s "$concat_list" ]; then
ffmpeg -fflags +genpts -f concat -safe 0 -i "$concat_list" -c:v libx264 -preset medium -crf 23 -tune film -an final_video.mp4
else
echo "No valid clips were created."
fi
# Clean up
rm "$concat_list"
rm clip_*.mp4
echo "Done!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment