44

I would like to create a video consisting of some text. The video will only be 0.5 seconds long. The background should just be some colour, I am able to create such video from a photo, but cant find anywhere how this could be done without a photo, just using text to create such video.

Nakilon
  • 34,866
  • 14
  • 107
  • 142
kalafun
  • 3,512
  • 6
  • 35
  • 49

1 Answers1

97

drawtext vs subtitles

This can be done using the drawtext or subtitles filters.

drawtext is simpler, but subtitles has much better styling and timing options. subtitles can automatically wrap the text while drawtext cannot.


drawtext filter examples

Add text to solid color background

enter image description here

Using the color filter for the background and the drawtext filter for the text. Example for a 320x240, 10 second, 25 fps, blue background. Text is size 30, colored white, and centered.

ffmpeg -f lavfi -i color=size=320x240:duration=10:rate=25:color=blue -vf "drawtext=fontfile=/path/to/font.ttf:fontsize=30:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2:text='Stack Overflow'" output.mp4

With audio file

Same as above, but video will automatically match audio duration by removing duration=10 and adding -shortest:

ffmpeg -f lavfi -i color=size=320x240:rate=25:color=blue -i audio.m4a -vf "drawtext=fontfile=/path/to/font.ttf:fontsize=30:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2:text='Stack Overflow'" -c:a copy -shortest output.mp4

With a transparent box behind text

Another example with a white box behind the text at 25% opacity with 5 pixel padding:

enter image description here

ffmpeg -f lavfi -i color=c=red:s=320x240:d=10 -vf "drawtext=fontfile=/path/to/font.ttf:fontsize=30:box=1:boxborderw=5:boxcolor=white@0.25:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2:text='Stack Overflow'" output.mp4

Multiple lines

enter image description here enter image description here
It's easier to center the two lines with multiple drawtext instances (left image). Right image is from the external file and line break examples.

There are 3 methods. You can chain together two drawtext filters, or reference an external text file with the textfile option, or add the line break in the command.

Alternatively, see the example below using the subtitles filter. This filter will automatically wrap long text.

Method 1: Multiple drawtext instances

ffmpeg -f lavfi -i color=c=green:s=320x240:d=10 -vf "drawtext=fontfile=/path/to/font.ttf:fontsize=30:fontcolor=white:x=(w-text_w)/2:y=(h-text_h-text_h)/2:text='Stack',drawtext=fontfile=/path/to/font.ttf:fontsize=30:fontcolor=white:x=(w-text_w)/2:y=(h+text_h)/2:text='Overflow'" output.mp4

Method 2: External text file

The contents of the text file, text.txt, looks like this:

Stack
Overflow

The ffmpeg command:

ffmpeg -f lavfi -i color=c=green:s=320x240:d=0.5 -vf "drawtext=fontfile=/path/to/font.ttf:fontsize=30:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2:textfile=text.txt" output.mp4

Method 3: Line break in command

ffmpeg -f lavfi -i color=c=green:s=320x240:d=0.5 -vf "drawtext=fontfile=/path/to/font.ttf:fontsize=30:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2:text='Stack
Overflow'" output.mp4

Positions

  • Top left: x=0:y=0 (with 10 pixel padding x=10:y=10)
  • Top center: x=(w-text_w)/2:y=0 (with 10 px padding x=(w-text_w)/2:y=10)
  • Top right: x=w-tw:y=0 (with 10 px padding: x=w-tw-10:y=10)
  • Centered: x=(w-text_w)/2:y=(h-text_h)/2
  • Bottom left: x=0:y=h-th (with 10 px padding: x=10:y=h-th-10)
  • Bottom center: x=(w-text_w)/2:y=h-th (with 10 px padding: x=(w-text_w)/2:y=h-th-10)
  • Bottom right: x=w-tw:y=h-th (with 10 px padding: x=w-tw-10:y=h-th-10)

subtitles filter example with audio

Using the color filter for the background and the subtitles filter for the text.

First, create SRT (SubRip) file. This example sets the duration to 10 hours. The duration doesn't really matter: it just needs to be longer than the audio file duration.

1
00:00:00,000 --> 10:00:00,000
Stack Overflow

Then run ffmpeg:

ffmpeg -f lavfi -i color=size=256x144:rate=15:color=blue -i "Audio File.m4a" -vf "subtitles=subtitles.srt:force_style='Alignment=10,Fontsize=30'" -c:a copy -movflags +faststart -shortest output.mp4
  • Alternatively, use Aegisub to create ASS (Advanced SubStation Alpha) subtitles and you won't have to use force_style. Downside is that ASS is a much more complicated format than SRT.

  • If you want to use force_style refer to the Format and Style lines in an ASS file to get an idea of how to use more force_style options, and also see Aegisub Manual - Ass Tags for advanced formatting.


Output image instead of video

If you want an image output instead replace output.mp4 with -frames:v 1 output.png.

llogan
  • 121,796
  • 28
  • 232
  • 243
  • just to add that you can get a solid from from hex code like: color=c=0xff0000 – nicruo Mar 28 '16 at 15:00
  • 1
    @nicruo That's probably worth mentioning. I added a link to the list of supported color names which also contains info on hex usage. – llogan Mar 28 '16 at 18:19
  • But how do you put two texts in there? – ethanjyx Dec 01 '16 at 23:02
  • 1
    @ethanjyx I just added three examples to place multiple lines of text. – llogan Dec 01 '16 at 23:49
  • I exactly need this command to be executed in android. Would you mind providing full code to execute in android here. – Dila Gurung May 09 '17 at 10:24
  • @DilaGurung I have no Android experience, but the command should look similar except you may have to remove any quotes. – llogan May 09 '17 at 20:33
  • Suppose I want to add style..how would i specify it. ":style=Bold:" is not working in my case. – Dila Gurung May 23 '17 at 19:52
  • @DilaGurung That requires your ffmpeg to be built with `--enable-libfontconfig`. Otherwise, consider using [subtitles](https://ffmpeg.org/ffmpeg-filters.html#subtitles) instead of drawtext. – llogan May 23 '17 at 22:54
  • 2
    For any others using this method to `concat` with other videos, be sure to [add an empty audio track](https://stackoverflow.com/questions/12368151/adding-silent-audio-in-ffmpeg) or your output will have no audio. – Hendy May 04 '18 at 04:54
  • Awesome! But how do I add an image to this video? Or better, maybe 2 image, one first half, second video second half, the text all the time? – tobidude Apr 27 '20 at 14:06
  • @tobidude See [How to add watermark with ffmpeg?](https://stackoverflow.com/a/10920872/) and see the [`enable` option](https://ffmpeg.org/ffmpeg-filters.html#Timeline-editing) (see [more examples](https://stackoverflow.com/search?q=%5Bffmpeg%5D+overlay+enable+is%3Aanswer)). – llogan Apr 27 '20 at 17:23
  • Great examples, is it possible that we use dynamic text for subtitles or using drawtext to wrap text according to video width and height? I have asked a question [here](https://stackoverflow.com/questions/70936224/ffmpeg-add-subtitles-to-live-stream-dynamically) but I did not get any answers yet. – Muhammad Feb 01 '22 at 11:40
  • How do I create text with transparent background and save it as png? – Ricardo Bohner Mar 06 '22 at 18:47
  • The correct link to ass tags: https://aegisite.vercel.app/docs/latest/ass_tags/ @llogan Please edit in the post. I am not able to do that. – Ashark May 02 '23 at 19:19