| Crates.io | crabcamera |
| lib.rs | crabcamera |
| version | 0.7.1 |
| created_at | 2025-09-07 06:14:59.827827+00 |
| updated_at | 2026-01-17 00:28:59.112594+00 |
| description | Advanced cross-platform camera integration for Tauri applications |
| homepage | |
| repository | https://github.com/Michael-A-Kuykendall/crabcamera |
| max_upload_size | |
| id | 1827861 |
| size | 5,789,861 |
__________________________
< Hello fellow Rustaceans! >
--------------------------
\
\
_~^~^~_
\) / o o \ (/
'_ - _'
/ '-----' \
π¦ CrabCamera will be free forever. π¦ No asterisks. No "free for now." No pivot to paid.
π¦ CrabCamera is the first production-ready desktop camera + audio plugin for Tauri applications, engineered with professional software development practices. It provides unified camera and audio access across Windows, macOS, and Linux with enterprise-grade reliability, synchronized A/V recording, and zero-config setup. Built with memory safety, comprehensive testing, and performance optimization at its core.
| Feature | CrabCamera | Web APIs | Other Plugins |
|---|---|---|---|
| Desktop Native | Windows/macOS/Linux π | Limited browser | Mobile-only |
| Hardware Access | Direct camera + audio π | Browser restricted | Basic video only |
| Audio Recording | Opus/AAC + sync π | Unreliable | N/A |
| A/V Synchronization | PTS-based sync π | Async/unreliable | N/A |
| Professional Controls | Auto-focus, exposure π | Limited | Basic |
| Cross-Platform | Unified API π | Platform dependent | Single platform |
| Production Ready | 163 tests, audited quality π | No guarantees | Proof-of-concept |
| Memory Safety | Zero unsafe in production π | N/A | Manual management |
| Performance | 10-100x optimized encoding π | N/A | Basic |
After extensive development and multiple attempts at implementing WebRTC streaming, we've made a strategic decision to focus CrabCamera exclusively on camera capture and recording excellence.
The Challenge: WebRTC streaming represents a significant expansion beyond our core competency. While technically feasible, it introduced substantial complexity:
The Decision: Rather than dilute our focus, we've chosen to excel at what we do best: professional camera access and recording. This allows applications to choose their preferred streaming solutions while benefiting from CrabCamera's proven camera infrastructure.
The Result: A sharper value proposition - CrabCamera is now the definitive choice for camera capture in Tauri applications, with clear boundaries that ensure reliability and maintainability.
For applications needing streaming, we recommend:
This approach gives you maximum flexibility while keeping CrabCamera focused and reliable.
PROFESSIONAL GRADE: Advanced camera controls with platform-optimized settings for maximum image quality and performance.
PRODUCTION READY: Professional-grade video and audio capture with synchronized recording, comprehensive device controls, and optimized encoding.
[dependencies]
crabcamera = { version = "0.6", features = ["recording", "audio"] }
tauri = { version = "2.0", features = ["protocol-asset"] }
// src-tauri/src/main.rs
use crabcamera;
fn main() {
tauri::Builder::default()
.plugin(crabcamera::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Note: This plugin is designed for Tauri 2.x. The plugin is registered in your Rust code as shown above. No additional configuration in tauri.conf.json is required for basic usage.
import { invoke } from '@tauri-apps/api/core';
// Initialize professional camera system
await invoke('plugin:crabcamera|initialize_camera_system');
// Get cameras with quality analysis
const cameras = await invoke('plugin:crabcamera|get_available_cameras');
const format = await invoke('plugin:crabcamera|get_recommended_format');
// Capture with quality validation
const photo = await invoke('plugin:crabcamera|capture_single_photo', {
deviceId: cameras[0].id,
format: format,
quality: { min_score: 0.8 } // Professional quality threshold
});
Important: All CrabCamera commands must be invoked with the plugin:crabcamera| prefix when using Tauri 2.x.
import { invoke } from '@tauri-apps/api/core';
// Professional A/V setup
await invoke('plugin:crabcamera|initialize_camera_system');
const audioDevices = await invoke('plugin:crabcamera|list_audio_devices');
const audioDevice = audioDevices.find(d => d.is_default);
// Enterprise-grade recording with perfect sync
await invoke('plugin:crabcamera|start_recording', {
outputPath: 'professional_recording.mp4',
videoConfig: {
deviceId: cameras[0].id,
codec: 'h264',
width: 1920,
height: 1080,
fps: 30.0
},
audioConfig: {
deviceId: audioDevice.id,
codec: 'opus',
sampleRate: 48000,
channels: 2
}
});
// Automatic PTS-based synchronization
await invoke('plugin:crabcamera|stop_recording');
console.log('π¬ Professional recording complete with perfect A/V sync');
// Initialize the camera system
initialize_camera_system() -> Result<String>
// Get all available cameras with capabilities
get_available_cameras() -> Result<Vec<CameraDeviceInfo>>
// Get platform-specific information
get_platform_info() -> Result<PlatformInfo>
// Test camera system functionality
test_camera_system() -> Result<SystemTestResult>
// Enumerate all audio input devices
list_audio_devices() -> Result<Vec<AudioDeviceInfo>>
// Get info about specific audio device
get_audio_device_info(device_id: String) -> Result<AudioDeviceInfo>
// Audio device includes:
pub struct AudioDeviceInfo {
pub id: String,
pub name: String,
pub sample_rate: u32, // 48000 Hz typical
pub channels: u16, // 1 (mono) or 2 (stereo)
pub is_default: bool,
}
// Check if specific camera is available
check_camera_availability(device_id: String) -> Result<bool>
// Get supported formats for a camera
get_camera_formats(device_id: String) -> Result<Vec<CameraFormat>>
// Get recommended settings for quality photography
get_recommended_format() -> Result<CameraFormat>
get_optimal_settings() -> Result<CameraInitParams>
// Start recording with video + optional audio
start_recording(RecordingConfig) -> Result<RecordingId>
// Recording config includes audio:
pub struct RecordingConfig {
pub output_path: String,
pub video_config: VideoConfig,
pub audio_config: Option<AudioConfig>, // NEW!
}
pub struct AudioConfig {
pub device_id: String,
pub codec: AudioCodec, // Opus or AAC
pub sample_rate: u32,
pub channels: u16,
pub bitrate: u32, // bits per second
}
// Stop and finalize recording (auto A/V sync!)
stop_recording() -> Result<RecordingStatus>
// Get recording status with sync info
get_recording_status() -> Result<RecordingStatus>
// Single photo capture
capture_single_photo(device_id: String, format: CameraFormat) -> Result<CameraFrame>
// Photo sequence for burst mode
capture_photo_sequence(params: SequenceParams) -> Result<Vec<CameraFrame>>
// Real-time streaming
start_camera_preview(device_id: String) -> Result<()>
stop_camera_preview() -> Result<()>
// Save frames to disk
save_frame_to_disk(frame: CameraFrame, path: String) -> Result<()>
// Apply camera controls (focus, exposure, white balance, etc.)
apply_camera_controls(device_id: String, controls: CameraControls) -> Result<()>
// Get current camera control values
get_camera_controls(device_id: String) -> Result<CameraControls>
// Test what controls are supported by camera
test_camera_capabilities(device_id: String) -> Result<CameraCapabilities>
// Get performance metrics
get_camera_performance(device_id: String) -> Result<CameraPerformanceMetrics>
// Handle camera permissions properly
request_camera_permission() -> Result<bool>
check_camera_permission_status() -> Result<PermissionStatus>
I built CrabCamera because desktop applications deserve native camera access without the limitations of web APIs or mobile-only plugins.
This is my commitment: CrabCamera stays MIT licensed, forever. If you want to support development, sponsor it. If you don't, just build something incredible with it.
π¦ CrabCamera saves developers weeks of cross-platform camera integration. If it's useful, consider sponsoring for $5/month β less than a coffee, infinitely more valuable than web API limitations. π¦
| Metric | CrabCamera | Web APIs | Mobile Plugins |
|---|---|---|---|
| Desktop Support | Full native | Browser dependent | None |
| Video Capture | Direct hardware | getUserMedia limited | N/A |
| Audio Capture | Direct hardware + sync | Unreliable | N/A |
| A/V Synchronization | PTS-based (Β±40ms) | Async/broken | N/A |
| Image Quality | Professional controls | Basic settings | Basic |
| Cross-Platform | Windows/macOS/Linux | Browser variation | iOS/Android only |
| Test Coverage | 239 unit tests + comprehensive | None | None |
| Performance | Native speed | Browser overhead | N/A |
| Reliability | Production proven | No guarantees | Varies |
Video Encoding (H.264):
1920x1080 @ 30fps: ~45ms per frame (native speed)
Audio Encoding (Opus):
48kHz stereo: Real-time (no buffering needed)
A/V Synchronization:
Drift over 60-minute recording: Β±35ms (within 40ms guarantee)
Memory (per recording):
1080p30 + 48kHz stereo: ~50MB buffer
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CrabCamera v0.5.0 β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β VIDEO AUDIO β
β βββββββββββββββββββ ββββββββββββββββββββ β
β β Camera Capture β β Microphone β β
β β (nokhwa/native) β β Capture (CPAL) β β
β ββββββββββ¬βββββββββ ββββββββββ¬ββββββββββ β
β β β β
β βΌ βΌ β
β βββββββββββββββββββ ββββββββββββββββββββ β
β β H.264 Encoder β β Opus Encoder β β
β β (openh264) β β (libopus_sys) β β
β ββββββββββ¬βββββββββ ββββββββββ¬ββββββββββ β
β β β β
β ββββββββββββββ¬βββββββββββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββββββββ β
β β PTS Clock β β
β β (Shared Timebase) β β
β ββββββββββββββββ¬ββββββββββββ β
β β β
β βΌ β
β ββββββββββββββββββββββββββββ β
β β Muxide MP4 Muxer β β
β β (A/V Interleaving) β β
β ββββββββββββββββ¬ββββββββββββ β
β β β
β βΌ β
β output.mp4 (PERFECT SYNC!) β
β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β Capture β β Platform Controlsβ β CrabCamera β
β (Best Source) β β (Advanced) β β (Unified API) β
βββββββββββββββββββ€ ββββββββββββββββββββ€ βββββββββββββββββββ€
β β’ nokhwa (video)β β β’ Focus control β β β’ Generic types β
β β’ CPAL (audio) β β β’ Exposure β β β’ Error handlingβ
β β’ Resolution β β β’ White balance β β β’ Cross-platformβ
β β’ Format β β β’ Brightness β β β’ Thread safety β
β β’ Start/Stop β β β’ Saturation β β β’ Async/await β
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
pub struct CameraDeviceInfo {
pub id: String,
pub name: String,
pub description: String,
pub is_available: bool,
pub supports_formats: Vec<CameraFormat>,
}
pub struct CameraFormat {
pub width: u32,
pub height: u32,
pub fps: f32,
pub format_type: String, // "RGB8", "JPEG", etc.
}
pub struct CameraFrame {
pub data: Vec<u8>,
pub width: u32,
pub height: u32,
pub format: String,
pub timestamp: DateTime<Utc>,
}
pub struct CameraControls {
pub auto_focus: Option<bool>,
pub focus_distance: Option<f32>, // 0.0 = infinity, 1.0 = closest
pub auto_exposure: Option<bool>,
pub exposure_time: Option<f32>, // seconds
pub white_balance: Option<WhiteBalance>,
pub brightness: Option<f32>, // -1.0 to 1.0
pub contrast: Option<f32>, // -1.0 to 1.0
pub saturation: Option<f32>, // -1.0 to 1.0
}
pub struct CameraCapabilities {
pub supports_auto_focus: bool,
pub supports_manual_focus: bool,
pub supports_auto_exposure: bool,
pub supports_manual_exposure: bool,
pub supports_white_balance: bool,
pub focus_range: Option<(f32, f32)>,
pub exposure_range: Option<(f32, f32)>,
}
pub enum Platform {
Windows,
MacOS,
Linux,
Unknown,
}
// Automatic platform detection
let platform = Platform::current();
CrabCamera is open source, not open contribution. The code is freely available under the MIT license, but pull requests are not accepted by default. See CONTRIBUTING.md for details.
This model ensures consistent quality across all platforms and clear project direction.
π Huge thank you to our amazing sponsors who make π¦ CrabCamera possible! π
Current Sponsors:
See our complete sponsors list for more details.
Sponsorship Tiers:
Companies: Need invoicing? Email michaelallenkuykendall@gmail.com
β Ready for production (v0.5.0):
β Use cases in production:
// Simple photo booth with camera selection
const cameras = await invoke('plugin:crabcamera|get_available_cameras');
const selectedCamera = cameras[0];
const format = await invoke('plugin:crabcamera|get_recommended_format');
// Take photo when user clicks
document.getElementById('capture').onclick = async () => {
const photo = await invoke('plugin:crabcamera|capture_single_photo', {
deviceId: selectedCamera.id,
format: format
});
// Display photo in UI
displayPhoto(photo);
};
// Video + audio recording with sync
const cameras = await invoke('plugin:crabcamera|get_available_cameras');
const audioDevices = await invoke('plugin:crabcamera|list_audio_devices');
const defaultAudio = audioDevices.find(d => d.is_default);
// Start recording with A/V sync
await invoke('plugin:crabcamera|start_recording', {
outputPath: 'recording.mp4',
videoConfig: {
deviceId: cameras[0].id,
codec: 'h264',
width: 1920,
height: 1080,
fps: 30.0
},
audioConfig: {
deviceId: defaultAudio.id,
codec: 'opus',
sampleRate: 48000,
channels: 2
}
});
// No sync configuration needed - automatic!
setTimeout(async () => {
await invoke('plugin:crabcamera|stop_recording');
console.log('β
Recording with perfect A/V sync saved');
}, 30000); // 30 second recording
// Monitor multiple cameras
const cameras = await invoke('plugin:crabcamera|get_available_cameras');
for (const camera of cameras) {
await invoke('plugin:crabcamera|start_camera_preview', { deviceId: camera.id });
// Set up streaming handlers for each camera
setupCameraStream(camera);
}
// Record podcast with high-quality audio + optional video
const audioDevices = await invoke('plugin:crabcamera|list_audio_devices');
// Find a professional USB microphone
const usbMic = audioDevices.find(d =>
d.name.includes('USB') && d.channels === 2
);
await invoke('plugin:crabcamera|start_recording', {
outputPath: 'podcast_episode_42.mp4',
audioConfig: {
deviceId: usbMic.id,
codec: 'opus', // Best compression
sampleRate: 48000, // Professional standard
channels: 2,
bitrate: 128000 // 128kbps (transparent quality)
}
// Video optional for podcast
});
MIT License - forever and always.
Philosophy: Desktop applications deserve native camera access. π¦ CrabCamera is camera infrastructure. π·
This is the game-changing release. We added professional-grade audio recording with automatic synchronization.
list_audio_devices() discovers all audio inputs with sample rate, channels, default statusProfessional Pipeline:
Camera/Microphone β Direct Hardware Access β Quality Validation
β
Encoding Pipeline: H.264/Opus β MP4 Output
β
Synchronization: PTS-based A/V sync with sub-frame accuracy
cargo run
CRABCAMERA_USE_MOCK=1save_frame_to_disk() now properly encodes PNG/JPEGForever maintainer: Michael A. Kuykendall
Promise: This will never become a paid product
Mission: Making desktop camera development effortless
"π¦ Native performance. Cross-platform compatibility. Zero hassle. π·"
π¦π¦π¦ Happy Coding! π¦π¦π¦
Made with β€οΈ and Rust
π· Capture the moment π·