-
Notifications
You must be signed in to change notification settings - Fork 2
Mediasoup의 디자인
Seungheon Han edited this page Dec 3, 2024
·
2 revisions
- 전체 시스템이 실행되는 호스트 컴퓨터 또는 서버를 나타낸다. 이 호스트는 여러 Worker 인스턴스를 포함하고 있다
- Mediasoup의 주요 프로세스 단위로, 각각의 Worker는 별도의 프로세스로 실행된다.
- Worker는 여러 개의 Router를 포함할 수 있고, 각 Router는 미디어 스트림을 전송하고 수신하는 네트워크 장치이다.
- Router는 Mediasoup의 중심 기능을 담당하며, Producer로부터 받은 미디어 스트림을 Consumer로 전송한다.
- Router는 서로 PipeTransport를 통해 연결되어 여러 Worker 간의 스트림을 전달할 수 있다
- Producer는 클라이언트(참여자)가 보낸 미디어 스트림(오디오/비디오)을 수신하는 역할을 한다.
- 예를 들어, 참가자가 자신의 마이크와 카메라를 켠 상태로 입장하면, Producer가 생성되어 해당 미디어 스트림을 Router에 전달한다.
- Consumer는 Producer가 생성한 미디어 스트림을 수신하여 다른 클라이언트(참여자)에게 전달하는 역할을 한다.
- 예를 들어, 시청자(뷰어)는 Consumer를 통해 다른 참여자가 송출한 오디오/비디오 스트림을 수신할 수 있다.
- Transport는 Mediasoup에서 미디어 데이터를 전송하기 위한 연결 방식이다. 위 다이어그램에서는 다양한 종류의 Transport가 사용되고 있다.
- WebRtcTransport: WebRTC 프로토콜을 사용하여 SRTP 기반의 전송을 담당한다. 일반적으로 브라우저와의 연결에 사용된다.
- PlainTransport: 기본 RTP 전송을 위해 사용되며, SRTP와 일반 RTP를 모두 지원한다. 예를 들어, GStreamer나 FFmpeg 같은 외부 도구와의 통신에 사용된다.
- PipeTransport: 다른 Router 간에 미디어 스트림을 전달하기 위해 사용된다.
mediasoup는 WebRTC를 기반으로 하는 비디오·오디오 스트리밍 프레임워크이다. 주로 SFU (Selective Forwarding Unit) 아키텍처를 지원하여 다자간 실시간 통신이 필요한 애플리케이션에서 효율적인 멀티미디어 처리를 제공한다.
- mediasoup는 Selective Forwarding Unit(SFU) 모델을 사용.
- 클라이언트에서 받은 미디어 스트림을 서버에서 중계하고, 각 클라이언트에 필요한 미디어만 전송하는 방식이다.
- 다자간 통신에서 P2P 연결이 어려운 경우 SFU가 중간에 위치하여 미디어를 중계하고, 클라이언트의 네트워크 환경에 맞춰 최적화된 스트림만 전송한다.
- mediasoup는 C++로 작성된 코어를 Node.js로 감싼 구조로 설계되어, 성능과 확장성이 뛰어나다
- 고사양 서버에서 수천 개의 동시 연결을 처리할 수 있으며, 특히 다수의 피어 간의 실시간 오디오 및 비디오 스트림을 효과적으로 중계할 수 있다.
- WebRTC 표준을 따르면서도 Node.js 환경에서 제어할 수 있는 유연한 API를 제공
- mediasoup의 API를 통해 WebRTC에 익숙하지 않더라도 손쉽게 다자간 미디어 처리를 구현할 수 있다
- 로드 밸런싱 및 다중 워커 프로세스 지원을 통해, 서버의 CPU 코어를 최대한 활용할 수 있다
- 또한 멀티 프로세싱을 지원하므로 하나의 서버에서 여러 워커를 구동하여 더 많은 피어와의 연결을 처리할 수 있다.
- mediasoup는 서버 중심에서 모든 미디어 처리를 관리하므로, 클라이언트에서의 복잡성을 줄일 수 있다
- 다중 화질 제공, 오디오 믹싱, 특정 클라이언트에게 맞춘 스트림 제공 등을 서버에서 관리할 수 있다
-
Worker 생성
- 서버 시작 시,
mediasoup.createWorker()
를 호출하여 Worker를 생성한다. 각 Worker는 미디어 처리의 독립적인 단위이다.
- 서버 시작 시,
-
Router 생성
- Worker 내에서
router.createRouter()
를 호출하여 라우터를 생성한다. 라우터는 미디어 코덱 설정을 관리하며, 미디어 스트림의 라우팅을 담당한다
- Worker 내에서
-
Transport 생성 및 설정
- 각 클라이언트와 통신하기 위해
router.createWebRtcTransport()
를 통해 Transport를 생성한다 - Transport는 ICE 및 DTLS를 통해 클라이언트와 보안 연결을 설정한다
- 각 클라이언트와 통신하기 위해
-
Producer와 Consumer 설정
- 클라이언트가 자신의 미디어 스트림을 서버로 전송하면, 서버는 해당 스트림을 Producer로 생성한다
- 다른 클라이언트가 이 스트림을 보고자 하면, 서버는 Producer를 소비할 수 있는 Consumer를 생성한다
-
미디어 라우팅
- 라우터는 각 피어가 소비할 미디어 스트림을 적절히 라우팅 한다. 서버는 필요한 클라이언트에게만 미디어를 전송해 불필요한 트래픽을 최소화 한다.
- 고성능 처리: mediasoup는 C++로 구현되어 고성능 미디어 처리가 가능하며, Node.js와 통합된 API를 제공
- 확장성: 다중 워커를 통해 CPU 자원을 효과적으로 사용하고, 여러 클라이언트를 안정적으로 처리
- 유연한 설정: 다양한 코덱과 트랜스포트를 지원하므로, WebRTC 기반 애플리케이션에서 유연한 설정이 가능
- 서버 중심의 미디어 제어: 서버에서 미디어 처리를 모두 관리하므로, 클라이언트에서 복잡한 로직을 처리할 필요가 줄어든다
- 복잡한 설정: WebRTC와 mediasoup 자체가 복잡한 개념을 포함하고 있어 초보자에게는 설정이 어려울 수 있다
- 클라이언트-서버 통신 추가 필요: ICE 후보, SDP 교환 등의 신호 교환을 위해 별도의 신호 서버가 필요하다
- 하드웨어 요구 사항: 고성능으로 동작하지만, 많은 사용자와 연결할 경우 서버에 상당한 CPU 및 메모리 자원을 요구할 수 있다
import * as mediasoup from 'mediasoup';
async function setupMediasoup() {
const worker = await mediasoup.createWorker();
const mediaCodecs = [
{
kind: 'video',
mimeType: 'video/VP8',
clockRate: 90000,
parameters: {},
},
{
kind: 'audio',
mimeType: 'audio/opus',
clockRate: 48000,
channels: 2,
},
];
const router = await worker.createRouter({ mediaCodecs });
const transport = await router.createWebRtcTransport({
listenIps: [{ ip: '0.0.0.0', announcedIp: 'YOUR_PUBLIC_IP' }],
enableUdp: true,
enableTcp: true,
preferUdp: true,
});
// ICE 및 DTLS 정보를 클라이언트에 전달하여 연결을 설정할 수 있습니다.
console.log('Transport created with id:', transport.id);
}
setupMediasoup();
- Mediasoup 포트 매핑 문제
- swagger 같은 응답 코드에 다양한 응답 보여주기
- Sudo가 계속 비밀번호를 요청함
- Docker 이미지가 너무 크다
- Git action에서 도커 이미지 빌드 시간을 단축시켜보자
- Docker compose를 이용해서 메모리 사용률을 줄여보자
- 방송 녹화 시 CPU 과부하 문제를 해결해보자
- Release 브랜치? 너 필요해?
- 로딩이 너무 짧아…!
- NestJS ORM으로 무엇을 사용해야 할까?
- WebRTC를 이용한 1:N 스트리밍 서비스에서 시그널링 서버가 필요할까?
- 실시간 채팅 구현: 인메모리 방식을 선택한 이유
- MySQL 아키텍처 개선: DB 의존성 분리와 서버 역할 명확화
- 브라우저 창이 최소화되면 비디오 송출이 안된다…!
- Mediasoup 기본 개념
- DLTS와 Signaling
- Tell, Don't Ask (TDA) 원칙이란
- VPC(Virtual Private Cloud) 학습 정리
- 순환참조: A 서비스 ‐ B 서비스 vs. A 서비스 ‐ B 레포지토리
- Dto 메서드 전략
- WebRTC란?
- 자바스크립트 패키지 매니저(npm, yarn, pnpm)
- shadcn/ui을 이용해 UI 개발 생산성 높이기
- React 이벤트 핸들러 네이밍(on vs handle)
- React-router-dom의 createBrowserRouter을 사용해보기
- fetch vs axios