Last active
September 23, 2024 05:33
-
-
Save lucasnegrao/90edae82fb3ce898d73e4d2976842a4e to your computer and use it in GitHub Desktop.
Using FFMPEG to concat videos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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