DEV Community

Javid Jamae
Javid Jamae

Posted on • Originally published at ffmpeg-micro.com

How to Add Subtitles to Video with FFmpeg

Originally published at ffmpeg-micro.com

You need captions on your video. Maybe it's for accessibility, maybe TikTok and Instagram penalize uncaptioned content in their algorithms, or maybe you just want your audience to watch with the sound off. Whatever the reason, you're going to reach for FFmpeg.

And then you'll spend an hour fighting with filter syntax.

Adding Subtitles with FFmpeg CLI

FFmpeg supports two main approaches for burning subtitles into video: the subtitles filter (for SRT/ASS files) and the drawtext filter (for simple text overlays). The subtitles filter is what you want for actual captions.

Assuming you have an SRT file ready, the basic command looks like this:

ffmpeg -i input.mp4 -vf "subtitles=captions.srt" -c:v libx264 -crf 23 -c:a aac output.mp4
Enter fullscreen mode Exit fullscreen mode

That works. But the moment you need to customize font size, color, or positioning, you're writing ASS override tags inside your SRT file or converting to ASS format entirely:

ffmpeg -i input.mp4 -vf "subtitles=captions.srt:force_style='FontSize=24,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,Outline=2'" -c:v libx264 -crf 23 -c:a aac output.mp4
Enter fullscreen mode Exit fullscreen mode

That single line is already hard to read. Add font paths (which differ between Linux, macOS, and Windows), character encoding issues, and the fact that FFmpeg silently fails on malformed SRT files, and you've got a debugging session ahead of you.

If you only need to process a handful of videos on your own machine, the CLI approach is fine. But if you're building a product that captions videos at scale, you don't want this running on your server.

Burning Subtitles via the FFmpeg Micro API

FFmpeg Micro wraps FFmpeg's subtitle capabilities into a REST API. You send your video and subtitle file, specify the filter, and get back a captioned video. No server, no font path issues, no dependency management.

The approach uses the filters field on the /v1/transcodes endpoint. You provide your video and SRT file as inputs, then apply the subtitles filter:

curl -X POST https://api.ffmpeg-micro.com/v1/transcodes \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "inputs": [{"url": "https://storage.example.com/video.mp4"}, {"url": "https://storage.example.com/captions.srt"}], "outputFormat": "mp4", "filters": [{"filter": "subtitles=captions.srt"}] }'
Enter fullscreen mode Exit fullscreen mode

Both files get downloaded and processed together. The subtitles filter references the SRT file by name, and FFmpeg burns the captions directly into the video frames.

Simple Text Overlays Without an SRT File

Sometimes you don't need timed captions. You just need a line of text burned into the video, like a watermark, a title card, or a call-to-action. FFmpeg Micro has a virtual option for that.

The @text-overlay option lets you add styled text without writing any FFmpeg filter syntax:

{
  "inputs": [{"url": "https://storage.example.com/video.mp4"}],
  "outputFormat": "mp4",
  "options": [{
    "option": "@text-overlay",
    "argument": {
      "text": "Subscribe for more tips",
      "style": {"position": "bottom-center", "fontSize": 48, "fontColor": "#FFFFFF", "outlineThickness": 2}
    }
  }]
}
Enter fullscreen mode Exit fullscreen mode

SRT File Format Quick Reference

If you're generating SRT files programmatically, the format is simple:

1
00:00:01,000 --> 00:00:04,000
Welcome to this tutorial.

2
00:00:04,500 --> 00:00:08,000
Today we're covering video captions.
Enter fullscreen mode Exit fullscreen mode

Each block has a sequence number, a timestamp range with comma-separated milliseconds (not periods), and the text. If you're using Whisper, Deepgram, or AssemblyAI, they output SRT directly. Pipe that into FFmpeg Micro and you've got an automated captioning pipeline.

Automating Captions at Scale

A typical automation flow:

  1. Video gets uploaded to your app
  2. Speech-to-text service generates an SRT file
  3. Your backend sends both files to FFmpeg Micro's /v1/transcodes endpoint
  4. Poll for completion or use a webhook
  5. Download the captioned video and serve it to your users

FFmpeg Micro has a free tier, so you can test this entire flow without paying anything. Sign up and grab an API key to try it with your own videos.

Top comments (0)