# CameraAccess API {#cameraaccess-api} Quagga2 exposes a `CameraAccess` API for direct control of camera functionality. This API provides shortcuts for commonly used camera operations. **Access**: `Quagga.CameraAccess` ## Overview {#overview} The CameraAccess API allows you to: - Request and release camera access - Enumerate available video devices - Control camera torch (flash) - Get information about active video streams and tracks All methods return Promises for async operation handling. ## Methods {#methods} ### `CameraAccess.request(videoElement, constraints)` {#cameraaccess-request} Initializes the camera and starts playback. **Parameters**: - `videoElement` (HTMLVideoElement | null) - Video element to display camera stream. If `null`, camera initializes but remains invisible. - `constraints` (MediaTrackConstraints, optional) - Camera selection and configuration constraints. **Returns**: `Promise` - Resolves when camera is ready, rejects on error. **Example**: ```javascript const video = document.querySelector('#camera-video'); // Request camera with default constraints await Quagga.CameraAccess.request(video); // Request specific camera await Quagga.CameraAccess.request(video, { facingMode: 'environment', // Back camera on mobile width: { ideal: 1280 }, height: { ideal: 720 } }); // Request camera by device ID const deviceId = 'abc123...'; await Quagga.CameraAccess.request(video, { deviceId }); // Initialize camera without displaying (for probing) await Quagga.CameraAccess.request(null); ``` **Use cases**: - Start camera before Quagga initialization - Probe camera availability and permissions - Initialize camera without displaying video ### `CameraAccess.release()` {#cameraaccess-release} Stops the video stream and releases all camera resources. **Returns**: `Promise` - Resolves when all tracks are stopped and resources released. **Example**: ```javascript // Stop camera await Quagga.CameraAccess.release(); console.log('Camera released'); ``` **Behavior**: 1. Pauses the video element 2. Stops all tracks in the media stream 3. Releases camera for use by other applications **Note**: Always call `release()` when finished with the camera to free system resources. ### `CameraAccess.enumerateVideoDevices(constraints?)` {#cameraaccess-enumeratevideodevices} Lists all available video input devices (cameras), optionally filtered by constraints. **Parameters**: - `constraints` (MediaTrackConstraints, optional) - Constraints to filter devices. When provided, only devices that can satisfy the given constraints will be returned. **Returns**: `Promise` - Array of video device information. **Example**: ```javascript // Get all video devices const devices = await Quagga.CameraAccess.enumerateVideoDevices(); devices.forEach(device => { console.log('Device:', device.label); console.log('Device ID:', device.deviceId); console.log('Group ID:', device.groupId); }); // Example output: // Device: Front Camera // Device ID: abc123... // Device: Back Camera // Device ID: def456... ``` **Filtering devices with constraints**: ```javascript // Get only devices that support a minimum resolution const hdDevices = await Quagga.CameraAccess.enumerateVideoDevices({ width: { min: 1280 }, height: { min: 720 } }); // Get only back-facing cameras const backCameras = await Quagga.CameraAccess.enumerateVideoDevices({ facingMode: 'environment' }); // Eliminate wide-angle only cameras by specifying aspect ratio const standardCameras = await Quagga.CameraAccess.enumerateVideoDevices({ aspectRatio: { ideal: 1.777 } // 16:9 }); ``` **Use cases**: - Build camera selector UI - Detect available cameras before initialization - Check for front/back camera availability on mobile - Filter out cameras that don't meet quality requirements - Eliminate wide-angle cameras that may not be suitable for barcode scanning **Note**: Device labels may be empty strings until camera permission is granted. When using constraints, the method will request temporary access to each device to test if it satisfies the constraints. ### `CameraAccess.getActiveStreamLabel()` {#cameraaccess-getactivestreamlabel} Gets the label of the currently active video track. **Returns**: `string` - Label of active video track (e.g., "Back Camera", "USB Camera"). **Example**: ```javascript const label = Quagga.CameraAccess.getActiveStreamLabel(); console.log('Using camera:', label); // Output: "Using camera: Back Camera" ``` **Use cases**: - Display which camera is currently active - Verify correct camera is being used - Logging and debugging ### `CameraAccess.getActiveStream()` {#cameraaccess-getactivestream} Gets the complete MediaStream object for the currently active video. **Returns**: `MediaStream | null` - The active MediaStream object, or `null` if no camera is active. **Example**: ```javascript const stream = Quagga.CameraAccess.getActiveStream(); if (stream) { console.log('Stream ID:', stream.id); console.log('Stream active:', stream.active); console.log('Video tracks:', stream.getVideoTracks().length); console.log('Audio tracks:', stream.getAudioTracks().length); // Clone the stream const clonedStream = stream.clone(); } // Pass stream to WebRTC peer connection if (stream?.active) { peerConnection.addStream(stream); } ``` **Use cases**: - Pass the stream to WebRTC peer connections - Clone the stream for multiple consumers - Check if the stream is still active via `stream.active` - Access the stream ID - Work with all tracks (video and audio) in the stream **Note**: For accessing just the video track, use `getActiveTrack()` instead. ### `CameraAccess.getActiveTrack()` {#cameraaccess-getactivetrack} Gets the MediaStreamTrack for the currently active video. **Returns**: `MediaStreamTrack | null` - Active video track object, or `null` if no camera is active. **Example**: ```javascript const track = Quagga.CameraAccess.getActiveTrack(); console.log('Track state:', track.readyState); console.log('Track settings:', track.getSettings()); console.log('Track capabilities:', track.getCapabilities()); // Get current resolution const settings = track.getSettings(); console.log(`Resolution: ${settings.width}x${settings.height}`); ``` **Use cases**: - Access advanced track capabilities - Monitor track state - Apply additional constraints - Access camera capabilities (zoom, focus, etc.) ### `CameraAccess.enableTorch()` {#cameraaccess-enabletorch} Turns on the camera torch (flash). **Returns**: `Promise` - Resolves when torch is enabled, rejects on error. **Example**: ```javascript try { await Quagga.CameraAccess.enableTorch(); console.log('Torch enabled'); } catch (error) { console.error('Failed to enable torch:', error); } ``` **Browser Support**: - ✅ Chrome (Android) - ✅ Chrome (Desktop with supported cameras) - ❌ Safari iOS 16.4 and earlier - ⚠️ Safari iOS later versions - may or may not work **Requirements**: - Camera must support torch capability - Camera must be actively streaming - Browser must support torch constraint **Note**: Always wrap in try-catch as not all devices support torch. ### `CameraAccess.disableTorch()` {#cameraaccess-disabletorch} Turns off the camera torch (flash). **Returns**: `Promise` - Resolves when torch is disabled, rejects on error. **Example**: ```javascript try { await Quagga.CameraAccess.disableTorch(); console.log('Torch disabled'); } catch (error) { console.error('Failed to disable torch:', error); } ``` **Browser Support**: Same as `enableTorch()`. ## Complete Example {#complete-example} ```javascript // Enumerate cameras and let user choose const devices = await Quagga.CameraAccess.enumerateVideoDevices(); const backCamera = devices.find(d => d.label.includes('back')); // Initialize camera const video = document.querySelector('#video'); await Quagga.CameraAccess.request(video, { deviceId: backCamera.deviceId }); console.log('Active camera:', Quagga.CameraAccess.getActiveStreamLabel()); // Enable torch for better scanning in dark environments try { await Quagga.CameraAccess.enableTorch(); } catch (error) { console.log('Torch not available'); } // ... use camera for scanning ... // Cleanup await Quagga.CameraAccess.disableTorch(); await Quagga.CameraAccess.release(); ``` ## Torch Control in Live Scanning {#torch-control} For torch control during live scanning, you may want to provide a toggle button: ```javascript let torchEnabled = false; document.querySelector('#torch-toggle').addEventListener('click', async () => { try { if (torchEnabled) { await Quagga.CameraAccess.disableTorch(); torchEnabled = false; } else { await Quagga.CameraAccess.enableTorch(); torchEnabled = true; } } catch (error) { console.error('Torch control failed:', error); alert('Torch not available on this device'); } }); ``` ## Advanced Camera Control {#advanced-camera-control} For advanced camera control (zoom, focus, etc.), use the MediaStreamTrack API: ```javascript const track = Quagga.CameraAccess.getActiveTrack(); const capabilities = track.getCapabilities(); // Check if zoom is supported if (capabilities.zoom) { console.log('Zoom range:', capabilities.zoom.min, '-', capabilities.zoom.max); // Apply zoom await track.applyConstraints({ advanced: [{ zoom: 2.0 }] }); } ``` Read more: [MediaStreamTrack Capabilities](https://www.oberhofer.co/mediastreamtrack-and-its-capabilities) ## Error Handling {#error-handling} Always handle errors when using CameraAccess methods: ```javascript try { await Quagga.CameraAccess.request(video); } catch (error) { if (error.name === 'NotAllowedError') { console.error('Camera permission denied'); } else if (error.name === 'NotFoundError') { console.error('No camera found'); } else { console.error('Camera error:', error); } } ``` ## Related {#related} - [Browser Support](browser-support.md) - Camera compatibility information - [Configuration Reference](configuration.md) - Camera configuration in Quagga.init() - [API Documentation](api.md) - Main Quagga API methods - [Tips & Tricks](../how-to-guides/tips-and-tricks.md) - Camera optimization tips --- [← Back to Reference](index.md)