Create Low-Latency fMP4 with FFmpeg

This article explains how to generate a fragmented MP4 (fMP4) file optimized for low-latency streaming using FFmpeg. You will learn the essential FFmpeg flags, encoder settings, and command-line examples required to split your MP4 container into real-time playable chunks, reducing playback delay for HLS, DASH, and CMAF workflows.

Understanding fMP4 and Low Latency

Standard MP4 files contain a single metadata block called the moov atom, which is typically written at the end of the file. This structure requires players to download the entire metadata block before playback can begin, making it unsuitable for live or low-latency streaming.

Fragmented MP4 (fMP4) solves this by dividing the video into a sequence of very short, self-contained segments (fragments). Each fragment consists of a track fragment header (moof) and media data (mdat). This allows the player to start rendering video as soon as the first tiny fragment is received.

Key FFmpeg Flags for fMP4 Generation

To write an fMP4 file, you must use FFmpeg’s -movflags option to alter the default behavior of the MP4 muxer. The most important flags include:

Optimizing Encoder Settings for Low Latency

Enabling fMP4 is only half the battle. To achieve true low-latency, you must also configure the video encoder to generate frequent keyframes and avoid buffering frames.

  1. Set a Short GOP (Group of Pictures) Size: Use the -g flag to force a keyframe at strict intervals (e.g., every 1 or 2 seconds). If your input frame rate is 30 fps, set -g 30 or -g 60.
  2. Disable Scene Cut Detection: Set -sc_threshold 0 to prevent the encoder from inserting extra, unexpected keyframes that disrupt fragment uniformity.
  3. Use Low-Latency Tuning: For the libx264 or libx265 encoders, use the -tune zerolatency flag to disable frame reordering (B-frames) and ensure frames are outputted immediately.

Step-by-Step FFmpeg Command

Below is the optimized FFmpeg command to convert an incoming live RTSP stream, webcam feed, or standard video file into a low-latency fMP4 stream:

ffmpeg -re -i input.mp4 \
  -c:v libx264 -preset ultrafast -tune zerolatency \
  -g 30 -keyint_min 30 -sc_threshold 0 \
  -c:a aac -b:a 128k \
  -f mp4 \
  -movflags empty_moov+frag_keyframe+default_base_moof+omit_tfhd_offset \
  output.mp4

Command Breakdown:

How to Verify Your fMP4 File

You can verify if your output file is correctly fragmented using ffprobe. Run the following command:

ffprobe -v trace output.mp4 2>&1 | grep -E "moof|mdat"

If the file is successfully fragmented, the output will show alternating moof and mdat boxes repeating throughout the file, confirming that your low-latency fMP4 structure is intact and ready for chunk-based delivery.