Video Calls
Build high-quality video calling experiences with BaxCloud's WebRTC infrastructure
Overview
BaxCloud provides a powerful video calling infrastructure that supports 1-on-1 calls, group calls, and large video conferences. Built on WebRTC (Web Real-Time Communication) technology, our platform delivers low-latency, high-quality video communication with adaptive streaming that automatically adjusts to network conditions.
Unlike traditional video streaming solutions that rely on RTMP or HLS, WebRTC establishes peer-to-peer connections with sub-500ms latency, making it perfect for interactive conversations. Our infrastructure handles all the complexity of NAT traversal, STUN/TURN servers, and media relay servers, so you can focus on building great user experiences.
1-on-1 & Group Calls
Support for any call size from 2 to 100+ participants with selective forwarding units (SFU)
Screen Sharing
Share your screen with crystal-clear quality at up to 30fps
Cloud Recording
Record calls and save them to cloud storage with automatic transcoding
How It Works
BaxCloud uses a Selective Forwarding Unit (SFU) architecture to efficiently handle video calls. Unlike peer-to-peer (P2P) or Multipoint Control Unit (MCU) architectures, SFU provides the best balance of quality, scalability, and resource efficiency.
SFU Architecture Benefits
- Each participant sends their video once to the server
- Server forwards streams to other participants without re-encoding
- Minimal server CPU usage and latency
- Scales to 100+ participants efficiently
- Each client can request different quality levels (simulcast)
Connection Flow
- Client authenticates and joins a room using your API key
- WebRTC connection is established via ICE (STUN/TURN)
- Client publishes camera/microphone streams to SFU
- SFU forwards streams to other participants
- Adaptive bitrate adjusts quality based on network conditions
Video Quality & Codecs
BaxCloud supports multiple video codecs and automatically selects the best one based on browser/device capabilities and network conditions. We employ adaptive bitrate streaming to ensure smooth video even on unstable connections.
Supported Codecs
- VP8: Widely supported, good compression (default)
- VP9: Better compression, lower bandwidth for same quality
- H.264: Hardware acceleration on most devices
- AV1: Next-gen codec, excellent compression (newer browsers)
Resolution Settings
- HD 1080p (1920×1080)2.5-4 Mbps
- HD 720p (1280×720)1.2-2.5 Mbps
- SD 480p (640×480)500-800 Kbps
- SD 360p (480×360)300-500 Kbps
Implementation Guide
Step-by-step guide to implementing video calls
Initialize the BaxCloud Client
Start by creating a BaxCloud client instance with your project credentials. You can find these in your dashboard under Settings → API Keys.
1import { BaxCloudClient } from '@baxcloud/react-sdk';
2
3const client = new BaxCloudClient({
4 projectId: 'your-project-id',
5 apiKey: 'your-api-key',
6});Connect to a Room
Connect to a video call room. If the room doesn't exist, it will be created automatically. Rooms are identified by a unique name and support multiple participants.
1const room = await client.connect({
2 roomName: 'my-room',
3 participant: {
4 userId: 'user-123',
5 name: 'John Doe',
6 avatarUrl: 'https://example.com/avatar.jpg',
7 isHost: true,
8 },
9 liveType: 'video_call',
10});
11
12console.log('Connected to room:', room.name);liveType parameter determines the room configuration. Use video_callfor standard calls (2-50 participants) or video_conference for larger meetings (50-100+ participants).Enable Camera and Microphone
After connecting, enable the participant's camera and microphone. This will publish their audio/video stream to other participants in the room.
1// Enable camera
2await client.enableCamera();
3
4// Enable microphone
5await client.enableMicrophone();
6
7// Disable camera
8await client.disableCamera();
9
10// Disable microphone
11await client.disableMicrophone();Implement Controls
Add UI controls to toggle camera, microphone, switch cameras, and share screen. These are essential features for any video calling application.
1const VideoControls = () => {
2 const toggleCamera = async () => {
3 if (client.isCameraEnabled()) {
4 await client.disableCamera();
5 } else {
6 await client.enableCamera();
7 }
8 };
9
10 const toggleMicrophone = async () => {
11 if (client.isMicrophoneEnabled()) {
12 await client.muteMicrophone();
13 } else {
14 await client.unmuteMicrophone();
15 }
16 };
17
18 const switchCamera = async () => {
19 await client.switchCamera();
20 };
21
22 const toggleScreenShare = async () => {
23 if (client.isScreenShareEnabled()) {
24 await client.disableScreenShare();
25 } else {
26 await client.enableScreenShare();
27 }
28 };
29
30 return (
31 <div className="flex gap-2">
32 <button onClick={toggleCamera}>
33 {client.isCameraEnabled() ? 'Disable Camera' : 'Enable Camera'}
34 </button>
35 <button onClick={toggleMicrophone}>
36 {client.isMicrophoneEnabled() ? 'Mute' : 'Unmute'}
37 </button>
38 <button onClick={switchCamera}>Switch Camera</button>
39 <button onClick={toggleScreenShare}>
40 {client.isScreenShareEnabled() ? 'Stop Sharing' : 'Share Screen'}
41 </button>
42 </div>
43 );
44};Advanced Features
Virtual Backgrounds
Apply virtual backgrounds or background blur to video streams. This uses browser-based video processing (requires modern browser with WebGL support).
1// Apply background blur
2await controller.applyBackgroundEffect({
3 effectId: 'blur-1',
4 effectType: 'blur',
5 intensity: 10, // 1-20
6});
7
8// Set virtual background image
9await controller.applyBackgroundEffect({
10 effectId: 'bg-1',
11 effectType: 'image',
12 imageUrl: 'https://example.com/background.jpg',
13});
14
15// Remove background effect
16await controller.removeBackgroundEffect();Network Quality Monitoring
Monitor network quality to provide feedback to users and adjust video quality based on connection conditions.
1// Get local participant's network quality
2const quality = controller.getNetworkQuality();
3console.log('Connection quality:', quality.connectionQuality);
4console.log('RTT:', quality.rtt);
5console.log('Packet loss:', quality.packetLoss);
6
7// Get a specific participant's quality
8const participantQuality = controller.getParticipantQuality('user-123');
9console.log('Participant quality:', participantQuality.connectionQuality);
10
11// Listen for quality changes
12controller.onNetworkQualityChanged((quality) => {
13 if (quality.connectionQuality === 'poor') {
14 console.warn('Poor network quality detected');
15 }
16});Cloud Recording
Record video calls to the cloud for compliance, playback, or content creation. Recordings include all video streams, screen shares, and audio tracks.
1// Start recording
2const recording = await client.startRecording({
3 roomName: 'my-room',
4 fileType: 'MP4',
5});
6
7console.log('Recording started:', recording.egressId);
8
9// Stop recording
10await client.stopRecording(recording.egressId);
11
12// List active recordings
13const activeRecordings = await client.listActiveRecordings('my-room');
14
15// Get recording details
16const recordingInfo = await client.getRecording(recording.egressId);Best Practices
1. Request Permissions Early
Request camera and microphone permissions before joining the call to avoid jarring permission prompts during the conversation.
1// Note: Permission handling is platform-specific
2// For web, use browser APIs before connecting
3navigator.mediaDevices.getUserMedia({ video: true, audio: true })
4 .then(() => {
5 // Permissions granted, proceed with connection
6 client.connect({ /* ... */ });
7 })
8 .catch((error) => {
9 console.error('Permission denied:', error);
10 });2. Handle Network Issues Gracefully
Listen for connection quality events and notify users when their network is poor.
1// Monitor network quality
2controller.onNetworkQualityChanged((quality) => {
3 if (quality.connectionQuality === 'poor') {
4 showNotification('Poor network connection. Video quality may be reduced.');
5 }
6});
7
8// Monitor connection state
9const connectionState = client.getConnectionState();
10if (connectionState === 'reconnecting') {
11 showNotification('Reconnecting...');
12} else if (connectionState === 'connected') {
13 showNotification('Reconnected successfully');
14}3. Optimize for Mobile
Use lower resolutions and frame rates on mobile devices to conserve battery and bandwidth.
1const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
2
3// Enable camera with mobile-optimized settings
4await client.enableCamera();
5
6// Auto-disable video when app goes to background
7document.addEventListener('visibilitychange', async () => {
8 if (document.hidden) {
9 await client.disableCamera();
10 } else {
11 await client.enableCamera();
12 }
13});4. Clean Up Resources
Always disconnect and clean up when leaving the call to free up resources.
1// Disconnect when leaving the call
2const leaveCall = async () => {
3 await client.disconnect();
4 // Client automatically stops camera, microphone, and closes connections
5};
6
7// React cleanup example
8useEffect(() => {
9 return () => {
10 client?.disconnect();
11 };
12}, [client]);Troubleshooting
Camera/Microphone Not Working
- Ensure permissions are granted in browser settings
- Check if another app is using the camera/microphone
- Verify HTTPS is enabled (required for WebRTC)
- Try restarting the browser
Poor Video Quality
- Check network connection speed (minimum 1 Mbps recommended)
- Reduce video resolution in settings
- Close other bandwidth-heavy applications
- Ensure adaptive bitrate is enabled
- Check if firewall is blocking WebRTC traffic
Echo or Audio Feedback
- Enable echo cancellation in microphone settings
- Ask participants to use headphones
- Reduce speaker volume
- Ensure only one instance of the app is running
Connection Failed
- Verify API credentials are correct
- Check if firewall allows WebRTC (UDP ports 3000-65535)
- Ensure TURN servers are accessible
- Try connecting from a different network
- Check browser console for detailed error messages
1const client = new BaxCloudClient({
2 projectId: 'your-project-id',
3 apiKey: 'your-api-key',
4 logLevel: 'debug', // 'debug', 'info', 'warn', 'error'
5});