diy ptz camera control

Noah Vogt ea35fe024f use visca over ip instead of rs485 to send command to ptz cameras 1 неделя назад
.gitignore 63c0d9646a add gitignore 6 месяцев назад
LICENSE 6b6559117a init commit 7 месяцев назад
README.md ea35fe024f use visca over ip instead of rs485 to send command to ptz cameras 1 неделя назад
ls_com_ports.py 44a228980f add helper file to list com ports with a LOCATION entry 6 месяцев назад
requirements.txt 6704684147 add missing requirement 7 месяцев назад
switch.py ea35fe024f use visca over ip instead of rs485 to send command to ptz cameras 1 неделя назад

README.md

diy_ptz_switch

For a typical livestream production environment consisting of 2 ptz cameras and one joystick / controller board, most commercial options like the Skaarhoj PTZ Fly are

  • expensive
  • offering no API
  • nearly impossible to automate

To fix this, I built a Python-based PTZ router that connects a traditional Pelco-D serial joystick to modern IP-based PTZ cameras. This server selects which camera receives the joystick input and provides a HTTP API for selecting the target camera and managing presets.

The router receives Pelco-D packets from the joystick via a USB-to-RS485 converter and translates them into VISCA-over-IP commands, which are sent to the cameras over the network (UDP port 52381).

See the following ascii diagram for the architecture.

                        +------------------------+
                        |      PTZ Joystick      |
                        |  (Pelco-D via RS-485)  |
                        +------------------------+
                                     |
                                     v
                     +--------------------------------+
                     |  /dev/ttyUSBX (JOYSTICK_PORT)  |
                     |  [async serial reader]         |
                     +--------------------------------+
                                     |
                                     v
                      +------------------------------+
                      |  Python asyncio PTZ Router   |
                      |------------------------------|
                      | - Parse Pelco-D packets      |
                      | - Translate to VISCA commands|
                      | - current_target: cam1/cam2  |
                      | - Forward to selected cam(IP)|
                      | - Handle HTTP API requests   |
                      |                              |
                      |   +----------------------+   |
                      |   |     HTTP API         |   |
                      |   |----------------------|   |
                      |   | POST /target/set     |   |
                      |   | GET  /target/get     |   |
                      |   | POST /preset/goto    |   |
                      |   | POST /preset/save    |   |
                      |   | GET  /mode/get       |   |
                      |   | POST /mode/set       |   |
                      |   +----------------------+   |
                      +------------------------------+
                                     |
                +--------------------+------------------+
                | (Network / UDP)                       | (Network / UDP)
                v                                       v
  +----------------------------+         +----------------------------+
  |  Camera 1 (192.168.1.3)    |         |  Camera 2 (192.168.1.4)    |
  |  [VISCA over IP]           |         |  [VISCA over IP]           |
  +----------------------------+         +----------------------------+

Configuration

The project uses a YAML configuration file located at ~/.config/diy_ptz_switch/config.yml.

Example configuration:

location_roles:
  "1-4.4": joystick
  "1-4.1": cam1 # Optional if using IP
  "1-4.2": cam2 # Optional if using IP

cameras:
  cam1: "192.168.1.3"
  cam2: "192.168.1.4"
  • location_roles: Maps USB port locations to roles (like joystick).
  • cameras: Maps camera names to their IP addresses for VISCA-over-IP communication.