Adding autotracking to a security camera
I recently got my hands on a generic Chinese camera.
The App Situation
This camera requires an extremely shady mobile app (V380 Pro — Google Play) to function. This is easily among the worst pieces of software I've ever interacted with. Slow, janky, and filled to the brim with ads — both regular ads, and promotion for their "cloud service" to store (among other things) camera footage.
I spent some more time in the app, looking at the capabilities that it exposes.
- It "implements" PTZ (Pan, Tilt, Zoom), but zoom doesn't work.
- It can save/load preset positions.
- It has a mode where it's supposed to autotrack people/objects. Funnily enough, the camera rotated in the opposite direction of the object when I tested this.
A man, a plan, a lan
I wanted to do the following things:
- Make the camera usable without the shitware app.
- Try to fix/implement autotracking.
- Prevent it from leaking my data all over the place.
When I dug into the settings in the app, I discovered a redeeming quality: this wonderful little wiretap supports ONVIF (for future me, ONVIF port was 8899).
ONVIF is a standard for controlling networked cameras. This is great news! I can implement the person-tracking functionality on my own!
I messed around with Frigate, trying to get its autotracking to work with the camera. However it just refused to work. Pan/Tilt worked perfectly, but autotracking did not.
I decided to take the matter into my own hands and see if I could implement autotracking on my own.
I made the following plan:
- Write two scripts:
- One that exposes a function that can be used to move/reset the camera.
- Another that fetches the video stream from the camera, uses OpenCV to do the detection, and move the camera so that it points straight at the target. Maybe record events?
- Drop all this onto a Raspberry Pi.
- Use the Pi's hotspot to connect to the camera, with very restricted internet access.
- Set up a Wireguard VPN to connect to this little network from outside.
This post will cover just the first part of this glorified plan.
Autotracking kinda works!
Tracking objects is pretty easy with OpenCV. Turns out, getting the camera to move properly is the hard part.
This is because this camera only implements a small subset of the ONVIF standard, and that too in an annoying way.
(I got to know about this thanks to this script taken from Frigate's docs.)
The camera supports ONVIF PTZ with the following caveats:
- It supports only
ContinuousMove(which is basically relative motion — you give it X and Y velocities). - The move is executed after you call
Stopon it. - There's no way to query or set the absolute position of the camera.
I (with a lot of help from Gemini 2.5 Pro) wrote the first script,
onvif_control.py. It exposes a move(x, y) method that moves the camera in
steps. This lets me calculate how much I'm moving with some accuracy.
I also wrote the person_tracker.py script that loads the RTSP video stream
into a separate thread, and uses OpenCV (with YOLOv3) to recognise people and
incrementally move towards them.
So far, this is working fine.
The biggest problem is that there's no way to return to a starting position. The camera doesn't seeem to expose any way to query the absolute position.
I tried storing the steps the camera has taken so that I can backtrack using
it, but that doesn't work because move() might not be successful all the time
(weird lags with the camera, reaching the end of motion range, etc). It kept
throwing my calculation off, so I abandoned it for the time being.
I also tried an approach where I essentially "calibrated" the camera by moving it to the extremes of its range of motion and measuring the steps it took to do that, but that didn't work either. This approach still holds some promise though, so I'll probably try this again.
My final idea is this: I can maybe reverse engineer the calls the V380 Pro app makes to the camera, and use that proprietary protocol to control it. That's a lot more work, but it seems like it will be more reliable. The app has a way to store PTZ presets, as I mentioned at the beginning. I can probably use that to my advantage if I figure this out.
I'll try to clean up and publish the scripts so far if I get time.
Stay tuned for a part 2!
Comments
Comment via ...