A full-stack WebRTC video conferencing application with live HLS streaming capabilities, built for the Fermion assignment.
fermion-demo.github.720p.mp4
- GitHub: https://github.com/RutamBhagat/fermion-task
- Video Demo: https://youtu.be/L1JWDoUv0XY
- Frontend: https://fermion-task-web.vercel.app/stream
- Backend: https://ec2-3-110-48-224.ap-south-1.compute.amazonaws.com
Page 1: stream - Multi-user WebRTC video conferencing
Page 2: watch - Live HLS streaming with DVR functionality
User Journey: Users can video conference on /stream, viewers can watch live on /watch
No Blackbox Solutions: Uses Mediasoup SFU (not LiveKit)
Functional Locally: Complete local development setup
- Mediasoup SFU: Scalable video conferencing architecture
- Multi-user Support: Real-time video/audio with multiple participants
- Socket.IO Signaling: WebRTC connection management and room coordination
- WebRTC to HLS Conversion: FFmpeg transcoding with composite video streams
- DVR Functionality: Time-shifting, backward seeking during live streams
- Advanced Buffer Management: Solved HLS live-edge jumping issues
- React Player Integration: Custom HLS configuration for optimal DVR experience
- Docker Compose Ready: Container orchestration for deployment
- Resource Cleanup: Automatic HLS segment cleanup and memory management
- Error Handling: Comprehensive error recovery for WebRTC and HLS streams
- Monitoring: Performance tracking and health checks
npm install- Install dependencies for all workspacesnpm run dev- Start both web and server in development mode (web on :3001, server on :3000)npm run dev:web- Start only the Next.js web app (port 3001)npm run dev:server- Start only the Hono server (port 3000)
npm run build- Build all apps using Turbonpm run check-types- TypeScript type checking across all workspacesnpm run check- Run Biome formatting and linting with auto-fix
Web App (apps/web/):
npm run dev- Next.js dev server with Turbopacknpm run build- Production buildnpm run start- Start production buildnpm run lint- ESLint checking
Server (apps/server/):
npm run dev- Development with tsx watchnpm run build- Build with tsdownnpm run start- Start built servernpm run compile- Compile to binary with Bunnpm run check-types- TypeScript checking
This is a Turborepo monorepo with two main applications:
apps/web/- Next.js 15 frontend with React 19apps/server/- Hono server with Socket.IO and Mediasoup
- Framework: Next.js 15 with React 19 and TypeScript
- Styling: TailwindCSS 4.x with shadcn/ui components
- WebRTC: mediasoup-client for SFU
- State Management: React Query (TanStack Query)
- Real-time: Socket.IO client
- Build: Turbopack for development
- Framework: Hono (lightweight Node.js framework)
- WebRTC: Mediasoup SFU for scalable video conferencing
- Real-time: Socket.IO for signaling
- Streaming: HLS stream generation and serving
- Runtime: Node.js with TypeScript
- P2P Mode: Direct peer-to-peer connections
- SFU Mode: Scalable video conferencing using Mediasoup
- Room System: Meeting rooms with generated IDs (format:
abc-def-ghi) - Media Controls: Camera, microphone, screen sharing controls
- WebRTC to HLS: Convert real-time WebRTC streams to HLS format
- Watch Pages:
/watch/[streamId]for HLS playback - Stream Management: Automatic cleanup of old HLS segments
use-webrtc.ts- WebRTC connection managementuse-socket.ts- Socket.IO communicationuse-media-devices.ts- Camera/microphone accessuse-hls-player.ts- HLS video player with error recoveryuse-hls-stream.ts- HLS stream managementuse-video-grid.ts- Video layout management
mediasoup.ts- Mediasoup SFU initialization and managementroom.ts- Room state and participant managementhls.ts- HLS stream generation and cleanupmonitoring.ts- Performance monitoring
- Uses Mediasoup SFU for scalable conferencing (not blackbox solutions like LiveKit)
- PeerJS fallback for simple P2P connections
- HTTPS required for WebRTC (browsers enforce this)
- Server generates HLS segments at
/hls/{streamId}/ - Automatic stream availability checking with retry logic
- Clean-up of old HLS directories when streams stop
- Meeting IDs generated as 3 segments of 3 lowercase letters (e.g., "abc-def-ghi")
- Rooms support multiple participants via Mediasoup SFU
- Socket.IO handles signaling between peers
- Start Development:
npm run dev(starts both web and server) - Type Checking:
npm run check-typesbefore committing - Code Quality:
npm run checkfor formatting/linting - Testing WebRTC: Open multiple browser tabs to simulate multiple users
- HLS Testing: Create stream, then visit
/watch/[streamId]to test HLS playback
turbo.json- Turborepo build pipeline configurationbiome.json- Code formatting and linting rules (tabs, double quotes)apps/web/components.json- shadcn/ui component configurationapps/server/src/config/mediasoup.ts- Mediasoup SFU configuration
- Node.js: Uses npm package manager (v10.9.2)
- HTTPS: Required for WebRTC - use
localhostwith HTTPS in production - Ports: Web (3001), Server (3000)
- CORS: Server configured for cross-origin requests
- AWS t2.micro: Free tier instance gets resource-exhausted during HLS transcoding
- Self-signed SSL: Backend uses self-signed certificate (visit backend URL to trust)
- HLS Storage: Local disk storage (production would use CloudFlare R2 + CDN)
- Instance Type: c7g.large or better for FFmpeg processing (63% better performance)
- SSL Certificate: Domain + Let's Encrypt for proper HTTPS
- Storage: CloudFlare R2 with CDN for HLS segment distribution
- Scaling: Redis state sharing for multi-instance deployment
The most complex technical challenge was implementing true DVR functionality for HLS streams:
- Live Edge Jumping: Solved with
liveDurationInfinity: trueconfiguration - Infinite Back Buffer: Allows unlimited backward seeking during live streams
- Memory Management: Balanced infinite history with controlled forward buffering
- React Player Integration: Optimized HLS.js configuration within React Player
- Multi-stream Composition: FFmpeg xstack filter for grid layout
- Format Conversion: Mediasoup PlainTransport to stable RTP streams
- Resource Management: Automatic process cleanup and port allocation
- Single Composite Stream: One HLS stream per room (expandable with worker pools)
- Late Join Handling: Participants must join before HLS starts
- Horizontal Scaling: Single-server implementation (designed for Redis scaling)
- Storage Strategy: Local disk vs production CDN distribution
These limitations represent intentional scope decisions demonstrating production awareness rather than technical constraints.