Extracting a Full Day’s Video from UniFi NVR
There are plenty of people looking to extract full-length video from their UniFi Protect instances, either for archival purposes, or (as in my case) to create full and multi-day timelapse videos. The iOS app and the web app both allow limited download of video, but the interface to define your clips is clumsy at best, crashy at worst, and in my experience extracting an entire day seems to fail more often than it succeeds. Given these limitations, I went looking for a more robust way to dump video from the devices – read on for my findings.
I run the UniFi Network Video Recorder, but I suspect these steps apply to the Pro and possibly to other related devices that run the Protect software.
As with all things unsupported by Ubiquiti, we start with SSH. You’ll need to get the SSH password (which you can reset in Settings → Advanced) and log on to the devices as root.
Video is stored in /srv/unifi-protect/video
in subdirectories by YYYY/MM/DD/
with .ubv
files named by the camera’s MAC address.
Some parts of that filename are self-evident, others I’ve taken a best guess:
MAC address [rotating|timelapse]
| |
B4FBE47EEF30_0_rotating_1642378105047.ubv
| |
Quality Start time in unix epoch time
On my system, the number I’ve labelled quality
seems to represents either the highest quality feed (0) or a lower quality (2) about half the resolution – maybe for scrubbing in the phone apps?
I’ve seen just two values so far in the third position: rotating
and timelapse
. Files with rotating
are part of the standard recordings that get purged based on time/disk space, while the timelapse
ones seem to be ones created by the system when generating exports in the UI.
Knowing where the files are, we now need to get them off the NVR, or at least get them accessible from another machine.
First, I enabled Samba on the NVR and shared the /srv/unifi-protect/video
directory. I did this an incredibly lazy way by enabling a guest user to see the directory. Please adjust settings according to your own risk profile.
Changes to my /etc/samba/smb.conf
Under [global]
map to guest = Bad User
And then create this block at the bottom:
[video]
path = /srv/unifi-protect/video
browsable = yes
guest ok = yes
And restart samba:
sudo systemctl restart smbd.service nmbd.service
You’ll be able to see the files from across the network:
Sadly, this doesn’t help, because as far as I can tell nothing outside of an NVR knows how to process the .ubv
file.
(At least neither ffprobe and VLC could do anything with it.)
So with that dead end reached, I tried the next obvious thing: the NVR itself must have a way to convert .ubv
to .mp4
, since the UI and the iOS apps do it when you export clips. And knowing how Ubiquiti build their systems, it’s almost certainly a separate component called by the main service.
Running ps -aux
shows the list of processes on the NVR, one of which is:
/usr/share/unifi-protect/app/node_modules/.bin/ubnt_avcodec_service
A quick search of the directory containing that binary shows a few other likely targets:
That ubnt_ubvexport
binary looks promising, let’s see what it can tell us:
Result! Exactly what we need – it’ll even take multiple inputs and stitch them into a single .mp4
.
Rather than write the .mp4
back to the NVR, I want to have the NVR push the files across to another machine on my network, so let’s install smbclient
and connect.
First, install:
sudo apt install smbclient
Create a directory to mount the share on:
sudo mkdir /mnt/video
Then mount a share on another (in my case, Windows) PC. Replace the username, server, share and (if you didn’t copy me) the mount point:
sudo mount.cifs -o sec=ntlmssp,username=USERNAME //PC_NAME/SHARE /mnt/video
And finally, choose a file to test:
cd /srv/unifi-protect/video
Within that directory, find a file to export, and within the same directory, run:
/usr/share/unifi-protect/app/node_modules/.bin/ubnt_ubvexport -s MACADDRESS_0_rotating_1642402659065.ubv -d /mnt/video/PREFIX
Change PREFIX
to set the prefix for the filename(s) generated in the output.
We can pass multiple -s arguments to have the files combined into a single .mp4, so to get the list of files within a directory for a single day:
for i in ls MACADDRESS_0*; do echo -n "-s $i "; done
You can find the MAC address of your cameras by checking in the UI under camera settings. The 0 for me means I get the higher quality stream, your mileage may vary.
The output of that command will be a list of arguments you can copy and paste into the command from before:
/usr/share/unifi-protect/app/node_modules/.bin/ubnt_ubvexport [big long list of -s arguments] -d /mnt/video/ubnt/PREFIX
That’ll take a little while, and then spit out a few massive files – in my case, between two and four files in high quality, plus another two in the lower quality. You get roughly 12 hours of the day in each of the main files at about 12GB each.
My next step is to take those files and sample a few frames per minute to create a timelapse. My experiments with ffmpeg
have proven quite slow, so I’m looking for a faster way to do this. Pointers welcome!
Enjoy Reading This Article?
Here are some more articles you might like to read next: