Render Arabic and Hebrew RTL Text in FFmpeg

Rendering right-to-left (RTL) scripts such as Arabic or Hebrew with FFmpeg's drawtext filter requires proper text shaping and bidirectional (BiDi) algorithm support. Standard FFmpeg builds using only basic FreeType will render RTL text reversed and without the necessary cursive ligatures. This guide explains how to properly display RTL languages using FFmpeg with native HarfBuzz and FriBidi support, as well as how to prepare text files for accurate rendering.

1. Ensure HarfBuzz and FriBidi Support

To correctly render RTL scripts, FFmpeg must be compiled with libfribidi (which handles bidirectional text layout) and libharfbuzz (which handles OpenType text shaping and Arabic ligatures).

Check your FFmpeg build configuration by running:

ffmpeg -buildconf

Verify that both --enable-libfribidi and --enable-libharfbuzz appear in the configuration output. Most modern package managers (such as Homebrew on macOS or recent Linux distributions) include these libraries by default.

2. Basic Command Syntax

When HarfBuzz and FriBidi are compiled into FFmpeg, the drawtext filter automatically handles character shaping and right-to-left reordering. You must specify a font that supports Arabic or Hebrew glyphs.

Example using an Arabic font:

ffmpeg -i input.mp4 -vf "drawtext=fontfile=/path/to/Amiri-Regular.ttf:text='مرحبا بالعالم':fontcolor=white:fontsize=48:x=(w-text_w)/2:y=(h-text_h)/2" -codec:a copy output.mp4

Example using a Hebrew font:

ffmpeg -i input.mp4 -vf "drawtext=fontfile=/path/to/NotoSansHebrew-Regular.ttf:text='שלום עולם':fontcolor=white:fontsize=48:x=(w-text_w)/2:y=(h-text_h)/2" -codec:a copy output.mp4

3. Using Text Files for Complex Strings

Passing non-Latin UTF-8 characters directly in the command line can lead to escaping and shell encoding issues. Storing the text in a UTF-8 encoded text file and referencing it via the textfile parameter is more reliable.

  1. Create a UTF-8 encoded text file named subtitle.txt:

    نص تجريبي باللغة العربية
  2. Run the drawtext command referencing the file:

    ffmpeg -i input.mp4 -vf "drawtext=fontfile=/path/to/Amiri-Regular.ttf:textfile=subtitle.txt:fontcolor=white:fontsize=36:x=(w-text_w)/2:y=h-th-50" -codec:a copy output.mp4

4. Workaround for Builds Without HarfBuzz or FriBidi

If your FFmpeg build lacks native HarfBuzz or FriBidi support, the text must be pre-shaped and reversed before being passed to drawtext. You can use the standalone fribidi command-line utility to prepare your text file:

fribidi --charset=UTF-8 input_rtl.txt > shaped_rtl.txt

Once processed, provide shaped_rtl.txt to the drawtext filter using the textfile parameter. The text will appear in the correct visual order on the video frame.