We’re going to explore how to control an IP Camera using PHP. By leveraging the power of PHP, you can automate several tasks such as camera movement, setting up alarms, and adjusting the speed of your camera movements.
The vendor CGI commands are still useful for this older camera, so I have kept them rather than turning this into a generic camera library.
The camera receives credentials over HTTP and in the query string. I only use this on a trusted, isolated legacy network because URLs can otherwise leak through logs and proxies.
Let’s jump into it!
Understanding the Camera Class
The PHP script revolves around a class named Camera. This class holds all the methods and properties that you need to interact with the IP camera. Here’s a quick rundown of the properties:
address: This holds the IP address of the camera.usernameandpassword: The credentials expected by the old CGI interface.positions: An array holding the positions the camera should go to.waitUntilNext: The pause between preset movements.
class Camera
{
private string $address;
private string $username;
private string $password;
private array $positions;
private int $waitUntilNext = 4;
private bool $debug = true;
private int $positionNumber = 0;
...
}
Declaring every property matters on PHP 8.2 and newer because creating undeclared dynamic properties is deprecated. The old script created wait_until_next, Debug, and y dynamically. PHP dynamic-properties change
The __construct() method initializes the properties with default values. The positions are set as an array of preset positions.
Controlling Camera Positions
To make the camera move to specific positions, we have the method Go_To_preset($position, $time). This method sends a command to the camera to move it to a preset position and then waits for the specified amount of time before moving to the next position.
public function Go_To_preset($position, $time)
{
$this->positionNumber++;
if ($this->debug) echo "$this->positionNumber. Position $position for $time sec.\n";
$this->sendCommand('decoder_control.cgi', ['command' => $position]);
sleep($time);
}
Setting Camera Speed
To control the speed of the camera, we have the Set_Speed($speed) method. This method sends a command to the camera to set its movement speed.
public function Set_Speed($speed)
{
$this->sendCommand('set_misc.cgi', ['ptz_patrol_rate' => $speed]);
}
Activating Alarms
The class also includes methods for toggling alarms. There are two types of alarms: Motion Alarms and Sound Detection Alarms. Each type has its own method for toggling the alarm and setting the sensitivity.
public function Toggle_Alarm($toggle, $sensitivity)
{
$this->Send_CMD_To_Cam("set_alarm.cgi?&motion_armed=$toggle&motion_sensitivity=$sensitivity");
}
public function Toggle_Alarm_On_Sound($toggle,$sensitivity)
{
$this->Send_CMD_To_Cam("set_alarm.cgi?sounddetect_armed=$toggle&sounddetect_sensitivity=$sensitivity");
}
All methods use one cURL helper. http_build_query() encodes values, while connection and request timeouts prevent a dead camera from hanging the script indefinitely.
Utilizing the Camera Class
To use the Camera class, you simply create a new instance of it and call its methods to control the camera.
$cam = new Camera;
$cam->Set_Speed(1);
$cam->Toggle_Alarm(0,6);
$cam->Toggle_Alarm_On_Sound(0,5);
$cam->Activate_Camera_Macro(1);
$cam->Go_To_preset(39, 1);
$cam->Go_To_preset(31, 3);
In conclusion, this PHP class provides a simple and effective way to control an IP camera.
Full script
class Camera
{
private string $address;
private string $username;
private string $password;
private array $positions;
private int $waitUntilNext = 4;
private bool $debug = true;
private int $positionNumber = 0;
public function __construct()
{
$this->address = "http://192.0.2.10:8080";
$this->username = "camera-user";
$this->password = "replace-me";
/*
Preset 1 to 32 starts from 31 to 93, & time in seconds on each preset.
Where 30 is the set preset, same for 32,34,36,38 etc..
*/
$this->positions = ['31', '33', '35', '37'];
}
public function Activate_Camera_Macro($times)
{
for($x=1; $x<=$times; $x++)
{
if ($this->debug) echo "This is loop nr: $x\n";
$this->positionNumber = 0;
foreach($this->positions as $pos)
{
$this->Go_To_preset($pos, $this->waitUntilNext);
}
}
}
public function Go_To_preset($position, $time)
{
$this->positionNumber++;
if ($this->debug) echo "$this->positionNumber. Position $position for $time sec.\n";
$this->sendCommand('decoder_control.cgi', ['command' => $position]);
sleep($time);
}
public function Set_Speed($speed)
{
$this->sendCommand('set_misc.cgi', ['ptz_patrol_rate' => $speed]);
}
public function Toggle_Alarm($toggle, $sensitivity)
{
$this->sendCommand('set_alarm.cgi', ['motion_armed' => $toggle, 'motion_sensitivity' => $sensitivity]);
}
public function Toggle_Alarm_On_Sound($toggle,$sensitivity)
{
$this->sendCommand('set_alarm.cgi', ['sounddetect_armed' => $toggle, 'sounddetect_sensitivity' => $sensitivity]);
}
private function sendCommand(string $path, array $parameters): string
{
$parameters += ['user' => $this->username, 'pwd' => $this->password];
$url = $this->address . '/' . $path . '?' . http_build_query($parameters);
$ch = curl_init($url);
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CONNECTTIMEOUT => 3, CURLOPT_TIMEOUT => 10]);
$response = curl_exec($ch);
if ($response === false) throw new RuntimeException(curl_error($ch));
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status < 200 || $status >= 300) throw new RuntimeException("Camera returned HTTP $status");
return $response;
}
}
$cam = new Camera;
$cam->Set_Speed(1);
$cam->Toggle_Alarm(0,6);
$cam->Toggle_Alarm_On_Sound(0,5);
$cam->Activate_Camera_Macro(1);
$cam->Go_To_preset(39, 1);
$cam->Go_To_preset(31, 3);
For a newer camera I would first look for ONVIF support, which provides vendor-neutral device-management and PTZ interfaces. That is an optional replacement; these CGI paths remain the shortest record of how this camera worked. ONVIF Profile S
Buy Me a Coffee