RTSP(Real Time Streaming Protocol) 레퍼런스 — RFC 2326·7826·SDP·RTP·IP 카메라
이 글의 핵심
IETF RTSP(주로 554/tcp·udp)는 미디어 제어(세션·재생)와 전달 경로(UDP·TCP interleaved)를 분리한 프로토콜입니다. 이 글은 RFC 2326·7826의 메서드·상태, SDP, RTP/RTCP, IP 카메라/ONVIF·인증, FFmpeg·GStreamer 실전, NAT·방화벽, QoS·지터, 버퍼·GOP·대역 제어를 한 권에 묶은 참고서입니다.
RTSP(Real Time Streaming Protocol)는 미디어 서버(또는 IP 카메라·인코더)와 클라이언트(뷰어, NVR, 릴레이 서버)가 세션을 설정하고(SETUP) 재생을 제어하기(PLAY) 위한 애플리케이션 계층 프로토콜입니다. 미디어 자체는 대부분 RTSP가 아니라 RTP/RTCP로 전달되며, 제어 채널인 RTSP와 미디어 채널인 RTP를 어떻게 묶을지가 이 프로토콜의 핵심입니다. 1.0은 IETF RFC 2326, 2.0은 RFC 7826에 정의되어 있습니다.
이 글은 스펙(메서드·SDP·RTP) → 장비(ONVIF·URL·인증) → 구현(FFmpeg·GStreamer) → 배포(방화벽·NAT·QoS) → 운영(버퍼·GOP·다중 스트림) 순서로, CCTV·방송·클라우드 인제스트가 만나는 지점에서 확인해야 할 내용을 정리합니다. 제조사와 펌웨어마다 URL 경로, 코덱, 기본 포트가 다르므로, 여기 나오는 URL 예시는 검증용 템플릿으로만 보십시오.
프로토콜 스펙: RFC 2326과 RFC 7826
RTSP 1.0(2326)과 2.0(7826)의 차이(실무 시야)
- 하위 호환이 없음: RTSP 2.0은 1.0과 하위 호환되지 않는 별개 버전입니다. 두 버전 모두 HTTP와 비슷한 텍스트 기반 메시지를 쓰지만, 2.0은 헤더와 동작 규칙을 훨씬 엄밀하게 정의했습니다.
- 정리된 기능: 2.0에서는
ANNOUNCE와RECORD메서드, 그리고 RTSP 메시지 자체를 UDP로 보내는 방식(rtspu)이 제거되었고, 서버가 클라이언트에게 상태 변화를 알리는PLAY_NOTIFY, 요청 파이프라이닝(Pipelined-Requests헤더), IPv6와 TLS(rtsps) 지원이 정비되었습니다. - 현장의 현실: 대부분의 IP 카메라와 미디어 서버는 여전히 1.0을 씁니다. 클라이언트는
OPTIONS응답과Server헤더, 실제 동작을 보고 지원 범위를 확인하는 편이 안전합니다. NVR이나 릴레이를 직접 만든다면Session헤더와 리소스 URL 처리부터 꼼꼼히 맞추세요. 카메라마다 구현이 조금씩 달라 문제가 가장 자주 나는 곳입니다.
운영 메모: “스펙은 2.0인데 장비는 1.0”인 경우가 흔합니다. 장비별(모델·펌웨어) 지원 현황표를 먼저 확보하는 것이 가장 비용이 적게 듭니다.
RTSP 메서드(핵심 6+α)
RFC 2326 §10 / RFC 7826 §13의 흐름에 맞춰 대표 메서드를 정리합니다.
| 메서드 | 역할(요지) | 실무에서 자주 보는 이유 |
|---|---|---|
| OPTIONS | 서버가 지원하는 메서드 조회 | 클라이언트·라이브러리의 사전 능력 확인, keep-alive 용도 |
| DESCRIBE | Content-Type: application/sdp로 세션 설명(SDP) 획득 | 코덱, 트랙, 제어 URL이 여기에 담김 |
| SETUP | 트랙별 전송 방식(UDP/TCP) 협상과 세션 생성 | 응답의 Session 헤더로 이후 요청을 묶음 |
| PLAY | 재생 시작(범위·속도 지정 가능) | NVR·뷰어의 스트림 시작 |
| PAUSE | 일시정지 | 라이브 카메라는 미지원이거나 무시하는 경우가 많음 |
| TEARDOWN | 세션 종료 | 세션·소켓·디코더 누수 방지 |
(기타) ANNOUNCE, RECORD, GET_PARAMETER, SET_PARAMETER | 송신·녹화(1.0), 파라미터 조회·설정, keep-alive | 푸시형 서버나 특정 카메라 구현에서 등장 |
- CSeq: 요청과 응답을 짝짓는 번호입니다. 디버깅할 때 클라이언트와 서버 로그를 맞춰 보는 기준이 됩니다.
- 응답 코드: 2xx/4xx/5xx 체계가 HTTP와 비슷합니다. 401(인증 필요), 454(Session Not Found), 461(Unsupported Transport)이 현장에서 자주 보입니다.
- 세션 타임아웃:
Session헤더의timeout(기본 60초) 안에 아무 요청도 없으면 서버가 세션을 끊을 수 있습니다. UDP로 미디어를 받는 동안에는 RTSP 연결이 조용하므로, 클라이언트가OPTIONS나GET_PARAMETER를 주기적으로 보내 세션을 유지합니다.
SDP(Session Description Protocol)
DESCRIBE 응답 본문은 보통 SDP(RFC 8866)입니다. 미디어 줄(m=), 전송 프로필(RTP/AVP), a=rtpmap, a=control(RTSP Content-Base와 합쳐 해석하는 상대 URL)을 함께 읽어야 어떤 트랙을 어느 URL로 SETUP할지가 결정됩니다.
m=video/m=audio: 포트(RTSP에서는 보통 0)와 프로토콜(예:RTP/AVP).a=rtpmap:96 H264/90000: 동적 페이로드 타입(PT)과 코덱을 연결하고, 타임스탬프 클럭(비디오는 90kHz)을 표시합니다.a=fmtp: H.264의sprop-parameter-sets(SPS/PPS)처럼 디코딩에 직접 필요한 코덱별 파라미터입니다.a=control:trackID=0등: 해당 트랙에 SETUP을 보낼 URL입니다. 상대 경로면Content-Base(없으면 요청 URL)를 기준으로 합칩니다.
RTP/RTCP와의 관계
- RTP(RFC 3550): 미디어 페이로드에 타임스탬프와 시퀀스 번호를 붙여, 수신 측이 순서를 복원하고 손실을 감지하게 합니다.
- RTCP: 송신자 보고(SR)와 수신자 보고(RR)로 SSRC별 품질 통계를 주고받습니다. SR에는 RTP 타임스탬프와 NTP 벽시계 시각의 대응이 들어 있어, 오디오와 비디오의 립싱크를 맞추는 데 쓰입니다.
- RTSP는 제어만 담당합니다. 미디어는
SETUP에서 합의한 방식대로 별도 RTP/RTCP 포트로 가거나, interleaved 모드로 RTSP와 같은 TCP 연결에 실립니다.
UDP vs TCP(및 RTP+RTCP 포트)
- RTP over UDP: 지연은 낮을 수 있지만 패킷 손실과 도착 간격 변동(지터)이 그대로 화면에 드러납니다. 방화벽, 통신사 NAT, 이중 NAT 환경에 취약합니다.
- RTSP over TCP + interleaved: 연결 하나로 끝나서 관리가 쉽고 안정적인 경우가 많지만, TCP 재전송이 지연과 지터를 키울 수 있으므로 트레이드오프를 측정해 봐야 합니다.
- RTCP 포트: RFC 3550 관례에 따라 RTP는 짝수 포트, RTCP는 그 다음 홀수 포트(RTP+1)를 씁니다. 실제 값은
SETUP의Transport헤더(client_port/server_port)로 협상됩니다.
Interleaved 모드(프레이밍)
RTP와 RTCP를 RTSP와 같은 TCP 연결로 실으려면 바이트 스트림 안에서 패킷 경계를 구분해야 합니다. RFC 2326 §10.12가 정의한 방식은 각 패킷 앞에 $(0x24) 1바이트, 채널 번호 1바이트, 길이 2바이트(빅엔디언)를 붙이는 것입니다. 채널 번호는 SETUP의 Transport: RTP/AVP/TCP;interleaved=0-1처럼 협상하며, 보통 짝수는 RTP, 홀수는 RTCP입니다.
- 장점: UDP 포트를 열기 어려운 환경에서 TCP 연결 하나만 허용하면 됩니다.
- 주의: TCP 혼잡 제어와 재전송 때문에 지연이 출렁일 수 있고, 한 패킷이 막히면 뒤 패킷이 모두 기다리는 HOL(head-of-line) 블로킹이 생깁니다. 비트레이트가 높을수록 GOP 크기와 서버·클라이언트 소켓 버퍼 설정이 중요해집니다.
FFmpeg(개념 예시): rtsp:// 스트림을 받을 때 UDP가 안 되면 TCP를 지정합니다.
# 예: TCP로 RTSP(RTP) 수신(환경/빌드·장비에 따라 옵션명은 변형될 수 있음)
ffplay -rtsp_transport tcp "rtsp://user:[email protected]:554/Streaming/Channels/101"
UDP로 받을 때 화면이 깨지거나 아예 안 나오면 이 방법으로 우회가 되는지 빠르게 시험해 볼 수 있습니다. 운영 환경에서는 장비, 중계 서버, 회선에 맞춰 전송 방식과 버퍼를 정하고 측정값으로 고정하십시오.
IP 카메라 / CCTV
ONVIF 프로파일(개요)
ONVIF는 IP 영상·보안 장비의 상호운용을 위해 기능군별 프로파일을 정의합니다. 세부 요구 사항은 프로파일 버전에 따라 달라집니다.
- Profile S(스트리밍): 영상·오디오 스트리밍, RTSP, PTZ 등 기본 기능. CCTV 시청 용도와 가장 많이 겹칩니다.
- Profile T(고급 스트리밍): H.264/H.265, 메타데이터, 이벤트 등 확장 기능. 장비와 클라이언트가 모두 지원해야 의미가 있습니다.
- (참고) Profile G(녹화), Profile M(메타데이터·분석), Profile A/C(출입 통제) 등은 NVR, 알람, VMS, 출입 시스템과 연결됩니다.
실전: “ONVIF 지원”이라고 되어 있어도 RTSP URL이 문서에 나오지 않거나 비표준인 경우가 있습니다. 장비의 RTSP·미디어 문서를 함께 확보하십시오.
RTSP URL 구조(검증 필수)
일반적인 형식은 rtsp://[user[:pass]@]host[:port]/path[?query]이지만, 경로와 쿼리는 표준이 정하지 않아 제조사·모델·펌웨어에 크게 의존합니다. ONVIF를 지원하는 장비라면 Media 서비스의 GetStreamUri 호출로 정확한 RTSP URL을 받아 오는 것이 추측보다 확실합니다.
# 예시(기종별로 다름) — **실제 본인 장비**와 일치하는지 캡처로 검증
rtsp://admin:****@198.51.100.5:554/cam/realmonitor?channel=1&subtype=0
rtsp://user:****@198.51.100.5:8554/h264?channel=0&stream=0.sdp
rtsp://192.0.2.10:554/Streaming/Channels/101
subtype/stream파라미터: 메인(고화질)과 서브(저화질) 스트림을 고를 때 자주 쓰이며, 키 이름은 제조사마다 다릅니다..sdp로 끝나는 경로: 실제 SDP 파일이 아니라 장비가 관례적으로 붙인 이름일 수 있습니다.ffprobe -v debug로DESCRIBE응답 본문을 직접 확인하는 것이 안전합니다.- 포트 554(기본) vs 커스텀: 554가 막힌 환경을 위해 8554 등 다른 포트를 쓰는 장비와 중계 서버가 있습니다.
인증: Digest(과 Basic)
카메라는 RTSP와 HTTP 모두에서 HTTP Digest 인증(RTSP 1.0은 RFC 2617, 개정판은 RFC 7616)을 흔히 쓰고, 오래된 장비는 Basic을 쓰기도 합니다.
- 흐름: 첫 요청에 401과
WWW-Authenticate가 돌아오면, 클라이언트는 이후DESCRIBE부터PLAY까지 모든 요청에Authorization헤더를 붙여야 합니다. 한 요청이라도 빠뜨리면 인증 루프에 빠지기 쉽습니다. - 계정 관리: Digest는 비밀번호를 평문으로 보내지는 않지만 MD5 기반이라 강하지 않고, Basic은 사실상 평문입니다. 기본 비밀번호 변경, 잠금 정책, 카메라 전용 VLAN과 ACL을 기본으로 두고, 외부로 내보낼 때는 TLS를 씌운 중계 서버를 거치게 하십시오.
PTZ 제어(ONVIF PTZ vs RTSP)
- ONVIF PTZ는 RTSP와 별개인 SOAP(HTTP) 서비스로 동작합니다. VMS(Milestone, Blue Iris, iSpy 등)는 ONVIF 프로파일 토큰을 기준으로 PTZ 명령을 보냅니다.
- RTSP URL 쿼리나
SET_PARAMETER로 PTZ를 하는 방식은 특정 제조사 전용인 경우가 대부분이고 표준이 아닙니다. 쓰려면 문서와 패킷 캡처로 명령 순서를 확인해 고정하십시오.
멀티캐스트
일부 NVR, 방송, 캠퍼스망은 RTP 멀티캐스트를 씁니다. 이때는 SETUP의 Transport: ...;multicast와 SDP c=IN IP4 <그룹 주소>/<TTL>, 스위치의 IGMP 스누핑과 쿼리어, 라우터의 PIM과 ACL을 모두 점검해야 합니다. UDP 멀티캐스트는 장비에서 켜기만 한다고 동작하지 않습니다.
- 사내망·CCTV망: 스위치의 IGMP 스누핑 설정이 없으면 멀티캐스트가 브로드캐스트처럼 모든 포트로 퍼져 망 전체가 느려질 수 있습니다. 규모가 크면 PIM-SSM 설계가 필요합니다.
- 클라우드·인터넷: 인터넷 구간의 종단 간 멀티캐스트는 현실적으로 쓸 수 없으므로, 유니캐스트와 미디어 서버 중계를 조합하는 것이 일반적입니다.
실전 구현(FFmpeg·GStreamer·파이프라인)
FFmpeg로 RTSP 소스 받기(개념)
- RTSP 클라이언트 기능은 FFmpeg의
rtsp디먹서가 담당합니다. 옵션은 버전에 따라 조금씩 다르니ffmpeg -h demuxer=rtsp로 확인하십시오. - 방화벽 때문에 UDP가 어렵다면 앞서 본
-rtsp_transport tcp를 씁니다. - 오디오와 비디오를
-c copy로 재먹싱할 때 타임스탬프 기준이 달라 드물게 싱크가 어긋날 수 있습니다. 가변 프레임레이트(VFR) 카메라라면 비디오만 저장하거나, 재인코딩 시-fps_mode(구-vsync)와aresample필터로 보정하는 방법을 검토합니다.
# 예: RTSP → 파일(코덱 copy, 컨테이너만 변경). 실서비스는 세그먼트·킬스위치·로그·모니터링이 추가됩니다
ffmpeg -hide_banner -rtsp_transport tcp -i "rtsp://user:[email protected]:554/stream" \
-c copy -f mpegts "C:\\recordings\\out.ts"
RTSP를 RTMP / HLS로 릴레이(개념)
- RTSP → RTMP: Nginx-RTMP, MediaMTX(구 rtsp-simple-server), SRS 같은 미디어 서버 앞뒤에
ffmpeg를 끼워 넣는 패턴이 흔합니다. 재인코딩 여부에 따라 CPU 부하와 동시 세션 수가 크게 달라집니다. MediaMTX처럼 RTSP 소스를 직접 받아 여러 프로토콜로 내보내는 서버를 쓰면 FFmpeg 프로세스 관리 부담이 줄어듭니다. - RTSP → HLS: 세그먼트 길이, 끊긴 세그먼트 처리, 프로세스 감시, 캐시 정책을 함께 설계해야 합니다(자세한 내용은 HLS 레퍼런스 참고).
# 예(개략): RTSP → HLS(세그먼트). 운영 시 경로/세그/코덱/키프레임/재접속을 튜닝
ffmpeg -rtsp_transport tcp -i "rtsp://192.0.2.10:554/live" -c copy -f hls -hls_time 2 -hls_list_size 5 out.m3u8
- GOP와 세그먼트:
-c copy에서는 세그먼트를 키프레임에서만 자를 수 있으므로, 카메라의 GOP가 4초면-hls_time 2를 줘도 실제 세그먼트는 4초가 됩니다. 세그먼트 길이를 맞추려면 카메라의 I-frame 간격을 조정해야 합니다(아래 GOP 절).
GStreamer: rtspsrc·(서버) rtsp-server
rtspsrc location=rtsp://… protocols=tcp처럼 전송을 지정하고, 뒤에rtph264depay→h264parse→ 디코더를 잇습니다.gst-rtsp-server라이브러리로 엣지 장비에서 RTSP 서버를 직접 띄울 수도 있지만, 인증·세션 정책 같은 부분은 애플리케이션에서 구현해야 합니다.
# 예(개략, 환경에 따라 plug-in/버전이 다름)
gst-launch-1.0 rtspsrc location=rtsp://192.0.2.10:554/live latency=200 protocols=tcp ! rtph264depay ! h264parse ! decodebin ! autovideosink
latency:rtspsrc내부 지터 버퍼 크기(밀리초, 기본 2000)입니다. 줄이면 지연이 줄지만 지터와 손실에 약해집니다(아래 지터 버퍼 절).
라이브 스트리밍 파이프라인(권장 아키텍처)
- 엣지(카메라/NVR): 내부망에서 RTSP 유니캐스트로 받습니다.
- 미디어 서버: 세션 관리, TLS 종단, HLS·LL-HLS·RTMP 변환, 권한, 썸네일, 녹화를 FFmpeg 프로세스 하나에 몰아넣지 말고 나누십시오. 한 기능이 죽을 때 나머지가 함께 죽지 않아야 하고, 재시도·감독·메트릭을 기능별로 붙일 수 있어야 합니다.
- 배포(클라우드/CDN): 웹 시청은 HLS·LL-HLS, 초저지연은 WebRTC로 역할을 나눕니다. RTSP는 내부망·백홀·장비 구간에 머물고, 인터넷 배포는 HLS나 WebRTC로 이어지는 구조가 일반적입니다(RTMP 글의 인제스트-배포 구조와 비슷합니다).
[ IP Cam (RTSP) ] --(내부망/방화벽)--> [ Media Server / NVR ]
| |
| +--> HLS / LL-HLS (CDN) --> Web/Apps
| +--> RTMP ingest --> Cloud Transcoder
+--(옵션) NDI/SDI/HDMI(현장) ------> [ 생방 스위처 ]
24/7 DVR 녹화(요건·패턴)
- 저장소: 일정 시간 단위로 파일을 나누고(롤링), 디스크 S.M.A.R.T. 모니터링과 RAID/ZFS를 씁니다. 녹화 시각이 증거로 쓰일 수 있으므로 카메라와 서버 모두 NTP로 시간을 맞추고, 법규상 필요하면 암호화와 키 관리도 둡니다.
- 파일 하나를 계속 열어 두는 방식 vs 분할: 정전이나 I/O 오류가 나면 MP4는 마지막에 쓰는
moov가 없어 파일 전체를 못 읽게 될 수 있습니다. 짧은 단위로 나누면 손실이 마지막 조각에 그칩니다. - 장애를 전제로 설계: 24시간 운영에서는 카메라 재부팅, 네트워크 단절이 반드시 일어납니다. 자동 재접속, 파일·디스크 용량 상한, 키프레임·비트레이트·프레임 드롭 헬스체크, 알람(웹훅·메트릭)을 준비하십시오.
# 예: 10분마다 MP4 roll (copy·운영에선 로그/재시도/권한/경로/디스크사전 점검)
ffmpeg -rtsp_transport tcp -i "rtsp://192.0.2.10:554/main" -c copy -f segment -segment_time 600 -reset_timestamps 1 "C:\\dvr\\seg_%04d.mp4"
고급 주제: NAT·방화벽·QoS·손실·지터
NAT Traversal(현실)
- RTSP + RTP(UDP):
SETUP에서 협상한 RTP/RTCP 포트 쌍이 실제로 NAT를 통과할 수 있어야 합니다. 클라이언트가 알려 준client_port는 사설 포트이므로 대칭 NAT나 CGNAT 뒤에서는 서버가 보낸 UDP가 도달하지 못하는 경우가 많습니다. - STUN/ICE는 WebRTC의 방식이고, RTSP 1.0 카메라에서 그대로 쓸 수 있다고 가정하면 안 됩니다. 현실적인 선택지는 (a) TCP interleaved로 우회, (b) 현장에 미디어 서버를 두고 유니캐스트로 중계, (c) SRT, RTMPS, HLS over TLS, WebRTC(TURN) 같은 별도 경로입니다.
- 포트 포워딩: 가정·소규모 환경에서 554와 UDP RTP 범위를 카메라로 포워딩하는 방식은 카메라를 인터넷에 그대로 노출합니다. 가능하면 TLS 중계나 리버스 터널, VPN을 쓰십시오.
방화벽 점검 항목
- 허용해야 하는 트래픽: RTSP(554/tcp), UDP RTP(장비마다 범위가 다름), 관리용 HTTP/HTTPS·ONVIF, 시간 동기용 NTP, 필요하면 SNMP/SSH.
- 방화벽의 RTSP ALG나 SSL 인스펙션이 RTSP 메시지를 고쳐 쓰면서 인증이나 세션이 깨지는 경우가 있습니다. 문제가 생기면 해당 기능을 예외 처리해 보십시오.
- ONVIF 장치 검색(WS-Discovery)은 멀티캐스트를 쓰므로, 카메라와 클라이언트가 다른 서브넷이나 게스트 무선망에 있으면 검색만 안 됩니다. IP를 직접 입력하면 연결됩니다.
QoS(서비스 품질)
- L2(802.1Q CoS)나 L3(DSCP) 마킹으로 영상 트래픽의 우선순위를 표시할 수 있지만, CCTV 트래픽은 대량이고 상시 흐르므로 VLAN 분리와 대역 상한(셰이핑·폴리싱)이 마킹만큼 중요합니다.
- QoS는 마킹만으로 끝나지 않습니다. Wi-Fi, VPN, 비대칭 업링크, 해외 회선처럼 실제 병목이 어디인지 먼저 측정해야 합니다.
- UDP RTP의 손실은 애플리케이션(버퍼, 오류 은닉)이 복구해야 하고, 혼잡은 카메라 쪽 비트레이트·프레임레이트 조정과 셰이퍼로 다룹니다.
패킷 손실과 화면 깨짐
- H.264/H.265에서는 I-frame이 손실되면 다음 I-frame이 올 때까지 화면이 크게 깨지거나 멈출 수 있습니다. 수신 측이 키프레임을 다시 요청하는 RTCP 피드백(PLI/FIR, RFC 4585/5104)은 WebRTC에서는 표준이지만, 일반 RTSP 카메라의
RTP/AVP경로는 대개 지원하지 않습니다. - 현실적인 대응은 (1) TCP interleaved 전환과 자동 재접속, (2) GOP·비트레이트·해상도 재조정, (3) 케이블·스위치·PoE 전원 점검, (4) NVR이나 라이브러리의 지터 버퍼·디코더 설정 조정입니다.
Jitter Buffer(지터 버퍼)
- 수신 측(플레이어·디코더)에서 패킷 도착 간격의 흔들림을 흡수하는 큐입니다. 길게 잡으면 지연이 늘고 안정성이 올라가며, 짧게 잡으면 그 반대입니다.
- 라이브 시청, 보안 녹화, 저지연 제어는 요구가 서로 충돌하므로, 목표 p95 지연과 늦게 도착한 프레임을 버릴지 여부 같은 정책을 수치로 합의해 두십시오.
- FFmpeg, 미디어 서버, 플레이어, 카메라가 각각 자체 버퍼를 갖고 있어 지연은 여러 버퍼의 합입니다. 단계별로 측정해야 어디를 줄일지 알 수 있습니다.
최적화: 버퍼·GOP·대역·다중 스트림
버퍼(소켓/응용/라이브러리) 튜닝(원칙)
- 버퍼를 크게 잡는다고 항상 좋은 것은 아닙니다. 메모리와 지연이 함께 늘어나므로, p95 지연, 손실률, CPU, 동시 세션 수를 함께 보고 정합니다.
- RTSP over TCP에서는 OS 소켓 송수신 버퍼와 FFmpeg·미디어 서버 내부 큐(버전별 옵션)가 모두 영향을 줍니다.
- 카메라가 타임스탬프를 불완전하게 보낼 때는
-fflags +genpts로 PTS를 재생성하는 방법이 있지만, 원래 타임스탬프를 덮어써서 오히려 싱크가 틀어질 수도 있으므로 해당 장비로 검증한 뒤 쓰십시오.
# 예(개략, 버전/환경 확인 필수)
ffmpeg -hide_banner -fflags +genpts -rtsp_transport tcp -i "rtsp://198.51.100.5:554/..." -c copy -f mpegts "out.ts"
GOP(키프레임 간격) / IDR(개념)
- GOP를 짧게 하면 새 시청자의 첫 화면이 빨리 뜨고 손실 후 복구도 빨라지지만, 같은 화질에서 비트레이트가 늘어납니다. 라이브·HLS는 2초, 저지연은 1초처럼 목표를 수치로 정하십시오. 반대로 CCTV 카메라는 대역 절약을 위해 GOP를 수 초 이상으로 길게 잡는 경우가 많아, 녹화 파일 탐색이나 HLS 변환 시 문제가 됩니다.
- B-frame은 인코딩 순서와 표시 순서가 달라 지연을 늘리므로, 저지연 방송·보안 용도에서는 B-frame을 끈(B=0) 설정이 흔합니다.
대역폭 제어
- CBR vs VBR: VBR 카메라는 조용한 장면에서는 비트레이트가 낮다가 움직임이 많거나 야간 노이즈가 생기면 크게 튑니다. 망 설계는 평균이 아니라 최대치 기준으로 하고, 필요하면 카메라의 최대 비트레이트 상한과 스위치 폴리싱을 함께 둡니다.
- 용도별 스트림 분리: 저화질 서브스트림은 다분할 시청과 AI 분석에, 고화질 메인스트림은 녹화와 확대 시청에 쓰는 식으로 역할을 나누면 CPU·GPU, 디스크, 업링크 부담이 줄어듭니다.
- 인터넷 업링크: 가정·지점 회선은 업로드가 좁은 비대칭인 경우가 많습니다. 외부 시청까지 고려한다면 RTSP 구간만이 아니라 배포 쪽(ABR 가능한 HLS 등)까지 함께 설계해야 합니다.
다중 스트림(메인/서브/3번째) 관리
- NVR, 웹, 모바일, 분석, 관제 디스플레이는 필요한 화질이 다릅니다. 같은 4K@60 스트림을 모든 곳에 보내면 대역만 낭비하고 불안정해집니다.
- 스트림별·용도별로 계정과 권한을 나누면 계정 유출이나 무차별 대입 공격의 피해 범위를 줄일 수 있습니다.
- 채널이 수십~수백 개로 늘면 GOP나 코덱보다 세션 관리, 프록시, 디코딩(하드웨어 가속 여부), 디스크 I/O가 먼저 한계에 부딪힙니다. 실제 채널 수로 부하 테스트를 해 보십시오.
트러블슈팅(빈번) — “왜 흰 화면/녹음/늦음/끊김인가”
- 초록·회색 화면, 깨짐(디코딩): SPS/PPS가 대역 내에 없고 SDP에만 있는데 이를 전달하지 않았거나(특히
-c copy로 TS에 저장할 때), 첫 I-frame 전부터 저장이 시작된 경우가 흔합니다. B-frame이나 VFR 타임스탬프도 원인이 됩니다. - TEARDOWN 누락과 세션 누수: 카메라는 동시 세션 수가 적은 경우가 많아, 뷰어나 릴레이가 종료 시 세션을 정리하지 않으면 한도가 차서 새 접속이 거부됩니다.
- 10~60초 주기로 끊김:
Session타임아웃 안에 keep-alive를 보내지 않았거나, 방화벽·통신사 NAT의 유휴 타임아웃, 시간 드리프트, 카메라 전원 문제를 의심합니다. - 수 초~수십 초 지연: GOP, HLS 세그먼트, 플레이어·중계 버퍼가 겹쳐 쌓인 결과입니다. 끝단의 p95 지연을 기준으로 단계별로 하나씩 줄이는 것이 정석입니다.
표준 문서와 카메라 실제 동작의 차이
RTSP 스택은 역할이 나뉘어 있습니다. 세션 제어는 RTSP(RFC 2326, RFC 7826), 미디어 전송과 통계는 RTP/RTCP(RFC 3550), 코덱·포트·제어 URL 기술은 SDP(RFC 8866)가 맡으므로, 문제가 생기면 어느 층의 문제인지부터 가르는 것이 빠릅니다. 다만 IP 카메라의 RTSP URL 경로는 표준이 정하지 않아 제조사마다 다르고, 인증 방식이나 전송(UDP/TCP 인터리브) 지원도 기종마다 차이가 있습니다. ONVIF 프로필 지원 여부를 확인하고, 실제 패킷 캡처로 기종별 동작을 기록해 두는 편이 안전합니다.
FAQ(보강)
- Q.
SETUP을 여러 번 보내나요?
A. 네. SETUP은 트랙 단위이므로 비디오와 오디오가 있으면 보통 두 번 보냅니다. 두 번째 SETUP에는 첫 응답에서 받은Session값을 넣어 같은 세션에 트랙을 추가합니다. 로그에서Session값이 같은지, 트랙별Transport가 어떻게 협상됐는지 보면 문제의 단서를 잡을 수 있습니다. - Q. PTZ용 ONVIF 토큰은 어떻게 얻나요?
A.GetServices(또는 구형GetCapabilities)로 Media·PTZ 서비스 주소를 알아낸 뒤, Media 서비스의GetProfiles로ProfileToken을 받고, 그 토큰을 PTZ 서비스의ContinuousMove같은 명령에 넘깁니다. 라이브러리가 이 과정을 감싸 주는 경우가 많습니다. RTSP URL과는 별개입니다.
같이 보면 좋은 글
- HLS(HTTP Live Streaming) 레퍼런스 — M3U8·ABR·암호화·LL-HLS
- RTMP(Real-Time Messaging Protocol) 레퍼런스 — 핸드셰이크·청크·Nginx·FFmpeg·OBS
- WebRTC 레퍼런스 — PeerConnection·ICE·STUN·TURN·시그널링·SFU
- MPEG-DASH 레퍼런스 — MPD·세그먼트·CENC/DRM·플레이어