Disable your interval 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 Ubuntu 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 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 /dev/video0 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:

$ echo '1-7' | sudo tee /sys/bus/usb/drivers/usb/unbind

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:

$ echo '1-7' | sudo tee /sys/bus/usb/drivers/usb/bind

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

So every time I want to use the external webcam, I run webcam.sh disable before connecting the external webcam. After disconnecting the external webcam I can always re-enable the internal webcam with webcam.sh enable, but I never bothered with it.