Jan Grulich

How to use PipeWire camera in Firefox

I decided to write a post about how to use the PipeWire camera support in Firefox, how to enable it, how to check if it’s working and how to debug possible problems.

Prerequsities

To use PipeWire camera support, you need Firefox 116 or newer. However, the latest Firefox 122 includes major PipeWire camera changes, making it actually usable (you can read about it in my previous blog post).The PipeWire camera is not enabled by default. To enable it, go to “about:config” in your address bar, find the “media.webrtc.camera.allow-pipewire” option, and enable it. Afterward, restart Firefox.

Using PipeWire camera in Firefox

When using the PipeWire camera, you should not notice any difference compared to using V4L2. The only change is that you will receive an additional system dialog from xdg-desktop-portal asking for camera access, which is a one-time occurrence. Your cameras will have ‘(V4L2)’ in their name if no libcamera is involved (more on that later). This indicates that they are using V4L2 through PipeWire. To check if PipeWire is being used, you can also use an application like Helvum to check if your camera is detected and used through PipeWire. Below, you can see what Helvum graphs look like when using my camera with PipeWire:

To verify that your camera is detected by PipeWire, you can use Helvum alone, without Firefox. This way, your camera on the left side will just not be connected to any client on the right side.

PipeWire camera is not working

1) I don’t get any system dialog or Firefox says access to the camera has been rejected

If your camera is visible in Helvum, then PipeWire can detect it. First, verify that you have not previously denied access to the camera or accidentally clicked “do not allow” when prompted. To do this, reset the permissions by running “flatpak permission-remove devices camera” to ensure you will get asked again. In case you still don’t get prompted, make sure xdg-desktop-portal is installed and running, as well as either xdg-desktop-portal-gnome or xdg-desktop-portal-kde. Note that for example xdg-desktop-portal-wlr doesn’t support camera portal, which is essential for this to work. You can also restart xdg-desktop-portal with “G_MESSAGES_DEBUG=ALL” env variable set to further debug issues with xdg-desktop-portal.

2) Camera is not working in general or once selected and allowed to be used

In this case best thing you can do is to open a bug, while providing information about your camera hardware and including output from Firefox you run with PIPEWIRE_DEBUG=5 MOZ_LOG="MediaManager:5,CamerasParent:5,CamerasChild:5,VideoEngine:5". Since it might be a missing format we (WebRTC) don’t support yet or issue in V4L2 integration or you having some modern camera that doesn’t work yet very well on Linux (e.g. Intel MIPI camera).

3) Google Meet doesn’t work

This is a known issue and actually a problem in Google Meet that stopped working after some recent update. There is an upstream ticket in Firefox to track this problem, but sadly hasn’t been resolved yet. To workaround this issue, visit any testing camera page (e.g. this one) first, and then use Google Meet.

4) Firefox crashes when sharing my camera with two websites

Also a known issue. Here is an upstream WebRTC ticket and I have a change already submitted for review. This change will be backported to Firefox as soon as it’s merged in WebRTC upstream.

5) Any other issue

Please, let me know with any other issue you have. Best thing you can do is to open a bug report to Firefox, where you pick “WebRTC: Audio/Video” as a component.

Using libcamera

For some modern cameras, this may be the only way to make them work in Firefox. This is not a comprehensive guide on how to use it, but it is what made it work in my setup on Fedora.

1) Install libcamera and libcamera plugin for PipeWire. On Fedora you can run:
sudo dnf install libcamera pipewire-plugin-libcamera

2) Restart PipeWire and Wireplumber (PipeWire session manager) by running:
systemctl --user stop wireplumber
systemctl --user stop pipewire
systemctl --user start wireplumber

You should see something like:
led 30 15:30:43 fedora wireplumber[91582]: [2:36:44.619446407] [91582]  INFO Camera camera_manager.cpp:284 libcamera v0.2.0
Compared to following output while not having the plugin installed:
led 30 12:54:29 fedora wireplumber[1925]: SPA handle 'api.libcamera.enum.manager' could not be loaded; is it installed?
led 30 12:54:29 fedora wireplumber[1925]: PipeWire's libcamera SPA missing or broken. libcamera not supported.

3) Check your camera in Helvum

In the screenshot above, my cameras are presented twice: once through the V4L2 integration in PipeWire and again thanks to libcamera. Unfortunately, I don’t know yet how to disable the V4L2 integration when using libcamera so that your cameras are not shown twice.

Anything else?

Currently, I am working on implementing a fallback mechanism to use V4L2 if PipeWire fails in certain scenarios (upstream bug | upstream change) to ensure that users still have a functioning camera in the case of a broken PipeWire/portal setup. However, I expect that many issues will be discovered as people begin to test this feature, for which I am very grateful.

PipeWire Camera Support in Firefox #2

I wrote the first blog post about PipeWire cameras in Firefox in May and a lot has happened since then. The first PipeWire support arrived shortly after the blog post was published and was released as part of Firefox 116 (August). We didn’t enable it by default, of course since it’s still a “work in progress”, but many of you tried it (thank you for that) and we were able to fix some issues that I, as the only tester at the time, hadn’t found. However, aside from all the crashes and minor issues we were able to fix relatively quickly, there was one major problem (or drawback) with the PipeWire camera that made it unusable with most popular video conferencing sites, such as Google Meet. Kind of a deal breaker, right? This has kept me busy ever since, but we are finally close to fixing it in upstream. I’m going to explain why this was a problem and how we fixed it, and forgive me in advance if I write anything wrong, I’m still learning and discovering things as they unfold.

There are Javascript APIs that are implemented by all the major browsers. The API documentation is here. It defines APIs sites can use to query information about media devices. I will now describe a simplified workflow used with V4L2 on the aforementioned Google Meet once you start a meeting:

  • GMeet makes enumerateDevices() call to get information about available devices
  • Firefox can respond with the list of available cameras (+ audio devices obviously) on the system because the information about cameras is available and no permission is needed
  • GMeet makes getUserMedia() call to get access to the camera since it knows there is a camera available
  • Firefox will prompt the user to get access to the selected devices (including camera) and start streaming

Now the same situation, but with PipeWire:

  • GMeet makes enumerateDevices() call to get information about available devices
  • Firefox cannot respond with the list of available cameras because this enumeration request cannot ask for user permission and we cannot access PipeWire without it. Firefox will return an empty list of camera devices and there will be only audio devices announced
  • GMeet makes getUserMedia() call, but only to get access to the devices that were previously announced, so only audio devices
  • Firefox will prompt the user to get access only to the selected audio devices and no camera

How did we solve this?

The documentation here also covers this situation. The enumerateDevices() request is allowed to return a placeholder device for each type. This means that we can return a placeholder camera device, which tells Google Meet there is actually a camera device to ask for. With this device placeholder, the subsequent getUserMedia() request will also request access to camera devices. How do we know that a camera device is present without having access to PipeWire, you ask? The camera portal from xdg-desktop-portal has a IsCameraPresent property for exactly the same purpose and we use it to know whether to insert the camera device placeholder or not.

While such a solution sounds simple on paper, it required a significant amount of changes to the entire media handling stack. There is not a small amount of PipeWire specific code, so this fix also involves some restructuring so that all the backend specific logic is in one place. And while I’m getting more and more familiar with the Firefox code, which is helping me to progress faster, there’s still a lot to learn.

Anyway, the reason I’m writing this blog post now is that all the related changes have been approved and will hopefully be landing soon, making Firefox fully usable with PipeWire . Although not yet merged, Fedora users can use a COPR repository I created. The repository has Fedora Firefox builds with all the necessary changes backported and PipeWire camera enabled by default. Just note that while I’ve been testing and using it for the past few months and it’s worked perfectly for me, you use it at your own risk. You better to use it just to test PipeWire camera support as the official Fedora Firefox package is the one we keep fully updated and my repo may lag behind. There will be a new PipeWire 1.0 release soon, which will be a big milestone for PipeWire and I hope that PipeWire camera support in Firefox and browsers in general will be part of the PipeWire success story.

Scroll To Top