What ffmpeg settings to get the best possible video resolution/framerate that my webcam is capable of?
I want to record the best possible video file (in terms of resolution/framerate/colors) from my webcam.
Right now I am using this command:
ffmpeg -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video0 output.mkv
My webcam seems to support this:
$ ffmpeg -f v4l2 -list_formats all -i /dev/video0
…
[video4linux2,v4l2 @ 0xf07d80] Raw : yuyv422 : YUV 4:2:2 (YUYV) : 640x480 160x120 176x144 320x176 320x240 352x288 432x240 544x288 640x360
[video4linux2,v4l2 @ 0xf07d80] Compressed: mjpeg : MJPEG : 640x480 160x120 176x144 320x176 320x240 352x288 432x240 544x288 640x360
I guess I got the resolution part, but how can I improve my command line to:
- Use no compression (I suspect the current .mkv output is compressed)
- Use the best framerate that the camera&computer is capable of, without duplicating frames either (no point saving the file at 100 fps if the webcam is not capable of capturing frames at that rate)
- All ideas to further improve the video quality are welcome
Do you really want no compression? Uncompressed video would be very large. Or do you want no transcoding? Or lossless?
No compression can be achieved as mentioned at https://superuser.com/a/1302502/128124
First determine your available formats with:
v4l2-ctl --list-formats-ext
as mentioned at: How can I list the available video modes for a USB webcam in Linux?
The highest ones for me are:
[0]: 'YUYV' (YUYV 4:2:2)
Size: Discrete 1280x720
Interval: Discrete 0.100s (10.000 fps)
[1]: 'MJPG' (Motion-JPEG, compressed)
Size: Discrete 1280x720
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.067s (15.000 fps)
You can then also check:
ffmpeg -f v4l2 -list_formats all -i /dev/video0
which contains for my device:
video4linux2,v4l2 @ 0x5579b13df240] Raw : yuyv422 : YUYV 4:2:2 : 640x480 320x180 320x240 352x288 424x240 640x360 848x480 960x540 1280x720
[video4linux2,v4l2 @ 0x5579b13df240] Compressed: mjpeg : Motion-JPEG : 640x480 320x180 320x240 352x288 424x240 640x360 848x480 960x540 1280x720
Then, If I record two 3.5 second very similar video of my making faces on the setup described at https://askubuntu.com/questions/348838/how-to-check-available-webcams-from-the-command-line/848390#848390 rev 18 with:
ffmpeg -y -f v4l2 -framerate 30 -video_size 1280x720 -input_format mjpeg -i /dev/video0 -c copy out.mjpeg.mkv
ffmpeg -y -f v4l2 -framerate 30 -video_size 1280x720 -input_format yuyv422 -i /dev/video0 -c copy out.yuyv422.mkv
the sizes are about:
- 15MB
- 60MB
and ffprobe
confirms respectively:
Stream #0:0: Video: mjpeg (Baseline), yuvj422p(pc, bt470bg/unknown/unknown), 1280x720, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)
Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 1280x720, 10 fps, 10 tbr, 1k tbn, 1k tbc (default)
Lossless is discussed at:
- Lossless universal video format
- https://stackoverflow.com/questions/11713882/lossless-ffmpeg-conversion-encoding
- https://video.stackexchange.com/questions/7903/how-to-losslessly-encode-a-jpg-image-sequence-to-a-video-in-ffmpeg
Tested on Ubuntu 20.04, Lenovo ThinkPad P51.