How to check available webcams from the command line?

v4l2-ctl --list-devices

sudo apt-get install v4l-utils
v4l2-ctl --list-devices

Sample output with a single camera:

Integrated Camera (usb-0000:00:1a.0-1.6):
        /dev/video0

Tested on Ubuntu 16.04.

video1 metadata device

On Ubuntu 19.10 Lenovo Thinkpad P51 however, it lists two such devices, video0 and video1, but I only have one camera, and can only see images from video0 with ffplay. This has been asked at:

  • Four /dev/video entries but just one camera
  • https://unix.stackexchange.com/questions/512759/multiple-dev-video-for-one-physical-device

What happens is that /dev/video1 contains some kind of video metadata only and not the images as can been seen from:

sudo v4l2-ctl --device=/dev/video0 --all
sudo v4l2-ctl --device=/dev/video1 --all

which shows respectively:

        Device Caps      : 0x04200001
                Video Capture 

        Device Caps      : 0x04a00000
                Metadata Capture

How to see the camera image live

  • https://unix.stackexchange.com/questions/3304/how-do-i-watch-my-webcams-feed-in-linux
  • What webcam apps are available and how to check if your webcam is working?

My favorite:

sudo apt install ffmpeg
ffplay /dev/video0

enter image description here

Take a single picture from the command line

Take a picture from terminal

ffmpeg -f v4l2 -video_size 1280x720 -i /dev/video0 -frames 1 out.jpg

Record a video from the command line

  • Webcam video recorder
  • capturing video from webcam and saving to a file
  • Anything better than Cheese for video capture?

Parameters chosen based on "How to get camera parameters like resolution" below:

ffmpeg -f v4l2 -framerate 30 -video_size 1280x720 -input_format mjpeg -i /dev/video0 -c copy out.mkv

Then:

ffprobe out.mkv

contains as expected:

Stream #0:0: Video: mjpeg (Baseline), yuvj422p(pc, bt470bg/unknown/unknown), 1280x720, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)

If you choose wrong parameters, the resolution might be slow. The camera already outputs a specific encoded format, and the simplest way to record is to just copy that format as above:

  • https://stackoverflow.com/questions/47292785/recording-from-webcam-using-ffmpeg-at-high-framerate
  • https://superuser.com/questions/1021899/what-ffmpeg-settings-to-get-the-best-possible-video-resolution-framerate-that-my

TODO If I replace -c copy out.mkv with out.ogv to try and record directly to an open format (unlike MJPEG), I got a low resolution video.

Interactive image/video capture with preview

Picture/Video capture programs

Until I learn how to run ffplay preview on one shell and capture at the same time from another shell with ffmpeg (they fight over the video device), I'll have to lower myself to this amazing GUI program:

sudo apt install cheese

enter image description here

Read camera data from C/C++

https://stackoverflow.com/questions/4290834/how-to-get-a-list-of-video-capture-devices-web-cameras-on-linux-ubuntu-c

A concrete C++ example that processes images from the camera on the GPU with OpenGL and shows it live: https://stackoverflow.com/questions/13693946/image-processing-with-glsl-shaders/40641014#40641014

enter image description here

How to get camera parameters like resolution

  • How can I find out the supported webcam resolutions?
  • https://superuser.com/questions/639738/how-can-i-list-the-available-video-modes-for-a-usb-webcam-in-linux
v4l2-ctl --list-formats-ext

produces some good information:

ioctl: VIDIOC_ENUM_FMT
    Type: Video Capture

    [0]: 'YUYV' (YUYV 4:2:2)
        Size: Discrete 640x480
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
        Size: Discrete 320x180
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
        Size: Discrete 320x240
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
        Size: Discrete 352x288
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
        Size: Discrete 424x240
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
        Size: Discrete 640x360
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
        Size: Discrete 848x480
            Interval: Discrete 0.050s (20.000 fps)
        Size: Discrete 960x540
            Interval: Discrete 0.067s (15.000 fps)
        Size: Discrete 1280x720
            Interval: Discrete 0.100s (10.000 fps)
    [1]: 'MJPG' (Motion-JPEG, compressed)
        Size: Discrete 640x480
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
        Size: Discrete 320x180
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
        Size: Discrete 320x240
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
        Size: Discrete 352x288
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
        Size: Discrete 424x240
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
        Size: Discrete 640x360
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
        Size: Discrete 848x480
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
        Size: Discrete 960x540
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
        Size: Discrete 1280x720
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.067s (15.000 fps)

How to get the corresponding ffmpeg encodings

v4l2-ctl --list-formats-ext gives the Linux kernel name of things, e.g . YUYV 4:2:2. But to do stuff with ffmpeg, you need to know the ffmpeg nama sometimes. You can do it like this:

ffmpeg -f v4l2 -list_formats all -i /dev/video0

sample output:

[video4linux2,v4l2 @ 0x555ba7267240] Raw       :     yuyv422 :           YUYV 4:2:2 : 640x480 320x180 320x240 352x288 424x240 640x360 848x480 960x540 1280x720
[video4linux2,v4l2 @ 0x555ba7267240] Compressed:       mjpeg :          Motion-JPEG : 640x480 320x180 320x240 352x288 424x240 640x360 848x480 960x540 1280x720

This for example told us that the ffmpeg name for YUYV 4:2:2 is yuyv422.


To list all video devices picked up by the kernel

ls -ltrh /dev/video*

To list all devices attached to USB use lsusb ; to list all devices attached to PCI use lspci