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.
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.

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.

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.

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.

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)

9. Other APIs
Finally, it checks for other browser APIs that extend media functionality:
- MediaStream Recording API (for recording)
- MediaStream Image Capture API (for taking photos)
- Screen Capture API (for screen sharing)
- Web Audio API (for audio processing)
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.

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-testerOr 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.