30 March, 2007

Encoding Flash Videos

One of our clients recently sent us a video that they want to have displayed on their website... and we've decided that the best option would be to use an FLV (Flash Video) file. We're also going to be using the same video format for an upcoming site of our own... one small part of the site will have uploaded videos, so they will need to be automagically converted to FLV. This sounds simple enough, right? Sure, it should be.

Turns out it's not all that simple.

After lots of trial and error, I came up with this command:
mencoder -vf scale=216:144,hqdn3d -af resample=44100:0:2 -hr-edl-seek -ovc lavc -lavcopts vcodec=flv:vqmin=3:v4mv:vmax_b_frames=0:vme=4:vqblur=0.0:tcplx_mask=0.2:mbcmp=6:trell:cbp:naq:dia=2:aic -oac mp3lame -lameopts vbr=2:q=5:aq=0:vol=2:mode=1 -ofps 10 -of lavf -lavfopts format=flv:i_certify_that_my_video_stream_does_not_use_b_frames dvd:// -o test.flv

Finally, I got a decent quality encode, with a decent file size, and not too ridiculous of an encode time... about 45 seconds encoding time for 1 minute of video. This was, however, on an already-busy 1.6GHz Pentium Mobile with 1gb RAM.

Now all I need to do is find another switch or perhaps another command to detect the video resolution and automatically maintain the proper aspect ratio when downscaling it... with that command, I scaled 720x480 down to 216x144 (0.3 times the size), but I had to pull out a calculator and figure out those numbers by myself... that doesn't work with an automated process. Oh well, one step closer at least!

Hell, I could make my own YouTube or Google Videos equivalent with this.... nice!

Okay so, a couple frustrating hours later, I've finally got this down pat. I was getting some very nasty distortion on parts of the video... turns out that was due to the "tcpl_mask" option... according to the mencoder manpage:
Temporal complexity masking (default: 0.0 (disabled)). Imagine a scene with a bird flying across the whole scene; tcplx_mask will raise the quantizers of the bird’s macroblocks (thus decreasing their quality), as the human eye usually does not have time to see all the bird’s details. Be warned that if the masked object stops (e.g. the bird lands) it is likely to look horrible for a short period of time, until the encoder figures out that the object is not moving and needs refined blocks. The saved bits will be spent on other parts of the video, which may increase subjective quality, provided that tcplx_mask is carefully chosen.
In theory, it sounds like a great option. It could potentially add a lot of compression.... in reality, it barely effected the file size at all, and it cause all kinds of headaches. Along the way to finding this, however, I did find some other useful video filters, and I learned a bit more about encoding videos. (I thought for some time that it was possibly interlacing or interleaving that was causing the problems... so I ended up reading up on them, learning exactly how they work and what they do... only to realize there was no way they were guilty). I also managed to find that magic switch to automagically scale the video. I just have to specify one dimension now and it figures out the matching dimension... I love it! So, finally, here is the fully functional, heavily optimized version of that command:

mencoder -vf pp=h1/v1/dr,scale=216:-3,harddup -af resample=44100:0:2 -hr-edl-seek -ovc lavc -lavcopts vcodec=flv:vqmin=3:v4mv:vmax_b_frames=0:vme=4:vqblur=0.0:mbcmp=6:trell:cbp:naq:dia=2:aic -oac mp3lame -lameopts vbr=2:q=5:aq=0:vol=2:mode=1 -ofps 10 -of lavf -lavfopts format=flv:i_certify_that_my_video_stream_does_not_use_b_frames dvd:// -o test.flv

Yay! My work is done here.

No comments: