Interactive terminal-based UI for managing v4l2-ctl camera settings via SSH/PuTTY.
🤖 Vibe coded with AI: This project was collaboratively developed with Claude (Anthropic AI). Human creativity meets AI assistance!
Device: /dev/video0 - UVC Camera (046d:0825) [d] Device | [r] Refresh | [i] Info | [c] Crowsnest | [q] Quit
═══════════════════════════════════════════════════════════════════════════════════════════════════════
User Controls
brightness 128 [0-255, step 1] ◄───────●────────►
contrast 32 [0-255, step 1] ◄─●──────────────►
saturation 32 [0-255, step 1] ◄─●──────────────►
white_balance_automatic OFF [toggle] [ ] ON [●] OFF
gain 64 [0-255, step 1] ◄───●────────────►
power_line_frequency 60 Hz [menu] [Disabled | 50 Hz | 60 Hz]
> white_balance_temperature 4000 [0-10000, step 10] ◄──────●─────────►
sharpness 24 [0-255, step 1] ◄─●──────────────►
backlight_compensation 0 [0-1, step 1] ◄●───────────────►
Camera Controls
auto_exposure Aperture P [menu] [Manual Mode | Aperture Priority Mode]
exposure_time_absolute 336 [1-10000, step 1] ◄●───────────────► (inactive)
exposure_dynamic_framerate OFF [toggle] [ ] ON [●] OFF
↑↓: Navigate | ←→: Adjust | Enter: Edit | Space: Toggle | 0: Default | s: Save | l: Load | i: Info | c: Crowsnest
v4l2ctl: white_balance_automatic=0
Set white_balance_temperature = 4000
Copy and paste this command to install and run:
cd ~ && git clone https://github.com/nic335/v4l2-ui.git && cd v4l2-ui && chmod +x v4l2-ui install.sh && ./install.shOr for standalone mode (no installation):
cd ~ && git clone https://github.com/nic335/v4l2-ui.git && cd v4l2-ui && chmod +x v4l2-ui && ./v4l2-uiIf you already have the repository:
cd ~/v4l2-ui
./v4l2-uiThat's it! The tool runs directly from its directory. No installation required.
First time? Make it executable: chmod +x v4l2-ui v4l2_control.py
- Live List Interface: View all camera controls in a single scrollable list
- Real-time Adjustment: Changes apply immediately as you adjust values
- Multiple Control Types: Supports integer sliders, boolean toggles, and menu options
- Device Selection: Only real capture devices shown (ISP/codec/metadata nodes filtered out)
- Visual Feedback: Sliders, checkboxes, and status messages for clear feedback
- Info Screen (
i): View device capabilities, supported pixel formats, resolutions, and frame rates - Crowsnest Editor (
c): Editcrowsnest.confcamera sections directly — pick device path type (by-id / by-hardware / by-video), resolution, FPS, and auto-fillv4l2ctlfrom current controls
- Python 3.x (built-in on most Linux systems)
- v4l2-ctl (from v4l-utils package)
- Curses library (built-in with Python)
No installation needed! Just run from the directory:
cd v4l2-ui
chmod +x v4l2-ui v4l2_control.py # First time only
./v4l2-uiFor access from anywhere on your system:
cd v4l2-ui
./install.shThen run from anywhere:
v4l2-uiStandalone mode:
cd v4l2-ui
./v4l2-uiAfter installation:
v4l2-uiDirect Python:
python3 v4l2_control.pyDevice Selection Screen:
↑↓- Navigate between devicesEnter- Select deviceq- Quit
Control Screen:
↑↓- Navigate between controls←→- Adjust selected control value (applies immediately)- Hold ←→ for progressive speed: x1 → x10 → x50
Enter- Type exact value for integer controlsSpace- Toggle boolean controls (ON/OFF)0- Reset selected control to default values- Save current settings as a presetl- Load settings from a saved preseti- Show device info screen (capabilities, supported resolutions & FPS)c- Open Crowsnest config editord- Change devicer- Refresh all control valuesq- Quit application
The bottom line of the screen displays a crowsnest-compatible configuration string that updates in real-time as you adjust controls. This line can be copied directly into your crowsnest configuration file.
Example output:
v4l2ctl: power_line_frequency=2,focus_absolute=250,focus_automatic_continuous=0,brightness=128,contrast=32
Simply copy this line and paste it into your crowsnest camera configuration to preserve your current settings.
Press c from the main control screen to open the interactive crowsnest.conf editor. It automatically finds your config at ~/printer_data/config/crowsnest.conf (or other common locations).
Crowsnest Config: /home/pi/printer_data/config/crowsnest.conf
══════════════════════════════════════════════════════════════
Select camera section to edit:
> cam 1: /dev/v4l/by-id/usb-046d_0825… 1280x960@30fps
cam 2: /dev/v4l/by-id/usb-Suyin_HD… 640x480@30fps [brightness=120]
cam 3: /dev/video0 640x480@30fps
↑↓: Navigate | Enter: Edit | n: New cam | x: Delete | q: Back
| Key | Action |
|---|---|
↑↓ |
Navigate between camera sections |
Enter |
Open the selected section for editing |
n |
Add a new [cam N] section (auto-numbered, port auto-incremented, pre-filled from first detected camera) |
x or Del |
Delete the selected section (asks for confirmation) |
q / Esc |
Return to main screen |
Edit [cam 1] ← ~/printer_data/config/crowsnest.conf
══════════════════════════════════════════════════════
device : /dev/v4l/by-id/usb-046d_0825_173921D0-video-index0 ◄/► cycle
path type : by-id (/dev/v4l/by-id/…) [by-id / by-hardware / by-video] ◄/► cycle
mode : ustreamer ◄/► cycle
port : 8080 Enter: edit
resolution : 1280x960 ◄/► cycle
max_fps : 30.000 ◄/► cycle
v4l2ctl : Enter: edit | a: auto-fill from controls
Editing [cam 1] — w: Save | q: Cancel
↑↓: Field | ◄►: Cycle | Enter: Edit | a: Auto v4l2ctl | w: Save | q: Cancel
| Key | Action |
|---|---|
↑↓ |
Move between fields |
◄► |
Cycle through available values for the focused field |
Enter |
Free-text edit for port, v4l2ctl, or any field |
a |
Auto-fill v4l2ctl from the non-default controls currently loaded for the active device |
w |
Save all changes back to crowsnest.conf (preserves all comments) |
q / Esc |
Cancel without saving |
Field details:
- device — Cycles through all detected V4L2 capture devices. Changing the device automatically resets
resolutionandmax_fpsto the first values supported by that device. - path type — Switches the device path format for the currently selected device. Only shows the types that actually exist on your system:
by-id—/dev/v4l/by-id/usb-…— stable across reboots, recommended for USB camerasby-hardware—/dev/v4l/by-path/platform-…— hardware bus path, stable for fixed hardwareby-video—/dev/video0— simple index, can change if devices are added/removed
- mode — Cycles between
ustreamerandcamera-streamer - resolution — Only shows resolutions actually supported by the selected device (queried live from the camera)
- max_fps — Only shows frame rates available for the selected resolution
- v4l2ctl — Comma-separated
control=valuepairs. Pressato auto-populate from all controls that differ from their default value on the currently loaded device
Note: Saving writes only the fields shown in the editor. All other lines in
crowsnest.conf(comments,enable_rtsp,rtsp_port,custom_flags, etc.) are preserved exactly as-is.
Save and load your favorite camera configurations for quick switching between different setups.
Saving a Preset:
- Adjust controls to your desired settings
- Press
sto save - Enter a name for the preset (e.g., "daylight", "lowlight", "streaming")
- Preset is saved to
~/.config/v4l2-ui/presets/
Loading a Preset:
- Press
lto load - Use
↑↓to select a preset from the list - Press
Enterto apply the preset - All saved control values will be applied immediately
Reset to Default:
- Navigate to any control and press
0to reset it to the camera's default value - Useful for undoing changes or starting fresh
Presets are stored as JSON files and include:
- Device information
- Timestamp of when saved
- All active control values (inactive controls are not saved)
- Examples: brightness, contrast, saturation, gain, white_balance_temperature
- Use
←→arrows to increment/decrement by step value - Progressive Speed: Hold arrow keys for faster adjustment
- First 8 presses: Normal speed (x1)
- Presses 9–40: Fast speed (x10)
- After 40 presses: Maximum speed (x50)
- Status message shows multiplier:
(x10)or(x50)
- Press
Enterto type an exact value - Visual slider shows current position in range
- Perfect for controls with large ranges (e.g., 0-10000)
- Examples: white_balance_automatic, exposure_dynamic_framerate
- Press
Spaceto toggle ON/OFF - Visual checkbox shows current state
- Examples: auto_exposure, power_line_frequency
- Use
←→arrows to cycle through available options - Shows all available options in brackets
- Run
~/v4l2-ui/v4l2-ui - Select your camera device (e.g.,
/dev/video0) - Navigate to
brightnesswith↑↓arrows - Use
←→to adjust, or pressEnterto type exact value - Changes apply immediately
- Navigate to
white_balance_automaticor similar boolean control - Press
Spaceto toggle ON/OFF - Change takes effect immediately
- Check camera connection:
ls /dev/video* - Verify v4l2-ctl is installed:
which v4l2-ctl
- Add user to video group:
sudo usermod -a -G video $USER - Log out and back in for changes to take effect
- Some controls depend on others (e.g.,
white_balance_temperaturerequireswhite_balance_automaticto be OFF) - Toggle the parent control to activate dependent controls
- Update to latest version:
cd ~/v4l2-ui && git pull - Try a different terminal emulator
- Ensure terminal supports UTF-8 encoding
We welcome contributions! Whether it's:
- 🐛 Bug fixes
- ✨ New features
- 📝 Documentation improvements
- 🎨 UI enhancements
- 🔧 Performance optimizations
Pull requests are welcome! See CONTRIBUTING.md for guidelines.
- Fork the repository
- Create your feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
You are free to:
- ✅ Use commercially
- ✅ Modify
- ✅ Distribute
- ✅ Private use
- Built with Python and curses
- Developed collaboratively with Claude AI (Anthropic)
- Inspired by the need for easy camera control over SSH
- Thanks to all contributors!