Trouble Shooting (에러 해결)

[RTSP] Ubuntu HLS 끊김 해결: MediaMTX(WebRTC) 도입 및 검은 화면 해결법

Binary Tree 2026. 1. 14. 11:40

1️⃣ 들어가며: 왜 WebRTC인가? (삽질의 시작)

MediaMTX WebRTC 스트리밍 성공 화면

 

처음에는 RTSP CCTV 영상을 웹 브라우저에 띄우기 위해 Node.js 기반의 HLS(HTTP Live Streaming) 서버를 구축했습니다. 구현은 어렵지 않았지만, 막상 운영해보니 치명적인 단점이 발견되었습니다.

  • 문제점: 영상 딜레이가 심하고, 스트리밍이 간헐적으로 뚝뚝 끊기는(Stuttering) 현상 발생.
  • 판단: "실시간 감시용으로 HLS는 한계가 있다. WebRTC로 넘어가자."

🤔 왜 HLS는 느리고 끊길까? HLS는 영상을 잘게 쪼개서(Chunk) 파일로 만든 뒤 다운로드하는 방식입니다. 태생적으로 **최소 3~10초 이상의 지연(Latency)**이 발생할 수밖에 없는 구조입니다. 반면, WebRTC는 P2P 기반의 실시간 통신을 위해 만들어져 **1초 미만의 초저지연(Ultra Low Latency)**이 가능합니다. CCTV 관제에는 WebRTC가 정답이었습니다.

 

결국 오픈소스 RTSP/WebRTC 서버인 MediaMTX를 도입하기로 결정했습니다. 하지만 이 과정도 순탄치 않았는데, Docker 설정 문제UDP 포트 이슈, 기존 서버(Nginx) 충돌 등 여러 난관을 극복한 과정을 기록으로 남깁니다.


2️⃣ 서버 환경 정보

이 작업은 클린한 서버가 아니라, 이미 수많은 테스트 프로젝트가 돌아가고 있는 **'혼잡한 개발 서버'**에서 진행되었습니다.

  • OS: Ubuntu 24.04.3 LTS
  • 서버 상태: 다수의 웹 서비스(Nginx 등) 및 미들웨어가 실행 중
  • MediaMTX 버전: v1.15.6
  • 목표: RTSP 영상을 WebRTC로 변환하여 끊김 없는 스트리밍 구현

3️⃣ Docker를 포기하고 바이너리를 선택한 이유

처음엔 국룰처럼 Docker 이미지를 사용하려 했습니다. 하지만 MediaMTX 최신 버전(v1.15.6)을 적용하는 과정에서 문제가 터졌습니다.

  1. 설정 파일 민감성: MediaMTX는 버전별로 mediamtx.yml 설정 키값이 매우 엄격하게 변합니다.
  2. 무한 재부팅: Docker 컨테이너로 띄우니 설정 파일 에러가 날 때마다 Restarting... 루프에 빠져 로그 확인과 디버깅이 너무 힘들었습니다.

💡 나의 결론: 배포 단계에서는 Docker가 편하지만, 초기 세팅이나 디버깅 단계에서는 블랙박스 같은 컨테이너보다 로그를 눈으로 직접 볼 수 있는 바이너리 실행이 훨씬 효율적이라 판단했습니다. "남들이 다 쓴다고 무작정 Docker를 쓰는 게 능사는 아니다"라는 걸 이번에 확실히 느꼈습니다.


4️⃣ MediaMTX 설치 및 설정 (v1.15.6 기준)

1. 다운로드 및 설치

GitHub 릴리즈에서 바이너리를 받아 /opt 경로에 설치했습니다.

# 다운로드 & 권한 부여
wget https://github.com/bluenviron/mediamtx/releases/download/v1.15.6/mediamtx_linux_amd64
chmod +x mediamtx_linux_amd64
mv mediamtx_linux_amd64 mediamtx

'./mediamtx --version' 실행 결과

2. 설정 파일(mediamtx.yml)의 함정

💡 설정 포인트:

  • webrtcLocalUDPAddress: :8189: UDP 포트를 8189로 고정하여 방화벽 관리를 편하게 했습니다.
  • webrtcAdditionalHosts: 외부 망에서 접속할 때, 서버가 자신의 공인 IP를 클라이언트에게 알려주도록 설정했습니다. (이거 안 하면 외부에서 접속 불가)
YAML
logLevel: info
logDestinations: [stdout]

rtsp: yes
rtspAddress: :8554

webrtc: yes
webrtcAddress: :8082
webrtcLocalUDPAddress: :8189 # UDP 포트 고정
webrtcAdditionalHosts:
  - 124.61.xx.xx # [중요] 본인 서버의 공인 IP 입력 (외부 접속용)
webrtcICEServers:
  - stun:stun.l.google.com:19302

hls: no

paths:
  cctv1:
    source: rtsp://210.99.xx.xx:1935/live/cctv001.stream
    sourceOnDemand: yes

  cctv2:
    source: rtsp://210.99.xx.xx:1935/live/cctv007.stream
    sourceOnDemand: yes

🚨 [필독] 검은 화면 해결: 방화벽 및 UDP 포트 포워딩

이 부분을 놓치면 100% 검은 화면만 보게 됩니다. WebRTC 설정에서 가장 많이 하는 실수가 TCP 포트만 열고 UDP를 안 여는 것입니다.

  • WebRTC 연결 (Signaling): TCP (8082)
  • 실제 영상 데이터 (Media): UDP (8189)

설정 파일(mediamtx.yml)에 적힌 8082(TCP)만 열어주면, 플레이어 UI는 뜨는데 영상이 무한 로딩(검은 화면)되는 현상을 겪게 됩니다.

✅ 필수 조치 사항

반드시 공유기나 방화벽에서 UDP 8189 포트를 열어줘야 영상이 정상적으로 들어옵니다.

  1. 방화벽(UFW) 오픈:
    # (Ubuntu UFW 사용 시 예시)
    sudo ufw allow 8189/udp
  2. 공유기 포트포워딩:
    • 외부 포트: 8189 (UDP)
    • 내부 IP: 서버 IP
    • 내부 포트: 8189 (UDP)

⚠️ 주의: TCP가 아니라 UDP입니다! 프로토콜 타입을 꼭 확인하세요.


6️⃣ 트러블슈팅: Nginx와의 포트 충돌

설정을 마치고 야심 차게 ./mediamtx를 실행했으나, 빨간 에러 로그가 반겨주었습니다.

ERR listen tcp :8082: bind: address already in use

 

 

**"주소가 이미 사용 중"**이라는 뜻입니다. 앞서 말했듯 이 서버는 이미 다른 프로젝트들이 많이 떠 있는 상태였습니다. 범인을 찾아봤습니다.

sudo lsof -i :8082
# [출력 결과]
# nginx ... TCP *:8082 (LISTEN)

 

 

범인은 Nginx였습니다. 기존에 떠 있던 웹 서비스 중 하나가 8082 포트를 점유하고 있어서, MediaMTX의 WebRTC 포트와 충돌이 난 것입니다.

💡 해결: 당장 Nginx가 필요 없었기에 과감하게 중지시켰습니다.

sudo systemctl stop nginx
sudo systemctl disable nginx

 

이후 MediaMTX가 정상적으로 포트를 바인딩하며 실행되었습니다.


7️⃣ 마무리: Systemd 등록 및 결과

마지막으로 서버가 재부팅되어도 자동으로 켜지도록 systemd 서비스를 등록했습니다.

# /etc/systemd/system/mediamtx.service
[Unit]
Description=MediaMTX Streaming Server
After=network.target

[Service]
Type=simple
WorkingDirectory=/opt/mediamtx
ExecStart=/opt/mediamtx/mediamtx
Restart=always

[Install]
WantedBy=multi-user.target

systemctl status mediamtx 녹색 불

📈 최종 요약

  • Node.js HLS: 딜레이 심함, 끊김 발생 ❌
  • MediaMTX WebRTC: 딜레이 거의 없음, 매우 부드러움 ✅
  • 주의사항: 반드시 UDP 8189 포트를 열어야 영상이 나옴 (TCP만 열면 검은 화면)

혹시 저처럼 RTSP 스트리밍을 구현하다가 "왜 자꾸 끊기지?" 고민하신다면 HLS를 붙잡고 있지 말고 **WebRTC(MediaMTX)**로 넘어오시는 걸 강력 추천합니다. 그리고 설정이 꼬일 땐 Docker 말고 바이너리로 먼저 테스트해보세요!