Skip to content

Instantly share code, notes, and snippets.

@Sopamo
Last active June 12, 2024 07:10
Show Gist options
  • Save Sopamo/e3c0f714432659171074dc3e78e254ec to your computer and use it in GitHub Desktop.
Save Sopamo/e3c0f714432659171074dc3e78e254ec to your computer and use it in GitHub Desktop.
Use your dslr as webcam on linux

How to use your DSLR as a webcam on linux

This will automatically start your webcam once you connect it to your computer.

1. Follow this article to setup your webcam

DSLR Webcam setup for linux

2. Install gstreamer

Installation instructions

3. Create a bash file in /usr/bin/dslrwebcam.sh which starts the webcam

#!/bin/bash

printf "\n\n\n######### Set the camera to video mode and manual ##########\n\n\n"

# Unmount the camera
# sudo killall gvfs-gphoto2-volume-monitor
# Since ubuntu 22.04 we need to restart all of gvfsd to properly unmount the camera
sudo pkill -e -HUP gvfsd

# Set the aperture setting you want
# To get available settings, run gphoto2 --get-config aperture
gphoto2 --set-config-value aperture=1

# Start video capture
gphoto2 --stdout --capture-movie | ffmpeg -i - -vcodec rawvideo -pix_fmt yuv420p -threads 4 -f v4l2 /dev/video0

## Instead of using ffmpeg you could also use gst-launch-1.0, but that doesn't work for me anymore on ubuntu 21.10
# gphoto2 --stdout --capture-movie | gst-launch-1.0 fdsrc fd=0 ! decodebin name=dec ! queue ! videoconvert ! tee ! v4l2sink device=/dev/video0

4. Make the file executable

chmod +x /usr/bin/dslrwebcam.sh

5. Install required python dependencies

sudo pip3 install pyudev

6. Create a python file in /usr/bin/monitor-webcam.py to automatically start the webcam once it becomes available:

#!/usr/bin/env python3

import pyudev
import subprocess
import os

def get_product_name(path):
    product_name_path = os.path.join(path, "product")
    if os.path.exists(product_name_path):
        with open(product_name_path, 'r') as file:
            content = file.read().strip()
        return content
    else:
        return None

def main():
    context = pyudev.Context()
    monitor = pyudev.Monitor.from_netlink(context)
    monitor.filter_by(subsystem='usb')
    monitor.start()

    for device in iter(monitor.poll, None):
        # ----------------------------------------------------------------------
        # -- Replace the following product name with the name of your camera. --
        # ----------------------------------------------------------------------
        # You can find out the path by commenting in the following line and running this command manually
        print(device.sys_path)
        print(device.action)
        print(get_product_name(device.sys_path))
        if device.action == "add" and get_product_name(device.sys_path) == "Canon Digital Camera":
          print("starting")
          subprocess.call(['/usr/bin/dslrwebcam'])

if __name__ == '__main__':
    main()

7. Make the python script executable

chmod +x /usr/bin/monitor-webcam.py

7.1 Update the name of your camera

sudo python3 /usr/bin/monitor-webcam.py
  • Start your camera
  • Check the name of your camera in the script output
  • Update the script to check for this name instead of "Canon Digital Camera".

8. Create a service file in /etc/systemd/system/dslr-webcam-monitor.service which runs the monitor script on startup

[Unit]
Description=Start the dslr webcam monitor

[Service]
Type=oneshot
ExecStart=python3 /usr/bin/monitor-webcam.py

[Install]
WantedBy=multi-user.target

9. Enable and start the new service

systemctl enable dslr-webcam-monitor.service
systemctl start dslr-webcam-monitor.service

10. Profit :)

All you have to do now is plug in and turn on your dslr camera to make it available as a webcam.

@dimarkov
Copy link

Thanks for the instructions. This works great. I have a short comment regarding the 'print(device.sys_path)' for figuring out the path --- one needs to switch the device off or on, to see the path. Maybe the code has to be changed to the following:

if device.sys_path == "/sys/devices/yourpath" and device.action == "add":
          print("starting")
          ...

otherwise the script will be executed also when one switches off the camera.

@milovangudelj
Copy link

Any idea as to why I get the following error message when trying to use hardware acceleration?

[mjpeg_cuvid @ 0x559982208080] No device available for decoder: device type cuda needed for codec mjpeg_cuvid.

even though when running ffmpeg -hide_banner -decoders | grep cuvid I get

 V..... av1_cuvid            Nvidia CUVID AV1 decoder (codec av1)
 V..... h264_cuvid           Nvidia CUVID H264 decoder (codec h264)
 V..... hevc_cuvid           Nvidia CUVID HEVC decoder (codec hevc)
 V..... mjpeg_cuvid          Nvidia CUVID MJPEG decoder (codec mjpeg)
 V..... mpeg1_cuvid          Nvidia CUVID MPEG1VIDEO decoder (codec mpeg1video)
 V..... mpeg2_cuvid          Nvidia CUVID MPEG2VIDEO decoder (codec mpeg2video)
 V..... mpeg4_cuvid          Nvidia CUVID MPEG4 decoder (codec mpeg4)
 V..... vc1_cuvid            Nvidia CUVID VC1 decoder (codec vc1)
 V..... vp8_cuvid            Nvidia CUVID VP8 decoder (codec vp8)
 V..... vp9_cuvid            Nvidia CUVID VP9 decoder (codec vp9)

I'm on Fedora 34 and I use an HP 250 G6 with an Intel Corporation HD Graphics 620 (rev 02) integrated graphics card.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment