시리즈: 실시간 통화, 어떻게 녹화하는가3/6
- 1.실시간 통화, 왜 녹화해야 하는가
- 2.내 서버에서 직접 녹화한다면
- 3.녹화 모드 해부 ← 현재 글
- 4.M3U8과 TS 파일의 모든 것
- 5.FFmpeg, 미디어의 스위스 아미 나이프
- 6.FFmpeg 실전 파이프라인
녹화 모드 해부 — Individual, Mix, Web의 내부 파이프라인
같은 채널을 녹화해도 Individual, Mix, Web 중 무엇을 고르느냐에 따라 서버 안에서 벌어지는 일이 완전히 달라집니다. 출력 파일 구조부터 CPU 부하, 비용까지 모두 이 선택 시점에 결정되기 때문입니다. 각 모드가 스트림을 어떻게 처리하는지, 오디오 믹싱과 비디오 합성이 내부적으로 어떤 연산을 거치는지, 그리고 헤드리스 브라우저로 화면을 캡처하는 Web 모드가 왜 가장 무거운지를 짚어 봅니다. 어떤 상황에 어떤 모드를 골라야 하는지 판단 기준까지 정리합니다.
같은 채널에서 녹화를 시작해도, 어떤 모드를 선택하느냐에 따라 서버 내부에서 벌어지는 일이 완전히 달라집니다. 출력 파일 구조, 서버 리소스 소비, 비용 — 모든 것이 모드 선택 시점에 결정됩니다.
Agora Cloud Recording은 세 가지 모드를 제공합니다: Individual, Mix, Web. 이 글에서는 각 모드의 내부 파이프라인을 해부하고, 언제 어떤 모드를 선택해야 하는지를 정리합니다.
Individual 모드 — 분리의 미학
Individual 모드의 핵심 철학은 단순합니다: 합성하지 않는다. 각 참가자의 스트림을 독립적으로 처리해서 별도 파일로 저장합니다.
파이프라인이 단순한 이유: Compositing(합성) 단계가 없습니다. 각 UID의 스트림을 받아서 개별 파일로 쓰는 것이 전부입니다. 기본 출력은 UID별 MP4 단일 파일이 아니라 M3U8 인덱스 + 다수의 TS 슬라이스로 이뤄진 HLS입니다. 출력 포맷을 결정하는 두 설정은 역할이 다릅니다: 바로 재생 가능한 병합 인덱스(단일 M3U8)가 필요하면 streamMode=standard로 두고, 별도의 MP4 파일이 필요하면 avFileType에 mp4를 추가합니다. streamMode=standard로 둔다고 MP4가 생성되는 것은 아니며, standard의 출력도 여전히 HLS(UID별 M3U8 + TS)입니다.
transcoding 여부는 streamMode에 종속됩니다. streamMode=original이면 재인코딩 없이 원본을 그대로 저장하는 non-transcoding 방식이고, streamMode=standard이면 통일된 프로파일로 재인코딩(transcoding)합니다. 위 다이어그램의 Re-encode가 조건부인 이유입니다.
타임스탬프가 핵심입니다. 각 파일에는 녹화 시작 시점 기준의 타임스탬프가 정확히 보존됩니다. 덕분에 나중에 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 범위는 -32768 ~ +32767입니다(2의 보수라 음수 쪽이 1 더 넓습니다). 이 범위를 초과하면 파형이 잘려서(clipped) "찢어지는" 소리, 즉 디지털 왜곡이 발생합니다. 이걸 방지하기 위해 AGC(Automatic Gain Control) 가 동작합니다. 여러 스트림을 합산하기 전에 각 스트림의 gain을 자동으로 낮춰서, 합산 결과가 범위를 초과하지 않도록 조절합니다.
Mix 모드 — Video Compositing 기술 상세
비디오 합성은 오디오보다 훨씬 계산 집약적입니다.
YUV420 이란 Y(밝기, Luma) + U,V(색차, Chroma) 색공간입니다. RGB와 달리 밝기와 색상 정보를 분리해서, 인간 눈이 색차보다 밝기 변화에 더 민감하다는 특성을 활용해 색차를 가로·세로 양방향으로 절반씩(즉 1/4로) 서브샘플링합니다. 정정: 4:2:0은 RGB 대비 픽셀당 데이터가 12 bit vs 24 bit로 약 50% 절감입니다(픽셀당 33% 절감은 4:2:2의 16 bit 케이스). 거의 모든 비디오 코덱이 내부적으로 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 모드는 합성 없이 UID별 파일을 독립 저장합니다. 기본 출력은 UID별 M3U8 인덱스 + 다수 TS 슬라이스(HLS)입니다. 출력 포맷은
streamMode가 아니라avFileType로 결정됩니다: 바로 재생 가능한 병합 인덱스(단일 M3U8)가 필요하면streamMode=standard, MP4 파일이 필요하면avFileType에mp4를 추가합니다(standard의 출력도 여전히 HLS). 가장 가볍고, 타임스탬프가 보존되어 후처리 유연성이 최대입니다. - Mix 모드는 PCM sample addition(오디오)과 pixel blitting(비디오)으로 모든 스트림을 단일 출력으로 합칩니다. 다시보기 영상이 필요할 때 가장 직관적입니다.
- Muxing(컨테이너에 담기)과 Mixing(스트림 합성)은 다른 개념입니다. 혼용하면 아키텍처 논의에서 혼선이 생깁니다.
- Web 모드는 Headless Chromium이 실제 웹 페이지를 렌더링하고 화면을 캡처합니다. 브라우저 UI 전체가 녹화 대상이라는 게 핵심입니다.
- AGC(Automatic Gain Control) 는 Mix 모드에서 여러 오디오 스트림 합산 시 Clipping을 방지하는 핵심 컴포넌트입니다.
- 모드 선택은 단순한 설정이 아니라 아키텍처 결정입니다. 출력 구조, 비용, 후처리 가능성이 모두 이 선택에 종속됩니다.
시리즈 네비게이션
실시간 통화, 어떻게 녹화하는가 시리즈
관련 글
- #12 실시간 통화 왜 녹화하나 — Cloud Recording Architecture — 모드 선택 이전, Cloud Recording의 전체 아키텍처와 동작 원리
- #13 On-Premise vs Cloud Recording — 같은 녹화를 자체 서버에서 할 때의 트레이드오프
- #17 FFmpeg 실전 파이프라인 — Agora 녹화 VOD — Individual 모드 파일을 후처리로 합성하는 실제 FFmpeg 파이프라인
- #22 PCM vs WAV — 컨테이너와 코덱 — Mix 모드 오디오 믹싱의 기반인 PCM 샘플과 컨테이너 개념
- #33 Cloud Recording 점프 재생 — moov/ENDLIST/DISCONTINUITY — 녹화 결과물(MP4/HLS)의 재생 가능성과 컨테이너 구조
참고 자료
- Agora Cloud Recording — Overview — Individual/Mix/Web 녹화 모드의 공식 정의와 동작 설명
- Agora Cloud Recording — Set up Web page recording — Web(Headless Chromium) 모드의 녹화 전용 페이지 설계 가이드
- Agora Cloud Recording — Recording configuration (transcoding/layout) — Mix 모드 합성 레이아웃과 출력 포맷 설정
- ITU-T Rec. H.264 — Advanced video coding — Mix/Web 모드 출력에 사용되는 H.264 코덱 표준
- Chroma subsampling — Wikipedia — YUV 4:2:0/4:2:2의 데이터 절감 비율 산수 근거
- FFmpeg Documentation — Individual 모드 후처리 합성에 쓰이는 필터/먹싱 레퍼런스