7.2 사례 2 - 오디오와 비디오 싱크 문제
스트림 시작 시각 차이(start_time)로 생기는 싱크 오프셋을 재현하고, TS의 오디오 선행, ffprobe/MediaInfo로 측정하는 방법, asetpts와 adelay로 보정하는 방법과 판단 기준을 설명합니다.
#증상
- 변환한 영상의 입 모양과 소리가 어긋난다(처음부터 어긋나거나 점점 어긋남).
- 원본에서는 맞았는데 프록시에서만 어긋난다.
- 특정 플레이어에서만 어긋난다.
#싱크는 "스트림 시작 시각"의 차이다
영상과 오디오는 별도의 스트림이고, 각 스트림은 자신의 시작 시각(start_time) 을 가집니다. 두 시작 시각이 다르면 플레이어가 그 차이를 어떻게 처리하느냐에 따라 싱크가 달라집니다. 먼저 측정해야 합니다.
ffprobe -v error -show_entries stream=codec_type,start_time,duration -of compact input.mp4
#재현 1: 오디오가 0.5초 늦게 시작하는 파일
오디오 입력에 -itsoffset 0.5를 주어 일부러 0.5초 늦춘 MP4를 만들었습니다.
stream|codec_type=video|start_time=0.000000|duration=4.000000
stream|codec_type=audio|start_time=0.476009|duration=4.023220
오디오의 start_time이 0.476초입니다(AAC 인코딩 지연 때문에 정확히 0.5가 아님). 이런 값이 보이면 비디오와 오디오가 0.4~0.5초 어긋나 시작한다는 뜻입니다.
#재현 2: 방송 TS의 미세한 시작 차이
앞 장들에서 쓴 녹화 TS를 측정했습니다.
stream|codec_type=video|start_time=1.480000
stream|codec_type=audio|start_time=1.458667
오디오가 비디오보다 약 21ms 먼저 시작합니다. MediaInfo에서 본 Delay relative to video : -21 ms와 같은 값입니다(3장). 21ms는 인지하기 어려운 차이(보통 ±40ms 이내는 허용)이지만, 50ms를 넘으면 어긋남을 느끼기 시작합니다.
#측정 기준
| 차이(오디오 − 비디오) | 판단 |
|---|---|
| ±40ms 이내 | 일반적으로 인지하기 어려움 |
| 40~100ms | 민감한 시청자는 인지 |
| 100ms 이상 | 명확히 어긋남 |
| 점점 커짐 | 샘플레이트·프레임레이트 변환 오류 또는 VFR |
방송 시스템의 허용 기준은 규격과 운영 정책에 따릅니다. 위 값은 일반적인 참고치입니다.
#보정 방법
원인이 시작 시각의 일정한 차이인 경우 보정할 수 있습니다.
#시작 시각 맞추기
# 오디오의 타임스탬프를 0부터 다시 시작
ffmpeg -i delayed.mp4 -af "asetpts=PTS-STARTPTS" -c:v copy -c:a aac fixed.mp4
결과: 비디오와 오디오의 start_time이 모두 0.000000이 되었습니다. 단, 이 방법은 오디오가 의도적으로 늦게 시작해야 하는 소재(예: 영상 앞부분에 오디오 없음)에서는 소리를 앞당겨 어긋나게 만들 수 있습니다. 싱크가 실제로 어느 방향으로 얼마나 어긋났는지 확인한 뒤 적용하세요.
#일정 시간 지연/앞당김
# 오디오를 500ms 늦춤 (모든 채널)
ffmpeg -i fixed.mp4 -af "adelay=500:all=1" -c:v copy -c:a aac d500.mp4
adelay는 오디오 앞에 무음을 삽입해 소리를 늦춥니다(그래서 start_time은 0으로 유지됩니다). 반대로 소리를 앞당기려면 -ss 또는 atrim으로 앞부분을 잘라냅니다. 싱크 보정은 눈과 귀로 확인하면서 값을 조정하는 작업이므로, 결과를 반드시 재생해서 점검하세요.
#점점 어긋나는 경우
처음에는 맞다가 시간이 갈수록 벌어지는 경우는 시작 시각 문제가 아닙니다.
| 원인 | 설명 | 확인 |
|---|---|---|
| VFR(가변 프레임레이트) | 프레임 간격이 일정하지 않은데 CFR로 가정하고 처리 | 3장 프레임 통계의 interval_kinds |
| 프레임레이트 변환 | 29.97 → 25 등에서 시간을 늘리거나 줄였는데 오디오는 그대로 | 변환 후 영상/오디오 길이 비교 |
| 샘플레이트 불일치 | 48kHz를 44.1kHz로 재생하는 식의 오류 | sample_rate |
| 재인코딩 중 오디오 드롭 | 입력이 손상되어 일부 오디오 프레임 누락 | 변환 로그의 경고 |
예를 들어 앞서 본 VFR 파일에서는 비디오 길이가 5.005초, 오디오가 5.013초로 약 8ms 차이가 있었습니다. 이 정도는 정상 범위이지만, 이 차이가 수백 ms로 커지면 문제입니다.
VFR을 CFR로 정규화하면서 길이를 유지하는 변환은 다음과 같습니다.
ffmpeg -i vfr.mp4 -vf "fps=30000/1001" -af aresample=async=1 -c:v libx264 -c:a aac cfr.mp4
fps=30000/1001: 프레임을 일정 간격으로 맞춤(빠진 프레임은 복제)aresample=async=1: 오디오 자신의 타임스탬프가 끊기거나 겹친 곳을 보정합니다(빈 구간은 무음으로 채우고 겹치는 구간은 잘라 냅니다). 영상과 오디오 사이의 오프셋을 알아서 맞춰 주는 필터가 아닙니다. 입 모양이 어긋난 파일은 위의 측정 절차로 오프셋을 구한 뒤-itsoffset이나adelay로 따로 보정해야 합니다.
#점검 순서
- 원본, 프록시 각각의 스트림 시작 시각과 길이를 측정한다.
- 차이가 일정한지, 커지는지 본다.
- 일정하면 시작 시각 보정, 커지면 VFR·프레임레이트 변환·샘플레이트를 확인한다.
- 보정 후 눈과 귀로 확인하고, 수치(start_time 차이)를 기록한다.
- 프록시 생성 파이프라인에는 자동 검증(두 스트림의 start_time 차이가 허용치 이내인지)을 넣는다.
#정리
- 싱크는 먼저 측정합니다:
start_time과duration의 스트림별 차이. - 일정한 차이는
asetpts/adelay로 보정하고, 점점 벌어지는 차이는 VFR·프레임레이트 변환·샘플레이트를 확인합니다. - 방송 TS의 수십 ms 차이는 정상 범위일 수 있으므로 허용 기준을 정해 두고 판단합니다.
#참고 자료
링크는 2026-10-28에 열람이 되는 것을 확인했습니다. 규격과 도구 문서는 개정될 수 있으므로 적용하기 전에 최신 판을 확인하세요.