Implementation Proposal · 2026-10-12

모니터 탭 화면·오디오 녹화 구현 계획

마지막 업데이트 2026-10-12

카드뷰·포커스뷰 탭을 한 번 캡처하고 단일 MediaRecorder로 녹화. 탭 오디오·진행자 마이크 정책, 청크 저장·업로드, 오류 복구와 저사양 성능 검증 계획.

구현 전 제안성능 미검증이슈 ID 미배정 · 학생 4명 / 진행자 1명

01 · 목표와 상태

진행자가 보는 모니터 탭 화면과 실제 재생 오디오를 하나의 영상으로 기록한다. 학생 4명·진행자 1명의 카드뷰와 개별 세션 포커스뷰를 지원하며 캡처·인코더를 각각 하나만 추가한다.

상태: 구현 전 제안. 사용자 요청은 카드뷰·포커스뷰 화면·오디오 녹화이며, 진행자 마이크 포함 여부와 저장 보존 기간은 미확정이다. 이 문서는 설계 검토용으로 런타임 수정 승인을 대신하지 않는다. 이슈 ID는 미배정이다.

추가 부하 0은 보장하지 않는다. 캡처·인코딩·저장·업로드 비용이 발생한다. 4:1 수업에 체감 영향이 없는지는 실제 진행자 장비에서 측정한다.

02 · 현재 구조와 적용 지점

확인한 경로 · PPI 저장소 기준역할과 변경 계획
apps/web/app/monitor-dashboard/[group]/page.tsx그룹별 room/session을 모아 카드뷰 표시. 카드뷰와 포커스뷰의 라우트 전환에도 유지되는 공통 상위 레이아웃 또는 세션 서비스에서 녹화 수명을 소유한다. 정확한 공통 조상과 포커스뷰 연결 방식은 구현 전 확인한다. 카드별 녹화기를 만들지 않는다.
apps/web/screens/monitor-dashboard-group-screen.tsx대시보드 헤더·카드 영역·알림 패널 구성. 헤더에 시작·종료·저장 상태 UI를 추가할 후보 지점.
apps/web/hooks/mediasoup/use-mediasoup-consumer.ts학생 마이크와 AI 오디오 수신 스트림 분리. 1차 탭 오디오 녹화에서는 consumer를 추가하거나 수신 경로를 수정하지 않는다.
apps/socket/src/recording/recordingManager.ts학생·AI 오디오 stem 저장·시간 정렬·합성. 기존 서버 녹음과 별도 기능으로 다룬다. 카드 UI 녹화 기능으로 간주하지 않는다.

새 기능 모듈 후보: apps/web/features/monitor/tab-recording/. 아래 책임 분리는 제안이며 새 파일·API는 아직 존재하지 않는다.

03 · 녹화 흐름과 오디오 정책

모니터 탭 → getDisplayMedia → 화면 트랙 1개 ───────────┐
캡처된 탭 오디오 ──────────┬→ 오디오 트랙 1개 ──────┤
진행자 마이크 (옵션) → 믹서 ┘                        ↓
                                              MediaRecorder 1개
                                                   ↓
                                        청크 임시 저장 → 순차 업로드
                                                   ↓
                                         서버 조립·검증 → 저장 완료

04 · 시작·종료와 오류 처리

  1. 시작: 버튼 클릭 안에서 getDisplayMedia 호출. 현재 탭 선택·탭 오디오 공유를 안내한다. preferCurrentTab 등은 힌트이며 현재 탭을 강제로 선택하지 못한다. displaySurface와 오디오 트랙 존재를 검사한다. 현재 탭 검증이 지원되지 않으면 미리보기로 선택 대상을 확인한다. 잘못된 대상·오디오 없음은 녹화 시작 전 재선택 안내.
  2. 준비: 지원 MIME을 isTypeSupported로 검사하고 생성·시작 오류도 처리한다. 캡처 화면 1280×720·최대 15fps를 요청하고 실제 getSettings와 선택 코덱을 진단에 기록한다. 설정이 달라지면 실제 값을 기준으로 품질을 평가한다.
  3. 녹화: 화면 트랙 하나·오디오 트랙 하나로 MediaRecorder 하나 생성. start(5000)을 출발값으로 사용한다. 청크 시간을 개수로 계산하지 않고 단조 시계로 경과 시간을 표시한다.
  4. 종료: 종료·브라우저 공유 중단·화면 트랙 ended를 같은 종료 함수로 합친다. 중복 stop을 방지하고 마지막 dataavailable과 저장 완료를 기다린다. finalize 성공 전에는 ‘저장 완료’를 표시하지 않는다.
  5. 실패: 권한 취소는 대기 상태로 복귀. 코덱·장치·저장 오류는 원인에 맞게 표시. 업로드만 실패하면 보관된 청크를 재시도한다. 저장 공간 고갈 등 보존 불가 상태는 녹화를 종료하고 확보된 부분과 누락 여부를 알린다.
  6. 수명: 같은 탭의 카드뷰 ↔ 포커스뷰 전환은 녹화기를 유지하고 하나의 영상에 연속 기록한다. 새 탭으로 이동한 화면은 기존 탭 캡처에 포함되지 않으므로 같은 탭 전환을 지원 범위로 둔다. 모니터 밖 SPA 경로 이탈은 useOverlay로 종료·저장 안내. 탭 닫기·새로고침 시 비동기 종료나 마지막 청크 보존은 보장할 수 없다. 저장된 청크 복구와 불완전 녹화 표시를 제공한다. 브라우저 권한 재요청 없이 자동 녹화 재개하지 않는다.

포커스뷰 진입 경로: apps/web/app/monitor-dashboard/[group]/[roomId]/page.tsx. 기존 화면을 캡처하므로 녹화 전용 카드 화면을 재합성하지 않는다.

상태 전이: idle → selecting → recording → stopping → saving → completed. 오류·재시도 상태는 보존 여부와 미업로드 청크 수를 함께 가진다. 프레임·청크 데이터는 React 상태에 넣지 않는다.

05 · 성능 예산과 저장 설계

초기 제안검증할 항목
720p · 15fps · 영상 1.5~2.5Mbps카드 4개 글자·학생 얼굴 식별. 가독성 부족이면 1080p·15fps와 비교.
오디오 96~128kbps학생·AI·진행자 음성의 명료도, 중복·누락·왜곡 여부.
청크 목표 5초timeslice 지연·큰 청크 처리. 실제 청크 크기에 따라 큐 관리.
저장량 약 0.9GB/시간 @ 합계 2Mbps비트레이트 목표는 실제 출력 크기를 보장하지 않음. 임시 공간·최대 수업 길이 산정.

06 · 구현 순서와 검증 계획

  1. 설계 승인: 탭 오디오 정책, 진행자 마이크 기본값, 지원 브라우저, 저장 정책 확정. code-quality-guardian 기준 combined 작업으로 분류하고 관련 baseline·harness 확인.
  2. 로컬 프로토타입: 단일 탭 캡처·오디오·녹화 종료를 구현. 가짜 MediaRecorder·저장 adapter로 권한 취소, 중복 종료, 마지막 청크, 공유 마이크 보존을 먼저 테스트.
  3. 내구성 저장: 청크 저장·제한 큐·재시도·서버 finalize 계약 구현. 역순·중복 업로드·누락 청크·저장 공간 고갈을 테스트.
  4. UI: 카드뷰·포커스뷰 모두 시작·종료·진행 시간·저장·복구 상태를 표시한다. 뷰 전환 중 녹화기 유지·중복 생성 방지를 검증한다. modal/dialog는 공통 useOverlay 사용. 실제 backend·장치 없이 모든 상태를 Storybook fixture로 만들고 관련 정적 빌드 검증.
  5. 실장비 검증: Chrome/Edge 데스크톱을 초기 대상 후보로 두고 Windows/macOS 각각 탭 오디오·마이크·코덱 지원을 확인. 지원표가 확정되기 전 다른 브라우저를 지원한다고 표시하지 않음.
  6. 최종 검토: 영향 파일 범위 lint·typecheck·관련 테스트, guardian-gate 리뷰. 실제 장비 기록과 함께 제한 배포 후 확대.
검증 사례합격 기준 · 제안
4:1 카드뷰·포커스뷰·두 뷰 전환, 영상·AI·학생 발화, 60분 녹화전체 영상 재생 가능, 뷰 전환 전후 연속 기록·끝부분 포함, 오디오 중복·녹화로 추가된 누락 없음. 시작·중간·끝 A/V 오차 절대값 200ms 이내 목표.
녹화 OFF/ON 동일 시나리오 각각 3회대표 저사양 PC에서 수업 영상 dropped-frame 비율 증가 2%p 이내, 조작 p95 지연 증가 50ms 이내 목표. CPU/GPU·long task·오디오 상태도 기록. 합격값은 실제 baseline 후 승인.
장시간 메모리·업로드메모리 버퍼 예산 준수, 시간에 비례하는 RAM 증가 없음. 임시 디스크 증가는 미업로드 데이터량으로 설명 가능.
네트워크 5분 단절·복구임시 공간이 충분하면 청크 보존·재전송·완성 영상 정상. 부족하면 안전 종료·부분 녹화 안내.
공유 중단·경로 이탈·탭 닫기·재접속정상 stop은 마지막 청크 보존. 강제 이탈은 불완전 표시·저장된 청크 복구. 공유 수업 트랙과 세션 연결 유지.
잘못된 공유 대상·오디오 미선택·권한 취소완전한 녹화처럼 표시하지 않고 재선택·지원 안내. 장치나 권한 없이 UI fixture 검증 가능.

07 · 확인된 근거와 미확정 항목

2026-10-12 저장소의 카드뷰 페이지, 그룹 화면, Mediasoup 수신 스트림과 서버 RecordingManager를 조회했다. 이 문서 작업에서 애플리케이션 코드는 수정하지 않았다. 녹화 프로토타입·성능 테스트·브라우저 호환 테스트는 아직 실행하지 않았다.

미확정: 실제 진행자 장비·브라우저 분포, 마이크 포함 기본값, 탭 음소거/출력 장치별 캡처 동작, 사용 가능한 저장 API, 인코더 가속 여부, 보존 기간·열람 정책. 성능 기준은 위 제안값으로 검토 후 확정한다.