Homebrew로 깐 ffmpeg에는 drawtext가 없다

· 약 3분

#ffmpeg #영상자동화 #macOS

결론부터 말씀드리면, 설치가 깨진 게 아닙니다. Homebrew가 배포하는 ffmpeg는 글자를 다루는 기능을 빼고 빌드됩니다. 그래서 drawtext가 없습니다.

이 글에서 다룰 것은 두 가지입니다. 1) 왜 없는지를 어떻게 확인하는지, 2) 없는 상태로 자막을 넣으려면 무엇을 포기해야 하는지.

오타를 의심하는 데 시간을 썼습니다

영상 파이프라인에 자막을 붙이려던 참이었습니다. ffmpeg에 drawtext 필터가 있으니 텍스트를 얹으면 될 일이라고 생각했습니다. 명령을 넣었더니 필터를 찾을 수 없다고 했습니다.

오타인 줄 알고 몇 번 다시 쳤습니다. 그다음엔 설치가 깨진 줄 알고 재설치를 고민했습니다. 둘 다 아니었습니다.

필터가 하나가 아니라 셋 다 없었습니다

$ for f in drawtext subtitles ass; do
    printf "%-10s " "$f"
    ffmpeg -hide_banner -filters | grep -qw "$f" && echo "있음" || echo "없음"
  done

drawtext   없음
subtitles  없음
ass        없음

drawtext는 텍스트를 직접 그리고, subtitlesass는 자막 파일을 태워 넣습니다. 쓰는 방식이 전혀 다른 셋입니다.

그런데 왜 한꺼번에 없을까요? 개별 필터의 문제라면 이렇게 될 수 없습니다. 셋을 묶는 공통 원인이 아래에 있다는 뜻입니다.

원인은 빌드할 때 이미 정해졌습니다

ffmpeg -version이 빌드에 쓴 옵션을 그대로 뱉습니다.

$ ffmpeg -version | head -3

ffmpeg version 9.0.1
configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/9.0.1_1 --enable-shared
  --enable-pthreads --enable-version3 --enable-ffplay --enable-gpl
  --enable-libsvtav1 --enable-libopus --enable-libx264 --enable-libmp3lame
  --enable-libdav1d --enable-libvmaf --enable-libvpx --enable-libx265
  --enable-openssl --enable-videotoolbox --enable-audiotoolbox --enable-neon

코덱은 넉넉합니다. x264, x265, vpx, av1, opus, mp3까지 다 들어 있습니다.

그런데 libfreetype이 없습니다. libass도, fontconfig도 없습니다. 이 셋이 글자를 그리는 쪽 라이브러리입니다. 폰트 파일을 읽고(freetype), 시스템 폰트를 찾고(fontconfig), 자막 포맷을 해석하는(libass) 역할을 나눠 맡습니다.

빌드할 때 이것들을 넣지 않으면 해당 필터는 컴파일 자체가 되지 않습니다. 고장 난 게 아니라 처음부터 만들어지지 않은 겁니다.

왜 빼는지는 모르겠습니다. 다만 결과를 보면 인코딩에 필요한 것은 전부 들어가고 글자를 다루는 것만 빠져 있습니다. 영상 변환 도구로서 폰트 렌더링이 필수가 아니니 의존성을 줄인 선택이었을 것입니다 — 이건 제 추측입니다.

길은 둘인데, 둘 다 뭔가를 포기해야 합니다

하나는 다시 빌드하는 것입니다. 폰트 라이브러리를 포함해 직접 컴파일하거나, 그렇게 빌드된 바이너리를 구해 씁니다. 필터를 그대로 쓸 수 있다는 게 장점입니다.

포기하는 건 안정성입니다. 이 파이프는 매일 도는 물건인데, 직접 빌드한 ffmpeg는 갱신할 때마다 같은 작업을 반복해야 합니다. 부러질 자리를 하나 더 만드는 셈입니다.

다른 하나는 자막을 ffmpeg 밖에서 그리는 것입니다. 텍스트를 이미지로 만들어 영상 위에 얹으면 drawtext가 없어도 됩니다. Python Pillow로 투명 배경 PNG에 글자를 그리고 overlay 필터로 합칩니다. overlay는 순수 영상 합성이라 폰트 라이브러리와 무관하게 늘 들어 있습니다.

포기하는 건 단계입니다. 한 번에 끝날 일이 이미지 생성과 합성 두 단계로 늘어납니다.

저는 두 번째를 택했습니다.

그런데 우회가 오히려 나았습니다

여기서 예상이 빗나갔습니다. 어쩔 수 없는 차선이라고 생각했는데 그렇지 않았습니다.

drawtext로 한글 자막을 다루면 줄바꿈과 정렬을 필터 문법 안에서 계산해야 합니다. Pillow는 그냥 Python입니다. 글자 폭을 재서 줄을 나누고, 특정 구간에만 다른 색을 주고, 같은 장면 안에서 문구를 순서대로 바꾸는 걸 평범한 코드로 짭니다.

지금 파이프는 자막 한 덩어리를 빈 줄 기준으로 쪼개서 배경 컷이 바뀔 때 함께 넘어가게 합니다. 이걸 필터 문법으로 짤 엄두는 나지 않았을 것입니다.

같은 자리에서 막혔다면

ffmpeg -version의 configuration 줄부터 보십시오. 거기에 libfreetype이 없으면 재설치로는 해결되지 않습니다.

설치가 깨진 게 아닙니다. 처음부터 그렇게 만들어진 겁니다.