홈 › 7장 트러블슈팅 케이스북

7.1 사례 1 - 타임코드가 어긋났을 때

드롭 프레임과 논드롭 프레임 혼동이 만드는 108프레임 차이, 프록시 변환 시 타임코드 트랙 보존 여부, -map 0으로 타임코드 스트림을 MP4에 넣을 때의 오류를 재현하고 점검 방법을 정리합니다.

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

#증상

  • 프록시에서 지정한 구간(in/out)을 원본에 적용하면 몇 프레임 또는 몇 초 어긋난다.
  • 1시간 지점 근처의 구간에서만 오차가 약 3.6초로 커진다.
  • 원본에서는 타임코드가 01:00:00:00부터인데 프록시에서는 00:00:00:00부터 시작한다.

#원인 1: 드롭 프레임(DF)과 논드롭(NDF)의 혼동

1장에서 설명한 대로 29.97fps 소재의 타임코드는 DF와 NDF가 있고, 같은 숫자라도 가리키는 프레임이 다릅니다. 두 방식으로 같은 숫자를 해석했을 때의 프레임 번호 차이를 계산했습니다.

00:59:58;00 (DF)  = 프레임 107,832
00:59:58:00 (NDF) = 프레임 107,940     → 차이 108 프레임
01:00:00;00 (DF)  = 프레임 107,892
01:00:00:00 (NDF) = 프레임 108,000     → 차이 108 프레임

108프레임 = 약 3.6초입니다. 시스템 중간 어딘가에서 구분자(; → :)가 바뀌거나, DF 여부를 모르고 NDF로 계산하면 1시간 근처에서 이 크기의 오차가 생깁니다. 오차가 시간에 비례해서 커지는 패턴이면 DF/NDF 문제를 먼저 의심하세요(0분 근처는 오차가 거의 없음).

확인: MediaInfo의 Time code of first frame(구분자 확인), FFprobe의 tag:timecode를 봅니다. 구분자가 ;이면 DF입니다.

대책

  • 타임코드를 문자열로만 저장하지 말고 DF 여부(boolean)와 프레임레이트를 함께 저장한다.
  • 프레임 번호 ↔ 타임코드 변환은 하나의 검증된 함수(1장의 정수 연산)만 쓴다.
  • 단위 테스트 경계값: 00:00:59;29 → 00:01:00;02, 00:09:59;29 → 00:10:00;00, 1시간이 프레임 107,892인지 확인.

#원인 2: 프록시에 시작 타임코드가 없다

원본이 00:59:58;00부터 시작하는 ProRes MOV를 H.264 MP4로 변환했습니다.

ffmpeg -i prores.mov -c:v libx264 -pix_fmt yuv420p -c:a aac proxy_tc.mp4
ffprobe -v error -show_entries stream=index,codec_type:stream_tags=timecode -of compact proxy_tc.mp4
stream|index=0|codec_type=video|tag:timecode=00:59:58;00
stream|index=1|codec_type=audio
stream|index=2|codec_type=data|tag:timecode=00:59:58;00

이번 테스트 환경(2026년 2월 빌드 FFmpeg)에서는 재인코딩만으로도 타임코드가 MP4에 유지되었습니다. 그러나 이것은 FFmpeg 버전과 옵션, 입력 파일의 구조에 따라 달라질 수 있는 동작입니다. 타임코드가 유지되는지를 프록시 생성 후마다 검증하세요. 유지되지 않는 경우를 대비해 두 가지를 해둡니다.

  1. 시작 타임코드를 DB에 별도로 저장한다(파일 의존을 줄임).
  2. 필요하면 변환 시 명시적으로 지정한다.
ffmpeg -i prores.mov -c:v libx264 -pix_fmt yuv420p -c:a aac -timecode "00:59:58;00" proxy_tc3.mp4

위 명령의 결과에서도 비디오 스트림과 data 스트림 모두 00:59:58;00이 기록되었습니다.

#원인 3: -map 0으로 타임코드 스트림까지 넣으려는 경우

오디오 누락을 피하려고 -map 0을 쓰면(4장) 타임코드 같은 데이터 스트림도 함께 매핑됩니다.

ffmpeg -i prores.mov -c:v libx264 -pix_fmt yuv420p -c:a aac -map 0 proxy_tc2.mp4
[mp4] Could not find tag for codec none in stream #2, codec not currently supported in container
Could not write header (incorrect codec parameters ?): Invalid argument
Nothing was written into output file, because at least one of its streams received no packets.

데이터 스트림(tmcd)을 MP4에 복사할 수 없어 변환이 실패했고, 결과 파일은 (불완전한 채로 남았다면) moov atom not found로 읽히지 않았습니다. 해결은 필요한 스트림만 명시하는 것입니다.

-map 0:v:0 -map 0:a            # 비디오 1개 + 모든 오디오 (데이터 스트림 제외)
# 또는
-map 0 -map -0:d               # 전체에서 데이터 스트림만 제외

타임코드는 -map이 아니라 위의 -timecode 옵션이나 DB로 따로 다룹니다.

#점검 순서

  1. 원본과 프록시의 시작 타임코드, DF 여부, 프레임레이트를 각각 분석 도구로 읽는다(3장).
  2. 구간 계산에 쓴 프레임레이트가 분수(30000/1001)인지, 29.97 같은 근사값인지 확인한다.
  3. 오차가 일정한가, 시간에 비례하는가를 본다. 일정하면 시작 타임코드 오프셋 문제, 비례하면 프레임레이트/DF 문제.
  4. 프록시의 프레임 수가 원본과 같은지 확인한다(VFR 변환이나 프레임 드롭이 있었다면 달라짐).
  5. 재현한 뒤 회귀 테스트로 보관한다.
오차 패턴 의심
모든 구간에서 정확히 N프레임 일정 시작 타임코드 오프셋(프록시가 0부터 시작)
시간이 갈수록 커짐(1시간에 약 3.6초) DF/NDF 혼동, 29.97를 30으로 계산
분 경계에서 1~2프레임 점프 DF 건너뜀 규칙 구현 오류(1800번이 ;02이어야 함)
중간에서 갑자기 차이 발생 프레임 드롭, VFR, 편성 전환으로 인한 타임코드 불연속

#정리

  • 오차의 형태(일정/비례/점프)가 원인을 알려 줍니다.
  • DF와 NDF는 1시간에 약 108프레임(3.6초) 차이가 나므로, 타임코드는 항상 DF 여부와 함께 다룹니다.
  • 변환 후에는 타임코드 보존을 검증하고, -map 0은 데이터 스트림 때문에 실패할 수 있습니다.