As derobert mentioned you can do the whole thing in mencoder, which uses the ffmpeg libraries itself, and is much more powerful, this will avoid the transcoding that you are currently doing. The -audio-delay option in mencoder sets an offset for the audio relative to the video, if the offset difference is absolute. You could also try different -autosync settings (the default value is 0, up to 30 is mentioned in the manual).
Get yourself a copy of FFmpeg. See the bottom of this post on how to do that.
Whether the video lags behind the audio or vice-versa, it doesn't really matter. The basic command is as follows. We will pass the input twice, as can be seen by two -i
options, then delay one input, and merge them back together.
ffmpeg -i in.flv -itsoffset offset -i in.flv -map 1:0 -map 0:1 -c copy out.flv
Here, offset
is the delay in seconds, e.g. 1.5
or 0.35
. This value has to be positive, so if your audio is lagging behind the video, we will have to offset the video. This is shown in the above example. Similarly, if the video is lagging behind the audio, we will have to offset the audio.
So, how do you choose whether to delay audio or video? Well, since we've delayed the whole in.flv
, we'll just pick the audio or video streams and merge them with the original audio or video streams. This is done in the -map
options.
Basically, map
has two numbers. The one before the colon specifies the input file number (starting at 0), and the second number specifies the input file stream (also starting at 0).
So, to delay the audio, use the following two options:
-map 1:0
means: Take the first stream from the second input file, (video from the original file)
-map 0:1
means: Take the second stream from the first input file (audio from the delayed file)
Turn it around if you have to delay your video:
-map 0:0
means: Take the first stream from the first input file (video from the delayed file)
-map 1:1
means: Take the second stream from the second input file (audio from the original file)
Finally -c copy
will simply tell FFmpeg to copy the video and audio bitstreams. This means that there will be no encoding process. This makes the command ultra-fast and you won't even lose any quality in the process. If, however, you run into synchronization errors, then you should leave out -c copy
and let FFmpeg re-encode the input.
You can get the latest stable FFmpeg version through Homebrew.
Open a Terminal and enter:
ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)"
See the installation requirements as well. You have to install the Commandline Tools for Xcode if you haven't. You will need an Apple ID for that.
Once Homebrew is installed, install FFmpeg:
brew install ffmpeg
Once that is done, we can use FFmpeg to fix your video.
Best Answer
EDIT: These instructions apply for VirtualDub v1.8.11 and VLC v1.1.9.
VirtualDub is definitely the correct choice of program for AVI files. I'll walk you through it.
Run VirtualDub by going to the folder where you saved it and running VirtualDub.exe.
Head to File > Open Video File, and select the AVI file from the file browser, and select Open.
Next, go to the Video drop-down menu, and select Direct Stream Copy (we don't want to re-encode what will be an already pretty poor quality stream).
Next, go to the Audio drop-down menu, and select Direct Stream Copy (with the same rationale as above).
Next, go to Audio > Interleaving. This will bring up a dialog box. Note the box with the label Delay audio track by...
Change the value in this box. If you want to get a good idea of what value to change it to, either keep changing it in VirtualDub and checking the result, or do it in VLC. You can change the audio timings on the fly in VLC by playing the video and then hitting J to reduce the audio offset, and K to increase it. Note the value where they appear to sync up, and then use that in VirtualDub. If you can't get them close enough, you can get more finely-grained control by, still in VLC, going to Tools > Track Synchronization. You can then adjust Advance of audio over video until you sync them up, and then use that value in VirtualDub.
Once done, go to File > Save as AVI, and enter the name you want for the file.