홈 › 3장 MediaInfo와 파일 분석

3.3 FFprobe로 JSON 분석하기

FFprobe의 show_format, show_streams, show_packets, show_frames 옵션과 JSON 출력 활용법, 프레임 수 검증과 PTS/DTS 읽기, 버전에 따른 필드 변경 주의점을 설명합니다.

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

#MediaInfo와 FFprobe의 역할 차이

구분 MediaInfo FFprobe
강점 방송 포맷 메타데이터, 사람이 읽기 쉬운 항목 패킷·프레임 단위 정보, FFmpeg와 같은 해석
약점 프레임 단위 정보 없음 방송 고유 항목 일부 부족
의미 "파일이 스스로 말하는 것" "FFmpeg가 실제로 읽어낸 것"

FFmpeg로 변환할 계획이라면 FFprobe의 해석이 곧 변환 결과의 기준입니다. 그래서 인제스트 분석은 두 도구를 함께 쓰는 것이 안전합니다.

#세 가지 분석 단계

FFprobe는 같은 파일을 세 단계 깊이로 볼 수 있습니다.

옵션 단위 비용 용도
-show_format 파일 매우 빠름 컨테이너, 길이, 크기, 비트레이트
-show_streams 스트림 매우 빠름 코덱, 해상도, 프레임레이트, 오디오 구성
-show_packets 패킷 파일 읽기 필요 PTS/DTS, 키프레임 위치, 패킷 크기
-show_frames 프레임 디코딩 필요, 느림 프레임 유형, 인터레이스 정보

#기본: 포맷과 스트림을 JSON으로

ffprobe -v error -show_format -show_streams -of json input.mxf

필요한 항목만 골라서 받을 수도 있습니다.

ffprobe -v error -select_streams v:0 \
  -show_entries stream=codec_name,profile,level,width,height,pix_fmt,field_order,r_frame_rate,avg_frame_rate,time_base,nb_frames,bit_rate,duration \
  -of json proxy.mp4

실제 출력은 다음과 같습니다.

{
  "streams": [
    {
      "codec_name": "h264",
      "profile": "High",
      "width": 640,
      "height": 360,
      "pix_fmt": "yuv420p",
      "level": 30,
      "field_order": "progressive",
      "r_frame_rate": "30000/1001",
      "avg_frame_rate": "30000/1001",
      "time_base": "1/30000",
      "duration": "5.005000",
      "bit_rate": "213848",
      "nb_frames": "150"
    }
  ]
}

#필드 읽기

  • level: 30: H.264 레벨이 정수로 표시됩니다. 30은 레벨 3.0, 31은 3.1입니다. MediaInfo의 High@L3와 같은 정보입니다.
  • field_order: progressive, tt(top field first), bb(bottom field first) 등으로 나옵니다. 앞서 본 MXF는 tt였습니다.
  • r_frame_rate vs avg_frame_rate: r_frame_rate는 스트림에서 추정한 기본 프레임레이트, avg_frame_rate는 전체 프레임 수를 길이로 나눈 평균입니다. 둘이 다르면 가변 프레임레이트(VFR) 를 의심합니다.
  • time_base: 타임스탬프의 단위입니다. 1/30000이면 PTS 1이 1/30000초입니다.
  • nb_frames: 컨테이너가 기록한 프레임 수입니다. TS나 일부 MXF에서는 N/A 로 나옵니다.

#프레임 수 검증: -count_frames

컨테이너가 기록한 프레임 수가 실제로 읽을 수 있는 프레임 수와 같은지 확인하는 가장 간단한 방법입니다.

ffprobe -v error -count_frames -select_streams v:0 \
  -show_entries stream=nb_frames,nb_read_frames -of default=nw=1 input.mxf

앞 장에서 만든 정상 MXF와, 파일 뒷부분을 잘라 낸 손상 MXF의 결과입니다.

정상 파일 : nb_read_frames=150
잘린 파일 : nb_read_frames=129

잘린 파일은 헤더의 길이 정보는 5.005초로 정상이지만, 실제로 읽을 수 있는 프레임은 129개뿐입니다. 길이 값만 믿으면 이런 파일을 놓칩니다. -count_frames는 파일 전체를 읽기 때문에 시간이 걸리므로, 인제스트 시 "의심 파일"에만 선택적으로 쓰는 것이 좋습니다.

#패킷 읽기: PTS, DTS, 키프레임

ffprobe -v error -select_streams v:0 \
  -show_entries packet=pts_time,dts_time,size,flags -of csv=p=0 \
  -read_intervals "%+#5" proxy.mp4
0.000000,-0.066733,5573,K__
0.033367,-0.033367,832,___
0.133467,0.000000,1126,___
0.066733,0.033367,327,___
0.100100,0.066733,265,___

열은 PTS, DTS, 크기, 플래그입니다.

  • 플래그 K는 키프레임(I) 입니다. 첫 패킷만 키프레임이고 크기(5,573바이트)가 가장 큽니다. 2장의 설명 그대로입니다.
  • PTS와 DTS가 다릅니다. 세 번째 패킷은 표시 시간(PTS)이 0.1335초인데 디코딩 시간(DTS)은 0.0이어서, B프레임 때문에 저장 순서와 표시 순서가 다릅니다. DTS가 음수로 시작하는 것도 B프레임 재정렬 지연을 반영한 값입니다.

-read_intervals "%+#5"는 "처음부터 5개 패킷만 읽어라"는 뜻입니다. 큰 파일의 앞부분만 빠르게 보고 싶을 때 유용합니다. 시간 구간("10%+5": 10초부터 5초 동안)도 지정할 수 있습니다.

#타임코드 읽기

MOV의 타임코드는 스트림 태그로 읽힙니다.

ffprobe -v error -show_entries stream=index,codec_type:stream_tags=timecode -of compact prores.mov
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

비디오 스트림과 data 스트림(tmcd 트랙) 두 곳에 타임코드가 나옵니다. MXF는 포맷 태그(format_tags=timecode)에 나타났습니다. 즉 파일 종류마다 타임코드가 있는 위치가 다릅니다. 분석 코드는 포맷 태그와 스트림 태그를 모두 찾아야 합니다(7편의 분석 도구가 이렇게 처리합니다).

#FFmpeg 버전에 따른 필드 변경

FFprobe의 출력 필드는 버전이 올라가며 바뀝니다. 예전 블로그나 도구에서 가져온 코드가 어느 날 값을 못 읽는 경우가 이 때문입니다.

예전 필드 현재 비고
pkt_pts_time pts_time 프레임 출력 필드. 구형 코드는 값을 못 찾게 됨
pkt_dts_time pkt_dts_time 패킷 기준 DTS (프레임 출력)
coded_picture_number 환경에 따라 없음 프레임 번호는 직접 세는 편이 안전

본 가이드에서 사용한 FFmpeg 빌드(2026년 2월 빌드)에서는 프레임 정보에 pts_time, interlaced_frame, top_field_first, pict_type, key_frame이 있었습니다. 다만 FFmpeg는 개발 과정에서 일부 필드를 폐기(deprecated)하고 다른 형태로 대체하는 일이 있으므로, 분석 코드는 필드가 없을 때를 반드시 처리해야 합니다.

#정리

  • MediaInfo는 "파일이 말하는 것", FFprobe는 "FFmpeg가 읽은 것"입니다. 둘을 함께 쓰세요.
  • 프레임레이트는 분수로, 길이와 프레임 수는 -count_frames로 교차 검증합니다.
  • 패킷 정보에서 PTS/DTS와 키프레임 위치를 읽을 수 있고, 타임코드 위치는 포맷마다 다릅니다.
  • FFprobe 필드명은 버전에 따라 변하므로 분석 코드는 방어적으로 작성합니다.

#참고 자료

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