Easily fix async video with ffmpeg
1. Correcting Audio that is too slow/fast
This can be done using the "-async" switch of ffmpeg which according to the documentation "Stretches/squeezes" the audio stream to match the timestamps. The parameter takes a numeric value for the samples per seconds to enforce.
ffmpeg -async 25 -i input.mpg <encoding options> -r 25
Try slowly increasing the -async value until audio and video matches.
2. Correcting Time-Shift (Variant 1)
Case 1: Audio ahead of video: As a special case the "-async" switch auto-corrects the start of the audio stream when passed as "-async 1". So try running
ffmpeg -async 1 -i input.mpg <encoding options>
Case 2: Audio behind video: Instead of using "-async" you need to use "-vsync" to drop/duplicate frames in the video stream. There are two methods in the manual page "-vsync 1" and "-vsync 2" and an method auto-detection with "-vsync -1". But using "-map" it is possible to specify the stream to sync against.
Interestingly Google shows people using -aync and -vsync together. So it might be worth experimenting a bit to achieve the intended result :-)
3. Correcting Time-Shift (Variant 2)
If you have a constantly shifted sound/video track that the previous fix doesn't work with, but you know the time shift that needs to be corrected, then you can easily fix it with one of the following two commands:
Case 1: Audio ahead of video:
ffmpeg -i input.flv -itsoffset 00:00:03.0 -i input.flv -vcodec copy -acodec copy -map 0:1 -map 1:0 output_shift3s.flv
Case 2: Audio behind video:
ffmpeg -i input.flv -itsoffset 00:00:03.0 -i input.flv -vcodec copy -acodec copy -map 1:0 -map 0:1 output_shift3s.flv
The difference is in the mapping parameters which specify which of the two supplied input files to map on which output channel. The "-itsoffset" option indicates an offset (3 seconds in the example) for the following input file. The input file is required to have exactly one video channel at position 0 and one audio channel at position 1.
I added "-vcodec copy -acodec copy" to avoid reencoding the video and loose quality. These parameters need to be added after the second input file and before the mapping options. Otherwise one runs into mapping errors.
Update: Also check the comment of an anonymous user below mentioning that he needed a different mapping with a more recent version of ffmpeg. The commands above were tested using ffmpeg 0.5/0.6