WirePlumber - ArchWiki

Jump to content

# WirePlumber

2 languages

- 日本語
- Русский

From ArchWiki

Related articles

- PipeWire

WirePlumber is a powerful session and policy manager for PipeWire. Based on a modular design, with Lua plugins that implement the actual management functionality, it is highly configurable and extendable.

## Installation

Install the wireplumber package. Any conflicting PipeWire Session Managers will be uninstalled.

WirePlumber uses systemd user units to manage the server.

## Configuration

### Configuration file layout

WirePlumber's configuration comprises global PipeWire-flavored JSON objects such as `context` and `alsa_monitor` that are modified to change its behavior. The configuration files are read from `~/.config/wireplumber/` (user configuration), `/etc/wireplumber/` (global configuration), and then `/usr/share/wireplumber/` (stock configuration).

WirePlumber starts by reading the main configuration file. This is a JSON-like file that sets up the PipeWire context, SPA plugins, modules, and components.

The single-instance configuration file at `/usr/share/wireplumber/wireplumber.conf` is the default configuration, which includes the functionality of all the other configurations within one process. See the documentation for the ALSA objects, "access" objects and Bluetooth objects.

### Modifying the configuration

The recommended way to configure WirePlumber is to add an SPA-JSON file to the appropriate `wireplumber.conf.d/` directory within `/etc/wireplumber/` or `~/.config/wireplumber/`. Some things to consider are:

- If there is an existing config you want to override, copy it from `/usr/share/wireplumber/` to the destination while keeping its name the same. Configuration files with the same name but in a lower priority location will be ignored. [1]
- Otherwise, if you are adding a new config, you should start it with a number bigger than 50 (e.g. `51-my-config.conf`), as the default configuration is mostly done at or below 50 in the alphanumeric ordering.

### Obtain interface name for rules matching

In the configuration, you need to specify `matches` rules with a property from an object of the interface you want to configure.

Use the command `wpctl status` to show all objects managed by WirePlumber. Find the `ID` assigned to the target interface. Then use command `wpctl inspect ID` to get a needed property.

Example, if you target interface is `HD Audio Controller Analog Stereo` and consider following output:

    $ wpctl status

    PipeWire 'pipewire-0' [0.3.56, user@hostname, cookie:1163266174]

    Audio
     ├─ Devices:
     │      42. HD Audio Controller                 [alsa]
     │     105. USB PnP Audio Device                [alsa]
     │
     ├─ Sinks:
     │  *   48. HD Audio Controller Analog Stereo   [vol: 0.50]
     │
     ├─ ...
     │
     ├─ Sources:
     │  *  101. USB PnP Audio Device Mono           [vol: 0.74]
     │
     └─ ...

the interface `ID` is `48`.

Then use inspect command to view object detail, listed all properties in that object:

    $ wpctl inspect 48

    id 48, type PipeWire:Interface:Node
        ...
        device.api = "alsa"
        device.class = "sound"
      * device.id = "42"
        device.profile.description = "Analog Stereo"
        device.profile.name = "analog-stereo"
        ...
      * factory.id = "18"
        factory.mode = "merge"
        factory.name = "api.alsa.pcm.sink"
        ...
      * media.class = "Audio/Sink"
      * node.description = "HD Audio Controller Analog Stereo"
      * node.name = "alsa_output.pci-0000_08_00.4.analog-stereo"
      * node.nick = "ALC1220 Analog"
        ...
      * object.path = "alsa:pcm:1:front:1:playback"
      * object.serial = "49"
        ...

Choose `device.name` or `node.name` property to use with the `matches` rules in the configuration.

Avoid using `device.id`, it is dynamic and changes often.

Multiple properties in `matches` rules is possible, see the `alsa_monitor.rules` section in the documentation for the WirePlumber ALSA configuration.

Note:

- You can determine the `Endpoint` class of this object from the `media.class` property.
- For ALSA, `node` objects are Sinks or Sources / `device` objects correspond to the card.
- Since v0.4.9, ALSA nodes use the PCM name to populate `node.nick`, which is useful at least on HDA cards using UCM, where all outputs (analog, HDMI, etc.) are exposed as `Node` on a single profile.

Tip:

- The command `pw-top` shows the PipeWire `Device` and `Node` currently in use.
- Similar inspection command from PipeWire is `pw-cli info ID`.

### Changing a device/node property

To change a device or node property, such as its description or nick, you must create an SPA-JSON file and add it into `/etc/wireplumber/` or `~/.config/wireplumber/` under the proper path and name.

For instance, to change the description of an ALSA node, you would create a file such as:

    /etc/wireplumber/wireplumber.conf.d/51-device-rename.conf (or ~/.config/wireplumber/wireplumber.conf.d/51-device-rename.conf)

    monitor.alsa.rules = [
      {
        matches = [
          {
            node.name = "alsa_output.pci-0000_00_1f.3.output_analog-stereo"
          }
        ]
        actions = {
          update-props = {
            node.description = "Laptop"
          }
        }
      }
    ]

If instead you wish to change something on a Bluetooth node or device, you could create a file such as:

    /etc/wireplumber/wireplumber.conf.d/52-bluez-rename.conf (or ~/.config/wireplumber/wireplumber.conf.d/52-bluez-rename.conf)

    monitor.bluez.rules = [
      {
        matches = [
          {
            node.name = "bluez_output.02_11_45_A0_B3_27.a2dp-sink"
          }
        ]
        actions = {
          update-props = {
            node.nick = "Headphones"
          }
        }
      }
    ]

The properties that you can change as well as the matching rules to select devices or nodes are documented at ALSA configuration and Bluetooth configuration.

### Disable a device/node

Since WirePlumber v0.4.7, users could now disable any devices or nodes by property `device.disabled` or `node.disabled`:

    /etc/wireplumber/wireplumber.conf.d/51-alsa-disable.conf (or ~/.config/wireplumber/wireplumber.conf.d/51-alsa-disable.conf)

    monitor.alsa.rules = [
      {
        matches = [
          {
            device.name = "alsa_card.pci-0000_08_00.4"
          }
        ]
        actions = {
          update-props = {
             device.disabled = true
          }
        }
      }
    ]

For the name of `alsa_card.*` in your system, see #Obtain interface name for rules matching.

Note: Common use-case, for example, is to disable NVIDIA's HDMI audio output.

### Setting node priority

To change which sink or source is automatically selected, you need to set its `priority.driver` and `priority.session` values:

    /etc/wireplumber/wireplumber.conf.d/52-set-priorities.conf

    monitor.alsa.rules = [
      {
        matches = [
          {
            node.name = "alsa_output.usb-Generic_USB_Audio-00.HiFi__Speaker__sink"
          }
        ]
        actions = {
          update-props = {
            priority.driver = 100
            priority.session = 100
          }
        }
      }
    ]

This example sets the priority of the speaker output sink of the on-board audio on the Asus B650E-F motherboard to 100, lowered from the original value of 1000. Consequently, the other output sinks, such as the S/PDIF output of the onboard audio device or the plugged in headphones, will be selected by default due to their higher priorities, instead of the analog speaker output.

### Simultaneous output to multiple sinks on the same sound card

See PipeWire#Simultaneous output to multiple sinks on the same sound card.

### Simultaneous output to transient devices

You may wish to output sound to onboard and external devices simultaneously - even when the external devices are not always plugged in. To accomplish this we create a virtual node that will always be present, regardless of what hardware is plugged in. We then link the transient hardware (in this example USB headphones) to the virtual node whenever they are plugged in.

First create a script that will run during login (this is usually easiest done via your window manager's Startup function).

    /usr/local/sbin/create-virtual-sink.sh

    #!/bin/bash

    # Create a new sink called Simultaneous Output
    pw-cli create-node adapter '{ factory.name=support.null-audio-sink node.name="Simultaneous Output" node.description="Simultaneous Output" media.class=Audio/Sink object.linger=true audio.position=[FL FR] }'

    # Connect the normal permanent sound card output to the new sink
    pw-link "Simultaneous Output:monitor_FL" alsa_output.pci-0000_05_04.0.analog-stereo:playback_FL
    pw-link "Simultaneous Output:monitor_FR" alsa_output.pci-0000_05_04.0.analog-stereo:playback_FR

    # Switch the default output to the new virtual sink
    wpctl set-default `wpctl status | grep "\. Simultaneous Output" | egrep '^ │( )*[0-9]*' -o | cut -c6-55 | egrep -o '[0-9]*'`

In the above example, initially the only output device is our 'normal' on-board soundcard (alsa_output.pci-0000_05_04.0.analog-stereo). You can find the designator for your card by running `wpctl status` and `wpctl inspect`.

Run the following script when your USB headphones are inserted in order to link them to the virtual sink:

    link-virtual-sink-headphones.sh

    #!/bin/bash
    # link the virtual sync to your headphones should run when detected by UDEV

    # wait a second for the drivers to load
    sleep 1s

    # link the headphones to your virtual sink
    sudo -u user1 env XDG_RUNTIME_DIR=/run/user/1000 pw-link "Simultaneous Output:monitor_FL" alsa_output.usb-Kingston_HyperX_Cloud_Flight_S_000000000001-00.analog-stereo:playback_FL
    sudo -u user1 env XDG_RUNTIME_DIR=/run/user/1000 pw-link "Simultaneous Output:monitor_FR" alsa_output.usb-Kingston_HyperX_Cloud_Flight_S_000000000001-00.analog-stereo:playback_FR

    # finish and return the code for success
    exit 0

Ideally you would run this script automatically when your headphones are inserted. The instructions on the udev page describe how you would create a custom rule for that. (Although note that you cannot run this script directly - because udev will not load drivers until after any specified script has run. So you will have to have an intermediate script with some nohup trickery or something like that). You will also need to modify the above script so that the XDG_RUNTIME_DIR matches your user id number and user1 will need to be replaced with your username.

You can add any arbitrary number of devices to this virtual sink in the same manner.

If you are having trouble keeping track what devices are connected where, the qpwgraph tool is excellent for getting a visual representation of which devices are connected to each other.

## Tips and tricks

### Delete corrupt settings

If the settings of WirePlumber are corrupted it is possible to delete all user settings:

    $ systemctl --user stop wireplumber.service
    $ rm -r ~/.local/state/wireplumber # deletes settings
    $ systemctl --user start wireplumber.service

### Keyboard volume control

See Keyboard shortcuts#Xorg to bind the following commands to your volume keys: `XF86AudioRaiseVolume`, `XF86AudioLowerVolume`, `XF86AudioMute` and `XF86AudioMicMute`.

To raise the volume, with a limit of 150%:

    $ wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+

To lower the volume:

    $ wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-

To mute/unmute the volume:

    $ wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle

To mute/unmute the microphone:

    $ wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle

Tip: To use sinks or sources other than the default ones, run `wpctl status` to list all available sinks, and use sink or source numbers in place of `@DEFAULT_AUDIO_SINK@` or `_SOURCE@`.

### Show volume level

To get the volume level and mute status of the default sink:

    $ wpctl get-volume @DEFAULT_AUDIO_SINK@

    Volume: 0.45

Note: The mute status is only visible when the sink is muted.

### Disable Bluetooth profile auto-switching

See PipeWire#Automatic profile selection.

### Keep Bluetooth running after logout / Headless Bluetooth

Note: You also need to enable lingering for the user running PipeWire/Wireplumber.

Since 0.4.8 the requirement to `support.logind` has to be disabled for the bluez seat-monitoring.

    ~/.config/wireplumber/wireplumber.conf.d/80-disable-logind.conf

    wireplumber.profiles = {
      main = {
        monitor.bluez.seat-monitoring = disabled
      }
    }

### Disable audio stack integration

If you do not want PipeWire/Wireplumber to take over control of your audio devices because you are opting for a different audio solution (e.g. PulseAudio/JACK/ALSA) but still want it to be available for screen sharing/video purposes you can make use of the `wireplumber@.service` template unit to enable a different set of default profiles. Wireplumber ships with a profile configuration that enables only the video parts and disables audio integration (including Bluetooth audio) by enabling the `video-only` template user unit.

Disable `wireplumber.service` user unit and enable `wireplumber@video-only.service` user unit.

## Troubleshooting

Since WirePlumber only exists to manage PipeWire sessions, WirePlumber-related fixes may be found in PipeWire#Troubleshooting.

## See also

- Documentation — Official documentation
- WirePlumber, the PipeWire session manager — Blog post by George Kiagiadakis (Collabora) from May 2020, detailing how WirePlumber works

Category:

- Multimedia