홈 › 1장 방송 영상 워크플로우 기초

1.4 타임코드와 드롭 프레임

영상의 주소인 SMPTE 타임코드의 구조, 드롭 프레임이 필요한 이유와 계산법, 프레임 번호와의 변환 방법을 예제 코드로 설명합니다.

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

#타임코드란

타임코드(Timecode)는 영상의 프레임마다 붙는 고유한 주소입니다. 시:분:초:프레임 형식으로 표기하고, 일반적으로 SMPTE 12M 규격을 따릅니다.

01:23:45:12   →  1시간 23분 45초 12프레임

방송 현장에서는 "5분 20초 지점부터 30초 구간"이 아니라 "00:05:20:00부터 00:05:50:00까지"처럼 프레임 단위로 구간을 지정합니다. EDL, 큐시트, 자막, 광고 삽입 위치, MAM의 마커와 서브클립이 모두 타임코드를 기준으로 움직입니다.

#프레임레이트별 표기

프레임레이트 프레임 필드 범위 비고
24, 25 00 ~ 23 / 00 ~ 24 정확히 정수
30 00 ~ 29 NDF 또는 시청 편의상 정수 처리
29.97 00 ~ 29 NDF(Non-Drop) 와 DF(Drop Frame) 두 종류
59.94 00 ~ 59 마찬가지로 NDF/DF

#드롭 프레임이 필요한 이유

29.97fps 영상의 1초는 30프레임이 아니라 약 29.97프레임입니다. 그런데 타임코드는 "1초 = 30프레임"으로 계산해서 숫자를 올리면, 타임코드 시계가 실제 시간보다 느려집니다.

1시간 분량 영상 = 약 107,892 프레임 (29.97 × 3600)
타임코드가 세는 프레임 수 = 108,000 프레임 (30 × 3600)
차이 = 108 프레임 ≈ 3.6초

실제 시계로 1시간이 지났을 때 타임코드는 00:59:56:12를 가리킵니다(107,892프레임 ÷ 30). 반대로 타임코드가 01:00:00:00이 되려면 실제로는 약 3603.6초가 걸립니다. 즉 타임코드 시계가 실제 시계보다 1시간에 3.6초 느리게 갑니다. 방송 시간표는 초 단위로 맞아야 하므로 이 차이를 없애기 위해 드롭 프레임(Drop Frame, DF) 방식을 사용합니다.

#드롭 프레임의 규칙

드롭 프레임은 영상 프레임을 실제로 버리는 것이 아닙니다. 타임코드 숫자를 건너뛰는 방식입니다.

  • 매 분이 시작될 때 프레임 번호 00, 01을 건너뜁니다. (예: 00:00:59:29 다음은 00:01:00:02)
  • 단, 10분 단위(0, 10, 20, 30, 40, 50분) 에는 건너뛰지 않습니다.

이렇게 하면 1시간에 2 × (60 − 6) = 108개의 숫자를 건너뛰어, 앞에서 계산한 108프레임 차이가 정확히 보정됩니다.

표기에서도 구분합니다. NDF는 01:00:00:00처럼 콜론만 쓰고, DF는 마지막 구분자를 세미콜론(또는 점)으로 써서 01:00:00;00으로 적습니다.

#직접 확인: 1분 경계의 6프레임

FFmpeg의 drawtext 필터는 timecode 옵션으로 타임코드를 화면에 새길 수 있습니다. 구분자가 :이면 논드롭 프레임, ;이면 드롭 프레임으로 계산합니다. 29.97fps(30000/1001)에서 00:00:59의 27번 프레임부터 연속된 6프레임을 새겨 비교했습니다.

ffmpeg -f lavfi -i "color=c=0x23272e:s=300x110:r=30000/1001" \
  -vf "drawtext=fontfile=consola.ttf:timecode='00\:00\:59\;27':timecode_rate=30000/1001:fontsize=40:fontcolor=white:x=(w-tw)/2:y=(h-th)/2" \
  -frames:v 6 df_%d.png
논드롭 프레임은 00:00:59:29 다음에 00:01:00:00, 드롭 프레임은 00:00:59;29 다음에 00:01:00;02로 이어지는 연속 6프레임 비교
위 줄: 논드롭(NDF), 아래 줄: 드롭 프레임(DF). 두 줄 모두 연속된 6프레임입니다.

드롭 프레임에서는 59;29 다음 프레임이 01:00;00이 아니라 01:00;02입니다. 사라진 것은 영상 프레임이 아니라 타임코드 숫자 두 개(;00, ;01)뿐이고, 화면은 끊김 없이 이어집니다. 이렇게 매 분마다 숫자를 건너뛰어(10분 단위는 제외) 29.97fps에서 생기는 누적 오차를 실제 시계에 맞춥니다.

#타임코드와 프레임 번호 변환

MAM이나 편집 도구를 만들다 보면 타임코드를 프레임 번호로 바꾸고 다시 되돌리는 작업이 필수입니다. 아래는 29.97fps 드롭 프레임 기준의 파이썬 예제입니다.

def tc_to_frames_df(h, m, s, f):
    """29.97 DF 타임코드 -> 절대 프레임 번호"""
    total_minutes = h * 60 + m
    dropped = 2 * (total_minutes - total_minutes // 10)
    return ((h * 3600 + m * 60 + s) * 30 + f) - dropped


def frames_to_tc_df(frame):
    """절대 프레임 번호 -> 29.97 DF 타임코드 문자열"""
    frames_per_10min = 17982          # 10분 = 600초 * 30 - 18
    frames_per_min = 1798             # 1분 = 60 * 30 - 2 (10분 배수 제외)

    d, m = divmod(frame, frames_per_10min)
    if m < 2:
        frame += 18 * d
    else:
        frame += 18 * d + 2 * ((m - 2) // frames_per_min)

    f = frame % 30
    s = (frame // 30) % 60
    mm = (frame // 1800) % 60
    h = frame // 108000
    return f"{h:02d}:{mm:02d}:{s:02d};{f:02d}"


print(frames_to_tc_df(1800))   # 00:01:00;02
print(tc_to_frames_df(0, 1, 0, 2))  # 1800

00:01:00;02가 프레임 번호 1800과 같다는 점이 핵심입니다. 건너뛴 00, 01 두 숫자는 실제 프레임이 없습니다.

#실무에서 주의할 점

  1. 파일에 NDF/DF 정보가 있는지 확인합니다. MXF는 시작 타임코드와 DF 여부를 메타데이터에 가지고 있고, MOV는 타임코드 트랙(tmcd)에 저장합니다. MediaInfo에서 Time code of first frame, Time code, striped와 같은 항목으로 볼 수 있습니다.
  2. 시작 타임코드가 00:00:00:00이 아닌 경우가 많습니다. 방송 소재는 보통 01:00:00:00부터 시작하는 것이 관례입니다(앞쪽 바와 톤, 카운트다운 때문). 프록시를 만들 때 시작 타임코드를 함께 옮기지 않으면 원본과 프록시의 구간이 어긋납니다.
  3. 프레임 정확도(Frame Accuracy)를 점검합니다. 인터레이스 영상이나 B프레임이 있는 코덱은 탐색 후 정확히 그 프레임을 보여주는지 확인해야 합니다. 프록시와 원본의 프레임 수가 같은지도 검증 항목입니다.
  4. 웹 플레이어는 초 단위입니다. HTML5 <video>의 currentTime은 초(실수) 단위라서, 프레임 단위 이동이 필요한 UI는 프레임 번호 / 프레임레이트를 직접 계산해야 합니다. 이때 29.97를 30000/1001로 정확히 다루는 습관이 중요합니다.

#정리

  • 타임코드는 프레임 단위 주소이며, 29.97fps에서는 NDF와 DF가 있습니다.
  • DF는 프레임을 버리지 않고 숫자만 건너뛰어 실제 시간과 맞춥니다.
  • 시작 타임코드와 DF 여부는 변환·검수 때 반드시 보존하고 확인해야 합니다.

#참고 자료

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