시리즈: 실시간 통화, 어떻게 녹화하는가3/6
- 1.실시간 통화, 왜 녹화해야 하는가
- 2.내 서버에서 직접 녹화한다면
- 3.녹화 모드 해부 ← 현재 글
- 4.M3U8과 TS 파일의 모든 것
- 5.FFmpeg, 미디어의 스위스 아미 나이프
- 6.FFmpeg 실전 파이프라인
녹화 모드 해부 — Individual, Mix, Web의 내부 파이프라인
같은 채널을 3가지 방식으로 녹화할 때 내부에서 일어나는 일. PCM 오디오 믹싱, YUV 비디오 컴포지팅, Headless Browser 캡처까지.
같은 채널에서 녹화를 시작해도, 어떤 모드를 선택하느냐에 따라 서버 내부에서 벌어지는 일이 완전히 달라집니다. 출력 파일 구조, 서버 리소스 소비, 비용 — 모든 것이 모드 선택 시점에 결정됩니다.
Agora Cloud Recording은 세 가지 모드를 제공합니다: Individual, Mix, Web. 이 글에서는 각 모드의 내부 파이프라인을 해부하고, 언제 어떤 모드를 선택해야 하는지를 정리합니다.
Individual 모드 — 분리의 미학
Individual 모드의 핵심 철학은 단순합니다: 합성하지 않는다. 각 참가자의 스트림을 독립적으로 처리해서 별도 파일로 저장합니다.
파이프라인이 단순한 이유: Compositing(합성) 단계가 없습니다. 각 UID의 스트림을 받아서 디코딩하고, 개별 파일로 쓰는 것이 전부입니다. 오디오와 비디오도 분리 저장됩니다.
타임스탬프가 핵심입니다. 각 파일에는 녹화 시작 시점 기준의 타임스탬프가 정확히 보존됩니다. 덕분에 나중에 FFmpeg 등으로 sync를 맞춰 합치거나, 화자별로 독립적으로 처리할 수 있습니다.
주요 사용 사례:
- STT(Speech-to-Text): 화자별로 분리된 오디오를 각각 처리하면 정확도가 높습니다
- AI 분석: 특정 참가자의 발화 패턴, 감정 분석 등
- 후처리 유연성: 나중에 원하는 레이아웃으로 직접 합성
- 비용 최적화: 가장 가벼운 파이프라인 → 가장 저렴
Mix 모드 — Audio Mixing 기술 상세
Mix 모드는 모든 참가자의 스트림을 하나의 파일로 합칩니다. 여기서 "합친다"는 말이 오디오와 비디오에서 전혀 다른 기술을 의미합니다. 오디오부터 살펴봅니다.
PCM(Pulse Code Modulation) 이란 아날로그 오디오를 디지털로 변환한 raw 데이터입니다. 초당 44,100개(CD 품질) 혹은 48,000개(방송 품질)의 샘플로 파형을 숫자로 표현합니다.
오디오 믹싱의 실제 연산은 단순합니다: 같은 시점(sample)의 amplitude 값을 산술적으로 더하는 것입니다. User A의 1번째 샘플 값 + User B의 1번째 샘플 값 + User C의 1번째 샘플 값 = 출력의 1번째 샘플 값.
문제는 여기서 발생합니다. 세 사람이 동시에 말하면 amplitude 합이 최대값을 초과합니다.
Clipping: 16-bit PCM에서 amplitude 범위는 ±32767입니다. 이 범위를 초과하면 파형이 잘려서(clipped) "찢어지는" 소리, 즉 디지털 왜곡이 발생합니다. 이걸 방지하기 위해 AGC(Automatic Gain Control) 가 동작합니다. 여러 스트림을 합산하기 전에 각 스트림의 gain을 자동으로 낮춰서, 합산 결과가 범위를 초과하지 않도록 조절합니다.
Mix 모드 — Video Compositing 기술 상세
비디오 합성은 오디오보다 훨씬 계산 집약적입니다.
YUV420 이란 Y(밝기, Luma) + U,V(색차, Chroma) 색공간입니다. RGB와 달리 밝기와 색상 정보를 분리해서, 인간 눈이 색차보다 밝기 변화에 더 민감하다는 특성을 활용해 색차 해상도를 절반으로 줄입니다. 결과적으로 RGB 대비 약 33% 적은 데이터로 유사한 시각 품질을 유지합니다. 거의 모든 비디오 코덱이 내부적으로 YUV를 사용합니다.
Pixel Blitting: 각 유저의 디코딩된 프레임(YUV 데이터)을 Canvas의 지정 좌표에 복사하는 작업입니다. "blitting"은 bitmap 데이터를 메모리 영역 간에 고속 복사하는 연산을 지칭합니다.
Layout Engine: Agora는 그리드, 사이드바, 커스텀 좌표 등 배치 설정을 API로 제어할 수 있습니다. 레이아웃 설정에 따라 각 유저 프레임이 Canvas의 어느 좌표에 blitting될지가 결정됩니다.
전체 파이프라인을 표로 정리하면:
| 단계 | 오디오 | 비디오 |
|---|---|---|
| 1. 디코딩 | Opus/AAC → PCM | H.264/VP8 → YUV420 |
| 2. 합성 | PCM sample addition + normalization | Frame compositing onto canvas (pixel blitting) |
| 3. 인코딩 | PCM → AAC | YUV → H.264 |
| 4. 먹싱 | Audio + Video → MP4 container | ← 같은 단계 |
CPU 부하가 높은 이유: 30fps 기준, 초당 30번 모든 참가자 프레임을 디코딩하고, Canvas에 합성하고, 다시 H.264로 인코딩합니다. 참가자가 많을수록, 해상도가 높을수록 선형적으로 부하가 증가합니다.
Muxing vs Mixing — 자주 혼동되는 두 개념
이 맥락에서 헷갈리기 쉬운 두 용어를 명확히 구분합니다.
Mixing: 여러 스트림을 하나로 합치는 것 (오디오 믹싱, 비디오 컴포지팅)
Muxing (Multiplexing): 이미 완성된 오디오/비디오 트랙을 하나의 컨테이너(MP4)에 담는 것
비유하자면:
- Mixing = 여러 재료를 섞어서 하나의 요리를 만드는 것 (재료가 합쳐져 구별 불가)
- Muxing = 완성된 반찬들을 도시락 통에 담는 것 (각 트랙은 독립적으로 존재, 컨테이너만 공유)
MP4 파일 안에는 H.264 비디오 트랙과 AAC 오디오 트랙이 별도로 존재합니다. 이 둘을 MP4 컨테이너로 묶는 것이 Muxing입니다. Mixing은 그 이전 단계에서, 여러 참가자 스트림을 각각 단일 트랙으로 합치는 작업입니다.
Web 모드 — Headless Browser의 세계
Web 모드는 아키텍처적으로 완전히 다른 접근입니다. Mix 모드처럼 Agora 서버가 스트림을 직접 처리하는 게 아니라, Agora 서버가 Chromium 브라우저를 실행하고, 그 브라우저가 녹화를 수행합니다.
Headless Browser 란 "머리(화면) 없는 브라우저"입니다. HTML, CSS, JavaScript, WebRTC — 브라우저의 모든 기능을 실행하지만, 모니터에 출력하지 않습니다. 대신 렌더링 결과를 메모리 내 프레임버퍼에 씁니다.
흐름을 요약하면:
- Agora 서버가 Chromium 프로세스를 시작
- 브라우저가 지정된 URL에 접속
- 그 웹페이지가 내부적으로 Agora Web SDK로 채널에 조인
- 웹페이지가 렌더링되면 Screen Capture API로 프레임별 캡처
- H.264로 인코딩 → MP4로 저장
Web 모드의 강점: 화이트보드, 채팅, 커스텀 UI, 외부 데이터 오버레이 등 브라우저에서 표현 가능한 모든 것이 녹화됩니다. Mix 모드로는 불가능한 "앱 UI 포함 녹화"가 가능합니다.
Web 모드의 비용: Chromium 프로세스 자체가 수백 MB의 메모리를 점유합니다. V8 JavaScript 엔진, Blink 렌더링 엔진, Skia 그래픽 라이브러리가 모두 동시에 실행됩니다. 가장 무거운 파이프라인입니다.
녹화 전용 웹페이지 설계 패턴
Web 모드를 사용하려면 Agora 서버가 접속할 웹페이지를 직접 만들어야 합니다. 이 페이지는 세 가지 역할을 합니다:
- URL 파라미터에서 channel/token을 읽어 자동으로 채널에 조인
- 원하는 레이아웃으로 참가자 비디오를 배치
- 녹화에 최적화된 UI (컨트롤 버튼 없음, 고정 해상도)
이 페이지는 실제 사용자에게 노출되는 앱과 분리된 녹화 전용 URL로 배포하는 것이 일반적입니다. 사용자는 이 URL을 직접 방문하지 않고, Agora 서버만 이 URL에 접속합니다.
리소스 소비 비교
각 모드의 병목이 어디에 있는지 비교하면:
| 병목 | Individual | Mix | Web |
|---|---|---|---|
| 디코딩 | 유저별 1회 | 유저별 1회 | 브라우저가 처리 |
| 합성 | 없음 | 매 프레임 compositing | 브라우저 DOM 렌더링 |
| 인코딩 | 유저별 독립 | 단일 고해상도 | 단일 고해상도 |
| 추가 프로세스 | 없음 | 없음 | Chromium 전체 |
Individual 모드는 합성이 없으므로 참가자가 늘어도 CPU 증가가 선형적입니다. Mix는 Canvas 크기(출력 해상도)가 고정되면 참가자 증가에 따른 합성 비용이 지배적입니다. Web은 Chromium 기반 비용이 베이스라인으로 항상 높습니다.
모드 선택 Decision Matrix
요구사항을 기준으로 정리하면:
| 요구사항 | 추천 모드 |
|---|---|
| 화자별 분리 (STT, AI 분석) | Individual |
| 다시보기 영상 하나로 | Mix |
| 화이트보드/웹앱 UI 포함 | Web |
| 비용 최적화 | Individual + FFmpeg 후처리 |
| 가장 빠른 구현 | Mix |
"비용 최적화" 항목에 대해 부연하면: Individual 모드로 저렴하게 녹화하고, 나중에 자체 서버에서 FFmpeg으로 합성하는 방식이 가능합니다. 녹화 비용은 낮지만, 후처리 인프라가 필요합니다. 이 FFmpeg 파이프라인은 이 시리즈 5, 6편에서 상세히 다룹니다.
핵심 요약
- Individual 모드는 합성 없이 유저별 파일을 독립 저장합니다. 가장 가볍고, 타임스탬프가 보존되어 후처리 유연성이 최대입니다.
- Mix 모드는 PCM sample addition(오디오)과 pixel blitting(비디오)으로 모든 스트림을 단일 출력으로 합칩니다. 다시보기 영상이 필요할 때 가장 직관적입니다.
- Muxing(컨테이너에 담기)과 Mixing(스트림 합성)은 다른 개념입니다. 혼용하면 아키텍처 논의에서 혼선이 생깁니다.
- Web 모드는 Headless Chromium이 실제 웹 페이지를 렌더링하고 화면을 캡처합니다. 브라우저 UI 전체가 녹화 대상이라는 게 핵심입니다.
- AGC(Automatic Gain Control) 는 Mix 모드에서 여러 오디오 스트림 합산 시 Clipping을 방지하는 핵심 컴포넌트입니다.
- 모드 선택은 단순한 설정이 아니라 아키텍처 결정입니다. 출력 구조, 비용, 후처리 가능성이 모두 이 선택에 종속됩니다.
시리즈 네비게이션
실시간 통화, 어떻게 녹화하는가 시리즈