Blog-Archiv

Freitag, 25. März 2022

Scroll Text Over Image with ffmpeg

Here is how to create a video that scrolls a multiline text over an image. You need to have the open source tool ffmpeg installed on your machine to do that. On WINDOWS, you also need some UNIX shell execution environment like CygWin.

Text and Image

Create a text file where you put your text into. All line breaks will be preserved. You should restrict your line length to about 36 characters, so that the text fits into the video's pixel width. You can also control this with the font size, but mind that you need a really big font to be readable on mobiles, too.

Then find an image that fits to your text.

Video by Script

Here is a script that creates a video from your text and image files, calculating the video's length from the number of text lines:

  • scrollTextOverImage.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
###################################################
# Creates a video where text scrolls over an image.
###################################################

syntax() {
	echo "SYNTAX: $0 imageFile textFile videoFile" >&2
	echo "	Scrolls text over image, result is a video." >&2
	exit 1
}

imageFile="$1"
textFile="$2"
videoFile="$3"

[ -f "$imageFile" -a -f "$textFile" ] || syntax
[ -z "$videoFile" ] && syntax

# calculate duration of video by number of text lines
numberOfLines=`wc -l <"\$textFile"`
videoSeconds=`awk 'BEGIN { print 12 + ('\$numberOfLines' + 1) * 1.5 }'`

echo "Generating $videoFile that scrolls $textFile over $imageFile, lasting $videoSeconds seconds ...." >&2

# escape percent sign, it would make ffmpeg fail
rm -f replaced.txt
sed 's/%/\\%/g' <$textFile >replaced.txt

ffmpeg -y -v error -loop 1 \
	-i "$imageFile" \
	-vf drawtext="\
		fontsize = 70:\
		fontcolor = white:\
		borderw = 7:\
		bordercolor = black:\
		line_spacing = 60:\
		textfile = \'replaced.txt\':\
		x = (w - text_w) / 2:\
		y = h - 80 * t" \
	-t $videoSeconds "$videoFile"

rm -f replaced.txt

Lines 5 to 16 define the call syntax of the script, pick up the incoming parameters and check them. Line 15 exits with syntax output when one of image or text are not existing files, line 16 when the target video file name was not given.

Line 19 finds out the number of lines inside the text file. This is the base for calculating the video length in seconds, done on line 20. Lines * 5 / 2 is equal to a multiplication with 2.5, expr does integer operations only. Asterisk '*' is a meta-character for the UNIX shell, so we need to escape it by a backslash '\'. Mind that this hardcoded factor 5 / 2 is bound to the scroll speed, and the video dimension 1920 x 1080!

So, where is the scroll speed? Lines 28 to 39 are the execution of ffmpeg. The scroll speed is the "80" on line 38. If you change this to 120, it will scroll faster, but mind that then the video will be longer than the scrolling lasts.

Following is about what happens starting from line 28. The trailing backslashes are useful to bring this very long command line into a readable shape.

The -y option on line 28 will overwrite any existing target file without getting interactive. The -v error option reduces control output to error messages.

Line 29 defines the input image via the -i option. The "quotes" are there for file names that contain spaces.

The -vf option on line 30 starts a filter-operation with name "drawtext". Its parameterization continues down to line 34, using colon ':' separators.

Line 31 gives you the text's font size. Here you can make the letters bigger and smaller. Mind that this will affect the video's length.

Lines 32 to 34 define letters to be white, with a black outline, so that it is readable over both dark and bright background images.

Line spacing on line 35 gives the distance between lines. Also this will affect the video's length.

Line 36 contains the name of the text file. It is enclosed in 'single quotes' to enable file names that contain spaces. The quotes are escaped by backslashes to hide it from the shell, else the $textFile shell variable there would not be substituted.

Lines 37 and 38 define the coordinates for the text.
The horizontal x coordinate on line 37 is defined to center the text (zero is left). The variables w and text_w are provided by ffmpeg, giving the width of the video, and the ready-calculated maximum width of the text.
Line 38 is the vertical scroll effect in y direction (zero is bottom). The variables h and t are provided by ffmpeg, giving the height and the current timestamp of the video. That means the longer the video lasts, the higher the text will move. 80 is the (hardcoded) scroll speed factor.

Line 39 finally declares the length of the generated video via the -t option, and names the output file as last command argument.

Call this script with image, text file and output video file as command line arguments. It will generate a video that scrolls the given text over the given image.

Resume

This script is just an approximation, because it contains hardcoded values. More care should be taken to calculate parameters for the ffmpeg call. Number of text lines, font size, line spacing, video heigth, scroll speed, all of these should go into the calculation of the video length.

In my next Blog I will introduce a script that can create a video out of a sequence of several background images with associated text files.




Keine Kommentare: