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

  1. Client authenticates and joins a room using your API key
  2. WebRTC connection is established via ICE (STUN/TURN)
  3. Client publishes camera/microphone streams to SFU
  4. SFU forwards streams to other participants
  5. 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
BaxCloud automatically enables simulcast, which sends multiple quality layers (high, medium, low) simultaneously. This allows each viewer to receive the best quality their network can handle without affecting other participants.

Implementation Guide

Step-by-step guide to implementing video calls

1

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});
2

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);
The liveType parameter determines the room configuration. Use video_callfor standard calls (2-50 participants) or video_conference for larger meetings (50-100+ participants).
3

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();
4

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();
Virtual backgrounds are CPU-intensive and may affect performance on older devices. Consider providing an option to disable this feature for users with performance issues.

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
Enable debug logging to get detailed information about connection issues:
1const client = new BaxCloudClient({
2  projectId: 'your-project-id',
3  apiKey: 'your-api-key',
4  logLevel: 'debug', // 'debug', 'info', 'warn', 'error'
5});