Most webcams today work after the USB Video Class (UVC) specification which is supported by the uvideo(4) device driver, which attaches to the video(4) device. The manpage is listing some supported devices, but there is a good chance that other devices work as well. For example webcams in Lenovo Thinkpads laptops do usually work.
A supported webcam (or other video device) shows up in dmesg like this:
uvideo0 at uhub0 port 8 configuration 1 interface 0 "Azurewave Integrated Camera" rev 2.01/69.05 addr 10 video0 at uvideo0 uvideo1 at uhub0 port 8 configuration 1 interface 2 "Azurewave Integrated Camera" rev 2.01/69.05 addr 10 video1 at uvideo1
You see that an uvideo device was detected and has been attached to video0. This device will be accessible through /dev/video0.
Modern laptops sometimes attach a second video device, which is the infrared camera for face recognition. The second camera does not produce a usable video stream.
You can find the usable camera with the video(1) command:
$ video -q -f /dev/video0
video device /dev/video0:
encodings: yuy2
frame sizes (width x height, in pixels) and rates (in frames per second):
320x180: 30
320x240: 30
352x288: 30
424x240: 30
640x360: 30
640x480: 30
848x480: 20
960x540: 15
1280x720: 10
controls: brightness, contrast, saturation, hue, gamma, sharpness, white_balance_temperature
$ video -q -f /dev/video1
video: /dev/video1 has no usable YUV encodings
The usable camera device shows supported resolutions and framerates. Note that the framerates only apply to the uncompresedYUY2 stream. More in that in "Recording a video".
To use the webcam as regular user, you need to change the device permissions accordingly.
One way of allowing your user to access the video devices is to change the permissions from .xsession and /etc/apm/resume.
~/.xsession: doas chown $user /dev/video0 /etc/apm/resume: chown $user /dev/video0
If you're not using xenodm(1) and you are starting your X session with startx(1), you can accomplish the same with fbtab(5).
/etc/fbtab: /dev/ttyC0 0600 /dev/video0
This section uses ffplay and ffmpeg from graphics/ffmpeg. To find out what your camera is capable of, run the following command:
$ ffplay -f v4l2 -list_formats all -i /dev/video0 [...] [video4linux2,v4l2 @ 0x921f8420800] Compressed: mjpeg : MJPEG : 1280x720 320x180 320x240 352x288 424x240 640x360 640x480 848x480 960x540 [video4linux2,v4l2 @ 0x921f8420800] Raw : yuyv422 : YUYV : 640x480 320x180 320x240 352x288 424x240 640x360 848x480 960x540 1280x720
The first line shows resolutions supported in the uncompressed YUYV format. The frame rates in this format can be very low.
The second line shows the supported MJPEG compressed video resolutions, which deliver much higher framerates (usually 30fps or 60fps).
Now try to play the webcam stream. Choose one of the MJPEG resolutions and run:
$ ffplay -f v4l2 -input_format mjpeg -video_size 1280x720 -i /dev/video0
[...]
Input #0, video4linux2,v4l2, from '/dev/video0':B sq= 0B f=0/0
Duration: N/A, start: 1599377893.546533, bitrate: N/A
Stream #0:0: Video: mjpeg (Baseline), yuvj422p(pc, bt470bg/unknown/unknown), 1280x720, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
The webcam stream should be displayed. Ffplay also shows the used resolution and the framerate (fps) used. If this works, you can go ahead and record the video with ffmpeg:
$ ffmpeg -f v4l2 -input_format mjpeg -video_size 1280x720 -i /dev/video0 ~/video.mkv
Webcams usually have brightness, contrast and other controls. Video(1) allows you to alter these settings. Find out which supported controls your camera has:
$ video -c brightness=128 contrast=32 saturation=64 hue=0 gamma=120 sharpness=3 white_balance_temperature=auto
You can change for example the brightness setting to 200:
$ video brightness=200 brightness: 128 -> 200
If you would like to reset all settings to their defaults, you can do so with
$ video -d $ video -c brightness=128 contrast=32 saturation=64 hue=0 gamma=120 sharpness=3 white_balance_temperature=auto
Some settings, like the "white_balance_temperature" support automatic adjustmens. You can set them to a fixed value or set them to "auto", which lets the camera decide and use whatever value it thinks is best.