How to set background to subtitle in ffmpeg?
Asked Answered
E

5

22

It is described here how ot burn a srt file into a video. However, I want to put a semi-transparent background to the subtitles so that the texts can be read more easily. How can I do that?

Experimentalize answered 16/9, 2014 at 13:30 Comment(0)
H
41

Using ASS subtitles to create opaque text background

ASS subtitles can have a semi-transparent background for the text.

With aegisub

The easiest way to do this is with aegisub.

enter image description here

  1. Open your subtitles file with aegisub.
  2. Click SubtitleStyles manager.
  3. Under Current Script choose Default, then press the Edit button.
  4. Experiment with the Outline and Shadow values. Check Opaque box.
  5. Under Colors click the color under Outline or Shadows. A window will appear. Adjust the value of the Alpha box to change transparency.
  6. Save the subtitles as an .ass file.

Now you can use the AAS file to make hardsubs or softsubs with ffmpeg.

Without aegisub

If you want hardsubs you can use the subtitles filter to add the transparent background with the force_style option.

ffmpeg -i input -filter_complex "subtitles=subs.ass:force_style='OutlineColour=&H80000000,BorderStyle=3,Outline=1,Shadow=0,MarginV=20'" output
  • This will work with any text based subtitles supported by FFmpeg because the filter will automatically convert them to ASS.

  • See SubStation Alpha (ASS) style fields for formatting options.

Issue with multiple lines

If your subtitles contains multiple lines, due to auto-wrapping of long lines or an intentional line break, the backgrounds will overlap and potentially look ugly as shown below:

enter image description here

You can avoid this by:

  1. Changing the Outline and Shadow sizes to 0.
  2. The alpha settings of the shadow will control the transparency of the background box. Click on the shadow color to adjust the Alpha of the shadow color to your desired transparency level.
  3. Edit the ASS file in a text editor. In the Style line change the value corresponding with BorderStyle to 4. This will fill the bounding box background of each subtitle event. Example Style line:

    Style: Default,Arial,20,&H00FFFFFF,&H000000FF,&H80000000,&H80000000,-1,0,0,0,100,100,0,0,4,0,0,2,10,10,10,1
    

Example:

enter image description here

Note that BorderStyle=4 is a non-standard value, so it may not work properly in all players.

Thanks to sup and wm4 for the BorderStyle suggestion.

Using drawbox

The drawbox filter can be used to create a background box. This may be useful if you want the box to span the width.

enter image description here

ffmpeg -i input -filter_complex "drawbox=w=iw:h=24:y=ih-28:t=max:[email protected],subtitles=subs.ass" output

Downside is that you have to account for line breaks or word wrapping for long subtitles. Simply making the box taller to compensate will suffice, but will look ugly because the subtitles baseline remains static: the single line subtitles will have more padding on the top than the bottom.

Homemaker answered 16/9, 2014 at 23:37 Comment(16)
This leaves a nasty line in there in case of two-line subtitles. Is there a way to ged rid if it?Weihs
@Weihs Not that I know of. An alternative method would be to make a static, transparent box using the drawbox filter, but that is not idea either.Homemaker
@LordNeckbeard man you saved my life! That's perfect! Works like a charm!! No need of adobe encore, adobe premiere and all that stuff paid that's unable to do such a simple stuff like this!Ruvalcaba
@eusoubrasileiro Good to hear. Just be aware of the "multiple lines may overlap and look ugly" issue. IIRC, it's a problem with libass. There's a bug report about it somewhere.Homemaker
@LordNeckbeard the issue could be resolved if the leading of the lines was adjustable in Aegisub. But I couldn't find a way to do this.Kaine
@LordNeckbeard This was super helpful! Thank you! (Now only if Aegisub would fix the ugly translucent overlap problem...)Sacrum
@LordNeckbeard Any idea where that bug report might be?Weihs
@Weihs If I recall correctly it was on the Aegisub Bug Tracker, but it's currently down.Homemaker
@LordNeckbeard I asked at the forums: forum.aegisub.org/viewtopic.php?t=85495 and they sent me to libass developemnt, so I filed a new bug: github.com/libass/libass/issues/268Weihs
@LordNeckbeard Actually, setting BorderStyle=4 fixes the issue (see the Github issue I opened), would you please update your answer? It only works with libass though.Weihs
@Weihs Updated. Thanks for the hint.Homemaker
@lordNeckbeard The solution with borderstyle=4 has a problem that one cannot set margins to the box. I found a hack how to do that in and posted it on the upstream tracker: github.com/libass/libass/issues/268 - though I have not scripted it yet. But that way, letters like "y" do not get displayed outside of the semi-transparent box.Weihs
Hm, so with libass github.com/libass/libass/releases/tag/0.13.7 and later, one can indeed just adjust border size and margins are respected, sweet! I was on too old software.Weihs
@LordNeckbeard That would have been impractical, T at the beginning of aline also had this problem. But as I said, with version 0.13.7 of libass, one can set the margin.Weihs
here after adjusting, using: Style: Transparent,PingFang SC,20,&H00FFFFFF,&H000000FF,&HBC5E5E5E,&H8B000000,0,0,0,0,100,100,0,0,3,0,1,2,10,10,10,134 to implement the half transparent background subtitle. Thanks.Halmstad
@Homemaker Your ffmpeg command has BorderStyle=3 among the filtering options. What do you think about just replacing it with BorderStyle=4 in those filtering options, instead of having to edit the .ass file and putting that option inside that file? Would this solve the multiple line subtitles issue according to you?Miguel
D
4

Create a png with a transparent box and a alpha channel in your favoured size. You can use e.g. gimp or photoshop.

Then use this command:

ffmpeg -i video.mp4 -i logo.png -filter_complex "[0:v][1:v]overlay=10:10" \
-codec:a copy out.mp4

where 10:10 is the distance from the upper left corner.

After that you can insert your subtitles.

Doordie answered 16/9, 2014 at 16:6 Comment(1)
If you want to do this "make a separate background box" method it would be easier and more efficient to just use the drawbox filter. Also, using filters, such as overlay or drawbox, will require re-encoding of the video, but using ASS subtitles for softsubs as shown in my answer will not modify the video.Homemaker
B
3
ffmpeg -i input.mp4 -filter_complex "subtitles=input.srt:force_style='BackColour=&H80000000,BorderStyle=4,Fontsize=11'" output.mp4

BackColour=&H80000000 means having a %50 opaque black background.

Its a hex representation of color, AABBGGRR.

Bimolecular answered 8/10, 2020 at 0:45 Comment(1)
Where do I get color numbers like 'H80000000'. Can't I say "red, green, black,... and so on"?Sydelle
A
1

With the current version of libass (0.15) and the current version of ffmpeg (N-100402-g0320dab265, compiled from source, probably the same as version 4.2), you can use this bash script

INFILE="movie.mp4"
SUBS="subtitles.srt"
OUTFILE="result.mp4"
ffmpeg -i "${INFILE}" -vf subtitles=${SUBS}:force_style='Borderstyle=4,Fontsize=16,BackColour=&H80000000'" "${OUTFILE}"

to burn subtitles.srt into movie.mp4 and save it as result.mp4.

The subtitles will appear correctly boxed in a 50% transparent rectangle, even when there are 2 lines in a subtitle.

Agoraphobia answered 13/12, 2020 at 1:3 Comment(0)
C
0

You can use this Aegisub script. This script automatically generate transparent background for every line of subtitle.

Subtitle transparent background

Closeknit answered 17/11, 2017 at 0:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.