Skip to content

A HTTP-CGI based controller for PTZ-Optics cameras

Notifications You must be signed in to change notification settings

j-trueman/PTZ-Optics

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

91 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TODO:

  • DOCUMENTATION!
  • Move all js dependancies to js-delivr
  • Migrate ionicons to fontawesome
  • Fix sliders
  • Fix CORS headers
  • Make settings dropdowns actually match current camera settings
  • General code refactoring
  • Streamline cgi-bin url resolving
  • Clean up keybinding
  • Remove PHP dependancy

Welcome!

My goal for this project is to make an easily accessible and intuitive controller for PTZ-Optics cameras. The backend of the controller is loosely based off the original (IMHO messy) controller built by PTZ-Optics themselves.

Contents:


Installation

Currently (Oct 2023) in order to use this camera controller, you will need to run a local web-server on whatever device you want to run it on, I use Easyphp devserver but you can use whatever one you want as long as it can interperet php1. So just click the green "Code" button and select "Download ZIP".

Then unzip and place all the files in the document root of your web-server. (in my case this is "D:/EasyPHP-Devserver-17/eds-www/").

For now you will also need to install a CORS Everywhere extension for your browser to allow the requests to get through to the camera. A good one for chrome is the "Moesif Origin & CORS Changer"

Once everything is setup you can open the "index.html" file via your webserver and it should pop up with the controller.

To set the IP that the controller communicates with, click on the "Preferences" button in the top right and change the "Camera IP" field to your camera's IP followed by clicking the "Reload Camera button.

UI Overview

I have designed the UI to be as easy to understand as possible.2 I've used mediaqueries to create 2 slightly different UIs for the controller. The first has 3 main sections:

The "Preset" panel is used for calling presets3 that the user has defined. The "Preview" panel displays a preview of whichever preset is currently being hovered over in the "Preset" panel. The "PTZ" panel has controls for the camera, allowing the user to (as the name sugests) pan, tilt and zoom the camera as well as adjust the focus.

The smaller version of the UI is practically identical minus the "Preview" panel as well as the "PTZ" panel being below the "Preset" panel.

How It Works

In this section i'll give a brief overview of how the backend of the controller operates and some code snippets as well.

HTTP and cgi-bin

PTZ-Optics cameras can be given isntructions by submiting an HTTP-GET request to scripts within the cgi-bin directory on the camera. There are two base paths that all the commands stem from on a PTZ camera. These are:

http://[camera ip]/cgi-bin/ptzctrl.cgi?ptzcmd&

and

http://[camera ip]/cgi-bin/param.cgi?

Ajax

These http-get requests can be submitted using jquery's built in ajax() function. This is what my one looks like

$.ajax({
  url: action_url,
  type: 'GET',
  headers: { 'Access-Control-Allow-Origin': `http://${camera_ip}/` },
})
  .done(function () {
    // console.log("success");
  })
  .fail(function (jqXHR, responseText, errorThrown) {
    console.log("error");
  })
  .always(function () {
    // console.log("complete");
});

Where action_url is the url of the command we want to execute within the cgi-bin directory

Keybinding

For keybinding, I currently use the Mousetrap library which has a simple function for making keybinds. For example:

Mousetrap.bind(x, function (e) {
  Console.log('Key Pressed');
}, 'keydown');

Where x is the key you want to detect in string form

Preferences and Settings

I use local document cookies for saving and fetching preferences like the document theme and preset names. To make this easier i use the js-cookie library. Here's an example of how to set a cookie using js-cookie:

Cookies.set('cookie-name', 'value')

And here's how would then fetch the value of that cookie:

Cookies.get('cookie-name')

Alternatively, you can just call Cookies.get() with no arguments to fetch the values and names of all cookies in the document.

Note:

I also hope to eventually transition this entire project over to electron-react so that I can just package it as an executable so this may all be deprecated within a year or two.


Issues

  • CORS headers don't seem to be working properly
  • Lerp function is jittery when the zoom or focus buttons are presesed and then released in quick succession

Footnotes

  1. I will most likely remove the dependancy on php sometime in the near future, it's only neccessary at the moment to allow for thumbnail downloads of preset positions

  2. This section will be updated whenever significant changes to the UI are made

  3. Setting presets currently requires going to a different page but I'll eventually change this to just a toggle to switch between calling and setting