ffmpeg provides the straight and easy way to burn-in SRT subtitle. By forece_style, you can customize your subtitle format like font, fontsize,outline,outlinecolor,borderstyle and so on. The disadvantage of burnt-in caption is that can make bad TV experience for those who does not want to see the subtitle on top of the screen. On the contrary, the benefit of the burnt-in subitie is that doesn't require any additional technical tools/modules on the client.

ffmpeg -i test_30sec.mov -vf "format=yuv240p, fps=30, subtitles=subtitle_en.srt:force_style='fontsize=25,Outline=2,OutlineColor=&H80000000'" out.mp4

Its result will be like below:


If you want to put dark block behind of the subtitle, you can do it easily by adding BorderStyle=4 like below:

ffmpeg -i test_30sec.mov -vf "format=yuv240p, fps=30, subtitles=subtitle_en.srt:force_style='fontsize=25,BorderStyle=4,Outline=8,OutlineColor=&H80000000'" out.mp4


Below is an example for HLS with burnt-in subtitles

ffmpeg -fflags +genpts -hide_banner -re -y -i "test_30sec.mov" \
        -map 0:v:0 -map 0:a:0 \
        -map 0:v:0 -map 0:a:0 \
        -map 0:v:0 -map 0:a:0 \
        -map 0:v:0 -map 0:a:0 \
        -map 0:v:0 -map 0:a:0 \
        -map 0:v:0 -map 0:a:0 \
        -c:v libx264 -profile:v main -x264opts no-scenecut -crf 18 -sc_threshold 0 -g 6 -keyint_min 6 -c:a aac -ar 48000 \
        -c:s mov_text \
        -filter:v:0 "scale=iw*sar*min(1920/(iw*sar)\,1080/ih):ih*min(1920/(iw*sar)\,1080/ih),pad=1920:1080:(ow-iw)/2:(oh-ih)/2,format=yuv420p,fps=30" -b:v:0 8M -maxrate:v:0 10M -minrate:v:0 6M -bufsize:v:0 8.5M -b:a:0 192k -vf "subtitles=subtitle_en.srt:force_style='fontsize=25,Outline=2,OutlineColor=&H80000000'" -muxdelay 0 -muxpreload 0 \
        -filter:v:1 "scale=iw*sar*min(1280/(iw*sar)\,720/ih):ih*min(1280/(iw*sar)\,720/ih),pad=1280:720:(ow-iw)/2:(oh-ih)/2,format=yuv420p,fps=30" -b:v:1 3M -maxrate:v:1 5M -minrate:v:1 4M -bufsize:v:1 6M -b:a:1 128k -vf "subtitles=subtitle_en.srt:force_style='fontsize=25,Outline=2,OutlineColor=&H80000000'" -muxdelay 0 -muxpreload 0 \
        -filter:v:2 "scale=iw*sar*min(960/(iw*sar)\,540/ih):ih*min(960/(iw*sar)\,540/ih),pad=960:540:(ow-iw)/2:(oh-ih)/2,format=yuv420p,fps=30" -b:v:2 2.5M -maxrate:v:2 2.8M -minrate:v:2 2.2M -bufsize:v:2 5M -b:a:2 128k -vf "subtitles=subtitle_en.srt:force_style='fontsize=25,Outline=2,OutlineColor=&H80000000'" -muxdelay 0 -muxpreload 0 \
        -filter:v:3 "scale=iw*sar*min(720/(iw*sar)\,406/ih):ih*min(720/(iw*sar)\,406/ih),pad=720:406:(ow-iw)/2:(oh-ih)/2,format=yuv420p,fps=30" -b:v:3 2M -maxrate:v:3 2.3M -minrate:v:3 1.8M -bufsize:v:3 4M -b:a:3 128k -vf "subtitles=subtitle_en.srt:force_style='fontsize=25,Outline=2,OutlineColor=&H80000000'" -muxdelay 0 -muxpreload 0 \
        -filter:v:4 "scale=iw*sar*min(640/(iw*sar)\,360/ih):ih*min(640/(iw*sar)\,360/ih),pad=640:360:(ow-iw)/2:(oh-ih)/2,format=yuv420p,fps=30" -b:v:4 1.5M -maxrate:v:4 1.8M -minrate:v:4 1.3M -bufsize:v:4 3M -b:a:4 128k -vf "subtitles=subtitle_en.srt:force_style='fontsize=25,Outline=2,OutlineColor=&H80000000'" -muxdelay 0 -muxpreload 0 \
        -filter:v:5 "scale=iw*sar*min(480/(iw*sar)\,270/ih):ih*min(480/(iw*sar)\,270/ih),pad=480:270:(ow-iw)/2:(oh-ih)/2,format=yuv420p,fps=30" -b:v:5 800K -maxrate:v:5 900K -minrate:v:5 600K -bufsize:v:5 1600K -b:a:5 96k -vf "subtitles=subtitle_en.srt:force_style='fontsize=25,Outline=2,OutlineColor=&H80000000'" -muxdelay 0 -muxpreload 0 \
        -var_stream_map "v:0,a:0 v:1,a:1 v:2,a:2 v:3,a:3 v:4,a:4 v:5,a:5" \
        -hls_time 5 -start_number 0 -hls_list_size 0 \
        -master_pl_name "hls-manifest.m3u8" \
        -hls_segment_filename sub%v-ts%004d.ts sub%v-ts.m3u8