-
Notifications
You must be signed in to change notification settings - Fork 2
11 18 회의
Seungheon Han edited this page Nov 30, 2024
·
1 revision
-
메인페이지와 방송 시청 화면 구현
-
필수 기능:
- 채팅
- 화질 조정
- 화면 공유
- 썸네일
-
제외 기능:
- 필터링과 검색은 구현하지 않음.
-
필수 기능:
-
로그인 기능 구현
- 네이버 OAuth
- Github OAuth
-
새로운 녹화 서버 생성 및 썸네일 처리
- PlainTransport로 새로운 Consumer를 만들어 스트리밍 데이터를 녹화 서버로 전송.
- 녹화 서버는 RTP 프로토콜 데이터를 처리하여 썸네일 생성.
- PlainTransport로 Consumer를 생성하고 Record Server로 데이터를 전송.
-
코드 예시:
const express = require('express'); const { spawn } = require('child_process'); const app = express(); const port = 3000; const RTP_PORT = 5004; function startFFmpeg(outputFile) { const ffmpeg = spawn('ffmpeg', [ '-protocol_whitelist', 'file,udp,rtp', '-f', 'rtp', '-i', `rtp://0.0.0.0:${RTP_PORT}`, '-c:v', 'copy', '-f', 'mp4', outputFile, ]); ffmpeg.stderr.on('data', (data) => { console.error(`FFmpeg error: ${data}`); }); ffmpeg.on('close', (code) => { console.log(`FFmpeg process exited with code ${code}`); }); return ffmpeg; } app.post('/start', (req, res) => { const outputFile = 'output.mp4'; const ffmpegProcess = startFFmpeg(outputFile); req.app.set('ffmpegProcess', ffmpegProcess); res.send('FFmpeg recording started.'); }); app.post('/stop', (req, res) => { const ffmpegProcess = req.app.get('ffmpegProcess'); if (ffmpegProcess) { ffmpegProcess.kill('SIGINT'); res.send('FFmpeg recording stopped.'); } else { res.status(400).send('No FFmpeg process is running.'); } }); app.listen(port, () => { console.log(`Server is running at http://localhost:${port}`); });
- Record Server에서도 Consumer를 생성.
- Mediasoup PlainTransport를 통해 두 Consumer를 연결하고 데이터 스트림을 전송.
- 이후 스트림 데이터로 녹화 및 썸네일 생성.
- 1번 방식으로 먼저 시도.
- 필요 시 2번 방식으로 전환.
- 담당: 희선
-
구현:
- Express를 사용해 간단한 구성.
- Typescript와 ffmpeg 라이브러리 사용.
- Prettier 적용. Lint 및 Git Actions는 적용하지 않음.
- Docker 세팅 포함.
- 의견: ffmpeg 처리만 필요하므로 NestJS는 사용하지 않음.
-
Broadcast 테이블 관리:
- 방송 시작 시 데이터 생성 (Conflict 해결 필요) → 승헌
- 사용자 접속 시 Viewers 업데이트 (수정 API) → 승헌
- 방송 종료 시 Broadcast 레코드 삭제, Attendance 테이블에 레코드 생성 → 광현
- 네이버 OAuth, Github OAuth → 승헌
- 로그아웃 기능 → 승헌
- Swagger API 문서화 → 희선
- 구현 방식 비교:
-
장점:
- 구현 단순.
- 별도 인프라 설정 필요 없음.
- 빠른 처리 속도.
- 현재 단일 서버 구조에서는 데이터 일치성 보장 필요 없음.
- 채팅 데이터의 영구 저장이 불필요 (휘발 가능).
-
장점:
- 확장성 유리.
- 무중단 배포 및 여러 서버 운용 시 데이터 일치성 보장.
- 채팅 내역 캐싱 및 TTL 설정 용이.
-
현재 선택: 인메모리 방식
- Redis 도입은 확장 필요성이 생길 경우 고려.
- Mediasoup 포트 매핑 문제
- swagger 같은 응답 코드에 다양한 응답 보여주기
- Sudo가 계속 비밀번호를 요청함
- Docker 이미지가 너무 크다
- Git action에서 도커 이미지 빌드 시간을 단축시켜보자
- Docker compose를 이용해서 메모리 사용률을 줄여보자
- 방송 녹화 시 CPU 과부하 문제를 해결해보자
- Release 브랜치? 너 필요해?
- 로딩이 너무 짧아…!
- NestJS ORM으로 무엇을 사용해야 할까?
- WebRTC를 이용한 1:N 스트리밍 서비스에서 시그널링 서버가 필요할까?
- 실시간 채팅 구현: 인메모리 방식을 선택한 이유
- MySQL 아키텍처 개선: DB 의존성 분리와 서버 역할 명확화
- 브라우저 창이 최소화되면 비디오 송출이 안된다…!
- Mediasoup 기본 개념
- DLTS와 Signaling
- Tell, Don't Ask (TDA) 원칙이란
- VPC(Virtual Private Cloud) 학습 정리
- 순환참조: A 서비스 ‐ B 서비스 vs. A 서비스 ‐ B 레포지토리
- Dto 메서드 전략
- WebRTC란?
- 자바스크립트 패키지 매니저(npm, yarn, pnpm)
- shadcn/ui을 이용해 UI 개발 생산성 높이기
- React 이벤트 핸들러 네이밍(on vs handle)
- React-router-dom의 createBrowserRouter을 사용해보기
- fetch vs axios