Saturday, January 5, 2013

Linux : Creating a Video Countdown

I had some videos that I was trying to alter, and I needed a "countdown" of about 15 seconds based on one of the frames from the video.  I ended up doing a lot of hacks, but finally pinned it down to the following steps.
 
First, you need to extract the audio chunk that you want to use, and edit it to the exact time you would like.  You can use Audacity to edit the sound to how you want it, fading in and out, etc, but if you want to start with an autio chunk from the video you are using, you can extract it doing :

 mplayer -dumpaudio -dumpfile audio_track.mp3 video_to_extract_from.avi

 lame --decode audio_track.mp3  audio_track.wav

The first one extracts into an MP3 file, the second one converts that to a .WAV file (Audacity in my case wasn't compiled with MP3 support).

Next, you need to choose your background.  You should use one with the same dimensions as the video you are attaching it to, so you might want to extract each frame from the video and choose one of those.  For example :

ffmpeg -i video_to_extract_from.avi frame%8d.jpg

Once done, you need to pick the frame you wanted.  I found it, and then renamed it to "base_image.jpg".  After that, you can create the countdown frames using the following (may have to tweak everything to get the countdown into the right place, and the colors right):

FRAME_BACKGROUND='base_image.jpg';TOTAL_SECONDS=15;FPS=29.97;STROKE_WIDTH=2;STROKE_COLOR='#18FF';TEXT_COLOR=white;RECTANGLE_FILL='#000C';RECTANGLE_POSITION=400,200,650,400;TIME_POINTSIZE=32;POSITION_TIME=+485+325;BREAK_TEXT_SIZE=24;POSITION_BREAK_TEXT=+439+241;FRAMES=`echo "$TOTAL_SECONDS * $FPS"|bc`;for FRAME in `seq -w 1 $FRAMES`; do TIME=`perl -e "print sprintf('%02.1f','$TOTAL_SECONDS' - ('$FRAME' * '$TOTAL_SECONDS' / '$FRAMES'))"`;convert $FRAME_BACKGROUND -fill $RECTANGLE_FILL -draw "rectangle $RECTANGLE_POSITION" -stroke $STROKE_COLOR -strokewidth $STROKE_WIDTH -pointsize $BREAK_TEXT_SIZE -annotate $POSITION_BREAK_TEXT 'Break Ends In:' -stroke none -fill $TEXT_COLOR -pointsize $BREAK_TEXT_SIZE -annotate $POSITION_BREAK_TEXT 'Break Ends In:' -stroke $STROKE_COLOR -strokewidth $STROKE_WIDTH -pointsize $TIME_POINTSIZE -annotate $POSITION_TIME "$TIME secs" -stroke none -fill $TEXT_COLOR -pointsize $TIME_POINTSIZE -annotate $POSITION_TIME "$TIME secs" image$FRAME.jpg; done

This will generate the new frames.  Next, you need to combine them into one video using :

ffmpeg -r 30 -f image2 -i image%03d.jpg -i ../track.wav video.avi

You may have to tweak the process to get it just the way you like, but it should work.

No comments:

Post a Comment