Skip to content

Instantly share code, notes, and snippets.

@rkaravia
Created January 1, 2023 19:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rkaravia/c1c8f2746be8f4c27e7fc93ad78673c2 to your computer and use it in GitHub Desktop.
Save rkaravia/c1c8f2746be8f4c27e7fc93ad78673c2 to your computer and use it in GitHub Desktop.
#!/bin/bash
if [ $# == 0 ]
then
cat <<EOF
Usage: $0 VIDEO_FILE
Adds an intermission in the middle of a video.
Needs youtube-dl, ffmpeg, and ffprobe in order to work.
EOF
exit
fi
CONCAT_LIST_FILE="concat_list_file.tmp"
# See https://stackoverflow.com/questions/687014/removing-created-temp-files-in-unexpected-bash-exit
trap 'rm -- "$CONCAT_LIST_FILE" part_1.mp4 part_2.mp4' EXIT
if [ ! -f intermission.mp4 ]
then
youtube-dl --output intermission --format 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/mp4' https://www.youtube.com/watch?v=O0wOD9TWynM
fi
TOTAL_DURATION=600
INPUT_DURATION=`ffprobe -v error -select_streams v:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 intermission.mp4`
FILLER_DURATION=`echo $TOTAL_DURATION - 2 \* $INPUT_DURATION | bc`
if [ ! -f intermission_black_filler.mp4 ]
then
# "-video_track_timescale 30k" is required to match tbn of intermission.mp4
ffmpeg -f lavfi -i color=size=1920x1080:rate=29.97:color=black -t $FILLER_DURATION -video_track_timescale 30k intermission_black_filler.mp4
fi
if [ ! -f intermission_10min.mp4 ]
then
cat > "$CONCAT_LIST_FILE" <<EOF
file intermission.mp4
file intermission_black_filler.mp4
file intermission.mp4
EOF
FADE_OUT_AFTER=25
FADE_IN_AFTER=`echo $TOTAL_DURATION - 60 | bc`
ffmpeg -f concat -i "$CONCAT_LIST_FILE" -af "afade=enable='between(t,0,$FADE_IN_AFTER)':t=out:st=$FADE_OUT_AFTER:d=5,afade=enable='between(t,$FADE_IN_AFTER,$TOTAL_DURATION)':t=in:st=$FADE_IN_AFTER:d=5" -c:v copy intermission_10min.mp4
fi
INVERSE_TBC=`ffprobe -v 0 -of compact=p=0:nk=1 -show_entries stream=time_base -select_streams v:0 "$1"`
TBC=`cut -d / -f2 <<< "$INVERSE_TBC"`
FRAMERATE=`ffprobe -v error -select_streams v -of default=noprint_wrappers=1:nokey=1 -show_entries stream=r_frame_rate "$1"`
SAMPLE_RATE=`ffprobe -v error -select_streams a -of default=noprint_wrappers=1:nokey=1 -show_entries stream=sample_rate "$1"`
FULL_DURATION=`ffprobe -v error -select_streams v:0 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1 "$1"`
HALF_DURATION=`echo $FULL_DURATION / 2 + 10 | bc`
START_PART_2=`echo $FULL_DURATION - $HALF_DURATION | bc`
RED='\033[0;31m'
NC='\033[0m'
echo -e "${RED}Part 1: 0 to $HALF_DURATION. Part 2: $START_PART_2 to $FULL_DURATION${NC}"
ffmpeg -ss 0 -i "$1" -c copy -t $HALF_DURATION part_1.mp4
ffmpeg -y -i intermission_10min.mp4 -r $FRAMERATE -video_track_timescale $TBC -ar $SAMPLE_RATE intermission_match_timebase.mp4
ffmpeg -ss $START_PART_2 -i "$1" -c copy -t $HALF_DURATION part_2.mp4
cat > "$CONCAT_LIST_FILE" <<EOF
file part_1.mp4
file intermission_match_timebase.mp4
file part_2.mp4
EOF
ffmpeg -f concat -safe 0 -i "$CONCAT_LIST_FILE" -c copy movie_with_intermission.mp4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment