728x90
반응형
[WebRTC] OpenVidu
Livekit 기반의 중계 서버를 애플리케이션에 쉽게 추가할 수 있도록 하는 WebRTC 프레임워크
LiveKit
- 확장 가능하고 유연한 WebRTC SFU (Selective Forwarding Unit) 기반의 오픈 소스 미디어 서버
- 실시간 비디오, 오디오 및 데이터 통신을 위한 도구를 제공
- 개발자가 WebRTC 애플리케이션을 쉽게 구축할 수 있도록 지원
특징
1. WebRTC 미디어 서버
- WebRTC 세션에서 비디오 및 오디어 스트림을 처리하고 라우팅하는 역할
2. 클라이언트 API 세트
- 다양한 언어 지원 : Java, Javascript, Node.js 등 다양한 언어를 위한 클라이언트 API 제공
- 미디어 파이프라인 제어 : 미디어 파이프라인은 미디어 스트림을 처리하는 일련의 단계를 말하며 개발자가 제어 가능
- 이벤트 처리 : 새로운 참여자가 세션에 참여, 미디어 스트림의 품질이 변경되는 등의 이벤트를 감지하고 조치를 취할 수 있음
구성 요소
- OpenVidu Server(Media Node) - 로컬에서는 도커를 이용
- 미디어 스트림을 처리하고 배포하는 역할
- LiveKit 미디어 서버를 기반
- 미디어 스트림을 다른 참여자들에게 전달
- OpenVidu Client(Browser or Application) - React 사용
- Kurento 서버와 통신하며 미디어 장치에 접근하고 스트림을 송수신
- OpenVidu REST API - Node.js 사용(Nest.js로 변경 예정)
- Kurento 서버와 통신하는 API
- 세션 생성, 토큰 발급 등 다양한 기능을 제어
동작 구조(Nest.js로 서버 구현)
- 클라이언트의 요청을 받고, Node.js 서버에서 LiveKit 서버에 세션(Room)을 생성
- 서버는 세션(Room)에 참여하는 사람이 생길 때마다 LiveKit 서버에서 Participant를 생성하고 토큰을 발급
- 클라이언트는 WebSocket을 통해 토큰을 사용하여 세션에 연결
- 세션에 연결한 뒤, 참가자는 WebRTC를 통해 미디어 트랙(비디오, 오디오 등)을 발행(Publish)하고 구독(Subscribe)할 수 있음
controller.ts
더보기
import {Controller, Post, Body, Res, Req} from '@nestjs/common';
import {LivekitService} from './livekit.service';
import {WebhookReceiver} from 'livekit-server-sdk';
import {Request, Response} from 'express';
import * as dotenv from 'dotenv';
import * as process from 'process';
dotenv.config();
@Controller()
export class LivekitController {
private readonly webhookReceiver: WebhookReceiver; // WebhookReceiver 인스턴스 선언
constructor(private readonly livekitService: LivekitService) {
const LIVEKIT_API_KEY = process.env.LIVEKIT_API_KEY || "devkey";
const LIVEKIT_API_SECRET = process.env.LIVEKIT_API_SECRET || "secret";
// WebhookReceiver 인스턴스 생성
this.webhookReceiver = new WebhookReceiver(LIVEKIT_API_KEY, LIVEKIT_API_SECRET);
}
@Post('/token')
async createToken(@Body() body: { roomName: string, participantName: string }, @Res() res: Response) {
const token = await this.livekitService.createToken(body.roomName, body.participantName);
res.json({token});
}
@Post('/livekit/webhook')
async handleWebhook(@Req() req: Request, @Res() res: Response) {
try {
const event = await this.webhookReceiver.receive(
req.body,
req.headers.authorization
);
console.log('Received webhook event:', event);
// 웹훅 이벤트 처리 로직 구현 (예: 이벤트 종류에 따라 다른 작업 수행)
} catch (error) {
console.error('Error validating webhook event:', error);
res.status(400).send();
}
res.status(200).send();
}
}
service.ts
더보기
import {HttpException, HttpStatus, Injectable} from '@nestjs/common';
import {AccessToken, WebhookReceiver} from 'livekit-server-sdk';
import * as dotenv from 'dotenv';
import * as process from 'process';
dotenv.config();
const LIVEKIT_API_KEY = process.env.LIVEKIT_API_KEY;
const LIVEKIT_API_SECRET = process.env.LIVEKIT_API_SECRET;
@Injectable()
export class LivekitService {
private webhookReceiver: WebhookReceiver;
constructor() {
const LIVEKIT_API_KEY = process.env.LIVEKIT_API_KEY;
const LIVEKIT_API_SECRET = process.env.LIVEKIT_API_SECRET;
if (!LIVEKIT_API_KEY || !LIVEKIT_API_SECRET) {
throw new Error('LIVEKIT_API_KEY and LIVEKIT_API_SECRET environment variables are required.');
}
this.webhookReceiver = new WebhookReceiver(LIVEKIT_API_KEY, LIVEKIT_API_SECRET);
}
async createToken(roomName: string, participantName: string): Promise<string> {
if (!roomName || !participantName) {
throw new HttpException('roomName and participantName are required', HttpStatus.BAD_REQUEST);
}
const at = new AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET, {identity: participantName});
at.addGrant({roomJoin: true, room: roomName});
return at.toJwt();
}
}
728x90
반응형
'크래프톤 정글 - TIL' 카테고리의 다른 글
크래프톤 정글 5기 TIL - 나만의 무기 만들기 7(상태 관리 - Zustand) (0) | 2024.08.06 |
---|---|
크래프톤 정글 5기 TIL - 나만의 무기 만들기 6(Canvas - Laser pen) (0) | 2024.08.06 |
크래프톤 정글 5기 TIL - 나만의 무기 만들기 4(WebRTC 구현 및 궁금증) (0) | 2024.07.07 |
크래프톤 정글 5기 TIL - 나만의 무기 만들기 3(WebRTC) (0) | 2024.07.03 |
크래프톤 정글 5기 TIL - 나만의 무기 만들기 2(카카오 Oauth, Canvas) (0) | 2024.07.02 |