When you watch a video and the audio is out of sync it can be pretty frustrating. Typically this happens with encoded videos where the audio and video streams are stored separately in the container. Sync issues are not typical in something like DV format where the audio is stored with each video frame.
If you just want to sync up while you are watching just use the VLC player. Depending on the version you could use hot keys. “J” and “K” worked for me. Some people mentioned Control-K and Control-L worked for them. Newer versions should have the Tools > Track Synchronization option which works awesome.
To permanently fix the problem is trickier. I am only writing about Linux solutions. There would of course be many Windows / Mac solutions also.
My video details:
$ avconv -i wl_oos.rmvb 2>&1 | grep -i stream Stream #0.0: Audio: aac, 44100 Hz, stereo, s16, 128 kb/s Stream #0.1: Video: rv40, yuv420p, 1280x692, 1097 kb/s, 23.98 fps, 23.98 tbr, 1k tbn, 1k tbc Stream #0.2: Data:  / 0x0000
1. First I would recommend trying mplayer / mencoder just because it is pretty simple.
Use mplayer and adjust delay till it seems good. Then try to fix with mencoder:
$ mplayer -delay 1.2 wl_oos.rmvb $ mencoder -delay 1.2 -oac copy -ovc copy wl_oos.rmvb -o wl_oos_fixed.rmvb
Depending on your audio and video codecs, above might work for you. However since I had AAC audio above mencoder command did not work for me. I had this error:
$ mencoder -delay 1.2 -oac copy -ovc copy wl_oos.rmvb -o wl_oos_fixed.rmvb ... Audio format 0x4134504d is incompatible with '-oac copy', please try '-oac pcm' instead or use '-fafmttag' to override it
As shown below I also tried converting the audio while adjusting sync but not much luck.
$ mencoder -delay 1.2 -oac lavc -lavcopts acodec=ac3:abitrate=192 -ovc copy wl_oos.rmvb -o wl_oos_fixed.rmvb
2. Next option would be to TRY ffmpeg / libav.
$ avconv -i wl_oos.rmvb -i wl_oos.rmvb 2&>1 | grep -i stream Stream #0.0: Audio: aac, 44100 Hz, stereo, s16, 128 kb/s Stream #0.1: Video: rv40, yuv420p, 1280x692, 1097 kb/s, 23.98 fps, 23.98 tbr, 1k tbn, 1k tbc Stream #0.2: Data:  / 0x0000 Stream #1.0: Audio: aac, 44100 Hz, stereo, s16, 128 kb/s Stream #1.1: Video: rv40, yuv420p, 1280x692, 1097 kb/s, 23.98 fps, 23.98 tbr, 1k tbn, 1k tbc Stream #1.2: Data:  / 0x0000</pre>
You can try just keeping the codecs and convert to a new container like avi and at the same time introducing the offset. Note you need to use the input file twice with this technique and then map the audio and video from the two different inputs. This did not work that good for me either.
$ avconv -i wl_oos.rmvb -itsoffset 1.2 -i wl_oos.rmvb -map 0:1 -map 1:0 -acodec copy -vcodec copy wl_oos_fixed.avi
3. Finally the recipe that worked for me:
You might not need to convert but since my video codec was rv40 I needed to make is something ffmpeg likes better as far as output.
1. Convert the video from rv40 to libx264 and the audio from aac to libvo_aacenc.
$ avconv -i wl_oos.rmvb wl_oos_fixed.mp4
2. Use avidemux open mp4, set video (copy), audio (copy), format mp4 and shift -1200ms. Save to wl_oos_fixed_av.mp4
** This worked for me. However if you have sync issues further in the file, even after you fixed the beginning you probably have Variable Bit Rate (VBR) and might need an entirely different approach. Like for instance splitting audio and video and demuxing with tools. Or stretch/squeeze of audio. There are several tools around but ffmpeg should be able to with the -async or -vsync options.