Configure Subtitles in HLS Streams Using FFmpeg

This article provides a straightforward guide on how to configure and package subtitle tracks into an HTTP Live Streaming (HLS) feed using FFmpeg. You will learn the essential FFmpeg commands, codec requirements, and stream mapping configurations needed to deliver multi-language WebVTT subtitles alongside your video and audio streams.


Understanding HLS Subtitles

HLS streams deliver subtitles using the WebVTT (Web Video Text Tracks) format. Instead of embedding subtitles directly into the video frame (hardcoding), HLS serves them as separate text tracks. This allows viewers to toggle subtitles on or off and select their preferred language directly from the media player.

To configure this in FFmpeg, you must convert your subtitle files (such as .srt) into WebVTT format and map them correctly inside the HLS master playlist (.m3u8).


The FFmpeg Command

Below is the standard FFmpeg command used to package a video file and two separate subtitle tracks (English and Spanish) into an HLS stream:

ffmpeg -i input.mp4 -i subtitle_en.srt -i subtitle_es.srt \
-map 0:v:0 -map 0:a:0 -map 1:s:0 -map 2:s:0 \
-c:v copy -c:a copy -c:s webvtt \
-f hls \
-hls_time 10 \
-hls_playlist_type vod \
-master_pl_name master.m3u8 \
-var_stream_map "v:0,a:0 s:0,language:eng,name:English s:1,language:spa,name:Spanish" \
output_%v.m3u8

Command Breakdown

Here is what each parameter does to configure the subtitle tracks:

  • -i input.mp4 -i subtitle_en.srt -i subtitle_es.srt: Defines the input sources. Input 0 is the video/audio, Input 1 is the English subtitle, and Input 2 is the Spanish subtitle.
  • -map options: Maps specific streams from the inputs to the output.
    • 0:v:0 maps the first video stream.
    • 0:a:0 maps the first audio stream.
    • 1:s:0 maps the first subtitle stream from the English SRT.
    • 2:s:0 maps the first subtitle stream from the Spanish SRT.
  • -c:s webvtt: Instructs FFmpeg to transcode the input subtitle formats (e.g., SRT) into the HLS-compatible webvtt format.
  • -f hls: Specifies the output format as HLS.
  • -master_pl_name master.m3u8: Generates a master playlist that links the video, audio, and subtitle tracks together.
  • -var_stream_map: This is the crucial setting that groups the streams.
    • v:0,a:0 links the first video and audio streams together.
    • s:0,language:eng,name:English defines the first subtitle stream (s:0), assigns it the ISO 639-2 language code (eng), and names it "English" for the player's menu.
    • s:1,language:spa,name:Spanish defines the second subtitle stream (s:1), assigns it the language code (spa), and names it "Spanish".
  • output_%v.m3u8: The naming template for the variant playlist files.

Verifying the Output

Once the command finishes running, FFmpeg will generate the following files:

  • master.m3u8 (The main playlist file containing references to all streams)
  • output_0.m3u8 (The video and audio playlist)
  • output_1.m3u8 (The English subtitle playlist)
  • output_2.m3u8 (The Spanish subtitle playlist)
  • Multiple .ts segments for video/audio, and .vtt segments for the subtitles.

When you load the master.m3u8 file into an HLS-compatible player (like Safari, VLC, or hls.js), the player will recognize the English and Spanish subtitle tracks and display them as options in the subtitle selection menu.