mirror of
https://gitlab.freedesktop.org/pipewire/wireplumber.git
synced 2026-05-26 10:08:21 +02:00
docs: add full documentation on WirePlumber's configuration options and files
This commit is contained in:
parent
0e98e4150b
commit
1ccc570f3f
2 changed files with 441 additions and 43 deletions
441
docs/configuration.md
Normal file
441
docs/configuration.md
Normal file
|
|
@ -0,0 +1,441 @@
|
|||
# WirePlumber Configuration
|
||||
|
||||
WirePlumber is a heavily modular daemon. By itself, it doesn't do anything
|
||||
except load the configured modules. All the rest of the logic is implemented
|
||||
inside those modules.
|
||||
|
||||
Modular design ensures that it is possible to swap the implementation of
|
||||
specific functionality without having to re-implement the rest of it, allowing
|
||||
flexibility on target-sensitive parts, such as policy management and
|
||||
making use of non-standard hardware.
|
||||
|
||||
## `wireplumber.conf`
|
||||
|
||||
This is WirePlumber's main configuration file. It is read at startup, before
|
||||
connecting to the PipeWire daemon. Its purpose is to list all the modules
|
||||
that need to be loaded by WirePlumber.
|
||||
|
||||
The format of this file is custom and resembles a script with commands:
|
||||
|
||||
```
|
||||
# comment
|
||||
command parameter1 parameter2 ...
|
||||
```
|
||||
|
||||
Lines are executed in the order they appear and each of them executes an
|
||||
action defined by the command. Lines starting with `#` are treated as comments
|
||||
and ignored. Possible commands are:
|
||||
|
||||
* `add-spa-lib`
|
||||
|
||||
Associates SPA plugin names with the names of the SPA modules that they
|
||||
can be loaded from. This takes 2 parameters: a name pattern and a library name.
|
||||
|
||||
This actually does not load the SPA plugin, it only calls `pw_core_add_spa_lib`
|
||||
with the 2 paramteres given as arguments. As a consequence, it is safe to
|
||||
call this even if the SPA module is not actually installed on the system.
|
||||
|
||||
Example:
|
||||
```
|
||||
add-spa-lib api.alsa.* alsa/libspa-alsa
|
||||
```
|
||||
|
||||
In this example, we let `libpipewire` know that any SPA plugin whose name
|
||||
starts with `api.alsa.` can be loaded from the SPA module
|
||||
`alsa/libspa-alsa.so` (relative to the standard SPA modules directory).
|
||||
|
||||
* `load-pipewire-module`
|
||||
|
||||
Loads a `libpipewire` module. This is similar to the `load-module` commands
|
||||
that would appear on `pipewire.conf`, the configuration file of the PipeWire
|
||||
daemon.
|
||||
|
||||
This takes at least 1 parameter, the module name, and optionally any module
|
||||
arguments, in the format that they would be given in `pipewire.conf`
|
||||
|
||||
Format:
|
||||
```
|
||||
load-pipewire-module module-name some-argument some-property=value
|
||||
```
|
||||
Example:
|
||||
```
|
||||
load-pipewire-module libpipewire-module-client-device
|
||||
```
|
||||
|
||||
This command does not affect the PipeWire daemon by any means. It exists
|
||||
simply to allow loading `libpipewire` modules in the pipewire core that
|
||||
runs inside WirePlumber. This is usually useful to load pipewire protocol
|
||||
extensions, so that you can export custom objects to PipeWire and other
|
||||
clients.
|
||||
|
||||
* `load-module`
|
||||
|
||||
Loads a WirePlumber module. This takes 2 arguments and an optional parameter
|
||||
block.
|
||||
|
||||
Format:
|
||||
```
|
||||
load-module ABI module-name {
|
||||
"parameter": <"value">
|
||||
}
|
||||
```
|
||||
|
||||
The `ABI` parameter specifies the binary interface that WirePlumber shall use
|
||||
to load this module. Currently, the only supported ABI is `C`. It exists to
|
||||
allow future expansion, writing modules in other languages.
|
||||
|
||||
The `module-name` should be the name of the `.so` file without the `.so`
|
||||
extension.
|
||||
|
||||
Optionally, if the `load-module` line ends with a `{`, the next lines up to
|
||||
and including the next matching `}` are treated as a parameter block.
|
||||
This block essentially is a
|
||||
[GVariant](https://developer.gnome.org/glib/stable/glib-GVariant.html)
|
||||
of type
|
||||
[`a{sv}`](https://developer.gnome.org/glib/stable/gvariant-format-strings.html)
|
||||
in the
|
||||
[GVariant Text Format](https://developer.gnome.org/glib/stable/gvariant-text.html).
|
||||
As a rule of thumb, parameter names in this block must always be strings
|
||||
enclosed in double quotes, the separation between names and values is done
|
||||
with the `:` character and values, regardless of their inner type, must always
|
||||
be enclosed in `<` `>`.
|
||||
|
||||
Note that starting the parameter block on the next line is an error. The
|
||||
starting brace (`{`) must always be on the `load-module` line.
|
||||
|
||||
Example:
|
||||
```
|
||||
load-module C libwireplumber-module-monitor {
|
||||
"factory": <"api.alsa.enum.udev">,
|
||||
"flags": <["use-adapter", "activate-devices"]>
|
||||
}
|
||||
```
|
||||
|
||||
Parameters are module-dependent. They are passed as a GVariant in the
|
||||
module's initialization function and it is up to the module to interpret
|
||||
their meaning. WirePlumber does not have any reserved parameters.
|
||||
|
||||
## Location of configuration files
|
||||
|
||||
WirePlumber's default location of its configuration files is determined at
|
||||
compile time by the build system. Typically, it ends up being `/etc/wireplumber`.
|
||||
|
||||
In more detail, this is controlled by the `--sysconfdir` meson option. When
|
||||
this is set to an absolute path, such as `/etc`, the location of the
|
||||
configuration files is set to be `$sysconfdir/wireplumber`. When this is set
|
||||
to a relative path, such as `etc`, then the installation prefix (`--prefix`)
|
||||
is prepended to the path: `$prefix/$sysconfdir/wireplumber`
|
||||
|
||||
WirePlumber expects its `wireplumber.conf` to reside in that directory.
|
||||
It is possible to override that at runtime by setting the
|
||||
`WIREPLUMBER_CONFIG_FILE` environment variable:
|
||||
|
||||
```
|
||||
WIREPLUMBER_CONFIG_FILE=src/config/wireplumber.conf wireplumber
|
||||
```
|
||||
|
||||
It is also possible to override the whole configuration directory, so that
|
||||
all other configuration files are being read from a different location as well,
|
||||
by setting the `WIREPLUMBER_CONFIG_DIR` environment variable:
|
||||
```
|
||||
WIREPLUMBER_CONFIG_DIR=src/config wireplumber
|
||||
```
|
||||
|
||||
## Location of modules
|
||||
|
||||
### WirePlumber modules
|
||||
|
||||
Like with configuration files, WirePlumber's default location of its modules is
|
||||
determined at compile time by the build system. Typically, it ends up being
|
||||
`/usr/lib/wireplumber-0.1` (or `/usr/lib/<arch-triplet>/wireplumber-0.1` on
|
||||
multiarch systems)
|
||||
|
||||
In more detail, this is controlled by the `--libdir` meson option. When
|
||||
this is set to an absolute path, such as `/lib`, the location of the
|
||||
modules is set to be `$libdir/wireplumber-$abi_version`. When this is set
|
||||
to a relative path, such as `lib`, then the installation prefix (`--prefix`)
|
||||
is prepended to the path: `$prefix/$libdir/wireplumber-$abi_version`.
|
||||
|
||||
It is possible to override this directory at runtime by setting the
|
||||
`WIREPLUMBER_MODULE_DIR` environment variable:
|
||||
```
|
||||
WIREPLUMBER_MODULE_DIR=build/modules wireplumber
|
||||
```
|
||||
|
||||
### PipeWire and SPA modules
|
||||
|
||||
PipeWire and SPA modules are not loaded from the same location as WirePlumber's
|
||||
modules. They are loaded from the location that PipeWire loads them.
|
||||
|
||||
It is also possible to override these locations by using environment variables:
|
||||
`SPA_PLUGIN_DIR` and `PIPEWIRE_MODULE_DIR`. For more details, refer to
|
||||
PipeWire's documentation.
|
||||
|
||||
# module-monitor
|
||||
|
||||
This module internally loads a SPA "device" object which enumerates all the
|
||||
devices of a certain subsystem. Then it listens for "node" objects that are
|
||||
being created by this device and exports them to PipeWire, after adjusting
|
||||
their properties to provide enough context.
|
||||
|
||||
`module-monitor` does not read any configuration files, however, it supports
|
||||
configuration through parameters defined in the main `wireplumber.conf`.
|
||||
Possible parameters are:
|
||||
|
||||
* `factory`
|
||||
|
||||
A string that specifies the name of the SPA factory that loads the intial
|
||||
"device" object.
|
||||
|
||||
Well-known factories are:
|
||||
|
||||
* "api.alsa.enum.udev" - Discovers ALSA devices via udev
|
||||
* "api.v4l2.enum.udev" - Discovers V4L2 devices via udev
|
||||
* "api.bluez5.enum.dbus" - Discovers bluetooth devices by calling bluez5 API via D-Bus
|
||||
|
||||
* `flags`
|
||||
|
||||
An array of strings that enable specific functionality in the monitor.
|
||||
Possible flags include:
|
||||
|
||||
* "use-adapter"
|
||||
|
||||
Instructs the monitor to wrap all the created nodes in an "adapter"
|
||||
SPA node, which provides automatic port splitting/merging and format/rate
|
||||
conversion. This should be always enabled for audio device nodes.
|
||||
|
||||
* "local-nodes"
|
||||
|
||||
Instructs the monitor to run all the created nodes locally in in the
|
||||
WirePlumber process, instead of the default behavior which is to create
|
||||
the nodes in the PipeWire process. This is useful for bluetooth nodes,
|
||||
which should run outside of the main PipeWire process for performance
|
||||
reasons.
|
||||
|
||||
* "activate-devices"
|
||||
|
||||
Instructs the monitor to automatically set the device profile to "On",
|
||||
so that the nodes are created. If not specified, the profile must be
|
||||
set externally by the user before any nodes appear.
|
||||
|
||||
# module-config-endpoint
|
||||
|
||||
This module creates endpoints when WirePlumber detects new nodes in the
|
||||
pipewire graph. Nodes themselves can be created in two ways:
|
||||
Device modes are being created by "monitors" that watch a specific subsystem
|
||||
(udev, bluez, etc...) for devices. Client nodes are being created by client
|
||||
applications that try to stream to/from pipewire. As soon as a node is created,
|
||||
the `module-config-endpoint` iterates through all the `.endpoint` configuration
|
||||
files, in the order that is determined by the `match-node.priority` field,
|
||||
and tries to match the node to the node description in the `[match-node]` table.
|
||||
Upon a successful match, a new endpoint that follows the description in the
|
||||
`[endpoint]` table is created.
|
||||
|
||||
## `*.endpoint` configuration files
|
||||
|
||||
These files are TOML v0.5 files. At the top-level, they must contain exactly
|
||||
2 tables: `[match-node]` and `[endpoint]`
|
||||
|
||||
The `[match-node]` table contains properties that match a pipewire node that
|
||||
exists on the graph. Possible fields of this table are:
|
||||
|
||||
* `priority`
|
||||
|
||||
Specifies the order in which the `.endpoint` files are being searched for a
|
||||
match with a node. If a node matches the description of more than one
|
||||
`.endpoint` file, the one with the highest priority wins.
|
||||
|
||||
The type of this field is unsigned integer. Bigger numbers mean higher
|
||||
priority.
|
||||
|
||||
* `properties`
|
||||
|
||||
This is a TOML array of tables, where each table must contain two fields:
|
||||
`name` and `value`, both being strings. Each table describes a match against
|
||||
one of the pipewire properties of the node. For a successful node match, all
|
||||
the described properties must match with the node.
|
||||
|
||||
The value of the `name` field must match exactly the name of the pipewire
|
||||
property, while the value of the `value` field can contain '*' (wildcard)
|
||||
and '?' (joker), adhering to the rules of the
|
||||
[GLib g_pattern_match() function](https://developer.gnome.org/glib/stable/glib-Glob-style-pattern-matching.html).
|
||||
|
||||
When writing `.endpoint` files, a useful utility that you can use to list
|
||||
device node properties is:
|
||||
|
||||
```
|
||||
$ wireplumber-cli device-node-props
|
||||
```
|
||||
|
||||
Another way to figure out some of these properties *for ALSA nodes* is
|
||||
by parsing the aplay/arecord output. For example, this line from `aplay -l`
|
||||
is interpreted as follows:
|
||||
|
||||
```
|
||||
card 0: PCH [HDA Intel PCH], device 2: ALC3246 [ALC3246 Analog]
|
||||
```
|
||||
|
||||
```
|
||||
{ name = "api.alsa.path", value = "hw:0,2" },
|
||||
{ name = "api.alsa.card", value = "0" },
|
||||
{ name = "api.alsa.card.id", value = "PCH" },
|
||||
{ name = "api.alsa.card.name", value = "HDA Intel PCH" },
|
||||
{ name = "api.alsa.pcm.device", value = "2" },
|
||||
{ name = "api.alsa.pcm.id", value = "ALC3246" },
|
||||
{ name = "api.alsa.pcm.name", value = "ALC3246 Analog" },
|
||||
```
|
||||
|
||||
The `[endpoint]` table contains a description of the endpoint to be created.
|
||||
Possible fields of this table are:
|
||||
|
||||
* `type`
|
||||
|
||||
Required. Specifies the factory to be used for construction.
|
||||
The only well-known factory at the moment of writing is: `pw-audio-softdsp-endpoint`
|
||||
|
||||
* `direction`
|
||||
|
||||
Required. Can be set to either `"sink"` or `"source"`. Specifies the
|
||||
direction of the media flow of this endpoint. A `source` is an endpoint that
|
||||
produces data (i.e. an audio capture device or a playback application) and
|
||||
a `sink` is an endpoint that consumes data (audio playback device or
|
||||
capture application).
|
||||
|
||||
* `name`
|
||||
|
||||
Optional. The name of the newly created endpoint. If not specified,
|
||||
the endpoint is named after the node (from the `node.name` property of the node).
|
||||
|
||||
* `media_class`
|
||||
|
||||
Optional. A string that specifies an override for the `media.class` property
|
||||
of the node. It can be used in special circumstances to declare that an
|
||||
endpoint is dealing with a different type of data. This is only useful in
|
||||
combination with a policy implementation that is aware of this media class.
|
||||
|
||||
* `priority`
|
||||
|
||||
Optional. An unsigned integer that specifies the order in which endpoints are
|
||||
chosen to be the default of a specific device group. Possible device groups
|
||||
are (determined by the endpoint's `media.class`):
|
||||
|
||||
* Audio/Sink
|
||||
* Audio/Source
|
||||
* Video/Source
|
||||
|
||||
Every time a new device endpoint is created, wireplumber picks the "default"
|
||||
of the group that it belongs to, based on this priority number: the endpoint
|
||||
with the biggest priority number wins.
|
||||
|
||||
If not specified, the default priority of an endpoint is equal to zero
|
||||
(i.e. the lowest priority).
|
||||
|
||||
* `streams`
|
||||
|
||||
Optional. Specifies the name of a `.streams` file that contains the
|
||||
descriptions of the streams to create for this endpoint. This currently
|
||||
specific to the implementation of the `pw-audio-softdsp-endpoint` and might
|
||||
change in the future.
|
||||
|
||||
## `*.streams` configuration files
|
||||
|
||||
These files contain lists of streams with their names and priorities.
|
||||
They are TOML v0.5 files.
|
||||
|
||||
Each `.streams` file must contain exactly one top-level array of tables,
|
||||
called `streams`. Every table must contain exactly two fields:
|
||||
`name` and `priority`.
|
||||
|
||||
The `name` of each stream is used to create the streams on new endpoints.
|
||||
|
||||
The `priority` of each stream is being interpreted by the policy module to
|
||||
apply restrictions on which app can use the stream at a given time.
|
||||
|
||||
# module-config-policy
|
||||
|
||||
This module implements demo-quality policy management that is partly driven
|
||||
by configuration files. The configuration files that this module reads are
|
||||
described below:
|
||||
|
||||
## `*.endpoint-link`
|
||||
|
||||
These files contain rules to link endpoints with each other.
|
||||
They are TOML v0.5 files.
|
||||
|
||||
Endpoints are normally created by another module, such
|
||||
as `module-config-endpoint` which is described above.
|
||||
As soon as an endpoint is created, the `module-config-policy` uses the
|
||||
information gathered from the `.endpoint-link` files in order to create a
|
||||
link to another endpoint.
|
||||
|
||||
`.endpoint-link` files can contain 3 top-level tables:
|
||||
* `[match-endpoint]`, required
|
||||
* `[target-endpoint]`, optional
|
||||
* `[endpoint-link]`, required
|
||||
|
||||
The `[match-endpoint]` table contains properties that match an endpoint that
|
||||
exists on the graph. Possible fields of this table are:
|
||||
|
||||
* `priority`
|
||||
|
||||
Specifies the order in which the `.endpoint-link` files are being searched
|
||||
for a match with an endpoint. If an endpoint matches the description of more
|
||||
than one `.endpoint-link` file, the one with the highest priority wins.
|
||||
|
||||
The type of this field is unsigned integer. Bigger numbers mean higher
|
||||
priority.
|
||||
|
||||
* `direction`
|
||||
|
||||
Required. Can be set to either `"sink"` or `"source"`. Specifies the
|
||||
direction of the media flow of this endpoint. A `source` is an endpoint that
|
||||
produces data (i.e. an audio capture device or a playback application) and
|
||||
a `sink` is an endpoint that consumes data (audio playback device or
|
||||
capture application).
|
||||
|
||||
* `name`
|
||||
|
||||
Optional. The name of the endpoint. It is possible to use wildcards here to
|
||||
match only parts of the name.
|
||||
|
||||
* `media_class`
|
||||
|
||||
Optional. A string that specifies the `media.class` that the endpoint
|
||||
must have in order to match.
|
||||
|
||||
* `properties`
|
||||
|
||||
This is a TOML array of tables, where each table must contain two fields:
|
||||
`name` and `value`, both being strings. Each table describes a match against
|
||||
one of the pipewire properties of the endpoint. For a successful endpoint
|
||||
match, all the described properties must match with the endpoint.
|
||||
|
||||
The `[target-endpoint]` table contains properties that match an endpoint that
|
||||
exists on the graph. The purpose of this table is to match a second endpoint
|
||||
that the original matching endpoint from `[match-endpoint]` will be linked to.
|
||||
If not specified, `module-config-policy` will look for the session "default"
|
||||
endpoint for the type of media that the matching endpoint produces or consumes
|
||||
and will use that as a target. Possible fields of this table are:
|
||||
|
||||
* `direction`, `name`, `media_class`, `properties`
|
||||
|
||||
All these fields are permitted and behave exactly as described above for the
|
||||
`[match-endpoint]` table.
|
||||
|
||||
* `stream`
|
||||
|
||||
This field specifies a stream name that the link will use on the target
|
||||
endpoint. If it is not specified, the stream name is acquired from the
|
||||
`media.role` property of the matching endpoint. If specified, the value of
|
||||
this field overrides the `media.role`.
|
||||
|
||||
The `[endpoint-link]` table specifies properties of the link. Possible fields
|
||||
of this table are:
|
||||
|
||||
* `keep`
|
||||
|
||||
A boolean field. If set to true, the link is always kept active and ignores
|
||||
policy rules regarding corking or stream priority. This link will also not
|
||||
affect the rules for other links. For example, if a keep=true link is
|
||||
activating a high priority stream, lower priority streams can still work on
|
||||
the same target endpoint for links with keep=false.
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
WirePlumber Configuration
|
||||
===
|
||||
|
||||
This directory contains WirePlumber's configuration files.
|
||||
There are 4 kinds of files:
|
||||
|
||||
* `wireplumber.conf`
|
||||
|
||||
This file lists the modules that are being loaded by WirePlumber.
|
||||
|
||||
* `*.endpoint` files
|
||||
|
||||
These files contain rules to create endpoints when WirePlumber detects
|
||||
new nodes in the pipewire graph. They are TOML v0.5 files.
|
||||
|
||||
The `00-stream-*.endpoint` files contain rules to create endpoints for the
|
||||
nodes of the client applications that connect to pipewire. You should not
|
||||
change or remove those unless you know what you are doing.
|
||||
|
||||
The rest of the `.endpoint` files contain rules to create endpoints for
|
||||
ALSA device nodes.
|
||||
|
||||
TODO: more info
|
||||
|
||||
* `*.endpoint-link` files
|
||||
|
||||
These files contain rules to link endpoints with each other. They are part
|
||||
of the policy module.
|
||||
|
||||
* `*.streams` files
|
||||
|
||||
These files contain a list of streams and their priorities.
|
||||
|
||||
The names of the streams are used to create streams on new endpoints.
|
||||
In order to use a specific list of streams for a specific endpoint,
|
||||
the relevant `.endpoint` file that contains the creation rule for that
|
||||
endpoint must reference the `.streams` file.
|
||||
|
||||
The stream priorities are being interpreted by the policy module to apply
|
||||
restrictions on which app can use the device at a given time.
|
||||
|
||||
The `media.role` of the application's stream is matched against the names
|
||||
of the streams when applying policy.
|
||||
Loading…
Add table
Reference in a new issue