Skip to content

Instantly share code, notes, and snippets.

@ahdinosaur
Last active August 19, 2024 10:21
Show Gist options
  • Save ahdinosaur/8dd10a8604ec9b44bf1b726d146aab14 to your computer and use it in GitHub Desktop.
Save ahdinosaur/8dd10a8604ec9b44bf1b726d146aab14 to your computer and use it in GitHub Desktop.
Use ffmpeg to create a supercut from a directory of videos
#!/bin/bash
set -euo pipefail
output_video=$1
# find good value that aligns with keyframes:
# ffprobe -loglevel error -select_streams v:0 -show_entries packet=pts_time,flags -of csv=print_section=0 -i FortV0001-0240.mp4
seconds_per_video=$2
mkdir -p ./cuts
if [[ $(ls -A ./cuts) ]]
then
rm ./cuts/*
fi
if [[ -f ./cuts.txt ]]
then
rm ./cuts.txt
fi
if [[ -f "${output_video}" ]]
then
rm "${output_video}"
fi
files="$(ls -1 ./videos | egrep '\.mp4$')"
num_files="$(ls -1 ./videos | egrep '\.mp4$' | wc -l)"
video_index=0
video_start=0
rounding_helper=0.01
total_seconds_per_video=10
frames_per_second=24
for file in ${files}
do
# TODO handle when video_start + seconds_per_video > total_seconds_per_video
echo "file" $file
echo "video index" $video_index
echo "video_start" $video_start
if (( $(echo "(${video_start} + ${seconds_per_video}) <= ${total_seconds_per_video}" | bc -l) ))
then
start_time=$(echo "${video_start} + ${rounding_helper}" | bc -l | awk '{printf "%f", $0}')
ffmpeg -hide_banner -loglevel error -ss "${video_start}" -i "./videos/${file}" -t "${seconds_per_video}" -c copy -avoid_negative_ts 2 "./cuts/${video_index}.mp4"
echo "file cuts/${video_index}.mp4" >> "./cuts.txt"
video_index=$((${video_index} + 1))
else
overflow_time=$(echo "${video_start} + ${seconds_per_video} - ${total_seconds_per_video} + ${rounding_helper}" | bc -l | awk '{printf "%f", $0}')
leftover_time=$(echo "${seconds_per_video} - ${overflow_time} + ${rounding_helper}" | bc -l | awk '{printf "%f", $0}')
echo "leftover_time" $leftover_time
ffmpeg -hide_banner -loglevel error -ss "${video_start}" -i "./videos/${file}" -t "${leftover_time}" -c copy -avoid_negative_ts 2 "./cuts/${video_index}.mp4"
echo "file cuts/${video_index}.mp4" >> "./cuts.txt"
video_index=$((${video_index} + 1))
echo "overflow_time" $overflow_time
ffmpeg -hide_banner -loglevel error -ss "0" -i "./videos/${file}" -t "${overflow_time}" -c copy -avoid_negative_ts 2 "./cuts/${video_index}.mp4"
echo "file cuts/${video_index}.mp4" >> "./cuts.txt"
video_index=$((${video_index} + 1))
fi
video_start=$(echo "scale=0; (${video_start} + ${seconds_per_video}) % ${total_seconds_per_video}" | bc -l | awk '{printf "%f", $0}')
done
ffmpeg -hide_banner -loglevel error -f concat -i ./cuts.txt -c copy "${output_video}"
#!/bin/bash
set -euo pipefail
filename_prefix=$1
seconds_per_video_list=$2
for seconds_per_video in ${seconds_per_video_list}
do
./supercut.sh "${filename_prefix} (${seconds_per_video}s per).mp4" "${seconds_per_video}"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment