Video surveillance software recommendations

I'm looking for a no-frills simple CLI-only software (no GUI dependencies) to record video and audio feed from a USB camera connected to a FreeBSD box. Motion detection would also be good to have. Any recommendations?
 
Thanks! So I imagine I would need something like webcamd for ffmpeg, any sample ffmpeg strings to get started in that configuration to save time studying every ffmpeg option?

Zoneminder looks very interesting, but I couldn't find any mention in the docs about the supported video devices or what protocol they even use to communicate with cameras. Strange.
 
It's not FreeBSD but this is what I use for surveillance in my apartment:


It's a 1" square cop cam with motion detection and night vision that uses a 32GB max microSD card. It charges through a USB port and is good for a couple hours without being plugged into the USB port for power. You mount it with the card plugged in and view the .mov (?) files through multimedia/vlc.

I got mine in 2 days for $20 and it was $$$ well spent.
 
You'll need two things: a driver for your USB webcam, and a software to record video.

The driver depends on the kind of webcam you have. Many are supported by the multimedia/webcamd port, see HPS’ page here: http://www.selasky.org/hans_petter/video4bsd/ (although CUSE is now in FreeBSD's base system, so you don't need the cuse4bsd port anymore) This works with my Logitech C210 and C310 webcams, for example. Another possibility is the multimedia/pwcbsd port; this one works with my Philips SPC 900 NC.

For CLI-only software you can use multimedia/mencoder (be sure to enable the V4L option) or multimedia/ffmpeg (be sure to enable the V4L option, and disable all X11-related options: VAAPI, VDPAU, XCB, XVIDEO … I hope I didn't forget any). Basically, both mencoder and ffmpeg can do the same, but the latter has a lot more options, a plethora of filters and other things. No motion detection, though, as far as I know. Look at the ffmpeg-all(1) manual page – It is very extensive (nearly 30k lines!) and contains lots of examples.

If motion detection is your top priority, then multimedia/motion is probably for you. It doesn't really have lots of features, but does what the name implies, it's a CLI-only utility, and it can call ffmpeg in the background to encode the video. And then there is the multimedia/pwcview port that contains a CLI-only utility called pwcsnap that supports motion detection. However, it only writes single images (snapshots) to the disk, not video streams (and no audio). The port requires X11 for building because of the included pwcview program, but the pwcsnap utility is CLI-only.
 
All right, thank you guys for suggestions, but I'm still not sure where I should point mencoder and/or ffmpeg to record the video. What should be the name of the device? How do I call it in those programs? How would I know that the webcam is indeed detected by the driver? I have C310 and did cuse_load="YES" in loader.conf, but still not sure. I get uaudio entries in messages, but that's about that.

Also, what is the purpose of CUSE and webcamd? Each of those does what exactly?
 
It is fairly ad-hoc but motion detection can be added by using OpenCV, grab an image from the camera at the lowest resolution possible, add up the values of all the pixels and store it; do the same again (i.e 3 seconds later) and compare the value against the old value (with a threshold). If they are wildly different; start the ffmpeg recording (or record directly using the OpenCV capture).

It is possibly a bit hobbyist but works surprisingly well.

Edit: Just seen that this is similar to what multimedia/motion solves; motion is probably a bit better ;)
 
All right, thank you guys for suggestions, but I'm still not sure where I should point mencoder and/or ffmpeg to record the video. What should be the name of the device?
/dev/video0
How do I call it in those programs?
Read the documentation.
How would I know that the webcam is indeed detected by the driver? I have C310 and did cuse_load="YES" in loader.conf, but still not sure. I get uaudio entries in messages, but that's about that.

Also, what is the purpose of CUSE and webcamd? Each of those does what exactly?
CUSE is a library that allows drivers for character devices to run in userland, so they don't have to run inside the kernel. (Just like FUSE allows filesystem drivers to run in userland.)

CUSE is not a webcam driver itself. You'll need a driver such as webcamd that runs on top of CUSE. When you load it, it will print messages indicating whether it found your webcam. Also, it will create the /dev/video0 device node.
 
Should I build it with HAL and DBUS support for C310 to work? Right now I've built it with only "CUSE" and "WEBCAM" flags set. C310 isn't detected as far as I can see. I don't want to enable every option (or use the default set) there because it takes in a lot of dependencies I may not need.
 
Should I build it with HAL and DBUS support for C310 to work? Right now I've built it with only "CUSE" and "WEBCAM" flags set. C310 isn't detected as far as I can see. I don't want to enable every option (or use the default set) there because it takes in a lot of dependencies I may not need.
I've built it with options CUSE, WEBCAM and HAL enabled (but I'm not sure if HAL is really necessary). Make sure that the CUSE kernel module is loaded (type kldstat to check). Add a line webcamd_enable="yes" to /etc/rc.conf.

I've also added the following to /etc/devd.conf, but I think it should not be necessary anymore with the current version of the webcamd port. I think this was only a workaround for an older version of the port.
Code:
# 0x046d / 0x0819 = Logitech C210
# 0x046d / 0x081b = Logitech C310
attach 100 {
        match "vendor"  "0x046d";
        match "product" "0x081[9b]";
        action "/usr/local/etc/rc.d/webcamd start $cdev";
};
Be sure to restart devd: service devd restart
Then plug the webcam in. It should be recognized and webcamd should start.
 
I just checked with my Logitech C310 (had not used it in a while). It works fine with the current version of the multimedia/webcamd port, without any manual changes to devd.conf. So forget what I wrote above about adding to devd.conf; it's not necessary.

When you plug in the webcam, the webcamd process starts automatically and creates /dev/video0. You can then use mplayer, for example, to test if the webcam works:
Code:
mplayer -tv driver=v4l2 tv://
It'll open a window with the camera image inside. See the mplayer(1) manual page for more options that can be specified with -tv, for example:
Code:
mplayer -tv driver=v4l2:width=1280:height=960 tv://

If you still have any problems starting webcamd, please provide the output of webcamd -l.
 
I managed to get webcamd working, two questions, however:
1. When I do a very simple ffmpeg -i /dev/video0 it tells me that device/input resolution is 640x480. How can I get it to operate in 1280x720 mode? The video itself records fine, but the resolution is not at maximum.
2. How do I provide ffmpeg with audio source from the same camera? Messages log tells me that there are several devices at play, uaudioX and mixerZ amongst them. I can only see mixerZ in /dev, no pcm or uaudio entries. Mixer command sees the USB audio device just fine. So I'd like to know what device node I can use to capture audio and how to feed both the video and audio stream to ffmpeg in a single command.
 
I managed to get webcamd working, two questions, however:
1. When I do a very simple ffmpeg -i /dev/video0 it tells me that device/input resolution is 640x480. How can I get it to operate in 1280x720 mode? The video itself records fine, but the resolution is not at maximum.
2. How do I provide ffmpeg with audio source from the same camera? Messages log tells me that there are several devices at play, uaudioX and mixerZ amongst them. I can only see mixerZ in /dev, no pcm or uaudio entries. Mixer command sees the USB audio device just fine. So I'd like to know what device node I can use to capture audio and how to feed both the video and audio stream to ffmpeg in a single command.
Please refer to the ffmpeg documentation, especially the manual page ffmpeg-all(1). It answers all of those questions. In particular, the webcam resolution can be changed with the -video_size option. For audio recording the device /dev/dsp is used (unless you use ALSA or some other framework). There is even an example in the manual page for recording audio + video at the same time; it's actually quite simple. Note that /dev/dsp might be a symlink that points to the actual sound device. Type cat /dev/sndstat to see the list of available sound devices – if one of them is record-only (no playback), then that's probably your webcam's microphone. With sysctl hw.snd.verbose you can control the verbosity of /dev/sndstat; see the sound(4) manual page for details.
 
Unfortunately, I wasn't successful in either one.

Firstly, -video_size option doesn't seem to change the raw size of the stream. I.e. it appears the camera itself is operating in 640x480 mode by default and there's nothing ffmpeg can do about that, it simply reads the first frame of the stream and correctly guesses the resolution. If I understand things correctly, I'll have to send some kind of command to the camera itself to switch it to 1280x720 mode, something that may be handled by the driver. But I'm not sure how to do that. Or should I maybe switch to a different stream?

Code:
Input #0, video4linux2, v4l2, from '/dev/video0':
 Duration: N/A, start: 1568315158.632417, bitrate: 147456 jb/s
  Stream #0:0: Video: rawvideo (YUV2 / 0x32595559), yuyv422, 640x480, 147456 kb/s, 30 fps, 30 tbr, 1000k tbn, 1000k tbc

Second, I cannot find any /dev/pcm entries in my /dev tree. They are mentioned everywhere, but they just don't exist in /dev. Therefore I cannot point ffmpeg to anything. What may be going on there? Here's the output from mixer:

Code:
Installed devices:
pcm0: <ATI R6xx (HDMI)> (play)
pcm1: <ATI R6xx (HDMI)> (play)
pcm2: <ATI R6xx (HDMI)> (play)
pcm3: <ATI R6xx (HDMI)> (play)
pcm4: <ATI R6xx (HDMI)> (play)
pcm5: <ATI R6xx (HDMI)> (play)
pcm6: <Realtek ALC1220 (Rear Analog 5.1/2.0)> (play/rec) default
pcm7: <Realtek ALC1220 (Front Analog)> (play/rec)
pcm8: <Realtek ALC1220 (Rear Digital)> (play)
pcm9: <USB audio> (rec)
pcm10: <USB audio> (play/rec)
No devices installed from userspace.

Here are the relevant entries from the boot log:

Code:
uaudio1 on uhub0
uaudio1: <vendor 0x046d product 0x081b, class 239/2, rev 2.00/0.12, addr 1> on usbus0
uaudio1: No playback.
uaudio1: Record: 48000 Hz, 1 ch, 16-bit S-LE PCM format, 2x8ms buffer.
uaudio1: Record: 32000 Hz, 1 ch, 16-bit S-LE PCM format, 2x8ms buffer.
uaudio1: Record: 24000 Hz, 1 ch, 16-bit S-LE PCM format, 2x8ms buffer.
uaudio1: Record: 16000 Hz, 1 ch, 16-bit S-LE PCM format, 2x8ms buffer.
uaudio1: No MIDI sequencer.
pcm9: <USB audio> on uaudio1
uaudio1: No HID volume keys found.

and here's my entire /dev/ tree:

Code:
/dev
/dev/log
/dev/reroot
/dev/reroot/reroot
/dev/cuse
/dev/console
/dev/sndstat
/dev/random
/dev/urandom
/dev/devctl
/dev/devctl2
/dev/geom.ctl
/dev/mdctl
/dev/input
/dev/input/event0
/dev/input/event1
/dev/input/event2
/dev/input/event3
/dev/input/event4
/dev/input/event5
/dev/kbdmux0
/dev/kbd1
/dev/mem
/dev/kmem
/dev/netmap
/dev/full
/dev/null
/dev/zero
/dev/pci
/dev/fd
/dev/fd/0
/dev/fd/1
/dev/fd/2
/dev/stdin
/dev/stdout
/dev/stderr
/dev/nfslock
/dev/auditpipe
/dev/audit
/dev/midistat
/dev/sequencer0
/dev/music0
/dev/tcp_log
/dev/io
/dev/klog
/dev/uinput
/dev/ctty
/dev/consolectl
/dev/sysmouse
/dev/fido
/dev/bpf
/dev/bpf0
/dev/efi
/dev/acpi
/dev/apmctl
/dev/apm
/dev/hpet0
/dev/usb
/dev/usb/0.1.0
/dev/usb/1.1.0
/dev/usb/0.1.1
/dev/usb/1.1.1
/dev/usb/1.2.0
/dev/usb/1.2.1
/dev/usb/1.2.2
/dev/usb/1.2.3
/dev/usb/1.2.4
/dev/usb/1.2.5
/dev/usb/1.3.0
/dev/usb/0.2.0
/dev/usb/1.3.1
/dev/usb/0.2.1
/dev/usb/0.2.6
/dev/usb/0.2.7
/dev/usb/0.3.0
/dev/usb/0.3.1
/dev/usb/0.3.2
/dev/usb/0.3.3
/dev/usb/0.3.4
/dev/usb/1.4.0
/dev/usb/1.4.1
/dev/usb/1.4.2
/dev/usb/1.5.0
/dev/usb/1.5.1
/dev/usb/1.5.2
/dev/usb/1.5.3
/dev/usb/1.5.4
/dev/ugen0.1
/dev/ugen1.1
/dev/ttyu2
/dev/ttyu2.init
/dev/ttyu2.lock
/dev/cuau2
/dev/cuau2.init
/dev/cuau2.lock
/dev/ttyu3
/dev/ttyu3.init
/dev/ttyu3.lock
/dev/cuau3
/dev/cuau3.init
/dev/cuau3.lock
/dev/ttyu4
/dev/ttyu4.init
/dev/ttyu4.lock
/dev/cuau4
/dev/cuau4.init
/dev/cuau4.lock
/dev/ttyu5
/dev/ttyu5.init
/dev/ttyu5.lock
/dev/cuau5
/dev/cuau5.init
/dev/cuau5.lock
/dev/atkbd0
/dev/kbd0
/dev/ufssuspend
/dev/zfs
/dev/netdump
/dev/usbctl
/dev/xpt0
/dev/mixer0
/dev/mixer1
/dev/mixer2
/dev/mixer3
/dev/mixer4
/dev/mixer5
/dev/mixer6
/dev/mixer7
/dev/mixer8
/dev/devstat
/dev/ada0
/dev/ada0p1
/dev/ada0p2
/dev/pass0
/dev/pass1
/dev/pass2
/dev/pass3
/dev/ttyv0
/dev/ttyv1
/dev/ttyv2
/dev/ttyv3
/dev/ttyv4
/dev/ttyv5
/dev/ttyv6
/dev/ttyv7
/dev/ttyv8
/dev/ttyv9
/dev/ttyva
/dev/ttyvb
/dev/ada1
/dev/gpt
/dev/gpt/EFI%20System%20Partition
/dev/gpt/efiboot0
/dev/gpt/swap0
/dev/gpt/Titan
/dev/msdosfs
/dev/msdosfs/EFI
/dev/msdosfs/EFISYS
/dev/ada1p1
/dev/ada1p2
/dev/ada1p3
/dev/ada2
/dev/ada3
/dev/ada2p1
/dev/ada2p2
/dev/ada3p1
/dev/ada3p2
/dev/ugen1.2
/dev/ugen1.3
/dev/ugen0.2
/dev/ugen0.3
/dev/ugen1.4
/dev/ukbd0
/dev/kbd2
/dev/ugen1.5
/dev/ukbd1
/dev/kbd3
/dev/mixer9
/dev/umidi0.0
/dev/mixer10
/dev/uhid0
/dev/uhid1
/dev/uhid2
/dev/ums0
/dev/video0
/dev/video1
 
Firstly, -video_size option doesn't seem to change the raw size of the stream. I.e. it appears the camera itself is operating in 640x480 mode by default and there's nothing ffmpeg can do about that
Works fine for me. Would you please show the ffmpeg command that you used, exactly? I suspect maybe the order of options is wrong. Options that apply to a certain input must precede that input on the command line. The following command works fine for me and records 10 seconds of video at 1280×720:
Code:
ffmpeg -f video4linux2 -video_size hd720 -t 10 -i /dev/video0 test.mkv
...
Input #0, video4linux2,v4l2, from '/dev/video0':
  Duration: N/A, start: 1568548982.942126, bitrate: 147456 kb/s
    Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 1280x720, 147456 kb/s, 10 fps, 10 tbr, 1000k tbn, 1000k tbc

Second, I cannot find any /dev/pcm entries in my /dev tree.
As I said before, the devices are named /dev/dsp*, not /dev/pcm. Also, they are created on demand when they are opened by an application that uses the OSS interface, so you don't see them listed when you just do ls /dev without running an audio application.
On my machine, the output from cat /dev/sndstat looks like this (with sysctl hw.snd.verbose=0 which is the default):
Code:
pcm0: <NVIDIA (0x0081) (HDMI/DP 8ch)> (play)
pcm1: <NVIDIA (0x0081) (HDMI/DP 8ch)> (play)
pcm2: <Realtek ALC1220 (Analog 5.1+HP/2.0)> (play/rec) default
pcm3: <Realtek ALC1220 (Rear Digital)> (play)
pcm4: <Realtek ALC1220 (Front Analog Mic)> (rec)
pcm5: <USB audio> (rec)
The first two are the audio outputs of the HDMI connectors of my Nvidia card. These are playback-only.
The next three are the onboard audio connectors of my mainboard.
The last one is the microphone of my Logitech C310 webcam. This device is record-only, of course. It's listed with the driver instance pcm5, so the corresponding base device would be /dev/dsp5. See the sound(4) manual page for more information; it explains how all of that fits together.

I'm not using ffmpeg for recording audio, so I can't tell you the details here (but everything is usually very well documented in the various ffmpeg manual pages).
For recording audio I use sox(1) which works fine with my Logitech C310. For example, the following command records 10 seconds of audio:
Code:
AUDIODRIVER=oss AUDIODEV=/dev/dsp5 sox -d test.wav trim 0 10
 
Yes the order of options was wrong when I tried it, the moment I put video_size before the input, it started recording in the correct resolution. So that part is solved, even though I cannot understand the exact process involved in turning 720p images into 640x480 and vice versa. I.e. if we suppose that the raw stream *is* actually 720p then why would ffmpeg "guess" that it's 640x480? And similarly, how can it just take 720p stream and dump 640x480 stream out of it without processing.

But that's all theoretical and two issues still remain:

frame rate is not the camera's maximal and hovers around 5-6 fps. I know it can record 25fps perfectly fine. However just putting -r 25 before the -i doesn't make it switch to higher fps, instead I get the final video that runs too fast - simply making those 5 fps go like 25 fps.

I also cannot guess the correct audio format that the camera provides. Do you happen to know what it is? ffmpeg -formats gives out a lot of audio formats. I've tried a couple of PCM formats, 8 bit signed and 16 bit signed LE, both are not the correct ones for the camera - I do get the output but it's noise.
 
Looking at verbose /dev/sndstat output I can see it's PCM and there's a mention of "spd 48000", however the closest I got to normal audio is recording using u8 codec at 11050 khz. The audio is still wrong and is pitched up.
 
Yes the order of options was wrong when I tried it, the moment I put video_size before the input, it started recording in the correct resolution. So that part is solved, even though I cannot understand the exact process involved in turning 720p images into 640x480 and vice versa. I.e. if we suppose that the raw stream *is* actually 720p then why would ffmpeg "guess" that it's 640x480? And similarly, how can it just take 720p stream and dump 640x480 stream out of it without processing.
Well, ffmpeg doesn't guess anything. It just takes what the camera delivers (via the V4L2 API). Obviously, by default the camera delivers a 480p stream. When you use the -video_size option, ffmpeg uses a V4L2 function to send a command to the camera to change the resolution of the stream that the camera sends.
(By the way, the C310 has a 1.2MP CMOS sensor with a native resolution of 1280×960 pixels.)
frame rate is not the camera's maximal and hovers around 5-6 fps. I know it can record 25fps perfectly fine. However just putting -r 25 before the -i doesn't make it switch to higher fps, instead I get the final video that runs too fast - simply making those 5 fps go like 25 fps.
Please use -framerate, not -r. The difference is explained in the manual page.

By the way, the C310 supports 30 fps only at 480p. At 720p it is considerably less – I think 10 fps or similar, I'm not sure. I used it only for Skype (back when it was still in the Ports Collection), so I didn't care much. USB 2.0 doesn't have enough bandwidth for 720p at 30 fps without compression.

I also cannot guess the correct audio format that the camera provides. Do you happen to know what it is? ffmpeg -formats gives out a lot of audio formats. I've tried a couple of PCM formats, 8 bit signed and 16 bit signed LE, both are not the correct ones for the camera - I do get the output but it's noise.
I'm sorry, I haven't tried recording audio from the webcam with ffmpeg yet. When using sox(1), it works out of the box, without having to specify anything (except for the device, of course). I think it reports the audio as 48 kHz 16bit signed PCM.
I don't remember whether it's little-endian or big-endian. But you can simply try both – If the endianness is wrong, you get white noise.
 
Back
Top