High Quality MP4 Encode
The commands below are used in the High-Quality Encoding video tutorial
For tutorial simplicity we provide a 2023 version of ffmpeg to get you started, but feel free to get a newer version from their website if you want it.
 
Please note some of the commands below are crossed out but kept for legacy reasons. After much testing I'd advise avoiding the -ss command for shifting audio, since it's very difficult to change the shift later in a reliable fashion using ffmpeg. I provide a script at the bottom of this page that allows you to change the shift of an ss-encoded file with 1ms precision and reliable results.
These commands are examples and not a blind fix-all, it depends on your workflow and you should be visually comparing to your source bluray to make sure the sync is the same when people are talking. You also need to be able to trust your video player - for instance certain versions of VLC like 3.0.18 seem to have bad audio sync, so a portable version of VLC is provided here if you need it (it's also available on the VLC site). If you watch the original bluray mkv and the audio sync seems a little off it's possible it's a bug, be careful, test with another known-good video player.
If in doubt, don't shift your audio during the final encode, you can do it later if you need to and it's best to have an un-shifted file as a base if you're not entirely positive!
Also if you plan to clean your metadata using the mutagen script on the resources page, you may not want to use the -movflags +faststart flag. Adjusting the metadata requires it to write the entire file to disk again if the mov atom is at the front of the file (faststart), so it will take much longer. Although if you want a faststart file you'll just have to soldier through it, since using a second ffmpeg copy pass to add faststart after changing the metadata would also re-add certain values like the ffmpeg encoder name/version which the script cleans up.
 
Final encoding using ffmpeg [90 min file size range]
Nearly lossless [4-10gb]:
for %i in (*.mxf) do ffmpeg -ss 00:00:00.00533 -i "%i" -i "%i" -c:a ac3 -b:a 640k -c:v libx264 -crf 18 -movflags +faststart -map 0:a -map 1:v "%i-AC3-0533-18.mp4"
for %i in (*.mxf) do ffmpeg -i "%i" -i "%i" -c:a ac3 -b:a 640k -c:v libx264 -crf 18 -movflags +faststart -map 0:a -map 1:v "%i-AC3-18.mp4"
Very good quality, reasonable file size (recommended) [2-5gb]:
for %i in (*.mxf) do ffmpeg -ss 00:00:00.00533 -i "%i" -i "%i" -c:a ac3 -b:a 640k -c:v libx264 -crf 21 -movflags +faststart -map 0:a -map 1:v "%i-AC3-0533.mp4"
for %i in (*.mxf) do ffmpeg -i "%i" -i "%i" -c:a ac3 -b:a 640k -c:v libx264 -crf 21 -movflags +faststart -map 0:a -map 1:v "%i-AC3.mp4"
Decent quality, small file size [1.5-3.5gb]:
for %i in (*.mxf) do ffmpeg -ss 00:00:00.00533 -i "%i" -i "%i" -c:a ac3 -b:a 640k -c:v libx264 -crf 23 -movflags +faststart -map 0:a -map 1:v "%i-AC3-0533-23.mp4"
for %i in (*.mxf) do ffmpeg -i "%i" -i "%i" -c:a ac3 -b:a 640k -c:v libx264 -crf 23 -movflags +faststart -map 0:a -map 1:v "%i-AC3-23.mp4"
Low quality, tiny file size [1-1.5gb]:
for %i in (*.mxf) do ffmpeg -ss 00:00:00.00533 -i "%i" -i "%i" -c:a ac3 -b:a 640k -c:v libx264 -crf 28 -movflags +faststart -map 0:a -map 1:v "%i-AC3-0533-28.mp4"
for %i in (*.mxf) do ffmpeg -i "%i" -i "%i" -c:a ac3 -b:a 640k -c:v libx264 -crf 28 -movflags +faststart -map 0:a -map 1:v "%i-AC3-28.mp4"
 
Although it isn't recommended, if you no longer have your mxf file and don't want to regenerate it, you can shift an existing mp4 like this. This also runs much faster than a full encode on an mxf would. These are two different commands, one forward and one back, because the SS command doesn't shift in both directions on a copy re-encode (it pretends it does, but doesn't actually work properly in the negative direction).
Also worth noting that unless you're shifting by Samples in each direction, there's some residual rounding involved to be aware of... so the N00531S command below seems to be the visual approximate opposite of AC3-0533 above, shifting 255 samples instead of the 256 you'd expect. As mentioned in the video tutorial, Samples length in time depends on the audio Sample Rate - so 256 Samples / 48000Hz = 0.005333... (*1000 = 5.333 milliseconds).
But as shown in the tutorial the 5.333 shift isn't precise, so N005336842 below actually seems to be the exact opposite of of AC3-0533 above. With samples you're shifting by a less granular amount so it'll likely always be slightly off, unless you used samples for your original shift as well.
Shift mp4 even further forward:
for %i in (*.mp4) do ffmpeg -ss 00:00:00.00533 -i "%i" -i "%i" -c:a ac3 -b:a 640k -c:v copy -map 0:a -map 1:v "output\%i-mp4shiftE00533.mp4"
Negative shift, opposite of mxf commands above:
for %i in (*.mp4) do ffmpeg -i "%i" -i "%i" -c:a ac3 -b:a 640k -af "adelay=delays=5.336842:all=1" -c:v copy -map 0:a -map 1:v "output\%i-mp4shift3N005336842.mp4"
Negative shift using samples rather than seconds (less precise):
for %i in (*.mp4) do ffmpeg -i "%i" -i "%i" -c:a ac3 -b:a 640k -af "adelay=delays=255S:all=1" -c:v copy -map 0:a -map 1:v "output\%i-mp4shift3N00531S.mp4"
I'm leaving the above commands for reference, but please note that after quite a lot of testing I've found they don't reliably counteract the -ss command, and I can't find a way to do it within ffmpeg. So I made a powershell script that uses the eac3to program along with ffmpeg to extract the audio, re-shift it reliably in any direction and distance you want, and then recombine it with the video. This is at the cost of one lossy audio re-encode as some of the commands above would have been, since you have to convert the audio to high-quality wav and then back to ac3 in order to get granularity better than 32ms (256samples*6, the size of an ac3 audio frame)