11

I am using FFmpeg to read in a series of single images and output them as a video.
The result is a timelapse of screenshots of a website in 1 minute intervals.

Now I would like to burn the original capture time of each image into the resulting video using the drawtext command. The capture time is available in the filename of each image. But I am failing to find some option for drawtext to access the filenames of the input images.

An alternative would be to access the creation date of each image from within drawtext (I cannot find a way to do this either). But I would definitely prefer to access the filename, as this would give me more options to format the text.

Is there a way to do this?
It would be great if any proposed solution would work on Windows too.

Jpsy
  • 525

3 Answers3

5

Looks like since the time of the previous answer, ffmpeg has acquired the capability of doing this on its own, using metadata from the image2 decoder:

ffmpeg \
    -f image2 \
    -pattern_type glob \
    -export_path_metadata 1 \
    -i '*' \
    -vf "drawtext=text='%{metadata\:lavf.image2dec.source_basename\:NA}'" \
    -y ../output.mkv

The filenames don't need any extension, ffmpeg will detect the image format anyway. So the files can be renamed as needed. Since the input is '*', the output is sent to the parent directory, to prevent confusion.

Daniel
  • 133
ateijelo
  • 151
3

Older versions of ffmpeg won't be able to do it in one line, as ffmpeg's drawtext filter is not that advanced.

You will need to pre-process the images in advance with some scripting.

Something like a simple bash script:

for i in *.png; do 
    time=$(echo $i | cut -d . -f 1)
    ffmpeg -i $i -vf "drawtext=text=$time" mod-$time.png
done

Then you can use the mod*.png files to create your video.

chacham15
  • 978
Znuff
  • 151
3

The answer of Znuff is great (accepted & upvoted) and paved the way for my own solution. As it is Unix-specific and I had to work on Win, here is my solution for Windows 7 and up:

I used two batch files (Master.cmd and Slave.cmd) to loop through all images and burn the filenames into them.

Master.cmd:

forfiles /p "MyImagesSubPath" /m "2014-02-15*.png" /c "cmd /c ..\Slave.cmd @file @fname

Slave.cmd:

ffmpeg -i "%~1" -vf "crop=1072:1192:24:101, drawtext=text=%~2: fontcolor=white: fontsize=60: box=1: boxcolor=black@0.6: x=50:y=50: fontfile=c\\:\\\\Windows\\\\Fonts\\\\myfont.ttf" "mod_%~1"

Explanation:

It is necessary to use two batches for multiple reasons:
1. The /c parameter of forfiles accepts only a command line of limited length (253 characters)
2. Nesting the FFmpeg command into the forfiles /c parameter would require an insane level of character excaping.

The filename filter "2014-....png" in Master.cmd is used to prevent the loop from reprocessing its own output (named "mod_....png") in an endless loop. You must adapt that filter string to match your source images.

The Slave batch is executed from within the sub directory "MyImagesSubPath" below the batch directory (this is, where you have to place your source images). Slave.cmd receives the filename with and without extension (.png) as its two parameters.

The filename parameter without extension is used as text to be burned into the image. The resulting images are stored with the prefix "mod_" in the same path as the original images. The filenames may contain blanks.

Jpsy
  • 525