If you already have an SRT file, here is how each free desktop tool burns it into the video, as of 19 October 2026. In HandBrake, import the SRT on the Subtitles tab and tick Burn In. In VLC, use Media > Convert / Save with Use a subtitle file, then tick Overlay subtitles on the video in the profile's Subtitles tab. With FFmpeg, run one command with the subtitles filter. All three re-encode the video, because the words become part of every frame.
HandBrake is the easiest of the three, FFmpeg gives the most control over font and position, and VLC works but is the fussiest. Exact settings for each are below. If you don't have a subtitle file at all, skip to the last section.
Before you start: hard vs soft subtitles
Burned-in (hard) subtitles are drawn into the picture: they show on every player and can't be switched off. Soft subtitles travel as a separate track or file that viewers turn on. HandBrake's subtitle documentation puts it the same way: a "Hard Burn" writes subtitles on top of the image permanently, while soft subtitles are selectable tracks. Feeds that autoplay on mute are the usual reason to burn in; more on the trade-off in burned-in captions vs closed captions, and on which platforms take a file instead in SRT vs VTT vs TXT.
Check two things in your SRT before burning, because you can't fix them afterwards:
- Encoding. Save it as UTF-8, or accented letters and non-Latin scripts turn into junk.
- Timing. Make sure it matches the final cut. The subtitle sync checker and the subtitle time shift tool work on the file in your browser, and a VTT can be turned into an SRT with the VTT to SRT converter.
Test on 30 seconds first. Burning a long video takes a while, and a wrong encoding or offset only shows up at the end. HandBrake's Preview button encodes a short stretch you choose with its Position and Duration controls, and Live Preview plays it back. In FFmpeg, put -t 30 before the output file name to stop writing after 30 seconds. VLC has no preview step, so check the finished file from start to end. When the test looks right, run the full file.
HandBrake: the Burn In option, step by step
HandBrake is free and open source and runs on Windows, Mac and Linux; version 1.11.2 is the latest on its news page.
- Click Open Source and choose your video.
- Pick a preset. The default Fast 1080p30 suits most uploads. HandBrake names presets for their maximum resolution and frame rate, so this one tops out at 1080p and 30 frames per second; for a 60 fps source, choose another preset or change the frame rate on the Video tab, and check the Dimensions tab on vertical video.
- Open the Subtitles tab and click Tracks. On Windows choose Import Subtitle; on a Mac, Add External Subtitles Track…. Select your .srt file.
- On the new track, set the character code (Char Code on Windows, Encoding on a Mac) to match the file, usually UTF-8. HandBrake's docs warn that the wrong code can leave the output with no subtitle track at all. Add an Offset in milliseconds if everything needs to move.
- Tick Burn In (on a Mac, Burned In). An MP4 can carry only one burned-in track.
- Set Save As and the destination folder, then click Start.
The same job from the command line, using options from HandBrake's command line reference:
HandBrakeCLI -i input.mp4 -o output.mp4 -Z "Fast 1080p30" --srt-file subs.srt --srt-codeset UTF-8 --srt-burn
Keep --srt-codeset UTF-8 for UTF-8 files: without it, HandBrakeCLI assumes the SRT is latin1. For fonts and colors, HandBrake's docs say an ASS subtitle file keeps all its styling when burned in, so convert your SRT to ASS in a subtitle editor and use --ssa-file and --ssa-burn instead.
VLC: Convert / Save with subtitles, and its limits
These labels are from VLC 3.0 on Windows and Linux; 3.0.24 is the current download on videolan.org.
- Open Media > Convert / Save (Ctrl+R).
- On the File tab, click Add... and choose the video.
- Tick Use a subtitle file, click Browse... and choose the SRT. VLC's documentation on subtitles describes this checkbox in the open dialog.
- Click Convert / Save.
- Choose the profile Video - H.264 + MP3 (MP4) and click the wrench icon, Edit selected profile.
- On the Video codec tab, untick Keep original video track: drawing text onto the picture needs the video re-encoded.
- On the Subtitles tab, tick Subtitles and Overlay subtitles on the video, then save the profile.
- Under Destination file, click Browse, give the file a name ending in .mp4, and click Start.
On a Mac, the menu is File > Convert / Stream, and the same Overlay subtitles on the video checkbox sits under Customize > Subtitles.
VLC gives you the fewest controls of the three. The convert window has no font, size or position settings for the burned text, and the default profile turns your audio into MP3. Play the output all the way through before you delete anything, and if the subtitles are missing, check that steps 6 and 7 saved.
FFmpeg: the subtitles filter, fonts and styling
FFmpeg draws subtitles with its subtitles filter, which needs a build made with the libass library. Run this from the folder that holds both files:
ffmpeg -i input.mp4 -vf "subtitles=subs.srt" -c:v libx264 -crf 20 -c:a copy output.mp4
- -vf "subtitles=subs.srt" draws the SRT onto each frame.
- -c:v libx264 -crf 20 re-encodes the video in constant-quality mode. HandBrake's quality guide, which uses the same x264 encoder, says a lower number gives higher quality and recommends 20 to 24 for 1080p video.
- -c:a copy keeps the audio exactly as it was. FFmpeg's documentation explains why only the video needs re-encoding: copying a stream can't apply filters, "since filters work on decoded frames".
To style the text, add force_style, which takes ASS style fields:
ffmpeg -i input.mp4 -vf "subtitles=subs.srt:force_style='Fontname=Arial,Fontsize=24,PrimaryColour=&H0000FFFF,OutlineColour=&H00000000,Outline=2,MarginV=30'" -c:v libx264 -crf 20 -c:a copy output.mp4
That gives yellow Arial text with a black outline, lifted off the bottom edge by MarginV. ASS colors are written alpha first, then blue, green and red, so &H0000FFFF is opaque yellow and &H00FFFFFF is opaque white. BorderStyle=3 puts a box behind the text instead of an outline. Try two or three font sizes on a 30-second test before the full run, since the right size depends on your video's resolution. The field names come from the ASS file format guide on libass's wiki, and the filter options from FFmpeg's filters documentation.
Three more options from the same documentation:
- fontsdir points the filter at a folder of font files, for a font that isn't installed.
- charenc sets the SRT's encoding if it isn't UTF-8.
- shaping=complex is the shaper the documentation says is required for correct rendering of complex scripts such as Arabic, Hebrew, Devanagari and Thai. It needs libass built with HarfBuzz, and the default, auto, already picks the best shaper available.
On Windows, a full path such as C:/Videos/subs.srt clashes with the filter's colon separators, which is why running the command from the folder and using just the file name is the simplest fix.
Which tool for which job
| Checked 19 October 2026 | Where the setting is | Style control | Audio | Runs on |
|---|---|---|---|---|
| HandBrake 1.11.2 | Subtitles tab, Burn In | From an ASS file; none for a plain SRT | AAC stereo in Fast 1080p30 | Windows, Mac, Linux |
| VLC 3.0.24 | Convert / Save, profile's Subtitles tab | None in the convert window | MP3 in the default MP4 profile | Windows, Mac, Linux |
| FFmpeg | subtitles filter | force_style, fonts folder or an ASS file | Copied unchanged with -c:a copy | Windows, Mac, Linux, command line |
No SRT file? Start from the video instead
None of these tools makes subtitles; they only burn a file you already have. If you don't have one, either generate an SRT first with a transcription tool or editor (the free editors in auto subtitles in Kdenlive and Shotcut both export SRT), or skip the file: Route 2 of the online burn guide makes captions straight from the video's speech, and burn subtitles into video online does that in the browser for MP4 or MOV videos up to 10 minutes, with styled captions burned into an MP4. It can't take an existing SRT, so if you have one, use the steps above.
