A robust Python application that continuously monitors a webcam, detects user presence using hybrid face and motion detection, and automatically creates timestamped video recordings when the user is present. Designed for performance monitoring with configurable quality settings, intelligent session management, and LSL (Lab Streaming Layer) integration for synchronization with other data streams.
- Hybrid Presence Detection: Combines face detection and motion detection for reliable user presence detection
- Automatic Recording: Starts recording when user is detected, stops after configurable absence timeout
- Intelligent Buffering: Continues recording for a configurable period after user leaves (default: 35 seconds)
- LSL Integration: Sends LSL markers for recording start/stop events, enabling synchronization with EEG, motion capture, and other data streams
- Configurable Settings: YAML-based configuration for video quality, detection parameters, buffer timeouts, and more
- Graceful Shutdown: Handles interruptions cleanly, ensuring video files are properly saved
- Robust Error Handling: Automatic camera detection, codec fallbacks, and graceful degradation
- Python 3.9.13 or higher
- Webcam/camera device
- (Optional) LSL library for marker stream integration
# Install the package and dependencies
pip install -e .
# Or install dependencies directly
pip install opencv-python numpy pyyaml pylslThe application uses a config.yaml file for configuration. A default configuration file is created automatically if one doesn't exist. You can customize the following settings:
resolution: Video resolution as [width, height] (default: [1280, 720])fps: Frames per second (default: 24)codec: Video codec (default: "mp4v", alternatives: "XVID", "MJPG", "H264")quality: Quality preset (default: "medium")
face_confidence: Face detection confidence threshold 0.0-1.0 (default: 0.5)motion_threshold: Motion detection threshold percentage (default: 30)face_check_interval: Check for face every N frames (default: 5)
absence_timeout: Continue recording for N seconds after user leaves (default: 35)
output_dir: Directory for recorded videos (default: "./recordings")min_duration: Minimum recording duration in seconds to save file (default: 5)
device_index: Camera device index (default: 0, will auto-detect if unavailable)
enabled: Enable LSL marker stream (default: true)stream_name: LSL stream name (default: "VideoRecorderMarkers")stream_type: LSL stream type (default: "Markers")source_id: LSL source identifier (default: "continuous_video_recorder")marker_start: Marker value for recording start (default: "RECORDING_START")marker_stop: Marker value for recording stop (default: "RECORDING_STOP")include_metadata: Include filename and session ID in marker metadata (default: true)
python main.pypython main.py --config /path/to/custom_config.yaml--config: Path to configuration file (default:config.yamlin current directory)
The application uses a hybrid detection approach:
- Face Detection: Checks for faces every N frames (configurable) using OpenCV's DNN face detector or Haar cascades
- Motion Detection: Continuously monitors motion using background subtraction (MOG2)
- Presence Logic: User is considered present if:
- Face is detected in the current frame, OR
- Motion is detected above threshold AND face was detected recently (within last 2 seconds)
- IDLE: No user detected, not recording
- RECORDING: User present, actively writing video
- BUFFERING: User left but within buffer timeout, still recording
- STOPPING: Buffer expired, finalizing current video file
When LSL is enabled, the application creates a marker stream that sends events when recording starts and stops:
- RECORDING_START: Sent when recording begins
- RECORDING_STOP: Sent when recording stops
Each marker includes:
- Precise LSL timestamp (synchronized with other LSL streams)
- Optional metadata: filename, session ID, duration (for stop markers)
This allows synchronization with:
- EEG/EMG data streams
- Motion capture systems
- Other physiological measurements
- Multi-modal data analysis
Recorded videos are saved with timestamped filenames in the format:
session_YYYY-MM-DD_HH-MM-SS.mp4
Example: session_2025-01-15_14-30-25.mp4
Logs are saved in the recordings/logs/ directory with timestamped filenames.
If the application can't find your camera:
- Check that the camera is connected and not in use by another application
- Adjust the
device_indexinconfig.yaml(try 0, 1, 2, etc.) - The application will attempt to auto-detect available cameras
If video recording fails:
- The application automatically tries a fallback codec (XVID)
- Try different codecs in
config.yaml: "mp4v", "XVID", "MJPG", "H264" - Ensure you have the necessary codec libraries installed
If LSL markers aren't being sent:
- Check that
pylslis installed:pip install pylsl - Verify LSL is enabled in
config.yaml:lsl.enabled: true - Check the logs for LSL-related warnings
- The application will continue without LSL if it's unavailable
If presence detection is unreliable:
- Adjust
face_confidencethreshold (lower = more sensitive) - Adjust
motion_threshold(lower = more sensitive to motion) - Ensure good lighting conditions
- Adjust
face_check_intervalfor performance vs. accuracy tradeoff
continuous_video_recorder/
├── main.py # Main application entry point
├── config.yaml # Configuration file
├── src/
│ ├── __init__.py
│ ├── detector.py # Face and motion detection logic
│ ├── recorder.py # Video recording management
│ ├── lsl_trigger.py # LSL marker stream for recording events
│ ├── config_loader.py # Configuration loading and validation
│ └── utils.py # Helper functions (logging, file management)
├── pyproject.toml # Dependencies and project config
└── README.md # This file
This project is open source. See LICENSE file for details.
Contributions are welcome! Please feel free to submit issues or pull requests.
For issues, questions, or feature requests, please open an issue on the project repository.