pastebin

Private paste #67863: Shell script to concatentate mpg videos with fade-to-black transitions

#!/bin/bash

declare -a MOVIE_FRAMES

if [ -z "`echo $@`" ]; then
	cat << EOF

Usage:
        $0 input1.mpg input2.mpg [...]

The following environmental variables matter:
        FADE_FRAMES        The number of frames to fade on
                             each side of each splice
                             [DEFAULT=50]
        BLACK_PICTURE_FILE The filename of your all-black
                             image file.
                             [DEFAULT="black.png"]
	OUTPUT_FILE        The output filename.
                             [DEFAULT="output.mpg"]

Caveats:
        This script makes no attempt to make sure that
        your input files are '.mpg', that they have the
        same frame rate, that they are the same size, or any-
        thing else. You *must* do this yourself. You will
        need ffmpeg patched with the pip vhook filter for
        this to work. You will also need to a solid still
        image file with the same dimensions as your videos (see
        BLACK_PICTURE_FILE above). JPG, PNG, GIF and probably
        some other formats are fine. You should probably
        rewrite all of this, especially the text processing on
	line 57.
EOF
exit
fi

if [ -z "$BLACK_PICTURE_FILE" ]; then
	BLACK_PICTURE_FILE="black.png"
fi

if [ -z "$FADE_FRAMES" ]; then
	FADE_FRAMES=50
fi

if [ -z "$OUTPUT_FILE" ]; then
	OUTPUT_FILE="output.mpg"
fi

COUNT=1

cat << EOF


 Determining number of frames each input movie.
 This could take some time. The only way to count
 the frames is to read the entire file, transcoding
 the video is a slow but convenient way to do this
 from a shell script. It would probably be easy to
 write a frame counter with libavcodec or libavfilter.


EOF

#Get the lengths and frame rates of the movies using ffmpeg
for movie in $@; do
	ffmpeg -i $movie -qscale 255 temp_testlength.mpg 2> temp_testlength
	MOVIE_FRAMES[$COUNT]=`echo \`cat temp_testlength | tr "\015" "\012" | grep frame= | tail -n 1 | cut -d = -f 2 | cut -d 'f' -f 1\``
	rm -f temp_testlength.mpg
	COUNT=$(($COUNT+1))
done

rm -f temp_testlength

COUNT=1

#Make one big movie
cat $@ > temp_movie.mpg

COUNT=1
TOTAL_FRAMES=0

#We need to build our command into a string because we don't know how many vhooks we'll need
FFMPEG_COMMAND="ffmpeg -i temp_movie.mpg "

#Insert the transitions into the ffmpeg command
for movie in $@; do
	FFMPEG_COMMAND="$FFMPEG_COMMAND -vhook '/usr/lib/vhook/pip.so -f "$BLACK_PICTURE_FILE" -t FFFFFF -x 0 -y 0 -s $((${MOVIE_FRAMES[$COUNT]}+$TOTAL_FRAMES-$FADE_FRAMES)) -e $((${MOVIE_FRAMES[$COUNT]}+$TOTAL_FRAMES+$FADE_FRAMES)) -d $FADE_FRAMES -m 0' "
	TOTAL_FRAMES=$(($TOTAL_FRAMES+${MOVIE_FRAMES[$COUNT]}))
done

FFMPEG_COMMAND="$FFMPEG_COMMAND -sameq \"$OUTPUT_FILE\""

echo Here\'s the command we\'re running:
echo
echo $FFMPEG_COMMAND
echo
echo

#Run the command!
bash -c "$FFMPEG_COMMAND"

if [ "$?" -eq 0 ]; then
	echo
	echo Success! Output file is: $OUTPUT_FILE
	echo
else
	echo
	echo Failure. ffmpeg could not create video.
	echo
fi

rm -f temp_movie.mpg

Private
Wrap long lines

2 + 5 =