docs: remove main.rst
This is out-of-date and wrong. I wanted to salvage the virtual-items configuration docs from in there, but we are going to change that soon - see https://gitlab.freedesktop.org/pipewire/wireplumber/-/issues/610 - so the entire file can go away.
This commit is contained in:
@@ -1,477 +0,0 @@
|
||||
.. _config_main:
|
||||
|
||||
Main configuration file
|
||||
=======================
|
||||
|
||||
The main configuration file is by default called ``wireplumber.conf``. This can
|
||||
be changed on the command line by passing the ``--config-file`` or ``-c`` option::
|
||||
|
||||
wireplumber --config-file=bluetooth.conf
|
||||
|
||||
The ``--config-file`` option is useful to run multiple instances of wireplumber
|
||||
that do separate tasks each. For more information on this subject, see the
|
||||
:ref:`Multiple Instances <config_multi_instance>` section.
|
||||
|
||||
The format of this configuration file is the variant of JSON that is also
|
||||
used in PipeWire configuration files. Note that this is subject to change
|
||||
in the future.
|
||||
|
||||
All sections are essentially JSON objects. Lines starting with *#* are treated
|
||||
as comments and ignored. The list of all possible section JSON objects are:
|
||||
|
||||
Common configs are present in the main configuration file(wireplumber.conf),
|
||||
rest of the configs that can be grouped logically are grouped into separate
|
||||
files and are placed under ``wireplumber.conf.d/``. More on this below.
|
||||
|
||||
* *context.properties*
|
||||
|
||||
Used to define properties to configure the PipeWire context and some modules.
|
||||
|
||||
Example::
|
||||
|
||||
context.properties = {
|
||||
application.name = WirePlumber
|
||||
log.level = 2
|
||||
}
|
||||
|
||||
This sets the daemon's name to *WirePlumber* and the log level to *2*, which
|
||||
only displays errors and warnings. See the
|
||||
:ref:`Debug Logging <daemon_logging>` section for more details.
|
||||
|
||||
* *context.spa-libs*
|
||||
|
||||
Used to find spa factory names. It maps a spa factory name regular expression
|
||||
to a library name that should contain that factory. The object property names
|
||||
are the regular expression, and the object property values are the actual
|
||||
library name::
|
||||
|
||||
<factory-name regex> = <library-name>
|
||||
|
||||
Example::
|
||||
|
||||
context.spa-libs = {
|
||||
api.alsa.* = alsa/libspa-alsa
|
||||
audio.convert.* = audioconvert/libspa-audioconvert
|
||||
}
|
||||
|
||||
In this example, we instruct wireplumber to only any *api.alsa.** factory name
|
||||
from the *libspa-alsa* library, and also any *audio.convert.** factory name
|
||||
from the *libspa-audioconvert* library.
|
||||
|
||||
* *context.modules*
|
||||
|
||||
Used to load PipeWire modules. This 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.
|
||||
|
||||
Users can also pass key-value pairs if the specific module has arguments, and
|
||||
a combination of 2 flags: ``ifexists`` flag is given, the module is ignored when
|
||||
not found; if ``nofail`` is given, module initialization failures are ignored::
|
||||
|
||||
{
|
||||
name = <module-name>
|
||||
[ args = { <key> = <value> ... } ]
|
||||
[ flags = [ [ ifexists ] [ nofail ] ]
|
||||
}
|
||||
|
||||
Example::
|
||||
|
||||
context.modules = [
|
||||
{ name = libpipewire-module-adapter }
|
||||
{
|
||||
name = libpipewire-module-metadata,
|
||||
flags = [ ifexists ]
|
||||
}
|
||||
]
|
||||
|
||||
The above example loads both PipeWire adapter and metadata modules. The
|
||||
metadata module will be ignored if not found because of its ``ifexists`` flag.
|
||||
|
||||
* *wireplumber.components*
|
||||
|
||||
Used to load WirePlumber components. Components can be either WirePlumber
|
||||
modules written in C or WirePlumber scripts written in Lua.
|
||||
|
||||
Syntax::
|
||||
|
||||
{ name = <component-name>, type = <component-type>, deps = <dependent-setting>, flags = <flags> }
|
||||
|
||||
* type:
|
||||
|
||||
Valid component types include:
|
||||
|
||||
* ``module``: A WirePlumber shared object module
|
||||
* ``script/lua``: A WirePlumber Lua script
|
||||
(all Lua Scripts implicitly requires libwireplumber-module-lua-scripting module)
|
||||
|
||||
Example::
|
||||
|
||||
wireplumber.components = [
|
||||
{ name = libwireplumber-module-lua-scripting, type = module }
|
||||
{ name = monitors/alsa.lua, type = script/lua }
|
||||
]
|
||||
|
||||
* deps: components can be loaded with a dependency on a wireplumber setting.
|
||||
* flags: ifexists & nofail flags are supported in this section as well.
|
||||
|
||||
|
||||
* `ifexists` - signals wireplumber to ignore if the module is not found.
|
||||
* `nofail` - signals wireplumber to ignore module initialization failures.
|
||||
|
||||
More Examples::
|
||||
|
||||
wireplumber.components = [
|
||||
# Load `libwireplumber-module-si-node` which is of type `module`.
|
||||
{ name = libwireplumber-module-si-node , type = module }
|
||||
|
||||
# Load `libwireplumber-module-reserve-device` module, only if the setting `alsa_monitor.alsa.reserve` is defined as true.
|
||||
{ name = libwireplumber-module-reserve-device , type = module, deps = alsa_monitor.alsa.reserve }
|
||||
|
||||
# Load `alsa.lua` which is of type `script/lua`.
|
||||
{ name = monitors/alsa.lua, type = script/lua }
|
||||
|
||||
# Load `alsa-midi.lua` Lua Script only if `alsa_monitor.alsa.midi` setting is defined as true.
|
||||
{ name = monitors/alsa-midi.lua, type = script/lua, deps = alsa_monitor.alsa.midi }
|
||||
|
||||
# Load `libwireplumber-module-logind` module if the setting `bluez-enable-logind` is true.
|
||||
{ name = libwireplumber-module-logind , type = module, deps = bluez-enable-logind, flags = [ ifexists ] }
|
||||
]
|
||||
|
||||
.. note::
|
||||
|
||||
- `name` & `type` keys are mandatory, while `deps` and `flags` keys are optional
|
||||
- All the components are loaded during the bootup and failure in finding them or any error during the loading process is a fatal error and WirePlumber will exit.
|
||||
|
||||
|
||||
* *wireplumber.settings*
|
||||
|
||||
All the Wireplumber configuration settings are now grouped under this
|
||||
section. They are moved away from Lua.
|
||||
|
||||
All the default settings are distributed into different
|
||||
files(\*settings.conf) under ``wireplumber.conf.d\``
|
||||
|
||||
All the settings are loaded into ``sm-settings`` metadata. Apart from the
|
||||
settings JSON files, Metadata interface can be used to change them.
|
||||
|
||||
:ref:`WpSettings <settings_api>` provides APIs to its clients
|
||||
(modules, lua scripts etc) to access and track them.
|
||||
|
||||
Settings can be persistent, more on this below.
|
||||
|
||||
There can be two types of settings namely plain settings(called just settings
|
||||
for reasons of simplicity) and rules.
|
||||
|
||||
* `Settings`
|
||||
|
||||
Syntax::
|
||||
|
||||
wireplumber.settings = {
|
||||
<setting1> = <value>
|
||||
<setting2> = <value>
|
||||
..
|
||||
}
|
||||
|
||||
Examples::
|
||||
|
||||
wireplumber.settings = {
|
||||
alsa_monitor.alsa.reserve = true
|
||||
alsa_monitor.alsa.midi = "true"
|
||||
default-policy-duck.level = 0.3
|
||||
}
|
||||
|
||||
Value can be string, int, float, boolean and can even be a JSON array.
|
||||
|
||||
WpSettings exposes the `wp_settings_get_{string|int|float|boolean}()` APIs
|
||||
to access the values.
|
||||
|
||||
Lua scripts, modules use these APIs to access settings.
|
||||
The client accessing the setting should know which API to use to access
|
||||
the setting accurately.
|
||||
|
||||
If the Setting is a JSON array like `bt-policy-media-role.applications`
|
||||
_get_string() API need to be used and the obtained JSON element will have
|
||||
to be parsed using the :ref:`JSON APIs. <spa_json_api>`
|
||||
|
||||
Persistent Behavior::
|
||||
|
||||
wireplumber.settings = {
|
||||
persistent.settings = true
|
||||
}
|
||||
|
||||
Persistent behavior can be enabled with the above syntax.
|
||||
|
||||
When enabled, the settings will be read from conf file only once and for
|
||||
subsequent reboots they will be read from the state(cache) files, till the
|
||||
time the setting is set back to false in the .conf file.
|
||||
|
||||
Settings can be changed through metadata, so when they are updated through
|
||||
metadata and if the user desires those settings to be persistent between
|
||||
reboots this persistent option can be used.
|
||||
|
||||
wp_settings_register_{callback|closure} () API can be used by clients to
|
||||
keep track of the changes to settings.
|
||||
|
||||
The persistent behavior is disabled by default.
|
||||
|
||||
* `Rules`
|
||||
|
||||
Rules are dynamic logic based settings.
|
||||
|
||||
Syntax
|
||||
|
||||
Simple Syntax::
|
||||
|
||||
wireplumber.settings = {
|
||||
<rule-name> = [
|
||||
{
|
||||
matches = [
|
||||
{
|
||||
<pipewire property1> = <value>
|
||||
<pipewire property2> = <value>
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
update-props = {
|
||||
<pipewire property> = <value>,
|
||||
<wireplumber setting> = <value>,
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Simple Example::
|
||||
|
||||
wireplumber.settings = {
|
||||
stream_default = [
|
||||
{
|
||||
matches = [
|
||||
# Matches all devices
|
||||
{ application.name = "pw-play" }
|
||||
]
|
||||
actions = {
|
||||
update-props = {
|
||||
state.restore-props = false
|
||||
state.restore-target = false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Stream_default rule scans for pw-play app and if found it applies the two
|
||||
properties listed above.
|
||||
|
||||
Advanced Syntax::
|
||||
|
||||
# Nested behavior
|
||||
wireplumber.settings = {
|
||||
<rule-name> = [
|
||||
{
|
||||
matches = [
|
||||
{
|
||||
# Logical AND behavior with the JSON object
|
||||
<pipewire property1> = <value>
|
||||
<pipewire property2> = <value>
|
||||
}
|
||||
|
||||
# Logical OR behavior across the JSON objects.
|
||||
{
|
||||
<pipewire property3> = <value>
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
update-props = {
|
||||
<pipewire property> = <value>,
|
||||
<wireplumber setting> = <value>,
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# Use of regular expressions
|
||||
wireplumber.settings = {
|
||||
<rule-name> = [
|
||||
{
|
||||
matches = [
|
||||
{
|
||||
# if a value starts with ``~`` it triggers regular expression evaluation
|
||||
<pipewire property1> = <~value*>
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
update-props = {
|
||||
<pipewire property> = <value>,
|
||||
<wireplumber setting> = <value>,
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# Multiple Matches with in a single rule is possible.
|
||||
wireplumber.settings = {
|
||||
<rule-name> = [
|
||||
{
|
||||
# Match 1
|
||||
matches = [
|
||||
{
|
||||
<pipewire property1> = <~value*>
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
update-props = {
|
||||
<pipewire property1> = <value>,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Match 2
|
||||
matches = [
|
||||
{
|
||||
<pipewire property2> = <~value*>
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
update-props = {
|
||||
<pipewire property2> = <value>,
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Advanced Example::
|
||||
|
||||
wireplumber.settings = {
|
||||
|
||||
alsa_monitor = [
|
||||
{
|
||||
matches = [
|
||||
{
|
||||
# This matches all sound cards.
|
||||
device.name = "~alsa_card.*"
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
update-props = {
|
||||
# and applies these properties.
|
||||
api.alsa.use-acp = true
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
matches = [
|
||||
# Matches either input nodes or output nodes
|
||||
{
|
||||
node.name = "~alsa_input.*"
|
||||
}
|
||||
{
|
||||
node.name = "~alsa_output.*"
|
||||
}
|
||||
]
|
||||
actions = {
|
||||
update-props = {
|
||||
node.nick = "My Node"
|
||||
priority.driver = 100
|
||||
session.suspend-timeout-seconds = 5
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
* wp_settings_apply_rule () is WpSettings API for rules.
|
||||
|
||||
|
||||
* *wireplumber.virtuals*
|
||||
|
||||
Virtual session items are a way of grouping different kinds of clients or
|
||||
applications(for example Music, Voice, Navigation, Gaming etc).
|
||||
The actual grouping is done based on the `media.role` of the client
|
||||
stream node.
|
||||
|
||||
Virtual session items allows for that actions to be taken up at group level
|
||||
rather than at individual stream level, which can be cumbersome.
|
||||
|
||||
For example imagine the following scenarios.
|
||||
* Incoming Navigation message needs to duck the volume of
|
||||
Audio playback(all the apps playing audio).
|
||||
* Incoming voice/voip call needs to stop(cork) the Audio playback.
|
||||
|
||||
Virtual session items realize this functionality with ease.
|
||||
|
||||
* *Defining Virtual session items*
|
||||
|
||||
Example::
|
||||
|
||||
virtual-items = {
|
||||
virtual-item.capture = {
|
||||
media.class = "Audio/Source"
|
||||
role = "Capture"
|
||||
}
|
||||
virtual-item.multimedia = {
|
||||
media.class = "Audio/Sink"
|
||||
role = "Multimedia"
|
||||
}
|
||||
virtual-item.navigation = {
|
||||
media.class = "Audio/Sink"
|
||||
role = "Navigation"
|
||||
}
|
||||
|
||||
This example creates 3 virtual session items, with names
|
||||
``virtual-item.capture``, ``virtual-item.multimedia`` and
|
||||
``virtual-item.navigation`` and assigned roles ``Capture``, ``Multimedia``
|
||||
and ``Navigation`` respectively.
|
||||
|
||||
First virtual item has a media class of ``Audio/Source`` used for capture
|
||||
and rest of the virtual items have ``Audio/Sink`` media class, and so are
|
||||
only used for playback.
|
||||
|
||||
* *Virtual session items config*
|
||||
|
||||
Example::
|
||||
|
||||
Capture = {
|
||||
alias = [ "Multimedia", "Music", "Voice", "Capture" ]
|
||||
priority = 25
|
||||
action.default = "cork"
|
||||
action.capture = "mix"
|
||||
media.class = "Audio/Source"
|
||||
}
|
||||
Multimedia = {
|
||||
alias = [ "Movie" "Music" "Game" ]
|
||||
priority = 25
|
||||
action.default = "cork"
|
||||
}
|
||||
Navigation = {
|
||||
priority = 50
|
||||
action.default = "duck"
|
||||
action.Navigation = "mix"
|
||||
}
|
||||
|
||||
|
||||
The above example defines actions for both ``Multimedia`` and ``Navigation``
|
||||
roles. Since the Navigation role has more priority than the Multimedia
|
||||
role, when a client connects to the Navigation virtual session item, it
|
||||
will ``duck`` the volume of all Multimedia clients. If Multiple Navigation
|
||||
clients want to play audio, their audio will be mixed.
|
||||
|
||||
Possible values of actions are: ``mix`` (Mixes audio),
|
||||
``duck`` (Mixes and lowers the audio volume) or ``cork`` (Pauses audio).
|
||||
|
||||
Virtual session items are not used for desktop use cases, it is more suitable
|
||||
for embedded use cases.
|
||||
|
||||
* *Split Configuration files*
|
||||
|
||||
The Main configuration file is split into multiple files. When loading the main
|
||||
JSON configuration file, WirePlumber will also look for additional files in the
|
||||
same directory suffixed with ``.d`` and will load all of them as well. For
|
||||
example, loading ``wireplumber.conf`` will also load any files under
|
||||
``wireplumber.conf.d/``. It will load all the JSON config files there. All the
|
||||
configurations are logically split into files and placed in this directory.
|
Reference in New Issue
Block a user