You can kill the background for speed, if you wish.[x]

Monday, September 29, 2008

My Video Rotation Adventures

So recently, I've been brushing up on my bash-fu. That is to say, learning it. Because although I have been passingly familiar with the command line on Linux (I run Ubuntu pretty much full-time on my laptop), I didn't know any fancy bash stuff. It started the other day when I had to mass rename some files (as part of another adventure in something that slips my mind at the moment), and I use some bash looping to do it.

Well, now I had an AVI to rotate. I had initially planned on using something like Kino or Pitivi, but I could only find rotation in Kino (under the oddly-named "composite" transition effect), and besides, Kino barfed trying to import my AVI, and ffmpeg would only export probably every hundredth frame to DV. So I decided to work on my bash-fu.

The video was one where my dad rotated the camera partway through the video. I initially planned on using something like VirtualDubMod to export the frames that are rotated, and rotating them manually with GIMP, and splicing it back together, but nothing exciting was happening before he rotated it, so I just decided to start after he had rotated the camera fully. I selected that section with AVIDemux, which is more or less the Linux equivalent of VirtualDubMod. I selected the portion of video I wanted and went File->Save->Save Selection as JPEG Images, named them "sequence", and put them in a folder ("ToRotate"). After some quick googling, I found a post that pointed me to ImageMagick. I installed it with a quick

sudo apt-get install imagemagick
and was on my way. Rotating them was easy (I love the command line for this), with
mogrify -rotate 90 *.jpg
. If you want to see the filenames flash by, you can add a
as well, as it's nice to see that it's actually doing something while rotating 3500 frames.

After that, it was a matter of putting them back together and adding the sound back in. For the former, I tried ImageMagick's

, but after it either died (with the unhelpful error message of "Killed") or barfed on mpeg2encode, I found a bug report that pointed me to the ffmpeg syntax for the same thing. This, however, required the numbers to be not zero-padded, which AVIDemux did. However, with my mass-renaming under my belt, I did a little loop as follows:

counter=0;for i in $( ls sequence*.jpg ); do mv $i frame$counter.jpg; echo $counter; let counter+=1; done

Which just went through and renamed sequence0000.jpg to frame0.jpg and so on. I changed the prefix to preempt any existing file collisions. Once I did that, I could use

ffmpeg -i frame%d.jpg rotated.avi
to re-create the video. It was also noticeably faster than ImageMagick, by the way.

The final step, adding the sound back in, was also a job for ffmpeg. For this, though, I resorted to the excellent FFMPEG GUI that I use to convert videos for my Sansa e260, WinFF, which despite its name is very cross-platform. I once again chopped out the part of the AVI I wanted with AVIDemux, but this time saved it as

, and then with WinFF converted it to Audio (mp3). I then was able to use AVIDemux to open the rotated video and replace the audio by going to Audio->Main Track, selecting "External mp3," and selecting the mp3 I had created with WinFF. I also had to change the framerate (Video->Framerate) from 25 to 30 fps, since ffmpeg evidently didn't agree with AVIDemux on how many FPS it should be, so the audio was too short for my clip. Perhaps this could have been tweaked on either end (ffmpeg or AVIDemux), but I'm not too worried. Changing it in AVIDemux the second time around worked fine.

My video was finally happily rotated, ready to go on Facebook, and I had learned some more bash/linux-fu. I probably could have found a program that would have just rotated it for me, but really...what's the fun in that?

1 comment:

Mathis Dirksen-Thedens said...

Indeed, this is a bit complicated. For the next rotate action, to save time, you can use:

mencoder -of avi -oac copy -ovc lavc -vf rotate=1 -o output.avi input.avi

The parameter rotate=1 means clockwise, rotate=2 would do the same but counterclockwise...