블로그 목록
Media10분 읽기

라이브 스트림 상태 점검 — ffprobe와 GStreamer

RTSP 등 live input의 연결 상태, stream metadata, packet·frame timestamp를 ffprobe와 GStreamer 도구로 확인합니다. timeout을 둔 probe, PTS·DTS 출력, frame CSV 추출, `gst-discoverer-1.0` 사용법을 나누고 각 명령이 실제 media 수신까지 보장하는지 여부도 구분합니다.

ffprobeffmpeggstreamerRTSPPTSDTS디버깅CLI

"이 RTSP 카메라 살아있나?", "녹화된 mp4의 타임스탬프가 비정상이라는데 어디 보지?". 라이브 스트림 트러블슈팅에서 가장 먼저 던지는 질문들입니다. 이 글은 현장에서 실제로 쓰는 4가지 점검 명령어를 사용처별로 정리합니다. 각 방법이 무엇을 보여주고, 어떤 신호를 읽어야 하는지에 초점을 둡니다.


점검 4가지 사용처 매트릭스

상황도구핵심 지표
RTSP/HTTP URL을 열 수 있나?ffprobe URL연결·인증·헤더 파싱 결과
패킷 타임스탬프가 정상인가?ffprobe -show_packetsDTS 순서와 PTS/DTS 관계
프레임별 시각을 csv로 뽑고 싶다ffprobe -f lavfi -i movie=...frame timestamp 매칭
코덱·해상도·라이브 여부 한 번에gst-discoverer-1.0메타데이터 한 화면

목적에 따라 도구를 골라야 합니다. 모든 도구를 매번 다 돌리는 건 시간 낭비입니다.


방법 1 — ffprobe 단순 호출: "살아있는지"만 확인

가장 가벼운 첫 단계. URL이 RTSP·HTTP·로컬 파일이든 그냥 찔러봅니다.

# RTSP 카메라 응답 확인 (실제 비밀번호는 셸 히스토리·프로세스 목록에 남기지 않도록 별도 주입)
ffprobe "rtsp://<user>:<password>@192.168.0.151:554/cam/realmonitor"

# 로컬 파일 메타데이터
ffprobe input.mp4

읽는 법

  • 메타데이터 출력 → 해당 시점에 연결·인증·헤더 파싱 성공. 지속적인 프레임 수신까지 증명하지는 않음
  • 수 초 이상 응답 없음 → 네트워크, 서버, 프록시 또는 RTSP 전송 협상 문제부터 확인
  • Connection refused → 포트 닫힘
  • 401 Unauthorized → 인증 정보 오류

타임아웃 옵션: 무한 대기 방지하려면 -rw_timeout 5000000 (마이크로초 단위, = 5초) 추가. CI나 모니터링 스크립트에서 필수.

ffprobe -rw_timeout 5000000 "rtsp://..."

방법 2 — -show_packets: 패킷 단위 타임스탬프 분석

스트림은 살아있는데 화면이 끊기거나 시간이 어긋나는 경우. 패킷 헤더를 까서 pts/dts를 직접 읽습니다.

ffprobe -show_packets input.mp4

# 비디오 트랙만
ffprobe -select_streams v:0 -show_packets input.mp4 | head -50

출력 핵심 필드

[PACKET]
codec_type=video
pts=0
pts_time=0.000000
dts=0
dts_time=0.000000
duration=3000
flags=K_      ← K가 있으면 keyframe(I-frame)
size=14572
[/PACKET]

해석 예시

pts_time:  0.000  0.033  0.067  0.100  0.133 ...   (30fps, 약 33ms 간격)
dts_time:  0.000  0.033  0.067  0.100  0.133 ...   (B-frame이 없으면 흔히 pts와 동일)

비정상 신호

신호의심
pts 간격이 예상과 다름가변 프레임레이트, 프레임 드롭, 타임스탬프 재작성 여부를 함께 확인
pts가 갑자기 큰 점프타임스탬프 wrap-around, 인코더 리셋
전송 순서에서 pts 역행B-frame 재정렬이면 정상일 수 있음. DTS·패킷 순서와 함께 확인
pts ≠ dtsB-frame이 있어 정상. 둘이 다른 게 자연스러운 상황 (#29 참고)

pts/dts가 왜 다를 수 있는지는 B-frame 이해하기 참조.

타임스탬프만 추리기

전체 패킷이 너무 많으면 pts_time만 뽑습니다.

ffprobe -show_packets input.mp4 -show_entries packet=pts_time -of csv=p=0
# 0.000000
# 0.033333
# 0.066666
# ...

방법 3 — lavfi 필터로 프레임별 타임스탬프 + 이미지 매칭

분석 목적상 "이 프레임이 어느 시점인가"를 csv로 만들어야 할 때가 있습니다. 예: 영상에서 추출한 이미지 100장이 각각 몇 초 시점인지 매칭.

프레임 타임스탬프 csv 만들기

ffprobe -f lavfi -i "movie=input.mp4,fps=fps=25" \
  -show_frames \
  -show_entries frame=pts_time \
  -of csv=p=0 > frames.txt

# 결과:
# 0
# 0.04
# 0.08
# 0.12
# ...

필드명 주의: 현재 ffprobe의 프레임 출력은 pts_time을 사용합니다. 과거 빌드에서는 pkt_pts_time이 보일 수 있으므로, 설치된 버전의 -show_frames 출력과 공식 문서를 기준으로 필드명을 선택하세요. FFmpeg 개발 브랜치에서는 2021년 7월 이 이름 변경이 반영됐습니다.

fps=25 필터는 입력 영상을 균일한 25fps로 리샘플하면서 프레임 타임스탬프를 새로 부여합니다.

이미지 추출 + 리스트와 매칭

# 영상에서 프레임을 jpeg으로 모두 추출
ffmpeg -i input.mp4 -vf fps=25 image-%04d.jpeg

# 이미지 파일 리스트
ls -1 image-*.jpeg > images.txt

# 둘을 paste로 합쳐서 (이미지, 시각) 페어 만들기
paste -d ' ' images.txt frames.txt > matched.txt
# image-0001.jpeg 0
# image-0002.jpeg 0.04
# image-0003.jpeg 0.08

RTSP에서 1초당 한 장 캡처

스트림에서 주기적으로 스냅샷이 필요할 때:

ffmpeg -i "rtsp://admin:1234@192.168.0.151:554/cam/realmonitor" \
  -f image2 \
  -vf fps=1 \
  img%03d.jpg
  • fps=1 → 1초당 한 장
  • 모니터링 시스템에서 카메라가 정말 화면을 내고 있는지 시각 검증할 때 유용

방법 4 — gstreamer로 한눈에 보기

ffprobe는 강력하지만 출력이 장황합니다. 메타데이터를 한 화면에 깔끔히 보고 싶으면 gstreamer의 gst-discoverer-1.0이 더 빠릅니다.

# RTSP 검사
gst-discoverer-1.0 "rtsp://<user>:<password>@192.168.0.151:554/cam/realmonitor"

출력 예시

아래는 형식을 설명하기 위한 축약 예시입니다. 실제 필드와 값은 URI, 플러그인, GStreamer 버전에 따라 달라집니다.

Topology:
  container: <발견된 컨테이너 또는 스트림 토폴로지>
    audio: <발견된 오디오 코덱>
    video: <발견된 비디오 코덱>

Properties:
  Duration: <알 수 없음 또는 보고된 길이>
  Seekable: <yes/no>
  Live: <yes/no>
  Tags:
    video codec: H.264
    audio codec: MPEG-4 AAC

Stream information:
  Resolution: <width>x<height>
  Frame rate: <분자>/<분모>

한 번에 잡히는 것

정보의미
Container/Topology발견된 컨테이너 또는 스트림 구성
Live라이브 스트림 여부
Seekable점프 가능 여부
Resolution해상도
Frame ratefps (30/1 = 30fps)
Bitrate비트레이트 (#18)
CodecH.264 profile 등 (#28)

언제 gstreamer를 쓰나

  • ffprobe보다 요약된 출력이 필요할 때
  • 컨테이너 타입과 코덱 프로파일을 빠르게 확인할 때
  • gstreamer 파이프라인 디버깅 중 (gstreamer 외 환경에서는 굳이 설치할 필요 없음)

ffprobe로 같은 정보를 얻으려면 옵션을 여러 개 조합해야 합니다.

# ffprobe로 비슷한 요약 만들기
ffprobe -v error \
  -select_streams v:0 \
  -show_entries stream=codec_name,profile,width,height,r_frame_rate,bit_rate \
  -of default=noprint_wrappers=1 \
  "rtsp://..."

한눈 정리

┌─────────────────────────────────────────────────────────────┐
│ 1. 살아있는지만?                  → ffprobe URL              │
│ 2. 타임스탬프 이상 의심            → ffprobe -show_packets   │
│ 3. 프레임-이미지 매칭 필요          → lavfi + frame csv      │
│ 4. 메타데이터 요약만 보고 싶다      → gst-discoverer-1.0     │
└─────────────────────────────────────────────────────────────┘

트러블슈팅 흐름

     [스트림 이슈 보고]
            │
            ▼
   ① ffprobe URL — 응답 오나?
            │
       ┌────┴────┐
       │         │
    응답함     응답 X
       │         │
       │      [네트워크/인증 의심]
       │
       ▼
   ② -show_packets — DTS 순서와 PTS 관계는 예상대로인가?
            │
       ┌────┴────┐
       │         │
    예상대로   예상 밖
       │         │
       │      [B-frame 재정렬·타임스탬프 생성 경로 확인]
       │
       ▼
   ③ gst-discoverer — 코덱·해상도 예상대로?
            │
        예상과 다름
            │
       [송출단 인코더 설정 점검]

자동화 한 줄 — 카메라 프로브 스크립트

모니터링 시스템에서 연결·인증·헤더 파싱 성공 여부를 확인하는 간단한 프로브입니다. 지속 수신 상태는 별도의 프레임/패킷 카운터로 확인해야 합니다.

#!/bin/bash
# rtsp-health.sh
URL=$1
TIMEOUT_US=5000000   # 5초

if ffprobe -v error -rw_timeout $TIMEOUT_US "$URL" > /dev/null 2>&1; then
  echo "OK: $URL"
  exit 0
else
  echo "FAIL: $URL"
  exit 1
fi
./rtsp-health.sh "rtsp://<user>:<password>@192.168.0.151:554/cam/realmonitor"
# echo $? 로 0/1 받아서 알람 시스템과 연동

관련 글

참고 자료

© 2026 Frank Kim. All rights reserved.