David Schlachter

Videoconferencing on FreeBSD

I've gone from doing two work videocalls per year in 2019, to roughly 15 hours per week in 2020. This has proved challenging on my FreeBSD desktop. This page describes different approaches for videoconferencing on FreeBSD, what I've found along the way and what's worked for me.

tl;dr: Virtualization and the Linux compatibility layer may work for you, but web clients are currently the easiest way to do a video call on FreeBSD.

Hardware

My setup consists of two webcams (internal webcam on Lenovo T480, Pixel 3a using DroidCam), an external soundcard, and a condenser microphone. The soundcard is supported natively, and the internal webcam works with webcamd.

Much better video quality is possible by using a phone camera, but DroidCam requires a video loopback device. DroidCam uses the v4l2loopback kernel module on Linux, which has not been ported to FreeBSD. So, despite DroidCam for Linux being open-source, the prospects of porting it, or any program using a non-local webcam, to FreeBSD are slim without v4l2loopback.

Virtualization and Linux compatibility layer

While there are no native videoconferencing applications on FreeBSD, you can run the native Linux versions (such as Zoom, Teams, and Skype) in a Linux virtual machine. VirtualBox can handle audio input/output, and you can also do this with bhyve (works very well). The main challenge is making the camera accessible to the VM.

VirtualBox on FreeBSD is limited to forwarding USB 1.1 devices to the VM. This may work for you if your webcam is very low-bandwidth. The advantage would be the ability to pass a single USB device to the VM.

If you're using bhyve, you can forward a USB controller to the VM using PCI passthrough. This may be impractical on a laptop, especially if you need to use any other USB devices simultaneously on the host (e.g. a keyboard). (Laptops usually only have one USB controller, so you would need to give control of all USB devices to the VM.) However, if you have a desktop machine that can accept a USB PCI card, this would be a very smooth solution to make a USB webcam available to the VM. (You may have trouble with suspend/resume though.)

An alternative to passing the webcam to the VM as a USB device is to pipe the video frames to a virtual device (using v4l2loopback) on the Linux guest. This allows you to use your internal or USB webcam without having to commit all USB devices to the VM. Be aware that the resolution of the built-in bhyve VNC server is limited to 1920x1080 (see man 8 bhyve) and only supports certain aspect ratios, which may disappoint you if you use a high-resolution monitor.

I've also succeeded in running the Zoom Linux client on FreeBSD using the Linux compatibility layer. This required installing maybe two dozen CentOS 7 libraries by hand from RPM files into /compat/linux. While I was able to run the Zoom client, sign in to the app, and start meetings, I was not able to use the camera or microphone. This would be a good solution if you could figure out the camera interface. This worked in the past with Skype so there may be some hope.

Web clients

Many video calling platforms have web clients that can be used on FreeBSD. Since implementing Audio Worklets in version 76, Firefox supports the Zoom web client. The Skype web client and Microsoft Teams only list compatibility for Chrome.

To use a web client, you'll need to set up the webcam on FreeBSD. Briefly: I installed webcamd, v4l-utils, and (just in case) libv4l. You'll want to check out man 8 webcamd and be sure to add your user to the webcamd group. You can test the webcam with pwcview. With all this, I'm able to use the webcam in both Firefox 79 and Chrome 83 installed with pkg (you can use a webcam testing website to verify). The microphone also works in Chrome without any extra configuration.

However, a bit of work is required to use the microphone in Firefox. Theoretically you can choose from multiple audio backends, but I was unable to set anything other than sndio in firefox-79.0,1. After installing sndio, you'll need to start its daemon, which you can do by simply running sndiod (use the -d flag to run it in the foreground). With the daemon running, I'm able to use the microphone in Firefox.