Track sleep using an IP camera with infrared
I live alone with my cat, and often wake up on strange angles with her sleeping on the other side of my legs than she was when I went to sleep.
I’ve been wondering what the quality of my sleep is like, and how much sharing a bed with a cat (or my partner) affects it, so I borrowed an IP camera with infrared from a friend.
This camera is old and so can’t do motion detection or write footage to a remote location (only SD card).
Below is the process by which I am recording the footage via an RTSP stream, analysing it for motion, then speeding it up so that I can watch a 2 minute summary.
Some of my notes after a few nights:
- My cat cleans herself a lot
- My partner grinds her teeth in her sleep
- I might have PLMS
- I am going to try locking my cat out for a few nights to see the difference this makes
- Play with
dvr-scan -roi
to specify region of interest to just detect motion of just me (head or feet), or cat - Haven’t done anything with audio yet
- Try graphing motion event timeline using timestamps outputted by
dvr-scan
Example output (roughly cropped to just my cat, you don’t need to watch me sleep ya weirdo):
Prerequisites
You will need a copy of ffmpeg and dvr-scan (which you’ll also need Python for). I’m running this on Windows and have my utils in my %path%
Before you go to sleep
- Change working dir to a new folder for each night
-
Start capturing RTSP stream into 5 minute long video files split using clocktime (so 1:00-1:05 etc). Each file is labeled
capture-xxxxx.mp4
where xxxxx is an incrementing 5 digit number.ffmpeg -i rtsp://user:pass@ip:port/11 -c:v copy -c:a mp2 -ar 44100 -aq 0 -ac 2 -map 0 -f segment -segment_atclocktime 1 -segment_time 300 -segment_format mp4 "capture-%05d.mp4"
The next morning
- Manually delete videos at the start and end that aren’t relevant (like reading in bed, getting out of bed etc)
-
Generate a file called
scan.txt
that contains the command for the next step that includes all remaining videos as parameterspowershell "'dvr-scan', (((Get-ChildItem capture*.mp4).name) -join ' -i ') -join ' -i ' | Set-Content scan.txt"
Example
scan.txt
content:dvr-scan -i capture-00009.mp4 -i capture-00010.mp4 -i capture-00011.mp4
- Open
scan.txt
and copy the contents into your clipboard - Run
dvr-scan
command using the contents of your clipboard.
This outputs one file per motion event, auto-naming all files using the filename of the first provided input file withDSME_xxxx
appended on the end eg.capture-00009.DSME_0000.avi
,capture-00009.DSME_0001.avi
etc.
NB. dvr-scan outputs .avi and my attempts at using -c to specify a different codec were unsuccessful - Manually delete videos of motion at the start and end that aren’t relevant
-
Output the filenames of videos of motion in the format that ffmpeg wants into a file called
files.txt
powershell "(Get-ChildItem *DSME* | ForEach-Object { 'file ''{0}''' -f $_.name }) | Set-Content files.txt"
Example
files.txt
content:file 'capture-00009.DSME_0000.avi' file 'capture-00009.DSME_0001.avi' file 'capture-00009.DSME_0002.avi'
-
Run
ffmpeg
to stitch the videos together at 20x speed (for 10x change0.05
to0.1
)ffmpeg -f concat -safe 0 -i files.txt -filter:v "setpts=0.05*PTS" output.avi
- Watch
output.avi
to see how badly you sleep