mailto: blog -at- heyrick -dot- eu

Webcam / IPCAM - control protocol

The HTTPAuth login method does not appear to be necessary if you can send requests directly to the camera including the ?loginuse=NAME&loginpas=PASS in the URL. Yes, it is amazing "security" (cough, choke) but at least it should make it fairly simple to create an application to interact with the camera.

Not that that's an excuse for laughable "security", but still...

 

Camera modes

The camera operates in one of three modes:
  • Some sort of IE specific protocol that uses an ActiveX to get itself going. It appears to be MJPEG encoded into some sort of ASF video stream.
    It is possible to record this using ffmpeg with the following command:
    ffmpeg -y -i "http://IPADDRESS:PORT/livestream.cgi?user=USER&pwd=PASS&streamid=3&audio=0&filename=videostream.asf" -t 30 -pix_fmt yuv420p -f mp4 output.mp4
    Note that this URL differs from all of the rest in using "user" and "pwd" instead of "loginuse" and "loginpas".
    Note also that MPlayer and VLC both fail to play this. It appears that the header is non-standard. ffmpeg guesses ("with a low score of 12"), and luckily for us, guesses correctly.

  • The Firefox/Safari mode, which gives a pretty looking UI and holds the image as an MJPEG image. The image can be directly loaded into most modern browsers with the URL:
    http://IPADDRESS:PORT/videostream.cgi?loginuse=USER&loginpas=PASS
    The result is a never-ending JPEG that consists of frames one after the other.

  • Mobile mode. This is minimal interface providing only back up/down/left/right controls and a slightly flickery video stream.
    I was interested to see what was different about the camera's mobile device behaviour that made it flickery. That's when I discovered that it actually sets up a timer and then just calls:
    http://IPADDRESS:PORT/snapshot.cgi?loginuse=USER&loginpas=PASS
    repeatedly to get still images, faking "video" from that.

While it is possible to extract each JPEG frame from an MJPEG stream (frames begin with &FF&D8 and end with &FF&D9, so the sequence "ÿÙÿØ" indicates a frame division), it is just simpler to spam snapshot.cgi to keep requesting JPEGs.

It is worth noting that MJPEG eats through quite a bit of data. Obviously the data rate will depend upon what you are looking at, however each frame of MJPEG is a keyframe. That is to say, there is no relationship between frames other than it being a picture of the same thing. Because of this, it is missing some of the features of proper video formats such as H.264 or XviD which can save a lot of bandwidth by sending occasional keyframes and then inter frames which contain instructions on what's changed in each frame.
As a consequence of this, using the camera over WiFi achieves approximately six frames per second, with thirty seconds of video consuming just under two megabytes. Or half that if it is transcoded to H.264.

 

The "Centre" control is broken

As we shall see later, the "Centre"/"Home" control is broken and does not set the centre position, but instead specifies the camera begin horizontal panning. As this is a firmware issue, it will be assumed that you have set Preset #16 to be the camera's home position.

 

Connecting to the camera

Normally, when you connect to the camera, using http://IPADDRESS:PORT/, an HTTP realm login popup appears asking for the username and password.
You can, however, bypass this step by simply providing this information in the HTTP request. Do not worry that you will be passing sensitive information in cleartext for anybody to look at - you pretty much need to do this anyway for the various commands here, as the HTTP realm is only used to identify yourself to the camera the first time. Once the camera knows who you are, and can tell the script running in your browser, it'll use the method of appending login details to every single command.

Don't believe me? Log into the camera then open a new tab. In this tab, go to http://IPADDRESS:PORT/get_login.cgi. The response is something like:

var loginuser="admin";

var loginpass="123456";

var pri=255;

However, if the username and password are already known, then they can be provided directly to control the camera and retrieve data, and the HTTP realm login prompt will not appear.

 

Sight and sound

There are three ways to retrieve images from the camera - the ASF stream, the regular MJPEG stream, and the still snapshots. The methods of calling each of these are detailed above.

Sound is available using:
http://IPADDRESS:PORT/audiostream.cgi?loginuse=USER&loginpas=PASS
Obviously it will be interesting trying to get sensible audio out of a camera with the microphone disconnected; however having run a few tests on the output, it is extremely noisy and with regular clicking. What gives me the most viable sounding output is to treat the audio as raw 8kHz ADPCM - however there is still the issue of the clicking. After examining the audio data, it seems that the audio is in 544 byte chunks, where the first 32 bytes are some sort of header beginning &55 AA 15 A8. I tried removing the 32 byte header, and the results were... noise with no weird clicks.
But, wait - if we can zoom in on things, we can uncover the truth. Here's the waveform of the start of the file:

Bingo! That's it.
Allow me to explain. ADPCM is a peculiar codec in that it does not hold a copy of the waveform, it instead holds a copy of the difference between one sample and the next. However it will need to have a "starting" value, which I presume is zero. This can be shown by the very first frame of the audio - the 512 bytes (which represents a little over a tenth of a second) is fairly quiet. It is only after the first frame that it all falls apart. Why? Easy - one can assume that each header block resynchronises the audio and the ADPCM offset is reset to zero. However in treating this as a raw ADPCM file, this new starting offset would be lost and the codec would just assume that the data carries on.

So what you will need to extract the audio is to strip off the 32 byte headers, then convert each 512 byte chunk from ADPCM to normal audio samples, remembering to treat each chunk as a separate entity. A good explanation and source code is available from Microchip.com App Note 643c.

 

Moving the camera

There are two ways of moving the camera:
  • The camera can move in a single step. This is achieved with the command:
    http://IPADDRESS:PORT/decoder_control.cgi?loginuse=USER&loginpas=PASSDIRECTION&onestep=1

  • The camera can also move continuously in the specified direction until it reaches the end of its position of travel or it receives a stop command. You begin movement with the following:
    http://IPADDRESS:PORT/decoder_control.cgi?loginuse=USER&loginpas=PASS&command=DIRECTION&onestep=0
    And end movement with this:
    http://IPADDRESS:PORT/decoder_control.cgi?loginuse=USER&loginpas=PASS&command=1&onestep=0

The camera movements are:

Up 0
Stop 1
Down 2
Left 4
Right 6
Centre/Home 25 a b
Sweep Up/Down 26 c
Sweep Left-Right 28 c
Left-Up 90
Right-Up 91
Left-Down 92
Right-Down 93

Note A - this command should complete when the camera is homed (it doesn't need to be 'stopped'), however...
Note B - this command is broken, it is recommended to set Preset #16 to the home position.
Note C - it's a tad pointless, but you can onestep the sweep commands.

 

Advanced camera control

You can control the speed of the pan and tilt. There are three speeds - slow, mid, and fast.

When set to Slow, a single left-to-right sweep takes about 40 seconds.
When set to Mid, a single left-to-right sweep takes about 25 seconds.
When set to Fast, a single left-to-right sweep takes about 10 seconds.
Fast mode is ridiculous. The camera doesn't have time to adapt to changing light (such as passing a window) and everything is blurry. It might be an interesting hack to set Fast mode before going to a preset, and unsetting it afterwards; however for normal operation I can't imagine it would be particularly useful.

The command to set the camera movement speed is:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS&param=100&value=SPEED

For SPEED, Slow is 1, Mid is 5, and Fast is 10.
You can have intermediate speeds. 3, for example, will perform a sweep in about 33 seconds. 15 or 20 will do it in a blurry 8 seconds - that's likely about as fast as the hardware can manage. Zero, incidentally, is marginally slower than 1, performing a sweep in 45 seconds.

 

Camera control 14 value 1 turns the IR function off, while value 0 turns it on. This seems back to front to me, but nevermind.

Thus, to turn IR off, we'd use:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS&param=14&value=1
And to turn IR back on again, we'd use:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS&param=14&value=0

 

Brightness and contrast are also handled by way of camera_control.cgi. To set the brightness:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS&param=1&value=BRIGHTNESS
Where BRIGHTNESS is a value between 1 (minimum) and 255 (maximum). The default is in the middle, 128.

Setting the contrast is the same, only it is param 2, as follows:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS&param=2&value=CONTRAST
As with the prior command, CONTRAST is a value between 1 (minimum) and 255 (maximum). The default is in the middle, 128.

To restore the default brightness, contrast, and speed, you should call:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS&param=7&value=0
If you need to know the current state, a call to:
http://IPADDRESS:PORT/get_camera_params.cgi?loginuse=USER&loginpas=PASS
will return some information similar to:

   var resolution=0;
   var vbright=128;
   var vcontrast=128;
   var vhue=0;
   var vsaturation=0;
   var OSDEnable=0;
   var mode=0;
   var flip=0;
   var enc_framerate=10;
   var sub_enc_framerate=15;
   var speed=5;
   var ircut=1;

 

  • Aside: If you look in the scripting for the camera, it refers to these functions using the acronym "PTZ". That stands for Pan, Tilt, and Zoom and is what this functionality is called even though these cheaper cameras have no facilities for zooming.

 

Esoteric camera control

To flip the top and bottom of the picture (for cases when the camera is mounted upside down), call:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS&param=5&value=1

To flip left and right, call:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS&param=5&value=2

To flip in both ways, call:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS&param=5&value=3

To restore the default orientation, use:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS&param=5&value=0

There is no way to flip top and bottom, then selectively flip and unflip left and right. To do this, you will need to keep track of the fact that up/down flip has happened, and then 'fake' toggling left/right on and off by alternately specifying up/down flip (for left/right normal) and full flip (for left/right flipped).

 

You can control the camera's refresh rate with:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS&param=3&value=0
for 50Hz operation, or:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS&param=3&value=1
for 60Hz operation.
Note that the refresh rate is not the video frame rate. This is intended to alter the camera so it doesn't flicker badly with mains powered illumination. In Europe, one would choose 50Hz, in the US one would choose 60Hz...

 

VGA (640×480) image size is selected with:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS&param=0&value=0
while QVGA (320×240) size is selected with:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS&param=0&value=1

It is not documented anywhere, however specifying param=0&value=2 will switch to a QQVGA (160×120) mode. This looks pretty naff, especially if zoomed to fit a 640×480 box, however it does have the advantage of more fluid video on slow links.

 

Finally, the MJPEG video frame rate:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS&param=6&value=FRAMERATE
where FRAMERATE is the desired number of frames per second, from 1 to 30. Note that even if you specify 30fps, it isn't going to run faster than your network link allows for. Which means 25-30fps for directly connected 100mbit Ethernet without other traffic; ~10-20fps for WiFi without other traffic; and ~5-10fps for remote access via a mobile device assuming an ~0.8mbit upload rate.
In general, unless you want to specifically slow the MJPEG frame rate down (to 1fps, for example), this can just be left alone.

 

Setting and recalling presets

There are 16 presets, numbered from 1 to 16. These are set using decoder_control.cgi in a somewhat less than intuitive manner.

Here's a lookup table:

PresetSetCall
1 30 31
2 32 33
3 34 35
4 36 37
5 38 39
6 40 41
7 42 43
8 44 45
9 46 47
10 48 49
11 50 51
12 52 53
13 54 55
14 56 57
15 58 59
16 60 61

Presets are invoked using:
http://IPADDRESS:PORT/decoder_control.cgi?loginuse=USER&loginpas=PASS&command=VALUE&onestep=0&sit=VALUE

Therefore, to go to preset #16 (or defined "Home" position), you would:
http://IPADDRESS:PORT/decoder_control.cgi?loginuse=USER&loginpas=PASS&command=61&onestep=0&sit=61

And to set preset #1, move the camera to the desired angle and then:
http://IPADDRESS:PORT/decoder_control.cgi?loginuse=USER&loginpas=PASS&command=30&onestep=0&sit=30

The preset value can be determined programmatically with code such as this:

DEFFNcalc_preset_value(preset%, set%)
  REM preset% is preset number, from 1 to 16
  REM set% is 1 if setting preset, or 0 if calling it
  REM It is expected that values are already sanitised.
  
  value% = 28 + (preset% * 2)
  IF (set% = 0) THEN value% += 1
=value%

 

There are many more things that can be done, such as the system configuration. However for the purposes of interfacing with the camera, and of creating software to view and control the camera, we have all that we need. The camera is, itself, fairly simplistic. This is useful as while the clever software uses either an app or an ActiveX control on IE (remind me - what decade is this?), it isn't so locked down with proprietary protocols that we cannot work with it ourselves.

 

To make things better, the /system folder is mounted read/write, so it is possible to alter and/or fix the web pages. I will probably:

  • Remove the IE links (especially the idiotic text mentioning the "IE kernel")
  • Fix the centre button to go to preset #16
  • Tidy up the display: audio and record do nothing on Firefox so can be removed, snapshot should open in a new tab, remove the refresh rate control (it's always going to be 50Hz), fix the typos.
  • If username not known (meaning you bailed out of the HTTP realm login), trap this and direct user to a page elling them exactly where they can go. The camera should give an unauthorised access message, but I've seen it go into the UI normal only with no user credentials (so nothing works).
  • Anything else I can think of. ☺

 

 

Your comments:

Please note that while I check this page every so often, I am not able to control what users write; therefore I disclaim all liability for unpleasant and/or infringing and/or defamatory material. Undesired content will be removed as soon as it is noticed. By leaving a comment, you agree not to post material that is illegal or in bad taste, and you should be aware that the time and your IP address are both recorded, should it be necessary to find out who you are. Oh, and don't bother trying to inline HTML. I'm not that stupid! ☺ ADDING COMMENTS DOES NOT WORK IF READING TRANSLATED VERSIONS.
 
You can now follow comment additions with the comment RSS feed. This is distinct from the b.log RSS feed, so you can subscribe to one or both as you wish.

David Pilling, 17th September 2016, 01:45
Newspapers today carrying story that MI5 are worried about Chinese made CCTV cameras (which the UK is full of). Is 'elling' a word.

Add a comment (v0.11) [help?] . . . try the comment feed!
Your name
Your email (optional)
Validation Are you real? Please type 06898 backwards.
Your comment
French flagSpanish flagJapanese flag
Calendar
«   September 2016   »
MonTueWedThuFriSatSun
   123
678911
12131415161718
202122232425
272930  

(Felicity? Marte? Find out!)

Last 5 entries

List all b.log entries

Return to the site index

Geekery

Search

Search Rick's b.log!

PS: Don't try to be clever.
It's a simple substring match.

Etc...

Last read at 09:35 on 2024/04/23.

QR code


Valid HTML 4.01 Transitional
Valid CSS
Valid RSS 2.0

 

© 2016 Rick Murray
This web page is licenced for your personal, private, non-commercial use only. No automated processing by advertising systems is permitted.
RIPA notice: No consent is given for interception of page transmission.

 

Have you noticed the watermarks on pictures?
Next entry - 2016/09/19
Return to top of page