Rick's b.log - 2016/09/10 |
|
It is the 21st of November 2024 You are 3.147.82.252, pleased to meet you! |
|
mailto:
blog -at- heyrick -dot- eu
Not that that's an excuse for laughable "security", but still...
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
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.
Don't believe me? Log into the camera then open a new tab. In this tab, go to
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.
Sound is available using:
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.
The camera movements are:
Note A - this command should complete when the camera is homed (it doesn't need to be 'stopped'), however...
When set to Slow, a single left-to-right sweep takes about 40 seconds.
The command to set the camera movement speed is:
For SPEED, Slow is
Camera control
Thus, to turn IR off, we'd use:
Brightness and contrast are also handled by way of camera_control.cgi. To set the brightness:
Setting the contrast is the same, only it is param
To restore the default brightness, contrast, and speed, you should call:
To flip left and right, call:
To flip in both ways, call:
To restore the default orientation, use:
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:
VGA (640×480) image size is selected with:
It is not documented anywhere, however specifying
Finally, the MJPEG video frame rate:
Here's a lookup table:
Presets are invoked using:
Therefore, to go to preset #16 (or defined "Home" position), you would:
And to set preset #1, move the camera to the desired angle and then:
The preset value can be determined programmatically with code such as this:
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
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.
Camera modes
The camera operates in one of three modes:
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.
http://IPADDRESS:PORT/videostream.cgi?loginuse=USER&loginpas=PASS
The result is a never-ending JPEG that consists of frames one after the other.
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.
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.
http://IPADDRESS:PORT/get_login.cgi
. The response is something like:
var loginuser="admin";
var loginpass="123456";
var pri=255;
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.
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:
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.
Moving the camera
There are two ways of moving the camera:
http://IPADDRESS:PORT/decoder_control.cgi?loginuse=USER&loginpas=PASSDIRECTION&onestep=1
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
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 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 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.
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS¶m=100&value=SPEED
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.
14
value 1
turns the IR function off, while value 0
turns it on. This seems back to front to me, but nevermind.
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS¶m=14&value=1
And to turn IR back on again, we'd use:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS¶m=14&value=0
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS¶m=1&value=BRIGHTNESS
Where BRIGHTNESS is a value between 1 (minimum) and 255 (maximum). The default is in the middle, 128.
2
, as follows:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS¶m=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.
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS¶m=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;
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¶m=5&value=1
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS¶m=5&value=2
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS¶m=5&value=3
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS¶m=5&value=0
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS¶m=3&value=0
for 50Hz operation, or:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS¶m=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...
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS¶m=0&value=0
while QVGA (320×240) size is selected with:
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS¶m=0&value=1
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.
http://IPADDRESS:PORT/camera_control.cgi?loginuse=USER&loginpas=PASS¶m=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.
Preset Set Call 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
http://IPADDRESS:PORT/decoder_control.cgi?loginuse=USER&loginpas=PASS&command=VALUE&onestep=0&sit=VALUE
http://IPADDRESS:PORT/decoder_control.cgi?loginuse=USER&loginpas=PASS&command=61&onestep=0&sit=61
http://IPADDRESS:PORT/decoder_control.cgi?loginuse=USER&loginpas=PASS&command=30&onestep=0&sit=30
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%
/system
folder is mounted read/write, so it is possible to alter and/or fix the web pages. I will probably:
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.
© 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. |