A TP-link Tapo C310 security camera streaming audio/video to the FOSS Viseron NVR software running on an Odroid-C2 single board computer/home server.
Because I couldn't resist the temptation of a technical challenge, despite my dislike of surveillance in general (sorry principles!).
The Tapo C310 makes a couple of authenticated RTSP streams available at
/stream1: a high res stream (1920x1080 or 2304x1296 depending on how you set it up)
/stream2: a low res stream (640x360)
These streams are a bit quirky; they're fixed at 15 fps, and use the
pcm_alaw audio and
h264 video codecs. This audio codec choice is a pain, as it means you have to re-encode if you want to put it in
.mp4 containers rather than
.mkv containers, which aren't as well supported (I'm looking at you, Firefox!).
Still, this is enough for us to plug into a Network Video Recorder (NVR) program which can pull the feed, process it, and save it.
Viseron is a fairly straightforward open source NVR program that should be just the job. I like it because it's modular, written in python, and quite efficient. This means that you don't have to play with all the bells and whilstles of AI object detection or graphics cards if you don't want to. It'll manage all the boring stuff, like deleting old video files, making the setup fairl simple.
Even better, it's shipped in Docker containers so it's super easy to spin it up and get it going without worrying about dependencies, daemons, or other faff like that! So we spin up a container
docker run \ -v /mnt/nvr/segments:/segments \ -v /mnt/nvr/recordings:/recordings \ -v /mnt/nvr:/config \ -v /etc/localtime:/etc/localtime:ro \ -p 8888:8888 \ --restart unless-stopped \ --detach \ --name viseron \ roflcoopter/viseron:latest
Note that we're binding some directories on our filesystem as volumes in the container. This allows the recordings and config files to be stored on an external HDD plugged into the server, rather than doing all that writing on fragile flash memory (which is a great way to kill your micro-SD card/eMMC!). We're also port forwarding on 8888 to allow us to view the admin interface on the local network. And finally we're using the
restart flags to keep the process alive in the background.
What about setting up Viseron itself? Well the documentation for configuring Viseron is pretty good, and as we're only using the basic
ffmpeg camera and
background_subtractor motion detection components the setup is quite simple:
## Cameras ffmpeg: camera: hillview_front: ### Recording stream name: Tapo C310 host: cameras.local.ip.address port: 554 path: /stream1/ username: username_set_in_tapo_app password: password_set_in_tapo_app audio_codec: aac codec: h264 fps: 15 width: 2304 height: 1296 ### Low-res stream substream: path: /stream2/ port: 554 audio_codec: aac codec: h264 fps: 15 width: 640 height: 360 recorder: lookback: 20 extension: mp4 ## Motion detectors background_subtractor: motion_detector: cameras: hillview_front: width: 320 height: 180 trigger_recorder: true fps: 1 area: 0.01 threshold: 15 alpha: 0.1 ## NVR nvr: hillview_front:
First we tell the
ffmpeg component how to connect to the camera. Since we've got access to high and low res streams we use them both so that the high-res stream is used when saving recordings but the low-res stream can be used for out motion detection (saving us valuable processing power!).
Next we specify the exact encoding parameters for each stream. We have to do this because we want to save our files in
.mp4 containers so they can be viewed using the web interface on Firefox, which means
ffmpeg needs to re-encode the streams. We also tell the recorder to save the 10 seconds prior to any event as well as the event itself.
We set up the motion detector to trigger the camera recorder when it detects motion, and tweak the default parameters to ensure we catch the motion we want but ignore random noise. This is well documented except for the
alpha property, which is poorly described. It's best to think of this as how sensitive the motion detector is to fleeting glimpses - a low alpha makes the motion detector sensitive to fleeting glimpses, whilst a high alpha allows the motion detector to ignore these.
The system works great!
Motion triggers recordings which I can view (with sound) from the web interface. If I'm away from home then I can check in on the Tapo app to get a live feed, knowing that the recordings are safe inside the house so even if the camera is damaged they'll still be stored. The docker container will even recover itself in the event of a power cut!
I don't think I'll ever need it (although the dash-cam I installed in my car with the same discomfort about surveillance has been proven worthwhile!), but it was fun to set up.