시리즈: 실시간 통화, 어떻게 녹화하는가1/6
- 1.실시간 통화, 왜 녹화해야 하는가 ← 현재 글
- 2.내 서버에서 직접 녹화한다면
- 3.Agora 녹화 모드 비교
- 4.M3U8과 TS 구조
- 5.FFmpeg 미디어 처리
- 6.FFmpeg 실전 파이프라인
실시간 통화, 왜 녹화해야 하는가 — Cloud Recording Architecture
WebRTC는 미디어 저장 방식을 정의하지 않으므로 녹화가 필요하면 별도 파이프라인을 설계해야 합니다. 이 글은 브라우저 `MediaRecorder`, 자체 미디어 서버, Agora Cloud Recording의 통제 범위와 운영 부담을 비교합니다. Cloud Recording의 non-streaming client 모델, `acquire → start → query → stop` 수명주기, REST 인증과 RTC token의 역할도 구분합니다.
목차(15개 항목)
- 클라이언트 녹화의 운영 조건
Recording service의 채널 참여 방식
Recording Lifecycle 심화
- 인증 체계: 두 개의 키가 왜 필요한가
- 스토리지 연동
- 핵심 요약
- 시리즈 네비게이션
- 관련 글
- 참고 자료
WebRTC 표준은 통화 녹화나 영구 저장을 정의하지 않습니다. 연결이 끝난 뒤 미디어를 보관하려면 클라이언트 또는 서버에 별도의 녹화 파이프라인을 구성해야 합니다.
서비스에 따라 상담 기록 보관, 수업 다시 보기, 품질 관리, 분쟁 대응 같은 요구가 생깁니다. 금융·의료처럼 규제가 적용되는 분야는 관할 법률, 처리 목적, 동의와 보유 기간을 별도로 검토해야 합니다.
이 시리즈는 이 문제를 다룹니다. 실시간 통화를 어떻게 녹화하는가 — 아키텍처부터 파일 포맷, FFmpeg 실전 파이프라인까지 6편에 걸쳐 풀어봅니다. 1편인 이 글에서는 "왜 녹화해야 하는가"와 Cloud Recording의 핵심 아키텍처를 다룹니다.
클라이언트 녹화의 운영 조건
가장 직관적인 접근은 브라우저에서 직접 녹화하는 겁니다. Web API에는 MediaRecorder가 있고, 스트림을 받아서 Blob으로 저장할 수 있습니다.
이 방식으로 프로덕션 요구사항을 충족하려면 다음 조건을 처리해야 합니다.
첫째, MediaRecorder는 전달받은 하나의 MediaStream을 녹화합니다. 그 스트림에는 로컬 또는 원격 track을 넣을 수 있지만, 여러 참가자를 한 화면과 한 오디오 track으로 합치려면 애플리케이션이 별도로 합성해야 합니다.
둘째, 믹싱과 인코딩 비용을 클라이언트가 부담합니다. OffscreenCanvas와 Web Audio API로 합성할 수 있지만 CPU·메모리·배터리 영향은 해상도, codec, 참가자 수, 장치에 따라 측정해야 합니다.
셋째, 업로드와 복구를 직접 구현해야 합니다. 위 예제처럼 chunk를 종료 시점까지 메모리에 모으면 탭 종료 시 유실될 수 있습니다. start(timeslice) 또는 requestData()로 주기적인 Blob을 만들 수 있지만, 증분 업로드·재시도·체크포인트는 애플리케이션 책임입니다.
넷째, 자체 미디어 서버는 통제력과 운영 부담을 함께 가져옵니다. Janus, Medea, Mediasoup 같은 SFU나 MCU를 운영하면 서버 측 녹화와 합성을 세밀하게 제어할 수 있지만, 용량 계획·장애 대응·확장 운영이 필요합니다.
클라이언트 녹화도 가능한 선택지지만, 여러 참가자의 안정적인 중앙 녹화가 필요하면 서버 관리형 녹화를 비교할 이유가 생깁니다.
Recording service의 채널 참여 방식
Agora 문서는 Cloud Recording service를 스트림을 발행하지 않는 RTC client와 동등한 존재로 설명합니다. Recorder UID는 채널 안에서 고유해야 하며, 설정한 UID의 미디어를 subscribe해 저장합니다.
Recorder는 어떻게 동작하는가
Recorder는 일반 RTC 참가자와 동일한 방식으로 채널에 조인합니다. 차이점은 두 가지입니다:
- Non-streaming client — Recorder는 미디어를 발행하지 않고 지정한 audio/video stream을 수신합니다.
- 사용자 목록 처리 — recorder가 자동으로 보이지 않는 것은 아닙니다. 애플리케이션이 채널 사용자 목록을 표시한다면 recorder UID를 숨겨 사용자 혼란을 막아야 합니다.
하나의 채널에 여러 Recorder를 동시에 투입할 수 있습니다
같은 채널에 Recorder를 여러 개 띄울 수 있습니다. 실제 사용 사례:
여러 recording session을 운영할 때는 UID와 lifecycle을 각각 추적해야 합니다. 장애 대비는 임의의 중복 recorder보다 Agora의 Cloud Recording high-availability 동작과 bak<n> 산출물 처리 절차를 기준으로 설계합니다.
Recording Lifecycle 심화
Cloud Recording은 4단계 REST API 호출로 제어합니다.
acquire — resourceId 확보
cname은 채널명이고 uid는 채널에서 고유한 Recorder UID입니다. resourceId는 발급 후 5분 내 start에 사용해야 합니다.
주의: resourceId의 만료와 resourceExpiredHour는 서로 다른 두 개의 메커니즘입니다. 혼동하지 마세요.
resourceId는resourceExpiredHour와 무관하게 항상 발급 후 5분 이내에start로 사용해야 합니다. 5분이 지나면resourceId가 만료되어start호출 시 error 433이 반환되며, 이 경우acquire를 다시 호출해 새resourceId를 받아야 합니다. 이것이acquire직후 곧바로start를 호출해야 하는 진짜 이유입니다. 두 호출 사이에 사용자 확인 UI를 넣거나, 별도 큐에 넣어서 처리하는 것은 권장하지 않습니다.resourceExpiredHour는resourceId의 만료와는 별개입니다. 이 파라미터는 녹화가 시작되어sid를 받은 시점부터query/updateLayout/stop등의 API를 호출할 수 있는 유효 기간을 설정합니다. 유효 범위는 1~720시간, 기본값은 72시간입니다.
start — 녹화 시작
start 호출 응답에서 sid(세션 ID)를 받습니다. sid는 이후 query와 stop에 모두 필요합니다. 반드시 DB에 저장하세요.
query — 상태 확인
녹화 중에 query를 주기적으로 호출해서 상태를 확인할 수 있습니다. serverResponse.fileList에서 현재까지 업로드된 파일 목록을 확인할 수 있습니다.
stop — 녹화 종료
stop 이후 해당 모드와 recordingFileConfig에 맞는 최종 파일이 스토리지에 업로드됩니다. serverResponse.uploadingStatus가 "uploaded"인지 확인하세요. "backuped"라면 Agora backup cloud에 보관된 상태이므로 storage failure 처리 절차를 따라야 합니다.
자세한 REST API 호출 예시와 코드는 Cloud Recording으로 스트림 자동 녹화하기를 참고하세요.
인증 체계: 두 개의 키가 왜 필요한가
Cloud Recording을 처음 도입할 때 가장 헷갈리는 부분이 인증입니다. 키가 두 종류나 있습니다.
| REST API (Cloud Recording) | RTC SDK (클라이언트) | |
|---|---|---|
| 인증 수단 | Customer ID + Customer Secret | Token (App ID + Certificate) |
| 용도 | 녹화 시작/중지 제어 | 채널 입장 |
| 위치 | 서버 사이드 | 클라이언트 사이드 |
| 방식 | HTTP Basic Auth | SDK 파라미터 |
| 발급처 | Agora 콘솔 → RESTful API | 서버에서 Token Builder로 생성 |
Customer ID + Customer Secret은 Agora REST 인증 정보입니다. Cloud Recording API 호출은 서버에서 수행하고 이 값을 클라이언트에 노출하면 안 됩니다. 실제 접근 범위는 사용하는 REST API와 계정 권한을 기준으로 관리합니다.
RTC Token은 특정 채널과 UID에 부여한 권한·만료 시간을 담습니다. 일회용은 아니며 유효 기간 동안 해당 권한으로 재사용될 수 있습니다. App Certificate가 활성화된 채널에서는 Recorder용 Token을 생성해 start 호출에 전달합니다.
스토리지 연동
Cloud Recording 결과를 받으려면 지원되는 제3자 클라우드 스토리지를 연동해야 합니다. 업로드 실패 시 Agora Cloud Backup에서 스토리지로 재전송되는 경우도 있으므로 webhook과 파일 목록을 함께 확인합니다.
지원 vendor와 region 값은 변경될 수 있으므로 Third-party cloud storage regions의 현행 표를 기준으로 설정합니다.
storageConfig는 start 호출 시 clientRequest 안에 포함합니다:
S3 권한 설정과 저장 흐름, TS 파일 실시간 업로드 동작, 끊김 복구 메커니즘은 녹화 파일은 어떻게 저장되는가에서 자세히 다룹니다.
핵심 요약
- MediaRecorder는 전달된 MediaStream을 녹화 — 다자간 합성, 증분 업로드와 복구는 애플리케이션이 구현합니다.
- Cloud Recording service는 non-streaming client로 채널에 참여 — 사용자 목록에서는 애플리케이션이 recorder UID를 구분해야 합니다.
- 여러 recording session은 각각 추적합니다 — 용도나 모드를 분리할 수 있지만 UID·resourceId·sid와 산출물을 session별로 관리하고, 장애 복구는 공식 HA 절차를 따릅니다.
resourceId는 발급 후 5분 내에start로 사용해야 함 — 5분 경과 시 만료(error 433)되어acquire를 다시 호출해야 하므로,acquire직후 곧바로start를 호출하세요. 이는resourceExpiredHour(sid발급 후query/stop등 호출 유효 기간, 1~720시간·기본 72)와는 별개의 메커니즘입니다.sid는 DB에 저장하세요.- 인증 정보는 목적이 다름: REST API용 Customer ID/Customer Secret과 RTC 채널 입장용 Token을 구분합니다.
시리즈 네비게이션
실시간 통화, 어떻게 녹화하는가 시리즈
관련 글
- #1 Cloud Recording으로 스트림 자동 녹화 — 이 글의 acquire→start→stop 라이프사이클을 실제 REST API 코드로 구현하는 후속편
- #11 Cloud Recording 녹화 파일은 어떻게 저장되는가? — S3 실시간 업로드, 끊김 복구, 재생까지 — storageConfig 연동, TS 실시간 업로드, 끊김 복구 메커니즘의 상세 동작
- #13 내 서버에서 직접 녹화한다면 — On-Premise vs Cloud Recording — 관리형 녹화와 자체 운영의 트레이드오프를 비교
- #14 Agora 녹화 모드 비교 — Individual, Composite, Web page — non-streaming recorder가 수신한 stream을 모드별로 합성·분리하는 방식
- #0 WebRTC란? ICE/STUN/NAT/TURN 기초 — 통화가 왜 본질적으로 ephemeral한지, P2P 연결 모델의 기반 개념
참고 자료
- Cloud Recording RESTful API 레퍼런스 — acquire/start/query/stop API와 응답 스펙.
- Best practice in integrating Cloud Recording — acquire 직후 start 호출, 중복 녹화 등 운영 지침.
- Third-party cloud storage regions —
storageConfig의 vendor/region 매핑. - MediaStream Recording —
MediaRecorder,timeslice,requestData()동작을 정의하는 표준. - RFC 8825 — Overview: Real-Time Protocols for Browser-Based Applications — WebRTC 미디어가 일시적(ephemeral)으로 흐르는 구조의 표준 개요