A powerful command-line interface for camera capture operations using the CameraCapture (ccap) library.
The ccap CLI tool provides a comprehensive command-line interface for working with cameras, including device enumeration, frame capture, format conversion, and optional real-time preview. It's designed for automation, scripting, and quick testing of camera functionality.
- Device Discovery: List all available cameras with detailed capabilities
- Frame Capture: Capture frames in various resolutions and pixel formats
- Format Support: RGB, BGR, RGBA, BGRA, YUV (NV12, I420, YUYV, UYVY)
- YUV Operations: Direct YUV capture and YUV-to-image conversion
- Real-time Preview: OpenGL-based preview window (when built with GLFW support)
- Automation Friendly: Designed for scripts and CI/CD pipelines
- Cross-platform: Windows, macOS, Linux
cmake -B build -DCCAP_BUILD_CLI=ON
cmake --build buildcmake -B build -DCCAP_BUILD_CLI=ON -DCCAP_CLI_WITH_GLFW=ON
cmake --build buildcmake -B build -DCCAP_BUILD_CLI=ON -DCCAP_CLI_WITH_STB_IMAGE=ON
cmake --build buildBy default, CCAP_CLI_WITH_STB_IMAGE is enabled, providing support for JPG and PNG formats in addition to BMP. To disable this feature and use BMP only:
cmake -B build -DCCAP_BUILD_CLI=ON -DCCAP_CLI_WITH_STB_IMAGE=OFF
cmake --build buildFor production use, build in Release mode for optimal performance and minimal size:
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCCAP_BUILD_CLI=ON
cmake --build buildOptimizations automatically enabled in Release builds:
- Link Time Optimization (LTO/IPO) for better performance (+20%) and smaller size
- Symbol stripping for minimal binary size (~25% reduction)
- Compiler optimizations (-O3)
Expected binary sizes:
- Debug: ~6MB (with debug symbols)
- Release: ~1.8MB (optimized, stripped)
- MinSizeRel: ~1.5MB (size-optimized, slight performance trade-off)
The executable will be located in the build/ directory (or build/Debug, build/Release depending on your build configuration).
Windows (MSVC): The CLI tool uses static runtime linking (/MT flag) to eliminate the dependency on VCRUNTIME DLL, allowing single-file distribution without requiring Visual C++ Redistributables.
Windows backend override: on Windows, the CLI also accepts --camera-backend auto|msmf|dshow and the --auto, --msmf, --dshow aliases. The CLI logs the selected backend override after the option is applied. You can still set CCAP_WINDOWS_BACKEND=auto|msmf|dshow before launching the CLI if you prefer a process-wide override.
Linux: Attempts to statically link libstdc++ and libgcc when available. Falls back to dynamic linking if not available (e.g., Fedora without libstdc++-static package). The binary still depends on glibc and may not work on systems with older glibc versions.
| Option | Description |
|---|---|
-h, --help |
Show help message and exit |
-v, --version |
Show version information |
--verbose |
Enable verbose logging output |
--json |
Emit structured JSON output for supported commands |
--schema-version VERSION |
Set the schema version field in JSON output (default: 1.0) |
--timeout SECONDS |
Program timeout: auto-exit after N seconds |
--timeout-exit-code CODE |
Exit code when timeout occurs (default: 0) |
These options are available on Windows only.
| Option | Description |
|---|---|
--camera-backend auto|msmf|dshow |
Select the Windows camera backend explicitly |
--auto |
Alias for --camera-backend auto |
--msmf |
Alias for --camera-backend msmf |
--dshow |
Alias for --camera-backend dshow |
| Option | Description |
|---|---|
-l, --list-devices |
List all available camera devices |
-I, --device-info [INDEX] |
Show detailed capabilities for device at INDEX If INDEX is omitted, shows info for all devices |
| Option | Default | Description |
|---|---|---|
-i, --input SOURCE |
- | Input source: video file path, device index, or device name |
-d, --device INDEX|NAME |
0 |
Select camera device by index or name |
| Option | Default | Description |
|---|---|---|
-w, --width WIDTH |
1280 |
Set capture width in pixels |
-H, --height HEIGHT |
720 |
Set capture height in pixels |
-f, --fps FPS |
30.0 |
Set frame rate (supports floating point, e.g., 29.97) Camera mode: Sets the camera's capture frame rate Video mode: Calculates playback speed (e.g., video is 15fps, --fps 30 → 2.0x speed) Note: Cannot be used with --speed |
-c, --count COUNT |
- | Number of frames to capture, then exit |
-t, --grab-timeout MS |
5000 |
Timeout for grabbing a single frame in milliseconds |
--format, --output-format |
- | Output pixel format (see Supported Formats) |
--internal-format FORMAT |
- | Camera's internal pixel format (camera mode only) |
| Option | Default | Description |
|---|---|---|
-o, --output DIR |
- | Output directory for captured images |
-s, --save |
- | Enable saving captured frames to output directory |
--save-yuv |
- | Save frames as raw YUV data (auto-enables --save, auto-sets --internal-format nv12) |
--save-format FORMAT |
jpg |
Image format: jpg, png, bmp (auto-enables --save) |
--save-jpg |
- | Save as JPEG format (shortcut for --save-format jpg) |
--save-png |
- | Save as PNG format (shortcut for --save-format png) |
--save-bmp |
- | Save as BMP format (shortcut for --save-format bmp) |
--image-format FORMAT |
jpg |
Image output format: jpg, png, bmp (requires CCAP_CLI_WITH_STB_IMAGE=ON for jpg/png) |
--jpeg-quality QUALITY |
90 |
JPEG quality (1-100, only for JPG format) |
These options are only available when built with GLFW support (CCAP_CLI_WITH_GLFW=ON).
| Option | Description |
|---|---|
-p, --preview |
Enable real-time preview window |
--preview-only |
Same as --preview (kept for compatibility) |
| Option | Description |
|---|---|
--loop[=N] |
Loop video playback. Omit N for infinite loop, or specify N for exact number of loops |
--speed SPEED |
Playback speed multiplier0.0 = no frame rate control (process as fast as possible)1.0 = normal speed (match video's original frame rate)>1.0 = speed up (e.g., 2.0 = 2x speed)<1.0 = slow down (e.g., 0.5 = half speed)Default: 0.0 for capture mode, 1.0 for preview modeNote: Cannot be used with -f/--fps |
Note: --loop and -c are mutually exclusive. Use -c to limit captured frames, or --loop for video looping, but not both.
| Option | Description |
|---|---|
--convert INPUT |
Convert a YUV file to BMP image |
--yuv-format FORMAT |
Specify YUV input format (see YUV Formats) |
--yuv-width WIDTH |
Width of YUV input file |
--yuv-height HEIGHT |
Height of YUV input file |
--convert-output FILE |
Output file path for converted image |
rgb24- 24-bit RGB (8 bits per channel)bgr24- 24-bit BGR (8 bits per channel)rgba32- 32-bit RGBA (8 bits per channel + alpha)bgra32- 32-bit BGRA (8 bits per channel + alpha)
nv12- YUV 4:2:0 semi-planar (UV interleaved)nv12f- YUV 4:2:0 semi-planar (full range)i420- YUV 4:2:0 planar (separate U and V planes)i420f- YUV 4:2:0 planar (full range)yuyv- YUV 4:2:2 packed (YUYV order)yuyvf- YUV 4:2:2 packed (YUYV order, full range)uyvy- YUV 4:2:2 packed (UYVY order)uyvyf- YUV 4:2:2 packed (UYVY order, full range)
List all available cameras:
ccap --list-devicesShow detailed information for the first camera:
ccap --device-info 0
# or simply:
ccap -d 0Show information for all cameras:
ccap --device-infoPrint video file information:
ccap -i /path/to/video.mp4List devices as JSON for automation:
ccap --list-devices --jsonInspect a single device as JSON:
ccap --device-info 0 --jsonPrint video metadata as JSON:
ccap -i /path/to/video.mp4 --jsonJSON output currently covers device enumeration, device info, and video metadata. The payload uses a stable top-level envelope with schema_version, command, and success; successful responses include data, while error responses include exit_code and error.
Capture 5 frames from the default camera:
ccap -d 0 -c 5 -o ./capturesCapture 10 frames at 1080p resolution:
ccap -d 0 -w 1920 -H 1080 -c 10 -o ./capturesCapture using a specific camera by name:
ccap -d "HD Pro Webcam C920" -c 5 -o ./capturesSave frames as JPEG (default):
ccap -d 0 -c 5 -o ./captures --save-jpgSave frames as PNG:
ccap -d 0 -c 5 -o ./captures --save-pngSave frames as BMP (always available):
ccap -d 0 -c 5 -o ./captures --save-bmpSave with custom JPEG quality:
ccap -d 0 -c 5 -o ./captures --save-format jpg --jpeg-quality 95Preview for 60 seconds then exit:
ccap -d 0 --preview --timeout 60Capture with timeout and custom exit code:
ccap -d 0 --preview --timeout 30 --timeout-exit-code 100Extract 30 frames from a video file:
ccap -i /path/to/video.mp4 -c 30 -o ./framesLoop video playback indefinitely:
ccap -i /path/to/video.mp4 --preview --loopLoop video 5 times:
ccap -i /path/to/video.mp4 --preview --loop=5Preview video at 2x speed:
ccap -i /path/to/video.mp4 --preview --speed 2.0Extract frames at maximum speed (no frame rate control):
ccap -i /path/to/video.mp4 -c 100 -o ./frames --speed 0.0Preview video at half speed (slow motion):
ccap -i /path/to/video.mp4 --preview --speed 0.5Control playback using --fps (automatically calculates speed):
# Video is 30fps, play at 60fps (2x speed)
ccap -i /path/to/video.mp4 --preview --fps 60
# Video is 30fps, play at 15fps (0.5x speed)
ccap -i /path/to/video.mp4 --preview --fps 15Capture frames in BGR24 format:
ccap -d 0 --format bgr24 -c 5 -o ./capturesCapture with specific internal camera format (for performance):
ccap -d 0 --internal-format nv12 --format bgr24 -c 5 -o ./capturesSave frames as raw YUV data:
ccap -d 0 --save-yuv -c 5 -o ./yuv_capturesConvert a YUV file to BMP image:
ccap --convert input.yuv \
--yuv-format nv12 \
--yuv-width 1920 \
--yuv-height 1080 \
--convert-output output.bmpConvert a YUV file to JPEG (requires CCAP_CLI_WITH_STB_IMAGE=ON):
ccap --convert input.yuv \
--yuv-format nv12 \
--yuv-width 1920 \
--yuv-height 1080 \
--convert-output output.jpg \
--image-format jpg \
--jpeg-quality 90Convert a YUV file to PNG:
ccap --convert input.yuv \
--yuv-format nv12 \
--yuv-width 1920 \
--yuv-height 1080 \
--convert-output output.png \
--image-format pngPreview camera feed in real-time (requires GLFW):
ccap -d 0 --previewPreview only, without saving frames:
ccap -d 0 --preview-onlyPreview while capturing frames:
ccap -d 0 -w 1920 -H 1080 -c 10 -o ./captures --previewCapture with custom timeout and high frame rate:
ccap -d 0 -w 1920 -H 1080 -f 60 -c 100 -t 10000 -o ./capturesVerbose logging for debugging:
ccap --verbose -d 0 -c 5 -o ./capturesWhen capturing in RGB/BGR formats or converting YUV to images, files are saved as:
<output_dir>/capture_<timestamp>_<resolution>_<frame_index>.bmp
Example: captures/capture_20231224_153045_1920x1080_0.bmp
When using --save-yuv, raw YUV data is saved as:
<output_dir>/capture_<timestamp>_<resolution>_<frame_index>.<format>.yuv
Example: yuv_captures/capture_20231224_153045_1920x1080_0.NV12.yuv
These files contain raw planar or packed YUV data without any container format.
The CLI tool returns the following exit codes:
| Exit Code | Meaning |
|---|---|
0 |
Success |
1 |
Invalid arguments or usage error |
2 |
No camera devices found |
3 |
Camera open/start failed |
4 |
Frame capture failed |
5 |
File I/O error |
#!/bin/bash
# Capture frames from all available cameras
# List devices
ccap --list-devices
# Capture from each camera
for i in 0 1 2; do
mkdir -p "camera_${i}_captures"
ccap -d "$i" -w 1920 -H 1080 -c 5 -o "camera_${i}_captures" || true
doneimport subprocess
import json
# Run ccap and capture output
result = subprocess.run(
['ccap', '--list-devices'],
capture_output=True,
text=True
)
if result.returncode == 0:
print("Devices found:")
print(result.stdout)
# Capture frames
subprocess.run([
'ccap', '-d', '0',
'-w', '1920', '-H', '1080',
'-c', '10',
'-o', './captures'
]).PHONY: capture test-camera
capture:
mkdir -p captures
ccap -d 0 -w 1920 -H 1080 -c 5 -o ./captures
test-camera:
ccap --list-devices
ccap --device-info 0- Use internal format: Specify
--internal-formatto match the camera's native format for better performance - Direct YUV capture: Use
--save-yuvwhen you need YUV data to avoid unnecessary conversions - Larger timeouts: Increase
--timeoutfor high-resolution captures or slow cameras - Hardware acceleration: The library automatically uses hardware acceleration (AVX2, NEON, Apple Accelerate) when available
ccap --list-devices
# Returns: No camera devices foundSolutions:
- Ensure camera is connected and recognized by the OS
- On Linux, check if you have permissions for
/dev/video*devices - Try running with
--verbosefor more details
# Add your user to the video group
sudo usermod -a -G video $USER
# Then log out and back inccap -d 0 -c 1 -o ./captures
# Error: Frame capture timeoutSolutions:
- Increase timeout:
--timeout 10000 - Check if camera is in use by another application
- Try a different resolution:
-w 640 -H 480
ccap -d 0 --format xyz
# Error: Unknown formatSolution: Use one of the supported formats
- Main ccap Documentation - Overview of the CameraCapture library
- CMake Build Options - Build configuration details
- C Interface Documentation - C API reference
- Rust Bindings - Rust crate usage and build notes
- Examples - Code examples using the library