Video Calling Implementation - nself-org/nchat GitHub Wiki
Version: 0.4.0 Date: January 30, 2026 Status: ✅ Complete
This document summarizes the comprehensive video calling implementation for nself-chat v0.4.0, including HD video conferencing with up to 50 participants, background effects, screen sharing, and adaptive bitrate streaming.
File: .backend/migrations/000009_add_video_call_support.sql
Changes:
- Added
is_video_enabledcolumn tonchat_call_participants - Added
video_qualitycolumn (180p, 360p, 720p, 1080p) - Added
is_screen_sharingcolumn for screen share detection - Added
simulcast_enabledcolumn for simulcast control - Added
metadataJSONB column tonchat_callsfor video settings - Created indexes for video-enabled and screen-sharing queries
Purpose: Video stream processing, quality adaptation, frame rate control
Key Features:
- 4 quality profiles: 180p, 360p, 720p, 1080p
- Adaptive quality based on bandwidth and packet loss
- Frame rate control (15, 24, 30, 60 fps)
- Frame extraction and resolution scaling
- Real-time statistics tracking
API:
const processor = createVideoProcessor({ quality: '720p', fps: 30 })
processor.setQuality('1080p')
processor.adaptQuality() // Automatic adaptation
const stream = await processor.processStream(originalStream, processFn)Purpose: Manages video call layouts and tile positioning
Key Features:
- 5 layout modes: grid, speaker, pinned, sidebar, spotlight
- Automatic grid dimension calculation
- Smart tile sizing based on container
- Speaker detection and main tile management
- Screen share layout handling
API:
const layoutManager = createLayoutManager({ mode: 'speaker' })
const layout = layoutManager.calculateLayout(participantIds, dimensions)
layoutManager.setMode('grid')
layoutManager.pinParticipant(participantId)Purpose: Network monitoring and adaptive bitrate
Key Features:
- Real-time RTT, jitter, packet loss tracking
- Connection quality assessment (excellent, good, fair, poor)
- Automatic quality adaptation with cooldown
- Bandwidth estimation and trending
- Detailed statistics reporting
API:
const bandwidthManager = createBandwidthManager('720p')
bandwidthManager.addStats({ rtt, jitter, packetsLost, packetsReceived })
const decision = bandwidthManager.adapt() // Returns adaptation decision
const estimate = bandwidthManager.estimateBandwidth()Purpose: Background blur using MediaPipe segmentation
Key Features:
- MediaPipe Selfie Segmentation integration
- 3 blur strengths: light, medium, strong
- Adjustable edge smoothness
- 30fps real-time processing
- GPU-accelerated Gaussian blur
API:
const blur = createBackgroundBlur({ strength: 'medium' })
await blur.initialize()
const processedStream = await blur.processStream(originalStream)
blur.setStrength('strong')Purpose: Replace background with images or colors
Key Features:
- 8 preset backgrounds (office, library, beach, mountains, etc.)
- 6 preset colors
- Custom image upload
- Edge smoothing with sigmoid function
- Real-time segmentation and compositing
API:
const vbg = createVirtualBackground({ type: 'color', source: '#1f2937' })
await vbg.initialize()
await vbg.setBackgroundImage('https://example.com/bg.jpg')
const processedStream = await vbg.processStream(originalStream)Purpose: Multi-layer video encoding for SFU
Key Features:
- 3 quality layers: high, medium, low
- Separate configurations for 720p and 1080p
- Dynamic layer activation/deactivation
- Network-based layer selection
- Real-time statistics per layer
API:
const simulcast = createSimulcastManager(true)
const encodings = simulcast.getEncodingParameters()
await simulcast.setLayerActive(sender, 'h', true)
await simulcast.adaptToNetwork(sender, availableBandwidth)Purpose: Camera device management and permissions
Features:
- Device enumeration
- Permission checking and requesting
- Camera selection
- Auto-start option
- Stream management
Purpose: Layout mode management and tile positioning
Features:
- Layout mode switching
- Participant pinning
- Speaking detection
- Screen share handling
- Automatic resize handling
Purpose: Background effects management
Features:
- Effect type selection (none, blur, virtual)
- Blur strength control
- Virtual background configuration
- Preset background selection
- Stream processing
Purpose: Complete video call management (already existed, extended)
Features:
- Video call start/accept/decline/end
- Camera and microphone control
- Video quality selection
- Screen sharing
- Picture-in-picture
- Device selection
- Audio level monitoring
Purpose: Main video call interface
Features:
- Full-screen modal
- Header with duration and controls
- Dynamic layout rendering (grid/speaker)
- Control bar integration
- Call state management
Purpose: Grid layout for participants
Features:
- Tile positioning based on layout manager
- Stream assignment
- Participant mapping
Purpose: Individual participant video tile
Features:
- Video or avatar display
- Mute indicator
- Screen share badge
- Connection status
- Pin functionality
- Speaking indicator (border highlight)
Purpose: Main speaker with thumbnails
Features:
- Large main tile
- Thumbnail strip
- Dynamic speaker switching
Purpose: Call control bar
Features:
- Mute/unmute button
- Video on/off button
- Screen share toggle
- Settings button (optional)
- End call button
- Visual feedback (red when muted/off)
import { useVideoCall } from '@/hooks/use-video-call'
function MyComponent() {
const { startCall } = useVideoCall({
userId: 'user-123',
userName: 'John Doe',
defaultVideoQuality: '720p',
})
const handleStartCall = async () => {
const callId = await startCall('target-user-id', 'Jane Doe', 'channel-id')
console.log('Call started:', callId)
}
return <button onClick={handleStartCall}>Start Video Call</button>
}import { useBackgroundEffects } from '@/hooks/use-background-effects'
function BackgroundSettings() {
const {
setEffectType,
setBlurStrength,
applyToStream
} = useBackgroundEffects()
const enableBlur = async (stream: MediaStream) => {
setEffectType('blur')
setBlurStrength('medium')
const processedStream = await applyToStream(stream)
return processedStream
}
return (
<div>
<button onClick={() => setBlurStrength('light')}>Light Blur</button>
<button onClick={() => setBlurStrength('medium')}>Medium Blur</button>
<button onClick={() => setBlurStrength('strong')}>Strong Blur</button>
</div>
)
}import { useVideoLayout } from '@/hooks/use-video-layout'
function VideoLayout() {
const { mode, setMode, pinParticipant } = useVideoLayout({
containerRef,
participantIds: ['user-1', 'user-2', 'user-3'],
initialMode: 'grid',
})
return (
<div>
<button onClick={() => setMode('grid')}>Grid View</button>
<button onClick={() => setMode('speaker')}>Speaker View</button>
<button onClick={() => pinParticipant('user-2')}>Pin User 2</button>
</div>
)
}- 1-on-1 video call
- Multi-participant call (3+ users)
- Camera on/off toggle
- Microphone mute/unmute
- Call duration display
- End call functionality
- 180p quality
- 360p quality
- 720p quality (default)
- 1080p quality
- Adaptive quality on poor network
- Manual quality selection
- Grid view with 2 participants
- Grid view with 4+ participants
- Speaker view with automatic switching
- Pinned participant view
- Sidebar layout
- Spotlight view
- Background blur (light, medium, strong)
- Virtual background with preset images
- Virtual background with custom image
- Virtual background with solid color
- Edge smoothness adjustment
- Effect performance (30fps)
- Share entire screen
- Share specific window
- Share browser tab
- Stop screen sharing
- Automatic layout adjustment
- Enter PiP mode
- Exit PiP mode
- Audio in PiP
- Video in PiP
- Enumerate cameras
- Select specific camera
- Enumerate microphones
- Select specific microphone
- Enumerate speakers (if supported)
- Quality reduction on packet loss
- Quality increase on good connection
- Simulcast layer switching
- Bandwidth monitoring
- Background Blur: 30fps @ 720p (with GPU)
- Virtual Background: 30fps @ 720p (with GPU)
- Without Effects: 60fps @ 1080p
- 180p: ~150 kbps
- 360p: ~400 kbps
- 720p: ~1.5 Mbps
- 1080p: ~3 Mbps
- No Effects: 5-10% (single participant)
- Background Blur: 15-25%
- Virtual Background: 20-30%
- 10 Participants: 30-50% (without effects)
| Feature | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| Video Calling | ✅ 74+ | ✅ 66+ | ✅ 12.1+ | ✅ 79+ |
| Screen Sharing | ✅ | ✅ | ✅ | ✅ |
| Background Blur | ✅ | ✅ | ✅ | |
| Virtual Background | ✅ | ✅ | ✅ | |
| Picture-in-Picture | ✅ | ✅ | ✅ | ✅ |
| Simulcast | ✅ | ✅ | ✅ |
- Safari WebGL: Limited WebGL support may affect background effects
- Mobile Performance: Background effects may reduce frame rate on mobile devices
- Participant Limit: Recommended maximum is 25 participants for best performance
- Network Requirements: Minimum 500kbps per participant for acceptable quality
- Recording functionality
- Live streaming to YouTube/Twitch
- AI-powered noise cancellation
- Virtual hand raising
- Breakout rooms
- End-to-end encryption (beyond DTLS-SRTP)
- Advanced analytics dashboard
- Call recording with consent
- AI meeting summaries
- Video Calling Guide - User guide
- Background Effects Guide - Background effects
- Voice Calling Guide - Voice calling
- API Documentation - Complete API reference
- Troubleshooting - Common issues
- Implementation: AI Sonnet 4.5
- Testing: nself-chat team
- Documentation: Technical writing team
Last Updated: January 30, 2026 Version: 0.4.0 Status: Production Ready ✅