본문으로 건너뛰기 영상 스트리밍 프로토콜 완벽 가이드 | RTMP·RTSP·HLS·DASH·CMAF 비교

영상 스트리밍 프로토콜 완벽 가이드 | RTMP·RTSP·HLS·DASH·CMAF 비교

영상 스트리밍 프로토콜 완벽 가이드 | RTMP·RTSP·HLS·DASH·CMAF 비교

이 글의 핵심

영상 스트리밍 프로토콜 RTMP, RTSP, HLS, DASH, CMAF, WebRTC 등 주요 프로토콜의 원리, 장단점, 실전 활용법을 비교 분석합니다.

들어가며

영상 스트리밍 프로토콜영상을 인터넷으로 전송하는 방법을 정의합니다. YouTube, Netflix, Twitch 등 모든 스트리밍 서비스는 이런 프로토콜을 사용합니다. 비유로 말씀드리면, 프로토콜택배 배송 방식입니다. RTMP빠른 퀵서비스, HLS안정적인 일반 택배, WebRTC즉시 배달입니다.

이 글을 읽으면

  • 주요 스트리밍 프로토콜의 원리를 이해합니다
  • 각 프로토콜의 장단점을 파악합니다
  • 상황별 최적의 프로토콜을 선택할 수 있습니다
  • 실전 구현 방법을 익힙니다

스트리밍 프로토콜 기초

스트리밍이란?

스트리밍은 영상을 다운로드하면서 동시에 재생하는 기술입니다.

다운로드:
[========================================] 100%
다운로드 완료 후 재생
스트리밍:
[=====>                                  ] 10%
다운로드 중인데 이미 재생 시작!

스트리밍의 2가지 방식

1. 라이브 스트리밍 (Live Streaming)

  • 실시간 방송 (Twitch, YouTube Live)
  • 낮은 지연시간 중요
  • 예: 스포츠 중계, 게임 방송 2. VOD (Video on Demand)
  • 녹화된 영상 (Netflix, YouTube)
  • 안정성과 품질 중요
  • 예: 영화, 드라마

프로토콜 선택 기준

기준설명
지연시간실시간성 (1초 vs 30초)
확장성동시 시청자 수 (100명 vs 100만명)
호환성브라우저/기기 지원
비용서버/CDN 비용
품질화질, 적응형 스트리밍

RTMP (Real-Time Messaging Protocol)

RTMP란?

RTMP는 Adobe가 개발한 실시간 영상 전송 프로토콜입니다. 라이브 스트리밍 인제스트(업로드)의 사실상 표준입니다. 특징:

  • TCP 기반 (안정적)
  • 낮은 지연시간 (1-5초)
  • Flash 기반 (브라우저 지원 종료)

RTMP 워크플로우

[스트리머] → RTMP → [서버] → HLS/DASH → [시청자]
   (OBS)              (Nginx)             (브라우저)
1. 스트리머: OBS로 RTMP 송출
2. 서버: RTMP 수신 → HLS/DASH 변환
3. 시청자: HLS/DASH로 시청

RTMP 구현 (Nginx)

nginx.conf:

rtmp {
    server {
        listen 1935;  # RTMP 포트
        
        application live {
            live on;  # 라이브 스트리밍 활성화
            
            # HLS 변환
            hls on;
            hls_path /tmp/hls;
            hls_fragment 3s;  # 세그먼트 길이
            hls_playlist_length 60s;
            
            # DASH 변환
            dash on;
            dash_path /tmp/dash;
            dash_fragment 3s;
        }
    }
}
http {
    server {
        listen 8080;
        
        # HLS 제공
        location /hls {
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            root /tmp;
            add_header Cache-Control no-cache;
            add_header Access-Control-Allow-Origin *;
        }
        
        # DASH 제공
        location /dash {
            types {
                application/dash+xml mpd;
            }
            root /tmp;
            add_header Cache-Control no-cache;
            add_header Access-Control-Allow-Origin *;
        }
    }
}

OBS 설정:

서버: rtmp://your-server.com/live
스트림 키: stream-key-123

RTMP 장단점

장점:

  • ✅ 낮은 지연시간 (1-5초)
  • ✅ 안정적인 전송 (TCP)
  • ✅ 업계 표준 (모든 인코더 지원) 단점:
  • ❌ 브라우저 직접 재생 불가 (Flash 종료)
  • ❌ 방화벽 문제 (1935 포트)
  • ❌ 확장성 제한

RTSP (Real Time Streaming Protocol)

RTSP란?

RTSPIP 카메라와 CCTV에서 주로 사용하는 프로토콜입니다. 특징:

  • UDP/TCP 지원
  • 양방향 제어 (재생, 일시정지, 탐색)
  • RTP/RTCP로 실제 데이터 전송

RTSP 구조

RTSP (제어 채널)

RTP (미디어 전송)

RTCP (품질 피드백)

RTSP URL 형식

rtsp://username:password@192.168.1.100:554/stream1
rtsp://     - 프로토콜
username    - 인증 사용자명
password    - 인증 비밀번호
192.168.1.100 - IP 주소
554         - 포트 (기본값)
/stream1    - 스트림 경로

RTSP 재생 (FFmpeg)

# RTSP 스트림 재생
ffplay rtsp://192.168.1.100:554/stream1
# RTSP → RTMP 변환
ffmpeg -i rtsp://192.168.1.100:554/stream1 \
       -c copy \
       -f flv rtmp://your-server.com/live/stream
# RTSP → HLS 변환
ffmpeg -i rtsp://192.168.1.100:554/stream1 \
       -c:v libx264 -c:a aac \
       -f hls -hls_time 3 -hls_list_size 10 \
       output.m3u8

RTSP 장단점

장점:

  • ✅ 낮은 지연시간
  • ✅ 양방향 제어
  • ✅ IP 카메라 표준 단점:
  • ❌ 브라우저 지원 없음
  • ❌ 방화벽 문제 (UDP)
  • ❌ 확장성 제한

HLS (HTTP Live Streaming)

HLS란?

HLS는 Apple이 개발한 HTTP 기반 스트리밍 프로토콜입니다. 가장 널리 사용되는 프로토콜입니다. 특징:

  • HTTP 기반 (CDN 활용 가능)
  • 적응형 비트레이트 (ABR)
  • 모든 Apple 기기 지원

HLS 구조

영상 → 세그먼트로 분할 → Playlist 생성
video.mp4

segment0.ts (6초)
segment1.ts (6초)
segment2.ts (6초)

playlist.m3u8 (세그먼트 목록)

HLS Playlist (M3U8)

Master Playlist (다중 화질):

#EXTM3U
#EXT-X-VERSION:3
# 1080p
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080
1080p.m3u8
# 720p
#EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720
720p.m3u8
# 480p
#EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=854x480
480p.m3u8

Media Playlist (세그먼트 목록):

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:6.0,
segment0.ts
#EXTINF:6.0,
segment1.ts
#EXTINF:6.0,
segment2.ts
#EXT-X-ENDLIST

HLS 생성 (FFmpeg)

# 단일 화질 HLS
ffmpeg -i input.mp4 \
       -c:v libx264 -c:a aac \
       -f hls \
       -hls_time 6 \
       -hls_list_size 0 \
       -hls_segment_filename 'segment%03d.ts' \
       playlist.m3u8
# 다중 화질 HLS (ABR)
ffmpeg -i input.mp4 \
  -filter_complex \
  "[0:v]split=3[v1][v2][v3]; \
   [v1]scale=w=1920:h=1080[v1out]; \
   [v2]scale=w=1280:h=720[v2out]; \
   [v3]scale=w=854:h=480[v3out]" \
  -map "[v1out]" -c:v:0 libx264 -b:v:0 5M \
  -map "[v2out]" -c:v:1 libx264 -b:v:1 2.5M \
  -map "[v3out]" -c:v:2 libx264 -b:v:2 1M \
  -map a:0 -c:a aac -b:a 128k \
  -f hls -hls_time 6 \
  -hls_playlist_type vod \
  -master_pl_name master.m3u8 \
  -var_stream_map "v:0,a:0 v:1,a:0 v:2,a:0" \
  stream_%v/playlist.m3u8

HLS 재생 (JavaScript)

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body>
    <video id="video" controls width="640"></video>
    
    <script>
        const video = document.getElementById('video');
        const videoSrc = 'https://example.com/master.m3u8';
        
        if (video.canPlayType('application/vnd.apple.mpegurl')) {
            // Safari (네이티브 HLS 지원)
            video.src = videoSrc;
        } else if (Hls.isSupported()) {
            // 다른 브라우저 (hls.js 사용)
            const hls = new Hls();
            hls.loadSource(videoSrc);
            hls.attachMedia(video);
            
            hls.on(Hls.Events.MANIFEST_PARSED, () => {
                video.play();
            });
        }
    </script>
</body>
</html>

HLS 장단점

장점:

  • ✅ HTTP 기반 (CDN 활용)
  • ✅ 방화벽 문제 없음
  • ✅ 적응형 비트레이트 (ABR)
  • ✅ Apple 기기 네이티브 지원
  • ✅ 무한 확장성 단점:
  • ❌ 높은 지연시간 (6-30초)
  • ❌ 세그먼트 파일 많음

DASH (Dynamic Adaptive Streaming over HTTP)

DASH란?

DASHMPEG 표준 스트리밍 프로토콜입니다. HLS의 오픈 표준 대안입니다. 특징:

  • HTTP 기반
  • 코덱 독립적 (H.264, H.265, VP9, AV1)
  • DRM 지원 우수

DASH 구조

영상 → 세그먼트 분할 → MPD 생성
video.mp4

init.mp4 (초기화 세그먼트)
segment1.m4s
segment2.m4s
segment3.m4s

manifest.mpd (세그먼트 목록)

DASH Manifest (MPD)

<?xml version="1.0"?>
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011">
  <Period>
    <!-- 비디오 -->
    <AdaptationSet mimeType="video/mp4" codecs="avc1.4d401f">
      <!-- 1080p -->
      <Representation id="1" bandwidth="5000000" width="1920" height="1080">
        <SegmentTemplate timescale="1000" 
                         initialization="init-$RepresentationID$.mp4"
                         media="segment-$RepresentationID$-$Number$.m4s"
                         startNumber="1">
          <SegmentTimeline>
            <S t="0" d="6000" r="9"/>
          </SegmentTimeline>
        </SegmentTemplate>
      </Representation>
      
      <!-- 720p -->
      <Representation id="2" bandwidth="2500000" width="1280" height="720">
        <!-- ... -->
      </Representation>
    </AdaptationSet>
    
    <!-- 오디오 -->
    <AdaptationSet mimeType="audio/mp4" codecs="mp4a.40.2">
      <Representation id="audio" bandwidth="128000">
        <!-- ... -->
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

DASH 생성 (FFmpeg + MP4Box)

# 1. 다중 화질 인코딩
ffmpeg -i input.mp4 \
  -c:v libx264 -b:v 5M -s 1920x1080 -profile:v high -level 4.1 1080p.mp4 \
  -c:v libx264 -b:v 2.5M -s 1280x720 -profile:v high -level 4.0 720p.mp4 \
  -c:v libx264 -b:v 1M -s 854x480 -profile:v main -level 3.1 480p.mp4
# 2. DASH 패키징 (MP4Box)
MP4Box -dash 6000 -frag 6000 -rap \
       -segment-name 'segment_$RepresentationID$_' \
       -out manifest.mpd \
       1080p.mp4 720p.mp4 480p.mp4

DASH 재생 (dash.js)

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.dashjs.org/latest/dash.all.min.js"></script>
</head>
<body>
    <video id="video" controls width="640"></video>
    
    <script>
        const url = 'https://example.com/manifest.mpd';
        const player = dashjs.MediaPlayer().create();
        player.initialize(document.getElementById('video'), url, true);
    </script>
</body>
</html>

DASH 장단점

장점:

  • ✅ 오픈 표준 (로열티 없음)
  • ✅ 코덱 독립적
  • ✅ DRM 지원 우수
  • ✅ HTTP 기반 단점:
  • ❌ Apple 기기 지원 약함
  • ❌ 복잡한 구현

CMAF (Common Media Application Format)

CMAF란?

CMAFHLS와 DASH를 통합하는 차세대 포맷입니다. 하나의 파일로 두 프로토콜 지원이 가능합니다. 특징:

  • fMP4 기반
  • HLS + DASH 동시 지원
  • 낮은 지연시간 (LL-HLS, LL-DASH)

CMAF 구조

기존:
HLS용 파일 (TS)  +  DASH용 파일 (MP4)
→ 2배 저장 공간, 2배 인코딩 시간
CMAF:
공통 파일 (fMP4)
→ HLS와 DASH 모두 사용
→ 1배 저장 공간, 1배 인코딩 시간

CMAF 생성 (FFmpeg)

# CMAF 인코딩
ffmpeg -i input.mp4 \
  -c:v libx264 -b:v 5M -s 1920x1080 -profile:v high \
  -c:a aac -b:a 128k \
  -f hls \
  -hls_segment_type fmp4 \
  -hls_fmp4_init_filename init.mp4 \
  -hls_segment_filename 'segment%03d.m4s' \
  -hls_playlist_type vod \
  playlist.m3u8

LL-HLS (Low-Latency HLS)

특징:

  • 지연시간: 2-3초 (기존 HLS의 1/10)
  • 부분 세그먼트 (Partial Segment)
  • HTTP/2 Server Push
#EXTM3U
#EXT-X-VERSION:9
#EXT-X-TARGETDURATION:6
#EXT-X-SERVER-CONTROL:CAN-BLOCK-RELOAD=YES,PART-HOLD-BACK=1.0
#EXT-X-PART-INF:PART-TARGET=0.5
#EXT-X-PART:DURATION=0.5,URI="part0.m4s"
#EXT-X-PART:DURATION=0.5,URI="part1.m4s"
#EXTINF:6.0,
segment0.m4s

CMAF 장단점

장점:

  • ✅ HLS + DASH 동시 지원
  • ✅ 저장 공간 절약 (50%)
  • ✅ 낮은 지연시간 (LL-HLS)
  • ✅ 미래 지향적 단점:
  • ❌ 최신 기술 (지원 제한적)
  • ❌ 복잡한 구현

WebRTC (Web Real-Time Communication)

WebRTC란?

WebRTCP2P 실시간 통신 프로토콜입니다. 초저지연이 특징입니다. 특징:

  • UDP 기반
  • 지연시간: 0.5-1초
  • 브라우저 네이티브 지원

WebRTC 구조

[발신자] ←→ Signaling Server ←→ [수신자]
    ↓                              ↓
    └──────── P2P 연결 ────────────┘
           (STUN/TURN)

WebRTC 구현 (JavaScript)

발신자:

// 1. MediaStream 획득
const stream = await navigator.mediaDevices.getUserMedia({
    video: true,
    audio: true
});
// 2. RTCPeerConnection 생성
const pc = new RTCPeerConnection({
    iceServers: [
        { urls: 'stun:stun.l.google.com:19302' }
    ]
});
// 3. 스트림 추가
stream.getTracks().forEach(track => {
    pc.addTrack(track, stream);
});
// 4. Offer 생성
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
// 5. Offer 전송 (Signaling Server)
sendToSignalingServer({ type: 'offer', sdp: offer.sdp });

수신자:

// 1. RTCPeerConnection 생성
const pc = new RTCPeerConnection({
    iceServers: [
        { urls: 'stun:stun.l.google.com:19302' }
    ]
});
// 2. Offer 수신
pc.setRemoteDescription(new RTCSessionDescription(offer));
// 3. Answer 생성
const answer = await pc.createAnswer();
await pc.setLocalDescription(answer);
// 4. Answer 전송
sendToSignalingServer({ type: 'answer', sdp: answer.sdp });
// 5. 스트림 수신
pc.ontrack = (event) => {
    videoElement.srcObject = event.streams[0];
};

WebRTC 장단점

장점:

  • ✅ 초저지연 (0.5-1초)
  • ✅ P2P (서버 부하 적음)
  • ✅ 브라우저 네이티브 지원 단점:
  • ❌ 확장성 제한 (P2P)
  • ❌ 방화벽/NAT 문제
  • ❌ 녹화 어려움

프로토콜 비교

전체 비교표

프로토콜지연시간확장성브라우저 지원주요 용도
RTMP1-5초중간라이브 인제스트
RTSP1-3초낮음IP 카메라
HLS6-30초높음VOD, 라이브
DASH6-30초높음VOD, 라이브
CMAF2-6초높음차세대 스트리밍
WebRTC0.5-1초낮음화상 통화

상황별 추천

1. 라이브 스트리밍 (대규모)

RTMP (인제스트) → HLS/DASH (배포)
지연시간: 10-30초
확장성: 무제한

2. 라이브 스트리밍 (저지연)

RTMP → LL-HLS 또는 WebRTC
지연시간: 1-3초
확장성: 중간

3. VOD (주문형 비디오)

HLS (Apple) + DASH (Android)
또는 CMAF (통합)

4. 화상 통화

WebRTC
지연시간: 1초 미만

5. IP 카메라

RTSP → RTMP/HLS 변환

실전 구현

완전한 라이브 스트리밍 시스템

아키텍처:

[스트리머] → RTMP → [Nginx-RTMP] → HLS/DASH → [CDN] → [시청자]
   (OBS)              (서버)                    (CloudFlare)  (브라우저)

Docker Compose:

# 실행 예제
version: '3'
services:
  nginx-rtmp:
    image: tiangolo/nginx-rtmp
    ports:
      - "1935:1935"  # RTMP
      - "8080:80"    # HLS/DASH
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./hls:/tmp/hls
      - ./dash:/tmp/dash

nginx.conf (완전판):

rtmp {
    server {
        listen 1935;
        chunk_size 4096;
        
        application live {
            live on;
            record off;
            
            # 인증 (선택)
            on_publish http://localhost:8000/auth;
            
            # HLS
            hls on;
            hls_path /tmp/hls;
            hls_fragment 3s;
            hls_playlist_length 60s;
            hls_continuous on;
            hls_cleanup on;
            hls_nested on;
            
            # DASH
            dash on;
            dash_path /tmp/dash;
            dash_fragment 3s;
            dash_playlist_length 60s;
            dash_cleanup on;
            dash_nested on;
            
            # 트랜스코딩 (다중 화질)
            exec ffmpeg -i rtmp://localhost/live/$name
              -c:v libx264 -b:v 5M -s 1920x1080 -f flv rtmp://localhost/hls/$name_1080p
              -c:v libx264 -b:v 2.5M -s 1280x720 -f flv rtmp://localhost/hls/$name_720p
              -c:v libx264 -b:v 1M -s 854x480 -f flv rtmp://localhost/hls/$name_480p;
        }
    }
}

트러블슈팅

1. HLS 지연시간 줄이기

문제: HLS 지연시간이 30초 이상 해결:

# 세그먼트 길이 단축
hls_fragment 2s;  # 6s → 2s
# Playlist 길이 단축
hls_playlist_length 10s;  # 60s → 10s
# 결과: 지연시간 30초 → 6-10초

2. CORS 에러

문제: 브라우저에서 HLS 재생 안 됨 해결:

location /hls {
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods "GET, OPTIONS";
    add_header Access-Control-Allow-Headers "Range";
}

3. 버퍼링 문제

문제: 영상이 자주 멈춤 해결:

// hls.js 버퍼 설정
const hls = new Hls({
    maxBufferLength: 30,      // 최대 버퍼 (초)
    maxMaxBufferLength: 600,  // 최대 최대 버퍼
    maxBufferSize: 60 * 1000 * 1000,  // 60MB
    maxBufferHole: 0.5        // 버퍼 홀 허용
});

마무리

영상 스트리밍 프로토콜상황에 맞게 선택해야 합니다. 핵심 요약:

프로토콜한 줄 요약
RTMP라이브 업로드 표준
RTSPIP 카메라 표준
HLS가장 범용적
DASH오픈 표준 대안
CMAF차세대 통합 포맷
WebRTC초저지연 P2P
실전 추천:
// 실행 예제
라이브 스트리밍:
RTMP (인제스트) → HLS (배포)
VOD:
HLS (Apple) + DASH (Android)
또는 CMAF (통합)
저지연 라이브:
WebRTC 또는 LL-HLS
IP 카메라:
RTSP → HLS 변환

다음 단계:


자주 묻는 질문 (FAQ)

Q. 이 내용을 실무에서 언제 쓰나요?

A. 영상 스트리밍 프로토콜 완벽 가이드. RTMP, RTSP, HLS, DASH, CMAF, WebRTC 등 주요 프로토콜의 원리, 장단점, 실전 활용법을 비교 분석합니다.

Q. 선행으로 읽으면 좋은 글은?

A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.

Q. 더 깊이 공부하려면?

A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.


같이 보면 좋은 글 (내부 링크)

이 주제와 연결되는 다른 글입니다.


이 글에서 다루는 키워드 (관련 검색어)

스트리밍, RTMP, HLS, DASH, CMAF, RTSP, WebRTC, 영상프로토콜 등으로 검색하시면 이 글이 도움이 됩니다.