Canon EOS M50 as Webcam with gPhoto and FFMPEG

Camera Mount

I have a Canon EOS M50 digital camera, and I just got a sweet VESA mount for it, so I wanted to use it as a webcam. This is partially because I assumed it would have very high picture quality, partly because I basically never use it, and partially because I know that it ought to be theoretically possible on my linux machine, since Canon makes a (closed source, paid) webcam utility for Mac and Windows, so I wanted to see how it would work on linux, if indeed it could.

It did not take long to find Video4Linux2 (a.k.a. “v4l2”) and gPhoto (gphoto2 in Aptitude), which can --capture-image or --capture-movie from a supported camera1 when attacked by USB. Best of all, you can --stdout it too, which means that movie can be piped into ffmpeg:

gphoto2 --stdout --capture-movie | ffmpeg -i - -vcodec rawvideo -pix_fmt yuv420p -threads 0 -f v4l2 /dev/videoX

Or, even better, if you have an Nvidia GPU that supports2 hardware acceleration for video transcoding:

gphoto2 --stdout --capture-movie | ffmpeg -hwaccel nvdec -c:v mjpeg_cuvid -i - -vcodec rawvideo -pix_fmt yuv420p -threads 0 -f v4l2 /dev/videoX

where X is the next available video device index (e.g. if you run ls /dev/video* and the highest value for X is 0, like /dev/video0, then you’ll use 1 in the command. If no video capture devices exist, use 0, as I’ll use hereafter).

You need first only install the relevant dependencies, sudo apt install gphoto2 v4l2loopback-utils, and load the v4l2loopback kernel module.

To confirm this is working, you can run ffplay /dev/video0 in another terminal–if your camera is on and your lens cover is removed, you should see a very happy person on your screen!

I also found some good tips for using gPhoto here, at the very end.

Let’s see if this works:

Command line output

All good so far…

ffplay test pass

Nice! Now let’s see if my video-conferencing apps will pick up the feed…

Signal video call test fail

$@&#!!!

So, this is where this Github issue comment came in to save my day:

modprobe v4l2loopback devices=1 max_buffers=2 exclusive_caps=1 card_label="VirtualCam"

In fact, modprobe v4l2loopback exclusive_caps=1 works just fine, so we know that was the missing piece. Indeed, this is covered in the Arch wiki on the topic. From the official documentation:

This will enable ’exclusive_caps’ mode that only reports CAPTURE/OUTPUT capabilities exclusively. The newly created device will announce OUTPUT capabilities only (so ordinary webcam applications (including Chrome) won’t see it). As soon as you have attached a producer to the device, it will start announcing CAPTURE capabilities only (so applications that refuse to open devices that have other capabilities apart from capturing can open it too.)

“caps” = capabilities.

Viola:

Signal video call test pass

Obviously, this wasn’t the craziest linux-y task, but I think it’s a good illustration of why its good to just try doing things, whether or not you think you need them and whether or not you even think they’ll work: you’ll learn something along the way. Generally, this looks like taking some kind of high-level abstraction, like “my camera can transmit live footage over a USB”, which you’ve used to deduce some other thing, like “I should be able to use such a video feed as a webcam”, and then turning it into some concrete understanding of a process, like “gPhoto can control my camera, initiating a movie capture to stdout, which ffmpeg can pick up and register as a video device at /dev/video0, using the v4l2 kernel module, as long as the reported capabilities match those expected by my application”. Often, this will even lend itself to a bunch of interesting follow-on research projects, like understanding the specific data type and procedure used by linux to transmit live video, how devices real and synthetic are mounted, or how hls works.


  1. You can actually check by just plugging in your particular camera and running gphoto2 --abilities ↩︎

  2. You can check with ffmpeg -hide_banner -decoders | grep mjpeg_cuvid ↩︎

Lane Russell

My personal weblog


I have a Canon EOS M50 digital camera, and I just got a sweet VESA mount for it, so I wanted to use it as a webcam

By Lane, 2024-02-25


On this page: