Photo showcase of the webcam tester library by Addpipe

Introducing the Webcam Tester Library: Test Webcams and Microphones Before Recording

Testing camera and microphone functionality in web browsers has always been a challenge for developers building video recording applications, video conferencing tools, or any web app that relies on getUserMedia. How many times have your users started a recording only to discover their camera wasn't working, or joined a video call with a muted microphone?

We've been there too. That's why we built the Webcam Tester Library: a comprehensive, open-source JavaScript library that tests webcam and microphone functionality right in the browser.

0:00
/0:08

The Problem We're Solving

If you've ever built a web application that uses getUserMedia(), you know the frustration. Users grant permissions, everything seems fine, and then:

  • The camera works, but shows a black screen
  • Audio doesn't capture, even though permissions were granted
  • The selected resolution isn't supported
  • Lighting conditions make the video unusable
  • The browser doesn't support the features you need

These issues often surface only when users are already in the middle of an important recording or video call. By that time, it's too late to fix them gracefully.

The Webcam Tester Library solves this by providing a comprehensive testing suite that checks everything before your main application runs.

What Does It Test?

The library runs a complete suite of tests covering every aspect of media device functionality:

1. Browser Support Check

First, it verifies that the browser supports the modern getUserMedia API. If not, it detects legacy implementations and warns about limited functionality.

2. getUserMedia Verification

getUserMedia only works in secure contexts (HTTPS, localhost, 127.0.0.1, file://, etc.). The library immediately checks this and alerts users if they're on an insecure connection.

3. Camera Permissions

Tests camera access and handles all common error scenarios, including user denial, browser blocking, macOS permissions, missing devices, and other errors. Each error type gets a specific, actionable message.

Screenshot showing the camera selection interface with multiple cameras listed

4. Microphone Permissions

Separately tests microphone access with the same comprehensive error handling. This is particularly important because camera and microphone permissions can fail independently.

Screenshot showing the mic selection interface with multiple mics listed

5. Device Enumeration

Lists all available audio inputs, video inputs, and audio outputs. This helps users understand what devices their system has and which ones are selected for testing.

Screenshot of the expandable device list showing multiple microphones, cameras, and speakers with the selected device marked

6. Active Video & Audio Capture

Verifies that the video and audio have been successfully created and that they have valid properties.

7. Video Resolution Testing

The library tests 8 standard resolutions from 144p all the way up to 4K:

  • 144p (256×144)
  • 240p (426×240)
  • 360p (640×360)
  • 480p (854×480)
  • 720p (1280×720)
  • 1080p (1920×1080)
  • 1440p (2560×1440)
  • 4K (3840×2160)

For each supported resolution, it also measures the frame rate. This is important information for apps that need specific video quality.

Screenshot of the expandable resolution test results showing checkmarks and X marks for each resolution with frame rates

8. Lighting Analysis

Using pixel data analysis, the library examines the camera feed and evaluates lighting conditions. It calculates brightness on a 0-255 scale and provides recommendations:

  • 0-50: Very dark (poor visibility)
  • 50-100: Dark (suboptimal lighting)
  • 100-180: Good (optimal range)
  • 180-220: Bright (acceptable)
  • 220-255: Very bright (overexposure risk)
Screenshot showing the lighting test result with the brightness value and the expandable explanation

9. Other APIs

Finally, it checks for other browser APIs that extend media functionality:

Useful Features

Permission Priming

  • On Chrome on macOS, it primes user permissions and the default devices (at the domain level; closing all tabs with said domain resets the permission)
  • On Firefox on macOS, it primes user permissions and the default device (at the browser tab x device level; refreshing the tab does not reset permissions)
  • On Safari on macOS, it primes user permission at the tab level (refreshing the tab resets the permission)

Device Selection

If a user has multiple cameras or microphones, the library presents a clean selection interface. Users can choose which devices to test before the testing begins.

Dark Theme Support

The library includes a built-in dark theme that can be enabled with a single configuration option. Perfect for applications with dark interfaces.

The webcam test library in dark theme

UI-less Mode

Need to run tests programmatically without showing any UI? Ui-less mode lets you execute all tests silently and access results via callbacks.

Real-time Camera Preview

Throughout the testing process, users can see their camera feed in a preview window. This provides immediate visual feedback and helps identify issues like incorrect camera selection or poor framing.

How to Use It

Installation

The library is available on NPM and can be installed with a single command:

npm install @addpipe/webcam-tester

Or you can include it directly from a CDN:

<script src="https://unpkg.com/@addpipe/webcam-tester@1.0.0/dist/webcam-tester.min.js"></script>

Basic Usage

Getting started is incredibly simple. First, create a container element in your HTML:

<div id="media-tester-container"></div>

Then initialize the library with a single function call:

import { insertWebcamTestLibrary } from '@addpipe/webcam-tester';

const tester = insertWebcamTestLibrary('media-tester-container');

That's it! The library handles everything else: permissions, UI, testing, and results display.

Using It Before Your Main Application

Here's a common pattern you can use: running the media tests before allowing users to proceed to the main recording interface:

import { insertWebcamTestLibrary } from '@addpipe/webcam-tester';

const tester = insertWebcamTestLibrary('test-container', {
    title: 'Check Your Devices',
    tests: ['cameraPermissions', 'micPermissions', 'devices', 'resolutions'],
    callbacks: {
        onAllTestsComplete: function(results) {
            const cameraOk = results.cameraPermissions?.type === 'success';
            const micOk = results.micPermissions?.type === 'success';
            
            if (cameraOk && micOk) {
                // Save selected devices
                const camera = tester.getSelectedCameraInfo();
                const mic = tester.getSelectedMicrophoneInfo();
                
                localStorage.setItem('preferredCamera', camera.deviceId);
                localStorage.setItem('preferredMic', mic.deviceId);
                
                // Redirect to recording interface
                window.location.href = '/recorder';
            } else {
                alert('Please grant camera and microphone permissions to continue');
            }
        }
    }
});

Configuration Options

The library is highly configurable. You can customize what tests run, how results are displayed, and what callbacks fire:

const tester = insertWebcamTestLibrary('container', {
    // UI Options
    showPrivacyNotice: true,
    showResults: true,
    showCameraPreview: true,
    darkTheme: false,
    title: 'Webcam Tester',
    
    // Device Selection
    allowCameraSelection: true,
    allowMicSelection: true,
    
    // Test Selection
    tests: [
        'getUserMedia',
        'secureContext',
        'cameraPermissions',
        'micPermissions',
        'devices',
        'capture',
        'resolutions',
        'lighting',
        'otherApis'
    ],
    
    // Callbacks
    callbacks: {
        onTestStart: function() {
            console.log('Testing started');
        },
        onTestComplete: function(result) {
            console.log('Test completed:', result);
        },
        onAllTestsComplete: function(allResults) {
            console.log('All tests finished:', allResults);
        },
        onError: function(testName, error) {
            console.error('Test error:', testName, error);
        }
    }
});

Ui-less Mode for Programmatic Testing

If you want to run tests without showing any UI and handle results yourself, use ui-less mode:

const tester = insertWebcamTestLibrary('hidden-container', {
    uiLess: true,
    tests: ['cameraPermissions', 'micPermissions', 'devices'],
    callbacks: {
        onAllTestsComplete: function(results) {
            // Process results programmatically
            const hasCamera = results.cameraPermissions?.result;
            const hasMic = results.micPermissions?.result;
            
            if (hasCamera && hasMic) {
                startApplication();
            } else {
                showSetupWizard();
            }
        }
    }
});

// Start tests programmatically
await tester.start();

Framework Integration

The library works seamlessly with modern frameworks and libraries. Here's how to use it in React:

import { useEffect, useRef } from 'react';
import { insertWebcamTestLibrary } from '@addpipe/webcam-tester';

function WebcamTester() {
    const testerRef = useRef(null);

    useEffect(() => {
        testerRef.current = insertWebcamTestLibrary('media-container', {
            callbacks: {
                onAllTestsComplete: (results) => {
                    console.log('Tests complete:', results);
                }
            }
        });

        return () => {
            if (testerRef.current) {
                testerRef.current.destroy();
            }
        };
    }, []);

    return <div id="media-container"></div>;
}

API Methods

Once initialized, the library instance provides several useful methods:

// Start tests programmatically (useful in UI-less mode)
await tester.start();

// Get all test results
const results = tester.getTestResults();

// Check if tests are running
const isRunning = tester.isRunning();

// Get the current media stream
const stream = tester.getCurrentStream();

// Get selected device information
const cameraInfo = tester.getSelectedCameraInfo();
const micInfo = tester.getSelectedMicrophoneInfo();

// Clean up resources
tester.destroy();

TypeScript Support

Full TypeScript definitions are included:

import { 
    insertWebcamTestLibrary, 
    WebcamDeviceTester, 
    TestResult 
} from '@addpipe/webcam-tester';

const tester: WebcamDeviceTester = insertWebcamTestLibrary('container-id', {
    uiLess: true,
    callbacks: {
        onAllTestsComplete: (results: Record<string, TestResult>) => {
            console.log(results);
        }
    }
});

Try It Live

Want to see it in action before installing? We've set up a live demo where you can test it with your own devices here.

Real-World Use Cases

We built this library based on our experience running Pipe, our browser-based video, audio, and screen recording platform. Here are some scenarios where it's particularly useful:

1. Video Recording Applications

Before users start recording, run the test suite to ensure their devices work properly. This dramatically reduces support tickets about "recording didn't work."

2. Video Conferencing Platforms

Let users test their setup before joining a meeting. Nothing worse than starting a call and spending minutes troubleshooting audio issues.

3. Online Education Platforms

Teachers and students need working cameras and microphones for virtual classrooms. Catch issues before class starts.

4. Video Interviews

Before candidates start recording themselves, they can ensure their camera and microphone are working properly.

Privacy First

Privacy is a core design principle. The library:

  • Runs entirely in the browser - no data leaves the user's device
  • Doesn't make network requests (except loading the library itself)
  • Automatically stops all media streams on removal and between retests

Open Source and Free

The library is open source under the AGPL-3.0 license.

The source code is available on GitHub, and we welcome issues, feature requests, and pull requests.

Introducing the Webcam Tester Library: Test Webcams and Microphones Before Recording
Share this
IT TAKES 1 MINUTE
Sign up for a 14 Day Trial

With our 14 days (336 hours) trial you can add audio, video and screen + camera recording to your website today and explore Pipe for 2 weeks