WebSocket-based PTZ Camera Controller for Logitech cameras. This project is a fork of xMRi/PTZControl, reimagined as a headless WebSocket server with a web interface. Thanks to xMRi for the original PTZ control implementation and Logitech camera interface work.
A Vue 3-based web interface is included in web-ui/ for easy camera control via browser. Features live MJPEG streaming, PTZ controls, zoom, and preset management.
cd web-ui
npm install
npm run devThe UI connects to ws://localhost:8765 and provides an intuitive interface for all camera functions.
Requires Visual Studio 2022 with C++ Desktop Development workload.
MSBuild PTZControlWS\PTZControlWS.sln /p:Configuration=Release /p:Platform=x64Output: PTZControlWS\x64\Release\PTZControlWS.exe
For easier connectivity, i have replaced the original connector with a standard USB-C port. This involves unsoldering it and wiring a USB-C module directly to the camera board.
Original Pinout Reference:
Modification Process:
I used this USB-C module for the mod:
Amazon link: https://amazon.fr/dp/B0DL5JJS5T?ref=fed_asin_title
Important: The camera is designed for 12V operation. However, it functions at 5V USB power in my testing. use at your own risk. While it works for my setup, running below spec voltage may affect longevity or functionality.
PTZControlWS.exe [options]
Options:
-p, --port <port> WebSocket port (default: 8765)
-n, --no-auto-connect Don't auto-connect to cameras on startup
-h, --help Show help
Connect to ws://localhost:8765 and send JSON commands:
// List all video devices
{"command": "list"}
// Auto-connect to supported PTZ cameras
{"command": "connect"}
// Connect to specific camera by index
{"command": "connect", "params": {"index": 0}}
// Connect by name filter
{"command": "connect", "params": {"name": "PTZ"}}
// Disconnect all cameras
{"command": "disconnect"}
// Select active camera (when multiple connected)
{"command": "select", "params": {"index": 0}}
// Get current status
{"command": "status"}// Pan: 1 = right, -1 = left, 0 = stop
{"command": "pan", "params": {"direction": 1}}
// Continuous pan (holds until stop)
{"command": "pan", "params": {"direction": 1, "continuous": true}}
// Tilt: 1 = up, -1 = down, 0 = stop
{"command": "tilt", "params": {"direction": 1}}
// Zoom: 1 = in, -1 = out
{"command": "zoom", "params": {"direction": 1}}
// Get current zoom level
{"command": "zoom_level"}
// Go to home position
{"command": "home"}
// Stop all movement
{"command": "stop"}// Recall preset (0-7)
{"command": "preset", "params": {"number": 0}}
// Save current position to preset
{"command": "preset", "params": {"number": 0, "save": true}}// Get/set camera settings
{"command": "settings", "params": {
"logitech_motion": true, // Use Logitech motion control
"motor_interval": 70 // Motor interval timer (ms)
}}// Start MJPEG stream (default port 8080)
{"command": "stream_start"}
// Start stream on custom port
{"command": "stream_start", "params": {"port": 8081}}
// Stop stream
{"command": "stream_stop"}
// Get stream status
{"command": "stream_status"}The MJPEG stream is accessible at http://localhost:8080/stream.mjpeg (or your custom port).
All commands return JSON:
{
"success": true,
"message": "Optional status message",
"data": { /* Optional response data */ }
}MIT License - See LICENSE file
Note: This README was generated with AI assistance.




