영상 인코딩 도구 고르기: ffmpeg preset과 faststart 실행 결과, GStreamer와의 역할 차이

이 글의 핵심

8초 720p 합성 영상을 libx264 crf 23으로 인코딩했을 때 preset ultrafast는 0.24초에 7.5MB, medium은 0.72초에 3.1MB, slow는 1.27초에 3.0MB였습니다. faststart를 켜면 MP4의 moov 박스가 mdat 앞으로 이동했습니다. 이 결과와 ffmpeg·GStreamer의 역할 차이를 정리했습니다.

영상 파일을 다룰 때 처음 만나는 도구는 ffmpeg와 GStreamer다. 둘 다 인코딩과 변환을 하지만 쓰임새가 다르다. 이 글은 ffmpeg에서 가장 많이 만지는 preset과 faststart를 실제로 실행해 보고, 두 도구의 역할 차이를 정리한다. 환경은 ffmpeg 9.0.2(Homebrew), macOS arm64이고, 입력은 testsrc2 합성 영상(1280x720, 30fps, 8초)이다. 합성 영상은 움직임과 질감이 실제 촬영 영상과 다르므로 숫자는 경향을 보는 용도다.

실행 결과

ffmpeg -f lavfi -i testsrc2=size=1280x720:rate=30 -t 8 \
  -c:v libx264 -preset <이름> -crf 23 -pix_fmt yuv420p out.mp4
preset인코딩 시간파일 크기
ultrafast0.24초7,499,196바이트
medium0.72초3,137,487바이트
slow1.27초3,027,167바이트
  • ultrafast는 빠르지만 같은 crf 값에서 파일이 medium의 약 2.4배였다.
  • medium에서 slow로 가면 시간이 약 1.8배 걸리고 크기는 약 3.5% 줄었다. 이 이득이 시간을 들일 만한지는 용도에 따른다.
  • 각 preset을 한 번씩만 실행한 값이라 오차가 있다.

화질(VMAF)까지 포함한 비교, crf 값별 변화, 실제 영상 기준의 폭은 ffmpeg libx264 실험: preset과 crf에서 다룬다.

faststart가 바꾸는 것

MP4 파일은 moov(재생 정보)와 mdat(실제 데이터) 박스로 이뤄지는데, 기본 인코딩 결과는 moov가 파일 끝에 있다. 웹에서 재생하려면 moov를 먼저 받아야 하므로 앞으로 옮기는 옵션이 -movflags +faststart다. 같은 파일에 ffmpeg -i in.mp4 -c copy -movflags +faststart out.mp4를 적용하자 박스 순서가 다음처럼 바뀌었다.

파일앞쪽 박스 순서
기본 인코딩ftyp, free, mdat, moov
faststart 적용ftyp, moov, free, mdat

-c copy는 다시 인코딩하지 않고 컨테이너만 다시 쓰므로 빠르다. 이 박스 순서 확인은 ffmpeg를 쓰지 않고 브라우저에서 영상을 처리하는 도구를 만들 때도 같은 이유로 테스트했다.

ffmpeg와 GStreamer: 역할 차이

구분ffmpegGStreamer
중심파일 변환·인코딩 명령 한 줄소스, 필터, 싱크를 이어 붙이는 파이프라인
잘 맞는 일포맷 변환, 인코딩 옵션 실험, 일괄 처리카메라·네트워크 스트림을 실시간으로 받아 처리
배우는 방식옵션과 필터요소(element)와 패드 연결

이 표는 일반적으로 알려진 역할 구분이고, 이 글에서 GStreamer는 실행하지 않았다(gst-launch를 설치하지 않았다). GStreamer의 요소 조립과 C·파이썬 연동은 GStreamer 실전 가이드에 정리했다. 코덱과 컨테이너의 배경 지식은 H.264 가이드와 MP4 컨테이너 가이드를 참고한다.

고르는 기준

  • 파일을 바꾸고 옵션을 비교한다: ffmpeg.
  • 카메라나 네트워크 스트림을 실시간으로 이어 붙인다: GStreamer 쪽을 먼저 검토한다.
  • 웹 재생용 MP4를 만든다: -movflags +faststart를 확인한다.

확인하지 못한 것

  • 실제 촬영 영상과 다른 해상도에서의 preset 효과.
  • 하드웨어 인코더(VideoToolbox, NVENC)와의 비교.
  • GStreamer 파이프라인의 실행 결과.