A sleek, dark-themed desktop camera application built with Qt 6 / QML and C++17. Capture snapshots and record video from any connected camera — all saved automatically to ~/StudioCapture/.
| Feature | Details |
|---|---|
| Live Camera Preview | Real-time video feed via Qt Multimedia's VideoOutput |
| Multi-Camera Support | Detect, list, and switch between all connected cameras |
| One-Click Snapshots | Auto-named JPG snapshots saved to ~/StudioCapture/ |
| Video Recording | H.264 MP4 recording via FFmpeg subprocess (threaded) |
| Camera-In-Use Detection | Visual overlay when the camera is held by another app |
| Hot-Swap Cameras | Refresh camera list and switch without restarting |
| Media Preview | Sidebar thumbnail of the last captured image/video |
| Open Media Folder | One-click to open ~/StudioCapture/ in your file manager |
| Technology | Purpose |
|---|---|
| Qt 6.8+ | Application framework |
| QML / Qt Quick | Declarative UI (dark, modern theme) |
| Qt Multimedia | Camera access, video sink, image capture |
| C++17 | Core logic (CameraController) |
| FFmpeg (external) | Video encoding via QProcess (H.264, MP4) |
| CMake 3.16+ | Build system |
StudioCapture/
├── CMakeLists.txt # Build configuration
├── src/
│ ├── main.cpp # App entry point, QML engine setup
│ ├── CameraController.h # Camera logic header (Q_PROPERTY, signals)
│ ├── CameraController.cpp # Camera, snapshot, and FFmpeg recording logic
│ └── qml/
│ ├── Main.qml # Root window layout (sidebar + main view)
│ ├── CameraView.qml # Live preview + error overlays
│ ├── CameraSelector.qml # Camera dropdown + refresh + count badge
│ ├── ControlBar.qml # Snapshot & Record buttons, REC indicator
│ └── MediaPreview.qml # Last-capture thumbnail + open-folder link
└── reference_ui.png # UI design reference
Install via the Qt Online Installer or your system package manager. Required Qt modules:
Qt CoreQt QuickQt Multimedia
FFmpeg must be installed and available on PATH for video recording to work.
Ubuntu / Debian:
sudo apt install ffmpegFedora:
sudo dnf install ffmpegmacOS (Homebrew):
brew install ffmpegWindows:
Download from ffmpeg.org and add to your system PATH.
sudo apt install cmake # Ubuntu/Debian
brew install cmake # macOS- Linux: GCC 9+ or Clang 10+
- macOS: Xcode 12+
- Windows: MSVC 2019+
# Clone the repository
git clone <repo-url> StudioCapture
cd StudioCapture
# Configure (adjust Qt path if needed)
cmake -B build -DCMAKE_PREFIX_PATH=~/Qt/6.9.1/gcc_64
# Build
cmake --build build
# Run
./build/appStudioCapture- Open
CMakeLists.txtin Qt Creator - Select a Qt 6.8+ kit with the Multimedia module
- Click Build → Run
- Select Camera — Pick a camera from the dropdown in the sidebar
- Start Camera — Click "Start Camera" to begin the live preview
- Snapshot — Click 📷 Snapshot in the bottom bar (auto-saved as JPG)
- Record — Click ⏺ Record to start MP4 recording; click ⏹ Stop Recording to finalize
- View Media — Click the thumbnail or "Click to open folder" in the sidebar to open
~/StudioCapture/ - Refresh — Click ⟳ Refresh to detect newly connected cameras
Note
All media is automatically saved to ~/StudioCapture/ with timestamped filenames like studiocapture_20260324_231500.jpg.
Warning
If the camera is in use by another application (e.g. a video call), the preview area will show a "Camera Is In Use" warning. Close the other application and try again.
The CameraController class (C++) manages the full camera lifecycle — discovery, start/stop, error handling — and exposes everything to QML via Q_PROPERTY bindings.
Recording bypasses Qt's QMediaRecorder in favor of a more reliable approach:
- Frames are captured from the
QVideoSinkon the main thread - Pixel data is enqueued into a thread-safe
std::deque - A background
QThreadpipes raw RGBA frames to an FFmpeg subprocess - FFmpeg encodes to H.264 baseline profile with
ultrafastpreset
Camera errors (device busy, disconnected) are caught via QCamera::errorOccurred and QCamera::activeChanged signals, updating both the status bar and the preview overlay in real-time.
StudioCapture follows a Qt 6 / QML + C++ backend architecture:
- Camera Management — A single CameraController C++ class manages the full camera lifecycle (discovery, start/stop, error handling) and exposes state to QML via
- Q_PROPERTY bindings and signals. This clean separation keeps all device interaction in C++ while the QML layer remains purely declarative UI.
- Snapshot Capture — Uses Qt Multimedia's built-in QImageCapture to save JPG snapshots. Files are auto-named with timestamps and saved to ~/StudioCapture/.
- Video Recording (FFmpeg subprocess) — Instead of using Qt's QMediaRecorder (which was found unreliable), recording is implemented as a producer-consumer pipeline:
- The main thread captures frames from QVideoSink, converts them to RGBA, and enqueues raw pixel data into a thread-safe std::deque.
- A background QThread dequeues frames and pipes them to an FFmpeg subprocess via stdin for H.264 encoding.
- A queue cap of 60 frames acts as back-pressure to prevent unbounded memory growth.
- Camera-in-Use Detection — Listens to QCamera::errorOccurred and QCamera::activeChanged signals to detect when the camera is held by another application, and surfaces this status to the QML UI as an overlay.
- QML UI — A modular, dark-themed interface split into focused components (CameraView, CameraSelector, ControlBar, MediaPreview).
- Single user, single camera at a time
No multi-camera simultaneous capture support - No cross-platform recording test
FFmpeg piping via QProcess may behave differently on Windows (e.g., binary mode for stdin)
