Record on motion detection with Xiaomi Dafang


Couple months ago, I read this article about hacking the Xiaomi Dafang camera to expand its capabilities. It’s a cheap $30 camera with neat features, such as MicroSD support, a rotating gimbal, microphone, infrared vision, among others. Thought it would be a fun project to try it out. The goal was to check if I could use this to record motion detection at night, without going to a third party service.

Camera

I went with the Xiami Dafang Portable HD, as it seemed cheap enough and containing enough functionality to play with. There are some comparisons of the versions of this camera here. Also, interestingly enough, this camera is sold under other brands, such as the Wyze cam. We’re not looking for any proprietary software, so we’ll just go with the Dafang.

Installing Custom Firmware

Installing the custom firmware is pretty straightforward. The setup is in two parts: installing the custom bootloader, then installing the custom firmware. See instructions here.

Accessing the Control Panel

Once the custom firmware is setup, and the camera is on, it will connect to the wifi as configured. Simply log in to your router to find the camera’s ip, and load it in a browser. Credentials are in the FAQ.

Viewing the Video Feed

VLC is a great tool to view the rtsp feed. Go to File > Open Network, then enter the rtsp url (by default rtsp://xiaomi_ip:8554/unicast). For additional security (if you’re enabling this remotely), there is a config to protect the feed with credentials, under /system/sdcard/config/rtspserver.conf. Simply SSH into the camera (using same credentials as above). A lot of config are stored under this folder and will be read again on camera reboot. Options are usually listed under the .dist file.

Configuring motion detection

From the control panel, there are a few options to setup the motion detection configuration. At this moment, the sensitivity goes from 0 (not very sensitive) to 4 (most sensitive to movement). You can also save config under /system/sdcard/config/motion.conf

Recording the stream on motion detection

This is what took me the most time. There are two ways to record video.

Linking this to the motion detection script, we just have to add this command under /system/sdcard/scripts/detectionOn.sh

However, a couple issues came up:

Solution appears simple, use avconv to record. Couple issues also came up.

Fixing the out of memory error

Whenever I tried running avconv, it would get killed by the kernel, and dmesg would display Out of memory: Kill process avconv. A quick fix could be to enable a swap file, but it would most likely kill the sdcard in a short time.

The solution was to replace the bootloader. free -m displayed I had 35M of memory before, after flashing the bootlader it went up to 100M. See instructions here.

Fixing the avconv (ffmpeg) delay when recording a stream

It looked like avconv tried to guess a bunch of data before recording, introducing lag and latency and missing a few seconds of movement. The solution was hidden in a couple flags, mainly flags low_delay, fflags nobuffer, and probesize 32. You can learn more about those options here. The final command was

/system/sdcard/bin/avconv -flags low_delay -fflags nobuffer -probesize 32 -i rtsp://0.0.0.0:8554/unicast -strict experimental -t 10 -y -vcodec copy -an /system/sdcard/DCIM/`date +%Y-%m-%d_%H.%M.%S`.h264

Final setup

In the end, here’s the final setup.

Create /system/sdcard/record.sh

 1 2 3 4 5 6 7 8 91011121314151617181920
#!/bin/sh
# Only record between those hours
HOUR=`date +"%H"`
if [ "$HOUR" -lt 1 ] || [ "$HOUR" -gt 7 ]; then
  exit 1
fi

# Delete anything that is not from today
DAY=`date +"%d"`
/system/sdcard/bin/busybox find /system/sdcard/DCIM/ -type f -not -name "`date +%Y-%m-`${DAY}*" -delete

STATUSFILE=/system/sdcard/recordstatus.txt
if [ -f $STATUSFILE ]; then
  echo "currently recording" >> "$STATUSFILE"
else
  echo "recording" >> "$STATUSFILE"
  /system/sdcard/bin/avconv -flags low_delay -fflags nobuffer -probesize 32 -i rtsp://0.0.0.0:8554/unicast -strict experimental -t 10 -y -vcodec copy -an /system/sdcard/DCIM/`date +%Y-%m-%d_%H.%M.%S`.h264
  echo "Recording `date +%Y-%m-%d_%H.%M`" >> /system/sdcard/recordlogs.txt
  rm "$STATUSFILE"
fi

Then add in /system/sdcard/scripts/detectionOn.sh

/system/sdcard/record.sh &

Videos will be saved under /system/sdcard/DCIM/. An easy way to download them is to move them under the /system/sdcard/www/ folder, which will make them available at http://ip/video.h264, or push them within the script via curl. See this example.

Happy hacking!