To burn multiple SRT subtitle tracks into a video using ffmpeg, you must use the -filter_complex option with distinct filter chains for each subtitle. Each chain starts by selecting the video stream as the primary input and then applies the subtitles= filter with the correct file path. This approach ensures that subtitles are rendered directly onto the video frames rather than being treated as separate streams.
Understanding the Filter Complex Structure
The core challenge when burning in multiple subtitles is that thesubtitles filter expects a video stream as its input, not another subtitle stream. A common mistake is attempting to chain subtitle filters together or referencing subtitle streams incorrectly. Instead, you need to create parallel processing paths within the -filter_complex argument.
Each path must begin with the main video stream from your source file. You can label this input stream as [0:v] if it is the first input. Then, for each subtitle track you wish to burn, you apply a separate subtitles= filter. The output of one subtitle filter becomes the input for the next, allowing you to stack them. However, it is often cleaner to treat them as independent layers if they do not overlap significantly, but standard practice involves chaining them sequentially on the same video base.
This method differs from simply adding subtitles as soft tracks. When you burn them in, they become part of the video pixels. This is essential for compatibility with players that do not support external subtitle files or specific codec containers. If you need to manage which subtitles are kept or removed before burning, you might look at guides on removing unwanted subtitle streams to clean up your source file first.
Selecting the Correct Inputs
Before constructing the command, identify your input files. Assume your video file isinput.mp4 and your subtitle files are en.srt, es.srt, and fr.srt. In ffmpeg, inputs are indexed starting from 0. Therefore:
0refers toinput.mp41refers toen.srt2refers toes.srt3refers tofr.srt
subtitles filter does not take a filename directly in the filter definition string in the way you might expect. You must specify the file path inside the filter options. The filter syntax looks like subtitles='filename=srt_file'. Note that single quotes are required around the entire filter option string to prevent shell interpretation issues.
Constructing the Command Step-by-Step
To combine these elements, we build the-filter_complex string. We start by labeling the video stream. Let's call the initial video stream [v0].
ffmpeg -i input.mp4 -i en.srt -i es.srt -i fr.srt -filter_complex "[0:v]subtitles='filename=en.srt'[v1]; [v1]subtitles='filename=es.srt'[v2]; [v2]subtitles='filename=fr.srt'[v3]" -map "[v3]" -c:v libx264 -c:a copy output.mp4
Let's break down this command structure. The -filter_complex argument contains three distinct filter chains separated by semicolons.
- First Chain:
[0:v]subtitles='filename=en.srt'[v1]takes the video from the first input (0:v) and burns the English subtitles, outputting to label[v1]. - Second Chain:
[v1]subtitles='filename=es.srt'[v2]takes the result of the first chain ([v1]) and burns the Spanish subtitles, outputting to[v2]. - Third Chain:
[v2]subtitles='filename=fr.srt'[v3]takes the result of the second chain ([v2]) and burns the French subtitles, outputting to[v3].
[v3] to the output. We also re-encode the video using libx264 because burning subtitles changes the pixel data, requiring a new encoding pass. Audio is copied directly using -c:a copy to preserve quality and save time.
If you encounter unexpected output when adding multiple subtitles, such as only one appearing or errors regarding stream indexing, ensure that your file paths are relative to where you run the command or use absolute paths. Also, verify that your ffmpeg version supports the subtitles filter with the filename option, which is standard in modern builds. For more details on handling multiple subtitle streams in MP4 containers, see resources on adding multiple English subtitles to an MP4 file.
Handling Overlapping Subtitles
When burning multiple subtitle tracks simultaneously, positioning is key. By default, ffmpeg places subtitles at the bottom center of the frame. If you have two languages displayed at the same time, they will overlap and become unreadable. To fix this, you can use theforce_style option within the subtitles filter.
For example, to move the Spanish subtitles higher, you could modify the second filter:
[v1]subtitles='filename=es.srt:force_style=Position=50%[v2]'
Adjust the Position value to suit your layout needs. This allows you to stack languages vertically without them clashing. Remember that style changes are applied per filter instance, so you can customize each language independently.
Verification and Troubleshooting
After running the command, play the output file in a media player that supports hard-coded subtitles. Check that all three languages appear at their respective timestamps. If a subtitle track is missing, verify the file path in thefilename argument. Common errors include typos in the .srt extension or incorrect quotation marks.
Additionally, be aware that burning subtitles increases the file size slightly due to the re-encoding process. If performance is a concern, consider using a faster preset like -preset fast instead of slow. For users who need to convert audio formats while keeping these burned subtitles, you can extend the command to include audio conversion filters, similar to workflows used for converting AC3 audio streams.
Frequently Asked Questions
Can I burn subtitles without re-encoding the video?
No, burning subtitles modifies the video pixels, which requires a full re-encoding pass. You cannot achieve this with a simple stream copy. This is why-c:v libx264 (or another encoder) is mandatory in the command.
What if my SRT files have different encodings?
Ensure all SRT files are UTF-8 encoded for best compatibility. If your subtitles contain special characters that appear as boxes or question marks, convert the SRT files to UTF-8 before running the ffmpeg command.How do I change the font size of the burned subtitles?
Use theforce_style option in the subtitles filter. For example, add :force_style=FontSize=24 to the filter string to increase the text size. You can also adjust font family and color using this parameter.
Why are my subtitles not showing up in some players?
Hard-coded subtitles should work everywhere since they are part of the video image. If they don't show, check if the video resolution or aspect ratio is causing clipping. Ensure the subtitles are positioned within the safe area of the video frame.Can I add logo overlays along with multiple subtitles?
Yes, you can chain additional filters likedrawtext or overlay within the same -filter_complex string. Just ensure each filter receives the correct input label from the previous step in the chain.