[Computer Network] Multimedia Streaming
텍스트나 이미지같은 정적 리소스 말고 대용량의 음성, 영상 데이터를 네트워크로 전송할 때 사용하는 프로토콜이 있음.
RTMP / RTMPS (Real Time Messaging Protocol)
어도비가 개발한 실시간 메세징 프로토콜으로, 스트리머가 영상을 서버로 보낼 때 사용한다.
OBS같은 Encoder 프로그램에서 원격 서버로 영상을 업로드 할 때 표준처럼 사용됨.
TCP인데도 연결을 유지하고, 데이터를 Stream으로 보내기에 지연시간이 짧다.
다만 End User에 도달할 때는 HLS/DASH 등 다른 프로토콜으로 변환된다.
HLS (HTTP Live Streaming)
애플이 제안한 HTTP 기반 스트리밍 프로토콜으로, 거대한 영상 파일을 Segment로 잘게 나눠서 전송한다.
HTTP 80 포트를 사용하니 방화벽 통과가 쉽고, 기존 웹 서버를 그대로 쓸 수 있어 편함.
MPEG-DASH (Dynamic Adaptive Streaming over HTTP)
HLS와 유사하지만 특정 회사에 종속적이지 않음. 국제 표준 HTTP 스트리밍 기술이다.
네트워크 상황에 따라 화질을 동적으로 변경함.
4K 같은 고품질 영상 전송에 최적화됨.
신호 처리에는 Session Initiation Protocol이나 Session Description Protocol을 사용한다.
데이터를 주고받기 전에 연결을 맺고, 어떤 코덱을 쓸지 협상하는 단계에서 사용함.
미디어를 보낼 때는 HLS나 MPEG-DASH를 사용한다.
웹 서버를 사용해 미디어를 Segment로 쪼개고 파일을 다운로드하듯 전송함.
실시간 제어가 필요할 때는 RTP Control Protocol이나 Real-Time Streaming Protocol을 사용한다.
데이터의 전송 품질을 모니터링하고, 재생 / 녹화 같은 기능을 네트워크 레벨에서 수행함.
실시간 통신이 필요할 때는 Web Real-Time Communication을 사용한다.
브라우저끼리 P2P 방식으로 영상과 음성을 주고받음.
즉, 스트리머가 RTMP로 영상을 보내면 서버가 Segment 단위로 쪼개고 시청자에게 HLS나 MPEG-DASH로 전달한다.
예전에는 RTP / RTSP / RTMP 같은 전용 프로토콜을 많이 썼는데,. 요즘은 CDN과 호환성 때문에 HTTP 기반 프로토콜을 사용함.
HLS / MPEG-DASH 는 파일을 만들고 다운로드해야하니 Latency가 좀 있는데, WebRTC나 RTMP는 Latency가 짧음.

유튜브에서 네트워크 탭 켜고 확인해보면 구글 전용 CDN인 googlevideo.com 을 사용함을 확인할 수 있음.
보통 파일 다운로드는 GET을 쓰는데, 다양한 파라미터나 데이터를 보내기 위해 POST를 사용한다.
Content-Type이 ump로 설정되어있는데.. YouTube Media Packet이라는 유튜브 전용 포맷을 사용함.
구글은 애초에 TCP 안쓰고 UDP 기반의 QUIC 쓰고..
PC와 안드로이드 환경의 유튜브는 MPEG-DASH를 메인으로 사용한다.
다만 IOS 환경에서는 HLS가 네이티브로 제공되니 HLS Fallback이 적용되기도 함.

애플의 CDN 서버로부터 영상을 받아올 때 찍히는 로그. 유튜브랑은 좀 다르다.
.ts 확장자를 사용함. 타입스크립트가 아니고.. MPEG-2 Transport Stream 형식을 의미한다.
요청 URL을 보면 애플의 CDN 도메인에 요청하고 있음을 알 수 있고, 경로만 봐도 세그먼트 파일을 가리키고 있는게 보인다.
.ts 확장자가 네트워크탭에 도배되면 그냥 HLS 라는거..


RTMP는 스트리머가 서버로 영상을 보낼 때 사용하는 표준 기술. 시청자에게 영상을 송출하는 프로토
콜과 다르다.
Handshake - 클라와 서버가 서로 통신 준비가 됐는지 확인
Conect - NetConnect.Connect 명령을 보내 논리적인 연결을 수립
CreateStream - 실제 데이터를 보낼 때 사용하는 Stream을 확보
Publish/Play - 스트리머는 Publish로 영상을 밀어넣고 시청자는 NetStream.Play로 영상을 받아온다
Data Transmission - 오디오 패킷과 비디오 패킷이 실시간으로 전송됨
TCP 3-way handshake가 끝난 후, 한 번 더 handshake를 수행한다.
C0 / S0 - 클라이언트와 서버가 서로 RTMP 버전을 확인한다. (보통 0x03 사용)
C1 / S1 - Timestamp와 난수를 교환한다. 난수는 데이터를 검증할 때 사용함.
C2 / S2 - 이전 단계에서 보낸 S1과 C1을 복사해서 그대로 돌려준다. 난수 패턴을 확인하고 연결을 시작함.
RTMP는 TCP 연결 위에서 데이터를 쭉 밀어넣으니 Latency가 짧아 송출용으로 적합함.
평문이니까 RTMPS 를 사용한다.
MPEG-DASH
유튜브, 넷플 등 대규모 트래픽을 처리하는 OTT 서비스가 주로 사용한다.
영상의 화질은 어떤지, Segment는 어디에 있는지 등 영상에 대한 메타 정보를 표현하기 위해 XML 파일인 Media Presentation Description (.mpd) 을 사용한다. (HLS의 .m3u8에 해당)
Segment는 .m4s 확장자를 사용한다.

서버가 데이터를 밀어주지 않고, 클라이언트인 브라우저가 주도권을 가진다.
클라는 네트워크 속도를 실시간으로 측정하고 빠르면 고화질 세그먼트를, 느리면 저화질 세그먼트를 요청함.
HLS
애플이 제안한거라 IOS 생태계에서는 별도 설치 없이 지원됨.
.m3u8 확장자를 Playlist로 사용한다. 재생할 파일 목록이 텍스트로 적혀있음.
Segment는 .ts 확장자를 사용함. 예전에는 10초가 기본이었지만 지금은 지연 시간을 줄이기 위해 6초 정도로 사용.
.ts 만들고 .m3u8 갱신하고 클라이언트가 다운로드까지 해야돼서 Latency가 좀 길다.
요즘은 효율성을 위해 .ts 대신 .mp4 쓰기도 함.

카메라나 마이크를 통해 Raw Data가 들어오고, Media Encoder가 효율이 좋은 코덱으로 Encoding 진행함.
Index File (.m3u8) 과 Segments (.mp4 or .ts) 로 잘라진다.
Origin Web Server는 생성한 파일을 가지고 있는 원본 서버. Nginx나 Apache정도면 충분하다. (MIME 타입을 등록해 줘야 함)
HTTP 프로토콜을 타고 전송되니 기존 웹 인프라와 CDN을 그대로 활용할 수 있다.
클라이언트는 Index File을 먼저 받고 그 순서대로 Segment를 요청해서 재생함.
실제로 구현할 때는.. 그냥 HTML의 <video> 태그 쓰면 끝임.. src에다가 m3u8 주소 넣어주고..
IOS 생태계 밖에서 쓸 때는 별도의 자바스크립트 라이브러리를 추가해 줘야 한다.
HLS의 가장 큰 장점은 그냥 파일 다운로드 방식으로 처리할 수 있다는 것.
서버가 정적 파일 호스팅만 가능하면 스트리밍 서버로 사용할 수 있음.

RTSP는 HTTP 기반 스트리밍이 뜨기 전에 쭉 사용했던 프로토콜이다. 지금도 CCTV, 화상회의, 보안 카메라에서 사용됨.
사실 RTSP는 영상 데이터 자체를 보내지는 않고, 비디오 서버를 원격으로 제어하는 명령을 처리할 뿐임.
클라는 웹 서버로부터 방송 정보가 담긴 Session Description 파일을 받는다.
이제 클라는 미디어 서버와 RTSP로 대화함.
SETUP은 준비고 TEARDOWN은 연결 끊는거임.
실제 영상과 소리는 RTP를 타고 별도로 전송되고, RTCP는 전송 품질을 주기적으로 보고한다.
HTTP는 Stateless지만 RTSP는 서버가 내가 지금 영상을 보고 있음 / 멈춤 등 상태를 기억하고 있음.
OBS Studio - 영상을 캡쳐하고 RTMP로 쏴주는 역할을 수행
Nginx-RTMP - RTMP 서버 구축할 때 가장 많이 쓰는 오픈소스
FFmpeg - 영상을 HLS나 DASH 포맷으로 변환할 때 사용함
HLS 서버의 본질은 파일 서버. 그냥 클라가 달라는 파일을 꺼내주면 그만임.
프론트 개발은 <video> 태그와 HLS 라이브러리로 끝난다.
정리하면...
RTMP는 스트리머가 서버로 영상 넣을 때 사용하고, HLS랑 MPEG-DASH는 서버가 시청자에게 트래픽 분산할 때 사용함.
RTSP와 RTP는 인방에서는 밀려났지만 CCTV, IP 카메라에서는 현역임.
일단 기본적으로 애플에서는 HLS를 쓰고 구글이나 다른 애들은 DASH를 사용함.
근데 웬만하면 최대 호환성을 위해 인코딩한 영상 하나를 HLS와 DASH 두 포맷으로 변환해서 제공한다.
클라이언트가 원하는 포맷 골라서 재생하고..
둘 다 Latency가 길다. Segment로 만들고 캐싱되어 전달돼야 하니까.
요즘은 Low Latency HLS와 Low Latency DASH 기술이 표준화되어 상용 서비스에 사용되는 중.
최대 장점은 nginx같이 정적 웹 서버만으로 스트리밍이 가능하다는 것.
HLS 나 MPEG-DASH나 기본 원리는 같기에 HLS 할 줄 알면 MPEG도 금방 할 수 있음.


WebRTC는 기본적으로 클라이언트끼리 데이터를 주고받는 P2P 통신을 기반으로 한다. 기본적으로 UDP를 사용함.
두 브라우저가 서로를 찾고 연결하려면 중계 서버의 도움이 필요한데.. App Engine을 중계 서버로 사용함.
WebRTC 자체는 Signaling 방법을 규정하지 않는다. 개발자가 쓰고싶은거 써도 됨.
Signaling이 끝나고 서로 연결되면 서로 미디어를 주고받는다.
라우터 공부할 때도 다뤘지만 연결 대상이 NAT 뒤에 숨어있는 경우가 많으니 STUN, TURN, ICE를 사용함.
카메라나 마이크 권한을 얻으려면 반드시 HTTPS 환경에서 처리되어야 하고, 모든 데이터는 TLS로 암호화되어 전송된다.
Datagram TLS를 사용해 UDP 위에서 전송되는 데이터의 도청과 변조를 방지하고, Secure Real-Time Transport Protocol을 사용해 오디오와 비디오 데이터를 안전하게 전송한다.
Stream Control Transmission Protocol는 DataChannel을 통해 일반 데이터를 전송할 때 UDP 위에서 TCP처럼 순서를 보장해주는 기능을 수행함.
프론트 개발 할 때는 자바스크립트가 다 추상화 해놔서 로우레벨까지 들어갈 일은 거의 없음..
getUserMedia - 사용자의 기기에 연결된 카메라, 마이크에 접근한다.
RTCPeerConnection - 피어간의 오디오 / 비디오 통신을 활성화한다. NAT를 통과하고 대역폭과 보안을 관리함.
RTCDataChannel - 오디오 / 비디오 외의 데이터를 양방향으로 주고받는다.

RTCPeerConnection이 연결을 맺기 위해 Signaling Server를 통해 상대와 주고받는 데이터를 Session Description Protocol라고 부른다.
프로토콜 버전, 세션 소유자 및 IP 주소 정보, 세션 이름 등의 정보를 포함하고 있음.
m=audio 1 RTP/SAVPF 111 ... -오디오를 보내고, RTP/SAVPF 프로토콜을 쓰고, 1번 포트를 사용함을 알려줌.
a=rtpmap:111 opus/48000/2 - 111번 코덱은 Opus고 48kHz 스테레오임을 알려줌.
사실 직관적이라 그냥 읽으면 됨
// STUN 설정
const configuration = {'iceServers': [{'urls': 'stun:stun.l.google.com:19302'}]};
const peerConnection = new RTCPeerConnection(configuration);
// TURN 설정
const iceConfiguration = {
iceServers: [
{
urls: 'turn:my-turn-server.mycompany.com:19403',
username: 'optional-username',
credentials: 'auth-token'
}
]
};
const peerConnection = new RTCPeerConnection(iceConfiguration);
STUN 서버는 구글의 무료 STUN 서버를 사용하자.
peerConnection 객체를 만들어 모든 통신을 담당하게 함.

STUN - 공인 IP 주소와 포트 번호가 뭔지 물어보는 서버.
내부망을 사용하는 Peer A는 STUN 에게 요청을 보낸다.
STUN 서버는 요청 패킷 헤더를 보고 공인 IP 주소와 포트를 알려줌.
이제 Peer A 는 이 공인 주소를 SDP에 적어 Peer B에게 알려준다.
다만.. 보안이 강한 Symmetric NAT 에서는 작동하지 않음.
TURN - P2P 연결이 불가능 할 때 데이터를 중계해주는 서버
STUN으로 연결에 실패하면 Peer A와 Peer B는 TURN 서버를 중계 서버로 사용한다.
Peer A가 TURN 서버에 데이터를 보내면 TURN 서버가 Peer B에게 전달함.
서버를 거치니까 사실상 P2P가 아니라고 볼수도.. 오버헤드도 커진다.
다만 개발자는 RTCPeerConnection 객체로 제어하니 논리적으로는 P2P.
Interactive Connectivity Establishment (ICE)
모든 연결 과정을 관리한다. (STUN + TURN)
브라우저가 상대방과 연결하기 위한 모든 경로를 찾고, 최적의 경로를 선택하고 연결해주는 프레임워크라고 생각하면 됨.
Host Candidate는 내 로컬 IP로 연결을 시도하고, Server Reflexive Candidate는 STUN 서버가 알려준 공인 IP로 연결을 시도함.
어차피 ICE가 후보들을 수집해 우선순위에 따라 연결하니 개발자는 ICE가 알아서 하도록 설정만 넘겨주면 된다.
구현할 때는 또 video 태그를 사용한다.
WebRTC로 받아온 데이터는 MediaStream 객체인데, 이걸 소리로 듣고 눈으로 보려면 <video>나 <audio> 태그의 srcObject 속성에 꽂아줘야 함.
Signaling Server도 만들어야 되고, ICE Server도 만들어야 되고. 관리할 게 좀 많음;
다만 서버리스 방식으로 사용하기 용이함. 서버리스 안할거면 Firebase 써도 좋고..
'Computer Science > Computer Network' 카테고리의 다른 글
| [Computer Network] Cryptography (1) | 2025.12.14 |
|---|---|
| [Computer Network] IP Address (0) | 2025.12.13 |
| [Computer Network] Router (0) | 2025.12.13 |
| [Computer Network] Congestion Control (0) | 2025.11.02 |
| [Computer Network] Transmission Control Protocol (1) | 2025.10.15 |
댓글
이 글 공유하기
다른 글
-
[Computer Network] Cryptography
[Computer Network] Cryptography
2025.12.14 -
[Computer Network] IP Address
[Computer Network] IP Address
2025.12.13 -
[Computer Network] Router
[Computer Network] Router
2025.12.13 -
[Computer Network] Congestion Control
[Computer Network] Congestion Control
2025.11.02