FFmpeg
FFmpeg is the leading multimedia framework, able to decode, encode, transcode, mux, demux, stream, filter and play pretty much anything that humans and machines have created
FFmpeg는 인간과 기계가 만들어낸 거의 모든 것을 디코딩/인코딩, 트랜스코딩, 먹스/디먹스, 스트림, 필터링 및 재생할 수 있는 선도적인 멀티미디어 프레임워크입니다.
동영상 편집에서 FFmpeg는 오픈소스로 이루어진 표준 프로그램입니다. 동영상 관련 프로그램을 만들면 꼭 FFmpeg가 끼게 되더군요. 이번에 만드는 사이트 최적화를 위해 테스트와 벤치마크를 진행했으며, 그 과정을 정리합니다.
로컬 테스트
다음 흐름으로 벤치마크 코드를 작성해, CRF 1826·비트레이트 4M10M·프리셋 4종 조합(총 40케이스)으로 HLS 인코딩 옵션을 바꿔 가며 출력 용량과 VMAF 점수를 비교해 최적 값을 도출해 봤습니다. 최종 목적은 강좌 공유 사이트에서 PPT로 보여주는 글자가 뭉개지지 않으며 적당히 높은 화질로 HLS 영상을 뽑아내는 것입니다.
옵션
- CRF(Constant Rate Factor): 화질 기준 인코딩 방식으로 압축 품질을 선택할 수 있습니다. 숫자가 낮을수록 화질이 좋고 용량이 커지며, 영상 내용에 따라 비트 수를 조절해 사용합니다. 비트 조절 기준은 픽셀 단위에서 이루어지는 색 변화량에 비례합니다.
- CRF 18 → 고화질, 큰 용량
- CRF 22 → 적당한 화질/용량 균형
- CRF 26 → 낮은 용량, 품질 저하 가능
- 비트레이트(bitrate): 초당 사용할 비트 양을 제한합니다.
- 프리셋(preset): x264 인코더가 얼마나 오래 고민해서 압축할지를 정하는 옵션입니다.
- veryfast → 빠르게 인코딩, 용량 효율 낮음
- fast → 빠른 편, 품질/용량 조금 개선
- medium → 기본값, 균형 좋음
- slow → 느림, 용량 효율 좋음
- ※ 같은 비트레이트 기준이면 느린 프리셋이 더 좋은 화질을 나타낼 수 있습니다.
- VMAF: FFmpeg의 옵션이 아닙니다. VMAF는 Netflix가 만든 영상 품질 평가 지표로, 편의상 이를 토대로 점수를 측정했습니다.
이제 아래 흐름의 테스트 코드로 Jitsi로 녹화한 강의 영상을 기준으로 테스트를 돌려 봤습니다.
위 프로세스의 테스트 코드로 값을 도출하면 아래와 같습니다. 전체적으로 시간이 많이 소요된 원인은 VMAF 측정 때문입니다. 컬럼별 특징은 다음과 같습니다.
- mode: 인코딩 방식
- preset: 속도/압축 효율 옵션
- crf_value: crf 인코딩의 화질 기준값
- target_bitrate: bitrate 인코딩의 목표 비트레이트
- encode_seconds: 인코딩 시간(참고 지표. 테스트 PC의 병렬 실행·시스템 부하에 따라 변동될 수 있음)
- total_seconds: 전체 처리 시간(VMAF 측정 포함)
- output_size: 결과 파일 크기
- measured_bitrate: 실제 측정 비트레이트
- vmaf_mean: 평균 품질
- vmaf_p5: 하위 5% 품질
- vmaf_min: 최저 품질
인코딩 시간은 병렬 실행 환경과 시스템 부하에 따라 변동될 수 있으므로, 이번 비교에서는 참고 지표로만 사용하는 것이 좋다고 판단했습니다. 로컬 PC다 보니 변수가 많다고 판단이 들더군요.
최종 판단은 VMAF 평균, VMAF p5, 출력 용량을 중심으로 했습니다.
데이터
| mode | preset | crf_value | target_bitrate | encode_seconds | total_seconds | output_size | measured_bitrate | vmaf_mean | vmaf_p5 | vmaf_min |
|---|---|---|---|---|---|---|---|---|---|---|
| crf | veryfast | 18 | 136.4 | 973.1 | 41.97 MB | 1,173,066 bps | 95.916 | 95.2646 | 87.1316 | |
| crf | veryfast | 20 | 137.0 | 969.0 | 33.94 MB | 949,010 bps | 95.4192 | 94.4778 | 87.5633 | |
| crf | veryfast | 22 | 136.6 | 977.9 | 27.55 MB | 770,355 bps | 94.804 | 93.5671 | 87.8429 | |
| crf | veryfast | 24 | 137.2 | 971.2 | 22.72 MB | 635,195 bps | 94.0202 | 92.4681 | 86.7679 | |
| crf | veryfast | 26 | 136.6 | 969.1 | 18.89 MB | 528,247 bps | 93.0715 | 91.063 | 85.4895 | |
| bitrate | veryfast | 4M | 145.0 | 1,002.5 | 120.30 MB | 3,363,767 bps | 97.1068 | 96.6758 | 87.4941 | |
| bitrate | veryfast | 5M | 130.5 | 950.8 | 143.54 MB | 4,013,489 bps | 97.2182 | 96.8788 | 86.6481 | |
| bitrate | veryfast | 6M | 129.8 | 950.5 | 161.76 MB | 4,522,577 bps | 97.278 | 96.993 | 86.8844 | |
| bitrate | veryfast | 8M | 131.4 | 948.9 | 188.04 MB | 5,257,395 bps | 97.3376 | 97.1369 | 86.261 | |
| bitrate | veryfast | 10M | 133.3 | 956.3 | 196.97 MB | 5,507,232 bps | 97.3626 | 97.2196 | 85.9719 | |
| crf | fast | 18 | 139.4 | 943.0 | 53.46 MB | 1,494,516 bps | 96.7741 | 96.5057 | 85.9342 | |
| crf | fast | 20 | 123.7 | 948.6 | 42.91 MB | 1,199,624 bps | 96.4961 | 96.0678 | 86.0927 | |
| crf | fast | 22 | 146.5 | 957.7 | 34.93 MB | 976,696 bps | 96.0943 | 95.4819 | 86.2577 | |
| crf | fast | 24 | 144.2 | 961.0 | 28.65 MB | 801,058 bps | 95.66 | 94.7476 | 86.9226 | |
| crf | fast | 26 | 143.9 | 952.8 | 23.81 MB | 665,763 bps | 95.0709 | 93.7191 | 87.6512 | |
| bitrate | fast | 4M | 168.5 | 990.2 | 119.44 MB | 3,339,445 bps | 97.2453 | 96.9265 | 87.082 | |
| bitrate | fast | 5M | 166.3 | 986.9 | 134.95 MB | 3,772,725 bps | 97.3048 | 97.0381 | 86.2122 | |
| bitrate | fast | 6M | 153.8 | 992.5 | 145.98 MB | 4,081,517 bps | 97.343 | 97.1178 | 85.7265 | |
| bitrate | fast | 8M | 159.6 | 1,004.6 | 161.52 MB | 4,515,925 bps | 97.3817 | 97.2271 | 85.6859 | |
| bitrate | fast | 10M | 169.5 | 1,013.7 | 170.84 MB | 4,776,514 bps | 97.4009 | 97.2985 | 85.6429 | |
| crf | medium | 18 | 161.7 | 988.8 | 56.88 MB | 1,590,215 bps | 96.8498 | 96.6205 | 85.8193 | |
| crf | medium | 20 | 161.7 | 971.4 | 45.58 MB | 1,274,350 bps | 96.5871 | 96.2419 | 85.9814 | |
| crf | medium | 22 | 158.4 | 975.5 | 36.85 MB | 1,030,287 bps | 96.264 | 95.7546 | 86.143 | |
| crf | medium | 24 | 140.9 | 971.9 | 30.18 MB | 843,782 bps | 95.8536 | 95.0984 | 86.6804 | |
| crf | medium | 26 | 138.1 | 991.5 | 25.02 MB | 699,329 bps | 95.3291 | 94.2866 | 87.4335 | |
| bitrate | medium | 4M | 205.3 | 1,031.3 | 120.51 MB | 3,369,406 bps | 97.2842 | 97.0156 | 87.1076 | |
| bitrate | medium | 5M | 214.1 | 1,033.8 | 135.75 MB | 3,795,327 bps | 97.3345 | 97.1194 | 86.1957 | |
| bitrate | medium | 6M | 219.6 | 1,043.1 | 146.32 MB | 4,090,826 bps | 97.3669 | 97.2008 | 85.7986 | |
| bitrate | medium | 8M | 217.8 | 1,043.4 | 161.49 MB | 4,515,022 bps | 97.3978 | 97.2969 | 85.6782 | |
| bitrate | medium | 10M | 204.5 | 1,031.7 | 170.32 MB | 4,761,776 bps | 97.4128 | 97.3563 | 85.6202 | |
| crf | slow | 18 | 123.2 | 1,002.2 | 58.77 MB | 1,643,090 bps | 96.9052 | 96.6692 | 85.7663 | |
| crf | slow | 20 | 199.4 | 1,018.4 | 47.47 MB | 1,327,204 bps | 96.6719 | 96.331 | 86.0551 | |
| crf | slow | 22 | 194.3 | 1,008.4 | 38.35 MB | 1,072,355 bps | 96.363 | 95.9045 | 86.1877 | |
| crf | slow | 24 | 185.1 | 1,003.1 | 31.35 MB | 876,415 bps | 95.9779 | 95.2382 | 86.6933 | |
| crf | slow | 26 | 181.5 | 991.2 | 25.91 MB | 724,473 bps | 95.4791 | 94.5503 | 87.7418 | |
| bitrate | slow | 4M | 204.8 | 1,051.4 | 119.93 MB | 3,353,010 bps | 97.2915 | 97.0247 | 87.1576 | |
| bitrate | slow | 5M | 130.7 | 902.4 | 135.27 MB | 3,781,923 bps | 97.3449 | 97.1384 | 86.1405 | |
| bitrate | slow | 6M | 177.5 | 891.0 | 145.62 MB | 4,071,401 bps | 97.3767 | 97.2007 | 85.7874 | |
| bitrate | slow | 8M | 180.5 | 892.9 | 161.70 MB | 4,520,882 bps | 97.406 | 97.3117 | 85.7257 | |
| bitrate | slow | 10M | 181.3 | 895.9 | 170.99 MB | 4,780,564 bps | 97.4193 | 97.3684 | 85.6088 |
표는 5행마다 mode가 바뀌도록 묶었습니다. 파란 배경은 crf, 주황 배경은 bitrate이며, 각 묶음 시작 행에는 구분선을 넣었습니다.
VMAF 평균, VMAF p5, 출력 용량을 기준으로 보면 다음과 같습니다.
- CRF가 bitrate보다 효율적으로 보입니다. bitrate에 용량을 더 줘도 점수가 크게 오르지 않는 모습이지만, 용량은 비례하여 올라가는 것을 확인할 수 있습니다.
- CRF 영상의 용량이 품질 점수 대비 매우 효율적이고, mean·p5 차이도 크게 발생하지 않고 있습니다. Bitrate는 이번 비교 범위에서 배제해도 되겠습니다.
설정 파일 크기 measured bitrate VMAF mean VMAF p5 CRF fast 22 34.93 MB 976,696 bps (0.98 Mbps) 96.0943 95.4819 CRF medium 22 36.85 MB 1,030,287 bps (1.03 Mbps) 96.2640 95.7546 CRF slow 22 38.35 MB 1,072,355 bps (1.07 Mbps) 96.3630 95.9045 Bitrate fast 4M 119.44 MB 3,339,445 bps (3.34 Mbps) 97.2453 96.9265 - veryfast 프리셋은 CRF에서 품질 손실이 크게 발생하는 것을 볼 수 있습니다. (CRF 22 기준)
preset 파일 크기 VMAF mean VMAF p5 veryfast 27.6 MB 94.8040 93.5671 fast 34.9 MB 96.0943 95.4819 medium 36.8 MB 96.2640 95.7546 slow 38.4 MB 96.3630 95.9045 - fast → medium → slow로 갈수록 mean·p5는 소폭 상승하지만, 용량 증가 대비 이득이 크지 않아 보입니다. (CRF 22 기준)
preset VMAF mean VMAF p5 파일 크기 fast 96.0943 95.4819 34.9 MB medium 96.2640 95.7546 36.8 MB slow 96.3630 95.9045 38.4 MB
로컬 테스트 결론
VMAF mean, VMAF p5, 출력 용량을 중심으로 정리하면 아래 옵션이 타당해 보입니다.
30분, 1시간 예상 용량은 5분 샘플 결과를 선형 확대한 값입니다.
| 목적 | 추천 설정 | 30분 예상 용량 | 1시간 예상 용량 | VMAF mean | VMAF p5 |
|---|---|---|---|---|---|
| 균형 추천 | crf medium 22 | 약 221 MB | 약 442 MB | 96.2640 | 95.7546 |
| fast 프리셋 대안 | crf fast 22 | 약 210 MB | 약 419 MB | 96.0943 | 95.4819 |
| 용량 우선 | crf medium 26 | 약 150 MB | 약 300 MB | 95.3291 | 94.2866 |
| 고품질 | crf medium 20 | 약 273 MB | 약 547 MB | 96.5871 | 96.2419 |
집중 테스트
위 테스트에서 CRF와 고정 비트레이트를 비교했고, 그 결과 비트레이트의 효율이 낮다고 정의를 내렸습니다. 이제 덜어낼 건 덜어내고 아래 옵션들을 적용해 봅시다.
아래 옵션을 실사용 후보군으로 보고 집중 테스트해 봅시다.
- preset = fast, medium
- crf = 20, 22, 24, 26
이들에 대해 벤치마크를 세 번 더 돌려 평균 값을 도출하면 다음과 같습니다.
| preset | crf | avg_output_mib | avg_measured_mbps | avg_vmaf_mean | avg_vmaf_p5 | |
|---|---|---|---|---|---|---|
| fast | 20 | 42.91 | 1.2 | 96.4961 | 96.0678 | |
| fast | 22 | 34.93 | 0.977 | 96.0943 | 95.4819 | |
| fast | 24 | 28.65 | 0.801 | 95.66 | 94.7476 | |
| fast | 26 | 23.81 | 0.666 | 95.0709 | 93.7191 | |
| medium | 20 | 45.58 | 1.274 | 96.5871 | 96.2419 | |
| medium | 22 | 36.85 | 1.03 | 96.264 | 95.7546 | |
| medium | 24 | 30.18 | 0.844 | 95.8536 | 95.0984 | |
| medium | 26 | 25.01 | 0.699 | 95.3291 | 94.2866 |
crf 값에 따라 vmaf 점수도 마찬가지로 내려갔지만, 평균값이 전부 93점 이상을 기록하는 것을 보면 품질이 괜찮게 나오는 것을 알 수 있습니다. 수치만 보면 fast보다 미세하게 medium이 나은 점도 확인할 수 있습니다. 용량을 아끼기 위해 crf는 22~26으로 가정하고, 품질 안정성도 고려해 medium이 좋을 것 같습니다.
실제 영상의 캡처본을 보면 품질이 가장 안 좋은 fast crf 20이 아래 사진입니다.
이를 보아도 글자가 제대로 표시되죠.

다른 영상들도 눈으로는 차이를 체감하기 어려웠습니다. vmaf 1~2점 차이는 눈에 띄는 화질 차이로 이어지지 않는 것으로 느껴졌습니다.
EC2 테스트
최종적으로는 medium 24로 택하였고, 배포 환경에서 옵션을 다음과 같이 바꿨습니다.
| 항목 | 수정 전 | 수정 후 | 변경 이유 |
|---|---|---|---|
| 비디오 코덱 | libx264 | libx264 | H.264 기반 HLS 호환성을 유지 |
| 해상도 제한 | scale='min(1920,iw)':-2 | scale='min(1920,iw)':-2 | 원본이 1920보다 크면 1080p급 너비로 제한하고, 비율 유지 |
| 프리셋 | medium | medium | 벤치마크에서 품질 안정성과 압축 효율의 균형이 좋았음 |
| CRF | 22 | 24 | VMAF 평균 95 이상을 유지하면서 용량을 줄이기 위해 조정 |
| Maxrate | 5M | 3M | CRF 24 구간 실측 비트레이트에 맞춰 비트레이트 상한을 조정 |
| Bufsize | 10M | 6M | maxrate의 2배 버퍼를 유지해 순간 비트레이트 변동을 완충 |
| 오디오 코덱 | aac | aac | HLS 호환성을 위해 유지 |
| 오디오 비트레이트 | 128k | 128k | 일반적인 스트리밍 음질 기준 유지 |
| 세그먼트 길이 | 10초 | 10초 | 기존 서비스 재생 구조와 캐싱 정책 유지 |
| HLS 타입 | vod | vod | VOD용 정적 플레이리스트 생성 |
이를 토대로 같은 영상을 배포 환경에서 S3를 이용해 배포해 보니,
기존 세팅은 636s가 소요되었고 새로 바뀐 세팅은 622s로 미세하게 줄었습니다.
이는 CPU 상황에 따라 달라질 수 있는 수준이라, 사실상 큰 의미는 없었습니다.
저장 공간도 74.8MB에서 73.8MB로 미세하게 줄었습니다.
아마 기존 세팅과 거의 유사했기에 이런 결과가 나왔습니다.
다만 리소스로 사용된 영상의 길이가 20분이어서 차이가 작게 보였을 뿐이며 분명한 개선이 발생했다는 점이 중요하죠.

💬 댓글