Automatically disable your internal webcam on Linux
A while ago I bought an external webcam with better image quality than the one built into my laptop. However, when I wanted to use it on my Linux system, I faced an unexpected problem. Not all programs or web sites allowed me to choose which webcam to use. And even worse: the ones that didn't give me the choice automatically chose the first available webcam device, /dev/video0
, which is of course the internal webcam.
Luckily there's a solution for everything in Linux. I just had to find a way to disable the internal webcam. My idea was that the external webcam would then become the first available webcam device and this would then be chosen automatically.
So I first looked at the product information of all connected USB devices:
$ for device in $(ls /sys/bus/usb/devices/*/product); do echo $device;cat $device;done /sys/bus/usb/devices/1-1/product HD Pro Webcam C920 /sys/bus/usb/devices/1-7/product Chicony USB2.0 Camera /sys/bus/usb/devices/usb1/product xHCI Host Controller /sys/bus/usb/devices/usb2/product xHCI Host Controller
As you see, the first two devices are webcams. The HD Pro Webcam C920 is the external one, while the Chicony USB2.0 Camera is the internal one. I wanted to disable the latter. The file with the product information for this webcam is /sys/bus/usb/devices/1-7/product
, and I needed the code 1-7
in its path. This means that the device is connected on USB bus 1 port 7.
With this information I could send a command to the USB driver to unbind the port:
After this, the internal webcam isn't found anymore by software or web sites. If I connect the external webcam after this command, it gets assigned /dev/video0
as the device file.
Re-enabling the internal webcam is easy too:
This is the same command as the previous one, but with bind
instead of unbind
in the path.
To make this easier to remember, I created a small shell script, webcam.sh
:
#!/bin/sh device="1-7" status=$1 case $status in enable) driver_command="bind";; disable) driver_command="unbind";; *) exit 1;; esac echo $device | sudo tee /sys/bus/usb/drivers/usb/$driver_command
After making it executable with chmod +x webcam.sh
, I could just run webcam.sh disable
before connecting the external webcam every time I wanted to use it. And after disconnecting the external webcam, I could always re-enable the internal webcam with webcam.sh enable
, but I never bothered with it.
I used the script for a while like this, until I realized I could even run this script automatically every time I connected or disconnected the external webcam, thanks to a udev rule.
So I added the following udev rule to /etc/udev/rules.d/99-disable-internal-webcam.rules
:
SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="46d/8e5/c", RUN+="/home/koan/webcam.sh disable" SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="46d/8e5/c", RUN+="/home/koan/webcam.sh enable"
I found the correct value for ENV{PRODUCT}
in the output of udevadm monitor --kernel --property --subsystem-match=usb
while connecting or disconnecting the external webcam.
So now I never have to bother with disabling, enabling or choosing a webcam device. If my external webcam isn't connected, all software chooses the internal webcam. As soon as I connect the external webcam, the software chooses this one. And as soon as I disconnect the external webcam, the software chooses the internal webcam again.