Cloud Recording 녹화 파일은 어떻게 저장되는가? — S3 실시간 업로드, 끊김 복구, 재생까지
Cloud Recording 산출물이 object storage에 기록되는 방식과 장애 후 처리 절차를 설명합니다. TS·M3U8·MP4의 분할 조건, recording server failover 시 생성되는 backup playlist, stop·query 응답의 file list를 구분합니다. 애플리케이션에서는 사용자 소유권을 확인한 뒤 저장된 object key로 짧은 수명의 presigned URL을 발급해야 합니다.
Agora Cloud Recording으로 상담 통화를 녹화하면 녹음 파일이 S3에 어떻게 올라가는지, 중간에 끊기면 어떻게 되는지, MP4는 몇 개나 생기는지 — 처음 도입할 때 궁금했던 것들을 정리합니다. 마지막에는 S3에 저장된 녹음을 presigned URL로 재생하는 실제 코드도 포함했습니다.
실시간으로 S3에 올라가는가?
녹화가 끝난 뒤 한꺼번에 올리는 방식이 아닙니다. 녹화 중에 미디어 조각(TS/WebM 파일)이 순차적으로 S3에 업로드됩니다.
Cloud Recording은 내부적으로 HLS(HTTP Live Streaming) 방식을 사용합니다. HLS는 미디어를 짧은 TS(Transport Stream) 조각으로 분할하고, M3U8 인덱스 파일로 순서를 관리하는 구조입니다.
HLS 조각은 녹화 중 업로드되고, MP4 파일은 녹화가 끝나거나 분할 임계치에 도달할 때 닫힙니다. TS와 MP4는 모두 인코딩된 미디어를 담는 컨테이너 출력입니다. MP4를 항상 TS 조각을 사후 결합한 결과로 보아서는 안 됩니다.
정정: "MP4는 녹화가 100% 끝나야만 만들어진다"는 건 정확한 표현이 아닙니다.
avFileType: ["hls","mp4"]로 설정하면 녹화 도중에도 분할 임계치(아래 참고)에 도달하면 그 시점의 MP4 조각이 닫히고 다음 조각이 새로 열립니다. 즉 각 MP4 조각은 "그 구간이 끝나는 시점"에 마무리되며, 마지막 조각이 녹화 종료 시점에 닫히는 구조입니다. 짧은 단일 상담에서는 조각이 1개뿐이라 "녹화 종료 = MP4 완성"처럼 보일 뿐입니다.
끊기면 어떻게 되는가?
업로드가 완료된 조각은 제3자 스토리지에 남습니다. 다만 게시자 네트워크 단절, 스토리지 업로드 실패, 녹화 서버 장애는 서로 다른 상황이며 결과 파일도 다르게 처리됩니다.
끊겼을 때 파일별 상태를 정리하면:
| 파일 | 상태 | 설명 |
|---|---|---|
| 이미 업로드된 조각 | 스토리지에 유지 | 업로드가 완료된 객체는 그대로 남음 |
| 업로드 재전송 M3U8 | suffix가 붙을 수 있음 | 가장 큰 최신 버전과 suffix 없는 파일을 비교 |
| HA 전환 후 파일 | bak<n>_ prefix | 장애 전·후 playlist를 함께 처리해야 함 |
단일 M3U8이 정상적으로 남아 있고 조각의 codec·timestamp가 호환된다면 FFmpeg stream copy로 MP4를 만들 수 있습니다.
HA 전환으로 bak<n> playlist가 생긴 경우에는 단일 M3U8 명령만으로 전체 구간이 합쳐지지 않습니다. Agora는 이 경우 전용 HA transcoder 사용 절차를 제공합니다.
MP4는 계속 새로 만드는가?
정상적으로 이어진 30분짜리 음성 상담은 분할 임계치에 도달하지 않으므로 Composite/Web page recording에서 보통 MP4 1개가 생성됩니다. 장애나 재시작이 발생하면 파일 수가 달라질 수 있습니다.
일반적인 1:1 상담이나 CS 통화에서는 MP4 분할을 신경 쓸 일이 거의 없습니다. 분할이 걱정되는 건 수 시간짜리 웨비나나 라이브 방송 녹화 정도입니다.
Composite와 Web page recording의 MP4는 현재 파일이 약 3시간 또는 약 2GB에 이르면 다음 파일로 분할됩니다. Individual recording은 MP4를 생성하지 않습니다. Web page recording에서는 maxVideoDuration으로 길이 기준을 별도 설정할 수 있습니다.
S3 녹음 파일 재생 — 실제 코드
Cloud Recording으로 S3에 저장된 MP4를 웹에서 재생할 때는, 인증된 백엔드가 presigned URL을 발급하고 브라우저가 S3에서 파일을 받도록 구성할 수 있습니다.
백엔드 (Node.js — presigned URL 생성)
프론트엔드 (HTML + JS — 재생 플레이어)
동작 흐름
CS 담당자가 웹에서 상담 녹음을 재생하는 전체 과정입니다.
이 구조의 특성은 다음과 같습니다.
- 데이터 전송 분리 — 파일 바이트 전송은 S3가 담당하지만, 사용자 인증·권한 확인과 URL 발급 부하는 백엔드에 남습니다.
- 제한된 접근 — S3 credentials를 프론트엔드에 노출하지 않고 URL 유효 시간을 제한합니다. URL은 서명 자격 증명 만료나 정책 변경으로 설정 시간보다 일찍 무효화될 수도 있습니다.
- 재생 호환성 —
ffprobe로 오디오 codec을 식별한 뒤 지원 대상 브라우저에서 오디오 전용 MP4를 재생합니다.
프로덕션에서는
위 코드는 세션 ID를 수동으로 입력하는 데모 수준입니다. 실제 서비스에서는 Agora의 callback notification을 활용합니다.
프로덕션에서는 webhook으로 녹화 상태를 추적하고, stop 또는 query 응답의 file list에서 실제 object key를 확인해 DB에 저장합니다. 알림 유실과 중복 전달을 고려해 sid 기준으로 idempotent하게 처리해야 합니다.
핵심 요약
- 미디어 조각은 녹화 중 업로드 — 완료된 객체는 제3자 스토리지에 남고, 업로드 실패나 서버 failover 시에는 별도 복구 파일이 생성될 수 있습니다.
- MP4는 Composite/Web page recording에서 선택 — 약 3시간 또는 약 2GB에서 분할되며 Individual recording은 MP4를 생성하지 않습니다.
- presigned URL은 권한 검사 뒤 발급 — 파일 전송은 S3가 맡지만 인증·인가와 URL 발급은 백엔드 책임입니다.
관련 글
- #12 실시간 통화, 왜 녹화해야 하는가 — Cloud Recording Architecture — 이 글의 상위 개념. 왜 Cloud Recording을 쓰는지, 전체 아키텍처를 먼저 보면 이해가 빠릅니다.
- #14 Agora 녹화 모드 비교 — Individual, Composite, Web page — MP4 분할 규칙이 모드마다 다른 이유. 이 글의 분할 임계치 이해에 필수.
- #15 M3U8과 TS 구조 — HLS 녹화 파일 읽기 — 본문의 TS 실시간 업로드/M3U8 인덱스가 정확히 어떻게 동작하는지.
- #33 Cloud Recording 점프 재생 — moov/ENDLIST/DISCONTINUITY — 끊긴 녹화를 FFmpeg로 복구할 때 마주치는 moov/ENDLIST 문제의 심화편.
- #17 FFmpeg 실전 파이프라인 — Agora 녹화에서 프로덕션 VOD까지 — TS+M3U8를 MP4로 합치고 VOD로 가공하는 파이프라인.
참고 자료
- Cloud Recording — Manage recorded files (Agora Docs) — MP4/M3U8/TS 생성 규칙, 분할 조건, 비정상 상황의 파일 처리.
- Cloud Recording — Composite recording mode (Agora Docs) —
avFileType등 녹화 시작 시 파일 포맷 설정 방법. - Cloud Recording RESTful API Reference (Agora Docs) — acquire/start/query/stop API와 인증 방식.
- Download and upload objects with presigned URLs — Amazon S3 — presigned URL의 권한과 유효 기간.
- HTTP Live Streaming (HLS) — RFC 8216 — M3U8 플레이리스트와 미디어 세그먼트(TS) 구조의 표준 명세.
- ffmpeg-formats: HLS demuxer (FFmpeg Documentation) —
ffmpeg -i recording.m3u8 -c copy복구 시 동작하는 HLS demuxer 동작.