Burn 29.97 FPS Drop-Frame Timecode in FFmpeg
This article explains how to burn a dynamic SMPTE drop-frame timecode
overlay into a 29.97 frames-per-second video using FFmpeg's
drawtext video filter. It covers the precise command-line
syntax required to ensure proper drop-frame synchronization, explains
the essential parameters, and shows how to customize the visual
appearance and placement of the overlay on your output file.
The Basic Command
To burn a drop-frame timecode starting at 01:00:00;00,
run the following command:
ffmpeg -i input.mp4 -vf "drawtext=fontfile=/path/to/font.ttf:timecode='01\:00\:00\;00':rate=30000/1001:x=(w-text_w)/2:y=h-th-50:fontsize=48:fontcolor=white:box=1:boxcolor=black@0.6:boxborderw=5" -c:a copy output.mp4Key Parameters Explained
Drop-Frame Semicolon Syntax (
timecode='01\:00\:00\;00') In SMPTE standard notation, a semicolon (;) or period (.) preceding the frame number denotes drop-frame timecode. FFmpeg detects the semicolon delimiter to trigger drop-frame counting logic, where frame numbers 00 and 01 are skipped at the start of every minute, except every tenth minute. Colons and semicolons inside the filter must be escaped with a backslash (\) to avoid parsing errors.Accurate Frame Rate (
rate=30000/1001) Always define the exact fractional rate30000/1001instead of using the rounded value29.97. Using29.97can introduce drift over long runtimes because true NTSC frame rates are mathematically fractional.Font Specification (
fontfile=/path/to/font.ttf) FFmpeg requires a valid TrueType or OpenType font to generate the text. Replace/path/to/font.ttfwith an actual path on your system (e.g.,/Windows/Fonts/arial.ttfon Windows or/System/Library/Fonts/Helvetica.ttcon macOS). For timecodes, monospaced fonts such as Courier or Roboto Mono are recommended to prevent horizontal jitter as numbers change.Positioning (
xandy)x=(w-text_w)/2: Horizontally centers the overlay.y=h-th-50: Positions the timecode 50 pixels from the bottom of the video frame.
Background Box (
box,boxcolor,boxborderw)box=1: Enables a rectangular background behind the timecode to ensure legibility against bright backgrounds.boxcolor=black@0.6: Sets the background to black with 60% opacity.boxborderw=5: Adds 5 pixels of padding around the text.
Reading Timecode from Source Metadata
If your source file already contains an embedded SMPTE timecode track
and you want to display that original value rather than a manually typed
starting point, use the timecode_rate parameter combined
with the internal metadata reader:
ffmpeg -i input.mov -vf "drawtext=fontfile=/path/to/font.ttf:text='%{pts\:hms}':rate=30000/1001:x=(w-text_w)/2:y=h-th-50:fontsize=48:fontcolor=white:box=1:boxcolor=black@0.6" -c:a copy output.movAlternatively, if you want to pull the native metadata timecode tag
into the drawtext filter directly:
ffmpeg -i input.mov -vf "drawtext=fontfile=/path/to/font.ttf:timecode='00\:00\:00\;00':rate=30000/1001:x=50:y=50:fontsize=36:fontcolor=yellow" -c:v libx264 -crf 18 -c:a copy output.mp4Encoding Considerations
- Re-encoding: Burning visual text onto video frames
requires re-encoding the video stream (
-c:v libx264or another supported encoder). It cannot be done using-c:v copy. - Audio Preservation: Use
-c:a copyto pass through the existing audio stream without re-encoding or introducing audio-sync offsets.