Add Subtitles to Video
Burn an SRT or WebVTT caption track into a durable video output. Run the preset directly on this page or call the same agent-ready endpoint from your product.
Prefer the shell? Add subtitles to a video with FFmpeg, the verified FFmpeg command for this edit.
See what the tool changes.
A real example: the after side is the unedited output of a KinoPipe job. Run the live form above to generate the same result from your own media.
Demo footage: public-domain timelapses (Bureau of Land Management, Oregon · NASA SVS). Processed by the same pipeline the API and MCP tools call.
Useful defaults, typed options.
The tool slug stays stable while your agent supplies named media inputs and a narrow set of documented options.
- SRT and WebVTT inputs
- Readable safe-area defaults
- Consistent rendering
- 01Validate the caption file
- 02Apply a readable style
- 03Render captions into frames
- 04Encode the final MP4
POST /api/v1/tools/add-subtitles-to-videoThe command this runs
ffmpeg -i input.mp4 -vf "subtitles=filename=captions.srt" -c:v libx264 -preset medium -crf 23 -c:a aac -b:a 160k -movflags +faststart output.mp4- subtitles=filename=captions.srt
- Hands the file to libass, which draws each cue onto the frames at the times the file gives. SRT and WebVTT both work. The path goes inside the filter string, which is why a filename with a colon or an apostrophe in it needs escaping and is a common way to lose twenty minutes.
- -c:v libx264
- A re-encode, and there is no way around it. The captions become part of the picture, so every frame that carries one has to be drawn again. Any tutorial promising burned-in subtitles with -c copy is describing something else.
- -c:s mov_text
- The other thing people mean by "add subtitles", and not what this does. That muxes a track the player can switch off, keeps the video stream untouched, and is invisible on most social feeds. Different job, different flag.
Where the caption file comes from
If you already have one, pass its URL as the captions input and you are done. If you do not, transcribe_video returns one: its second output is a finished SRT, and that download URL goes straight into this tool without a step in between.
The transcription runs on our own hardware rather than an outside API, using Parakeet-TDT 0.6B v3, which covers 25 European languages, detects the language itself and produces punctuation and word-level timings.
What this will not do
It will not let the viewer turn them off, translate them, or choose a language. One burn, one language, forever.
It will not style them. No font, no size, no colour, no position: you get what libass does by default. If the look matters more than the ship date, burn them somewhere else for now.
It will not fix a caption file whose timings drift. Burning is faithful to the file, so a transcript that runs half a second late produces a video whose subtitles run half a second late.
Doing it yourself
The command is one line and it works. What this saves you is the pairing: transcribe, take the SRT, burn it, and get back a URL, without a caption file ever touching your disk or your agent having to know that the path lives inside a filter string.
Know the boundaries before you run.
About burn subtitles
Related media tools
Add a Watermark to Video
Overlay a logo or watermark image with controlled position, size and opacity.
ExploreCreate a Social Video Clip
Cut and reframe a source video for Shorts, Reels or vertical social feeds.
ExploreCompress Video for Web
Reduce video file size while preserving a crisp, web-ready image.
Explore