홈 › 3장 MediaInfo와 파일 분석

3.6 자동 QC - 블랙, 프리즈, 무음, 라우드니스 검사

FFmpeg의 blackdetect, freezedetect, silencedetect, ebur128, cropdetect 필터로 영상 품질 검사를 자동화하는 방법과, 결과 해석과 임계값 설정 기준을 설명합니다.

최종 수정 2026-10-28 · 읽는 시간 약 6분 · 운영 프리즘(Prism) · 편집 원칙

#QC(Quality Control)란

방송사에서 QC는 송출 전에 소재가 기준을 충족하는지 검사하는 일입니다. 전통적으로는 QC 담당자가 영상을 처음부터 끝까지 보며 확인했지만, 파일 기반 환경에서는 자동 검사가 먼저 돌고 사람은 경고가 난 구간만 확인합니다.

자동 QC에서 흔히 검사하는 항목은 다음과 같습니다.

분류 검사 항목
구조 컨테이너 완결성, 코덱·해상도·프레임레이트 규격 일치, 타임코드 연속성
영상 블랙 프레임, 프리즈(정지) 프레임, 레터박스/필러박스(검은 띠), 블록 노이즈, 색상 범위
오디오 무음 구간, 라우드니스(음량), 피크, 채널 구성, 위상

앞 글에서 구조 검사를 다뤘으므로, 이번에는 FFmpeg 필터만으로 구현할 수 있는 영상·오디오 검사를 실습합니다.

#테스트 영상 만들기

검사가 제대로 동작하는지 알려면 정답을 알고 있는 영상이 필요합니다. 아래 명령으로 8초짜리 영상을 만들었습니다.

  • 영상: 0~2초 빨간 화면, 2~5초 검은 화면, 5~8초 테스트 패턴
  • 오디오: 0~2초 440Hz 톤, 2~5초 무음, 5~8초 880Hz 톤
ffmpeg -y -filter_complex "\
color=c=red:s=640x360:r=25:d=2[a];color=c=black:s=640x360:r=25:d=3[b];testsrc2=s=640x360:r=25:d=3[c];\
[a][b][c]concat=n=3:v=1:a=0[v];\
sine=f=440:d=2[s1];anullsrc=r=48000:cl=mono:d=3[s2];sine=f=880:d=3[s3];\
[s1][s2][s3]concat=n=3:v=0:a=1[a]" \
-map "[v]" -map "[a]" -c:v libx264 -pix_fmt yuv420p -c:a aac qc.mp4

#1) 블랙·프리즈·무음 검출

세 필터를 한 번에 실행하는 명령입니다. 영상은 디코딩만 하고 출력은 버립니다(-f null -).

ffmpeg -hide_banner -i qc.mp4 \
  -vf "blackdetect=d=0.5:pix_th=0.10,freezedetect=n=-60dB:d=1" \
  -af "silencedetect=n=-50dB:d=0.5" \
  -f null - 2>&1 | grep -E "black_|freeze_|silence_"

실행 결과(요약):

black_start:2 black_end:5 black_duration:3
lavfi.freezedetect.freeze_start: 0
lavfi.freezedetect.freeze_duration: 2
lavfi.freezedetect.freeze_end: 2
lavfi.freezedetect.freeze_start: 2
lavfi.freezedetect.freeze_duration: 3
lavfi.freezedetect.freeze_end: 5
silence_start: 2
silence_end: 5.000023 | silence_duration: 3.000023
필터 결과 해석
blackdetect 2초~5초 만들어 둔 검은 화면 구간을 정확히 검출
freezedetect 0~2초, 2~5초 빨간 화면과 검은 화면 모두 "정지"로 검출
silencedetect 2초~5초 무음 구간 검출

#주요 옵션의 의미

옵션 의미 조정 기준
blackdetect=d 검은 화면이 최소 몇 초 이상 지속되어야 보고할지 방송 사고 기준(0.5~2초)에 맞춤
blackdetect=pix_th 픽셀을 검다고 볼 밝기 임계값(0~1) 소재의 블랙 레벨에 맞춤
freezedetect=n 프레임 간 차이를 "같다"고 볼 노이즈 허용치 인코딩 노이즈가 많으면 값을 올림
freezedetect=d 정지로 판단할 최소 지속 시간 정지 화면이 의도된 구간이 있으면 길게
silencedetect=n 무음으로 볼 음량 임계값(dB) -50dB 전후에서 시작
silencedetect=d 무음 최소 지속 시간 의도된 무음 연출이 있으면 길게

#2) 라우드니스 측정

방송 음량 규정은 대부분 LUFS(Loudness Units relative to Full Scale) 기준의 라우드니스로 관리합니다. FFmpeg의 ebur128 필터가 EBU R128 방식의 측정을 제공합니다.

ffmpeg -hide_banner -nostats -i qc.mp4 -af ebur128=peak=true -f null - 2>&1 | sed -n '/Summary/,$p'
Integrated loudness:
  I:         -21.8 LUFS
Loudness range:
  LRA:        10.2 LU
True peak:
  Peak:      -17.7 dBFS
  • I (Integrated): 전체 프로그램의 평균 라우드니스. 방송 기준 값과 비교합니다.
  • LRA: 라우드니스 범위(음량 변화 폭).
  • True Peak: 실제 파형 피크. 클리핑·왜곡 위험을 판단합니다.

위 테스트는 무음이 포함되어 있고 톤의 크기가 작아 값이 낮게 나왔을 뿐입니다. 어떤 기준(예: 유럽 EBU R128 -23 LUFS, 미국 ATSC A/85 -24 LKFS)을 적용할지는 납품·송출 규격에 따라 다릅니다. 방송사나 플랫폼 규정을 확인해서 설정하세요.

#직접 확인: 구간별 측정값이 움직이는 모습

진폭이 다른 핑크 노이즈 8초 3구간(0.1, 0.5, 1.0)을 이어 붙인 24초 오디오를 ebur128로 측정하고, 로그의 100ms 단위 값을 그래프로 그렸습니다(framelog=info로 순간값이 로그에 출력됩니다).

ffmpeg -hide_banner -nostats -i loud.wav -af ebur128=framelog=info -f null - 2>&1 | grep "M:"
핑크 노이즈 3구간의 라우드니스 측정 그래프. Short-term 값이 구간이 바뀔 때 약 3초에 걸쳐 -34.6, -20.6, -14.6 LUFS로 수렴하고 Integrated는 -16.7 LUFS
실측 라우드니스. 빨강: Momentary(400ms), 파랑: Short-term(3초), 초록 띠: -23 LUFS ±1 목표 범위.
  • 각 구간의 Short-term 값은 약 -34.6 → -20.6 → -14.6 LUFS로 수렴했고, 전체 Integrated는 -16.7 LUFS였습니다. 구간별 값을 평균한 것이 아니라 게이팅이 적용된 프로그램 전체 값입니다.
  • Momentary는 구간 변화에 빠르게 반응하고, Short-term은 3초 창이라 구간이 바뀐 뒤 약 3초가 지나야 안정됩니다. 처음 3초는 값이 채워지지 않았습니다(그래프에서 바닥에 붙은 부분).
  • 그래서 합격 판정은 어느 한 순간의 값이 아니라 Integrated와 LRA로 해야 합니다. 이 샘플은 목표(-23 LUFS)보다 6 LU 이상 큽니다.

#3) 레터박스·필러박스(검은 띠) 검출

4:3 소재를 16:9에 넣거나 반대로 한 경우에 생기는 검은 띠는 cropdetect로 감지할 수 있습니다.

# 테스트: 640x360 영상에 위아래 검은 띠를 붙여 640x480으로 만든 뒤 검사
ffmpeg -hide_banner -ss 5.5 -t 1 -i qc.mp4 -vf "pad=640:480:0:60,cropdetect=24:2:0" -f null - 2>&1 | grep -o "crop=[0-9:]*" | tail -1
crop=640:360:0:60

"640×360 영역을 y=60 위치에서 자르면 검은 띠가 제거된다"는 결과로, 의도한 값을 정확히 찾았습니다. 이 결과는 프록시나 송출 변환 시 화면비 처리에 활용할 수 있습니다.

#4) 파형 모니터와 벡터스코프로 눈으로 확인하기

수치 검사로 못 잡는 문제(밝기 범위 이탈, 색 편향)는 스코프로 확인합니다. FFmpeg의 waveform과 vectorscope 필터로 SMPTE 컬러 바를 분석해 나란히 놓았습니다.

ffmpeg -f lavfi -i smptebars=size=640x360:r=25 -frames:v 1 -filter_complex \
  "split=3[a][b][c];[b]waveform=filter=lowpass:scale=digital:graticule=green:flags=numbers+dots,scale=400:360[w];[c]vectorscope=mode=color2:graticule=green:flags=name,scale=360:360[v];[a]scale=640:360[o];[o][w][v]hstack=3" scope.png
SMPTE 컬러 바 원본, 파형 모니터, 벡터스코프를 나란히 놓은 이미지
왼쪽부터 원본, 파형 모니터(가로: 화면 위치, 세로: 밝기), 벡터스코프(각도: 색상, 중심에서의 거리: 채도).
  • 파형 모니터: 가로는 화면의 좌우 위치, 세로는 밝기입니다. 8비트 방송 영상의 정상 범위(리미티드 레인지)는 16~235이므로 이 범위를 벗어나는 신호가 있는지 봅니다. 컬러 바의 각 막대가 서로 다른 높이의 가로선으로 나타납니다.
  • 벡터스코프: 색상은 각도, 채도는 중심에서의 거리입니다. 컬러 바의 점이 R, Mg, B, Cy, G, Yl 표시 안에 들어오면 색이 정상입니다. 점이 한쪽으로 쏠려 있으면 색 편향(화이트 밸런스, 변환 오류) 을 의심합니다.
  • 자동화할 때는 signalstats 필터로 프레임별 밝기 최소·최대(YMIN, YMAX)를 수치로 뽑아 범위를 벗어난 프레임 수를 세는 방식이 더 실용적입니다. 스코프 이미지는 문제가 보고된 소재를 사람이 확인하는 도구로 씁니다.

#자동 QC 파이프라인 구성

실제 시스템에서는 이런 검사를 인제스트 직후의 작업 단계 하나로 구성합니다.

인제스트 완료
   ↓
① 구조 검사: Footer/RIP, IsTruncated, 프레임 수 (MXF)
   ↓
② 규격 검사: 코덱, 해상도, 프레임레이트, 주사 방식이 규격과 일치하는가
   ↓
③ 영상·오디오 검사: blackdetect / freezedetect / silencedetect / ebur128
   ↓
④ 결과를 구간(시작·끝 타임코드) + 종류 + 심각도로 DB에 저장
   ↓
⑤ 사람이 경고 구간만 프록시로 확인 후 승인/반려

④에서 결과를 타임코드 구간으로 저장하는 것이 중요합니다. FFmpeg 출력은 초 단위이므로, 소재의 시작 타임코드와 프레임레이트를 이용해 타임코드로 바꿔서 저장해야 MAM의 마커로 바로 쓸 수 있습니다(1장 타임코드 편 참고).

#성능 고려

  • 영상 필터는 모든 프레임을 디코딩해야 하므로 UHD나 롱 GOP에서는 시간이 오래 걸립니다. 프록시(저해상도)에서 검사하면 훨씬 빠르지만, 원본에서만 보이는 문제(블록 노이즈, 미세한 색상 문제)는 놓칩니다. 용도에 따라 원본/프록시 검사를 나누세요.
  • 필터를 한 번의 실행에 묶으면(위 예시처럼) 파일을 한 번만 읽고 디코딩합니다. 검사마다 따로 실행하면 같은 파일을 여러 번 디코딩해 낭비입니다.
  • 여러 파일을 동시에 처리할 때는 CPU 코어 수를 기준으로 동시 작업 개수를 제한하세요.

#정리

  • 자동 QC는 "오류 판정"이 아니라 사람이 확인할 구간을 좁혀 주는 도구입니다.
  • FFmpeg 필터(blackdetect, freezedetect, silencedetect, ebur128, cropdetect)만으로도 기본 QC 파이프라인을 만들 수 있습니다.
  • 임계값은 소재 유형과 납품 규격에 맞게 조정하고, 결과는 타임코드 구간으로 저장해 MAM 마커와 연결합니다.

#참고 자료

링크는 2026-10-28에 열람이 되는 것을 확인했습니다. 규격과 도구 문서는 개정될 수 있으므로 적용하기 전에 최신 판을 확인하세요.