Understanding the Root Cause of Timing Drift
The primary reason for seeking issues and audio-video drift during muxing is the interaction between Variable Frame Rate (VFR) sources and the container's expectation of Constant Frame Rate (CFR). When you encode video with x264, especially from a screen capture or camera source, the encoder may produce frames at irregular intervals. If this VFR stream is muxed directly into an MP4 or MKV container alongside AC3 audio without conversion, the player struggles to calculate the correct position for each frame.
Additionally, AC3 audio has a fixed sample rate, typically 48kHz. If your source audio is at 44.1kHz or another rate, and you do not resample it, the timestamps will not align perfectly with the video frames over time. This misalignment accumulates, leading to noticeable sync errors, particularly after several minutes of playback or when jumping to specific chapters.
Converting Video to Constant Frame Rate
To resolve the most common timing issues, you must force the video stream to be Constant Frame Rate before muxing. This ensures that every frame occupies the exact same amount of time, allowing the player to seek accurately based on simple time offsets rather than complex frame-level timestamps.
- Identify your source: Check if your input video is VFR by running
ffprobe -v error -select_streams v:0 -show_entries stream=avg_frame_rate,nb_read_frames. If the frame rate varies or is reported as "variable," you need to convert it. - Apply the
fpsfilter: Use the-vf fps=fps=30(or your target frame rate) flag in your ffmpeg command. This filters the video stream, dropping or duplicating frames as necessary to maintain a steady clock. - Verify the output: After encoding, check the new stream properties to confirm the frame rate is now constant.
This step is critical because it decouples the visual timing from the erratic nature of the source material. For more detailed guidance on handling VFR inputs, you might find our guide on converting VFR to CFR helpful, which covers additional edge cases like timestamp resetting. See FFMPEG: How to convert VFR to CFR without messing up the timing.
Aligning Audio Sample Rates for AC3
AC3 is a standard audio codec that expects a specific sample rate, usually 48,000 Hz. If your source audio is PCM or AAC at 44,100 Hz, simply copying it (-c:a copy) will cause drift. You must resample the audio to match the video's temporal grid.
- Use the
-arflag: Add-ar 48000to your ffmpeg command to force the audio output to 48kHz. - Ensure AC3 encoding: Specify
-c:a ac3to ensure the codec is set correctly. Some containers prefer AC3 over E-AC3 for compatibility, so sticking to standard AC3 avoids potential parser issues in older players. - Handle multiple streams: If you have multiple audio tracks, ensure they are all resampled consistently. Inconsistent sample rates between tracks can also cause seeking glitches in some media players.
By standardizing the audio sample rate, you guarantee that the number of audio samples per second matches the expected duration of the video frames, preventing the gradual drift that plagues many muxing operations.
Optimizing Muxing Flags for Seekability
Even with correct frame rates and sample rates, the way ffmpeg writes the final container metadata affects how quickly and accurately a player can seek. Using the right muxer flags ensures that index data is written correctly.
- Use
-movflags +faststart: This is essential for MP4 files. It moves the metadata (moov atom) to the beginning of the file, allowing players to parse headers immediately without downloading the entire file first. This significantly improves seeking performance in web-based players. - Set
-fflags +genpts: This flag forces ffmpeg to generate missing presentation timestamps. In complex muxing scenarios, especially when combining streams from different sources, timestamps can sometimes be lost or out of order. This flag regenerates them based on the input durations. - Avoid
-copytsunless necessary: While copying timestamps preserves the original timeline, it often carries over the VFR issues mentioned earlier. Letting ffmpeg recalculate timestamps based on the new CFR video stream is usually safer for seeking.
If you are dealing with subtitle streams alongside your audio and video, ensuring they are synchronized requires similar attention to timing. Our article on keeping English subtitles while converting audio provides useful context for managing multi-stream synchronization. Check out How to Copy Video, Covert All Audio Streams to AC3, and Only Keep Subtitles in English Using FFmpeg.
Complete Command Example
Here is a robust command structure that addresses these issues. Adjust the input paths and frame rates as needed for your specific project.
ffmpeg -i input_video.mp4 -i input_audio.wav \
-vf fps=fps=30 -c:v libx264 -preset fast -crf 23 \
-ar 48000 -c:a ac3 -b:a 192k \
-movflags +faststart \
-fflags +genpts \
output_final.mp4
This command forces the video to 30fps, resamples audio to 48kHz, encodes AC3 at 192kbps, and optimizes the container for fast starting and accurate seeking. Always test the output with a media player that supports seeking, such as VLC or MPC-HC, to verify that no drift occurs over long durations.
Frequently Asked Questions
Why does my video still drift after using fps=30?
If drift persists, check your audio sample rate; it must be exactly 48kHz for AC3. Also, ensure you are not using -copyts, which preserves potentially broken timestamps from the source. Regenerating timestamps with -fflags +genpts usually resolves remaining issues.
Can I use E-AC3 instead of AC3 for better quality?
Yes, E-AC3 (Dolby Digital Plus) offers better efficiency and quality, but it requires more modern hardware and software support. If you are targeting older devices or strict broadcast standards, stick to standard AC3. Ensure your muxer supports E-AC3 if you choose this path.
How do I fix seeking issues in HTML5 video players?
HTML5 players rely heavily on the moov atom position. Always use -movflags +faststart for MP4 files. Additionally, ensure the video is CFR, as VFR can confuse browser-based decoders. Test with Chrome and Firefox separately, as their implementations differ slightly.
What if my source audio is already 48kHz?
If the source is already 48kHz, you can skip the -ar 48000 flag, but it is safe to leave it in. However, always verify the codec; if the source is AAC, you must re-encode to AC3 using -c:a ac3 regardless of the sample rate.
Does changing frame rate affect video quality?
Using the fps filter may drop or duplicate frames to achieve the target rate, which can introduce minor artifacts. However, this is preferable to the severe sync issues caused by VFR. For minimal quality loss, use a high-quality preset like -preset slow and appropriate CRF values.