0

I set up a script that generates a simple video with one mp3 audio and one text on screen. I would like to add the option to specify a font type and use that for formatting of the text on the video.

This is my code:

import subprocess
from pathlib import Path
from myproject import AUDIOS_FOLDER, FONTS_FOLDER


font_name = "Montserrat-LightItalic"
font_path = str(FONTS_FOLDER / font_name) + '.ttf'
assert Path(font_path).is_file()

ffmpeg_command = [
    'ffmpeg',
    '-y',
    '-f', 'lavfi',
    '-i', 'color=c=gray:s=640x480:d=4',
    '-i', f'{str(AUDIOS_FOLDER / "i_have_a_cat.mp3")}',
    '-vf', f'drawtext=text=\'I have a cat\':fontsize=24:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2:fontfile=\'{font_path}\'',
    str(ffmpeg_poc_path / 'output.mp4')
]

subprocess.run(ffmpeg_command)

The problem I am facing is that the :fontfile=\'{font_path}\' setting doesn't get activated. The above code produces the exact same output as if I drop the :fontfile=\'{font_path}\' section entirely.

I tried using alternative font names without using the font_path, e.g.:

'-vf', f'drawtext=text=\'I have a cat\':fontsize=24:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2:fontfile=\'arialbd.ttf\''

or

'-vf', f'drawtext=text=\'I have a cat\':fontsize=24:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2:fontfile=\'sseriff.ttf\''

but these didn't work either, despite both files existing at C:\Windows\Fonts on my local device. So at this stage, I concluded that neither the system default fonts, nor the custom installed, project-specific ones work.

Note 1: I also tried with and without single and double quotes, with no success:

:fontfile='sseriff.ttf'
:fontfile=\'sseriff.ttf\'
:fontfile="sseriff.ttf"
:fontfile=\"sseriff.ttf\"

Note 2: As for the project-specific fonts which I intend to collect under: project_root/fonts directory, I came across this comment and I transformed the path as advised here; with no success:

font_path = font_path.replace("\\", "\\\\").replace("C:", "C\:")
# example result: C\:\\user\\OneDrive\\Desktop\\myproject\\fonts\\Montserrat-LightItalic.ttf

Note 3: Based on Rotem's advice below, I copied the custom font files from C:\Windows\Fonts to my working directory. In the below case, I used the arialbd.ttf custom font:

'-vf', f'drawtext=text=\'I have a cat\':fontsize=24:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2:fontfile=arialbd.ttf'

Note that no quotes should be used around the filename; otherwise, the font won't be applied.

While this works perfectly, I am still unable to reference an arbitrary font type via an absolute path. The following approach doesn't work:

font_path = FONTS_FOLDER / "arialbd.ttf"
assert font_path.is_file()

font_path_str = str(font_path)
# path looks like this: c:\user\OneDrive\myproject\fonts\arialbd.ttf

ffmpeg_command = [
    'ffmpeg',
    '-y',
    '-f', 'lavfi',
    '-i', 'color=c=gray:s=640x480:d=4',
    '-i', f'{str(audios_path / "i_have_a_cat.mp3")}',
    '-vf', f'drawtext=text=\'I have a cat\':fontsize=24:fontcolor=white:x=(w-text_w)/2:y=(h-text_h)/2:fontfile={font_path_str}',
    str(ffmpeg_poc_path / 'output.mp4')
]

I also tried to duplicate all backslashes and convert C:\ to C\:\ but still no success.

2
  • 2
    For testing, copy sseriff.ttf file from the Fonts folder to the folder of the Python script (to the "working directory"), and try fontfile="sseriff.ttf". You may also try full path: fontfile="c:\\Windows\\Fonts\\sseriff.ttf". Note: I can't find sseriff.ttf file in my c:\Windows\Fonts folder - make sure that the file exists (there is sseriff.fon file, and I don't know if FFmpeg supports .fon files).
    – Rotem
    Commented Nov 5, 2023 at 18:50
  • Thank you for your advice, @Rotem. Indeed the sseriff.ttf is not found at C:\Windows\Fonts. But arialbd.ttf is there. I copied this file across to my working directory and reran the script as you recommended and when provided without any quote symbols, it works! But if I want to provide any kind of path to the fontfile argument, it still doesn't work :( I edited my post.
    – lazarea
    Commented Nov 9, 2023 at 17:15

1 Answer 1

0

I managed to fix it.

It seems that when we specify a .ttf file that is in the working directory, there is no need for quotes:

-vf drawtext=text=\'I have a cat\':fontfile=arialbd.ttf'

But when specifying an absolute path to the .ttf file, it is a must to add an escaped single quote around the path and to also escape all backslashes and colons:

-vf drawtext=text=\'I have a cat\':fontfile=\'C\:\\user\\OneDrive\\myproject\\fonts\\arialbd.ttf\''

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .