MpegFlowBlogBack to home
← Recipes·Burn captions·video operations

Burn captions / subtitles into video with FFmpeg

Hard-code SRT or ASS subtitles into the video frames. When sidecar VTT isn't supported, when archival requires baked-in captions, or when the player can't handle subtitle tracks.

ByMpegFlow Engineering Team·FFmpeg recipe
·3 variants·May 9, 2026

When to use this

Burn captions into video when you need the captions to be part of the video pixels — typical cases: legacy player compatibility (no sidecar VTT support), broadcast archival (captions must survive any future re-encode), social-media-style autoplay captions, or accessibility compliance where the captions can't be turned off. The trade-off: burned-in captions can't be turned off or translated at the player; you commit to one language and one styling. For modern web/OTT, sidecar VTT is almost always preferable.

Command variants

Burn SRT subtitles (default styling)
ffmpeg -i input.mp4 \
  -vf "subtitles=captions.srt" \
  -c:a copy \
  output.mp4

Simplest case. Default SRT rendering: white text on transparent background, bottom-center.

Burn with custom styling
ffmpeg -i input.mp4 \
  -vf "subtitles=captions.srt:force_style='FontName=Arial,FontSize=18,PrimaryColour=&Hffffff,BackColour=&H80000000,BorderStyle=4,Outline=1,Shadow=0,MarginV=20'" \
  -c:a copy \
  output.mp4

Use ASS-style force_style overrides. BackColour with alpha gives a translucent box.

Burn ASS subtitles (already styled)
ffmpeg -i input.mp4 \
  -vf "ass=captions.ass" \
  -c:a copy \
  output.mp4

When the .ass file already contains the styling. Useful for broadcast-grade caption files.

What each parameter does

  • -vf "subtitles=..."

    Video filter that renders subtitles into frames. Path must be accessible to FFmpeg; absolute paths are safer than relative.

  • force_style

    Override SRT rendering with ASS-style parameters. The most common SRT styling lever — controls font, color, position, background.

  • BackColour with alpha

    &H80000000 = 50% transparent black box behind text. Improves readability on busy backgrounds.

  • BorderStyle=4

    Solid box around text vs simple outline. 1=outline, 3=opaque box, 4=transparent box.

  • -c:a copy

    Stream-copy audio. The video filter requires re-encode of video, but audio passes through unchanged.

What this outputs

A re-encoded video file with captions baked into the pixels. File size and quality depend on the encoder settings (defaults to libx264 medium-preset). Captions are visually permanent — you cannot extract them or turn them off after this point.

Pitfalls

  1. Subtitle file path issues: FFmpeg's subtitle filter is finicky about paths. Use absolute paths and escape any special characters (e.g., \: for colons in paths).
  2. Encoding gets slow: burning subtitles re-encodes video. Stream-copy is impossible. Plan for libx264 medium-preset speeds, not faster.
  3. Default SRT styling is often illegible on mobile — too small, no background. Always use force_style for production.
  4. Right-to-left languages (Arabic, Hebrew) need special handling. ASS files handle RTL properly; SRT alone often doesn't.
  5. Time alignment drift: if captions.srt was generated at a different framerate than the input video, captions may drift over long durations. Verify with a 5-minute clip first.
  6. Once burned, captions can't be turned off, translated, or styled. Make this trade-off deliberately.

At production scale

Caption burning is libx264-bound at production scale. NVENC GPU encoding works but renders subtitles in the GPU pipeline, which sometimes produces subtle anti-aliasing differences from CPU rendering. For accessibility-compliant burned captions in broadcast workflows, stick with libx264 + ASS-styled captions for predictable rendering. At >100K minutes/month with burned captions as a standard step, the encoding cost roughly doubles vs sidecar-VTT delivery; budget accordingly.

How MpegFlow handles this

MpegFlow models caption burning as a dedicated DAG stage that runs after the main encode. This lets you skip burning when the customer's player supports sidecar VTT (saving compute), and run it conditionally when the delivery platform requires baked-in captions.

Topics
  • FFmpeg
  • captions
  • subtitles
  • video-operations
  • accessibility
  • Broadcast
See also
  • Architecture
    Broadcast Grade Vod Transcoding
  • Recipe
    Extract Audio From Video
Running this at scale?

Get the orchestration layer for free.

The burn captions command above is the easy part. The queue, retries, audit trail, encoder-version pinning, and multi-tenant security around it are what every video team rebuilds from scratch. We did the rebuild — design partners run it free during beta.

Apply More recipes
© 2026 MpegFlow, Inc. · Trust & complianceAll systems nominal·StatusPrivacy