SHA256
1
0
forked from pool/wireplumber

Accepting request 1147639 from home:alarrosa:branches:multimedia:libs:devel

- Add patch from upstream to remove the "clear-persistent"
  sub-command and add a "settings" sub-command:
  * 0001-wpctl-add-settings-subcomand-to-show_-delete-or-change.patch

- Update to version 0.4.82 (0.5.0 pre-release 2)
  * Highlights:
    - Bluetooth auto-switching is now implemented with a virtual
      source node. When an application links to it, the actual
      device switches to the HSP/HFP profile to provide the real
      audio stream. This is a more robust solution that works with
      more applications and is more user-friendly than the previous
      application whitelist approach
    - Added support for dynamic log level changes via the PipeWire
      settings metadata. Also added support for log level patterns
      in the configuration file
    - The "persistent" (i.e. stored) settings approach has changed
      to use two different metadata objects: sm-settings and
      persistent-sm-settings. Changes in the former are applied in
      the current session but not stored, while changes in the
      latter are stored and restored at startup. Some work was also
      done to expose a wpctl interface to read and change these
      settings, but more is underway
    - Several WirePlumber-specific node properties that used to be
      called target.* have been renamed to node.* to match the
      PipeWire convention of node.dont-reconnect. These are also
      now fully documented
  * Other changes:
    - Many documentation updates
    - Added support for SNAP container permissions
    - Fixed multiple issues related to restoring the Route

OBS-URL: https://build.opensuse.org/request/show/1147639
OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/wireplumber?expand=0&rev=66
This commit is contained in:
Takashi Iwai 2024-02-20 08:29:47 +00:00 committed by Git OBS Bridge
parent ebd240d4c1
commit 71654b8284
9 changed files with 437 additions and 87 deletions

View File

@ -0,0 +1,274 @@
From bebfc07d84b149a07af1dd2d5d26fafc76237b4e Mon Sep 17 00:00:00 2001
From: Julian Bouzas <julian.bouzas@collabora.com>
Date: Wed, 14 Feb 2024 12:04:01 -0500
Subject: [PATCH] wpctl: add settings subcomand to show, delete or change
settings
---
src/tools/wpctl.c | 196 ++++++++++++++++++++++++++++++++++++----------
1 file changed, 156 insertions(+), 40 deletions(-)
diff --git a/src/tools/wpctl.c b/src/tools/wpctl.c
index 13abe5db..d8b14eb7 100644
--- a/src/tools/wpctl.c
+++ b/src/tools/wpctl.c
@@ -82,7 +82,10 @@ static struct {
struct {
const gchar *key;
- } clear_persistent;
+ const gchar *val;
+ gboolean remove;
+ gboolean save;
+ } settings;
struct {
guint64 id;
@@ -393,7 +396,6 @@ status_run (WpCtl * self)
g_autoptr (WpIterator) it = NULL;
g_auto (GValue) val = G_VALUE_INIT;
g_autoptr (WpPlugin) def_nodes_api = NULL;
- g_autoptr (WpMetadata) persistent_settings = NULL;
struct print_context context = { .self = self };
def_nodes_api = wp_plugin_find (self->core, "default-nodes-api");
@@ -515,23 +517,6 @@ status_run (WpCtl * self)
/* Settings */
printf ("Settings\n");
- persistent_settings = wp_object_manager_lookup (self->om, WP_TYPE_METADATA,
- WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY,
- "metadata.name", "=s", "persistent-sm-settings",
- NULL);
- printf (TREE_INDENT_NODE "Persistent:\n");
- if (persistent_settings) {
- it = wp_metadata_new_iterator (persistent_settings, 0);
- for (; wp_iterator_next (it, &val); g_value_unset (&val)) {
- const gchar *key, *value;
- wp_metadata_iterator_item_extract (&val, NULL, &key, NULL, &value);
- printf (TREE_INDENT_LINE " - %s: %s\n", key, value);
- }
- g_clear_pointer (&it, wp_iterator_unref);
- }
-
- printf (TREE_INDENT_LINE "\n");
-
printf (TREE_INDENT_END "Default Configured Devices:\n");
if (def_nodes_api) {
for (guint i = 0; i < G_N_ELEMENTS (DEFAULT_NODE_MEDIA_CLASSES); i++) {
@@ -1368,21 +1353,30 @@ out:
g_main_loop_quit (self->loop);
}
-/* clear-persistent */
+/* settings */
static gboolean
-clear_persistent_parse_positional (gint argc, gchar ** argv, GError **error)
+settings_parse_positional (gint argc, gchar ** argv, GError **error)
{
- if (argc >= 3)
- cmdline.clear_persistent.key = argv[2];
- else
- cmdline.clear_persistent.key = NULL;
+ cmdline.settings.key = NULL;
+ cmdline.settings.val = NULL;
+ if (argc >= 3) {
+ cmdline.settings.key = argv[2];
+ if (argc >= 4)
+ cmdline.settings.val = argv[3];
+ }
+
+ if (cmdline.settings.remove && cmdline.settings.save) {
+ g_set_error (error, wpctl_error_domain_quark(), 0,
+ "Cannot use --delete and --save flags at the same time");
+ return FALSE;
+ }
return TRUE;
}
static gboolean
-clear_persistent_prepare (WpCtl * self, GError ** error)
+settings_prepare (WpCtl * self, GError ** error)
{
wp_object_manager_add_interest (self->om, WP_TYPE_METADATA, NULL);
wp_object_manager_request_object_features (self->om, WP_TYPE_METADATA,
@@ -1391,10 +1385,21 @@ clear_persistent_prepare (WpCtl * self, GError ** error)
}
static void
-clear_persistent_run (WpCtl * self)
+settings_run (WpCtl * self)
{
+ g_autoptr (WpMetadata) settings = NULL;
g_autoptr (WpMetadata) persistent_settings = NULL;
+ g_autoptr (WpIterator) it = NULL;
+ g_auto (GValue) val = G_VALUE_INIT;
+ settings = wp_object_manager_lookup (self->om, WP_TYPE_METADATA,
+ WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY,
+ "metadata.name", "=s", "sm-settings",
+ NULL);
+ if (!settings) {
+ fprintf (stderr, "Settings metadata not found\n");
+ goto out;
+ }
persistent_settings = wp_object_manager_lookup (self->om, WP_TYPE_METADATA,
WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY,
"metadata.name", "=s", "persistent-sm-settings",
@@ -1404,12 +1409,115 @@ clear_persistent_run (WpCtl * self)
goto out;
}
- if (cmdline.clear_persistent.key)
- wp_metadata_set (persistent_settings, 0, cmdline.clear_persistent.key, NULL,
- NULL);
- else
- wp_metadata_clear (persistent_settings);
-
+ if (!cmdline.settings.key && !cmdline.settings.val) {
+ /* No key or value */
+ if (!cmdline.settings.remove && !cmdline.settings.save) {
+ /* Print all settings */
+ printf ("Settings:\n");
+ it = wp_metadata_new_iterator (settings, 0);
+ for (; wp_iterator_next (it, &val); g_value_unset (&val)) {
+ const gchar *key, *value, *saved_value;
+ wp_metadata_iterator_item_extract (&val, 0, &key, NULL, &value);
+ saved_value = wp_metadata_find (persistent_settings, 0, key, NULL);
+ if (saved_value)
+ printf (" - %s: %s (saved: %s)\n", key, value, saved_value);
+ else
+ printf (" - %s: %s\n", key, value);
+ }
+ g_clear_pointer (&it, wp_iterator_unref);
+ } else if (!cmdline.settings.remove && cmdline.settings.save) {
+ /* Save all current settings */
+ it = wp_metadata_new_iterator (settings, 0);
+ for (; wp_iterator_next (it, &val); g_value_unset (&val)) {
+ const gchar *key, *type, *value;
+ wp_metadata_iterator_item_extract (&val, 0, &key, &type, &value);
+ wp_metadata_set (persistent_settings, 0, key, type, value);
+ fprintf (stderr, "Saved setting %s with value %s\n", key, value);
+ }
+ } else if (cmdline.settings.remove && !cmdline.settings.save) {
+ /* Delete all saved settings */
+ wp_metadata_clear (persistent_settings);
+ fprintf (stderr, "Deleted all saved settings\n");
+ } else {
+ g_assert_not_reached ();
+ }
+ } else if (cmdline.settings.key && !cmdline.settings.val) {
+ /* only key */
+ if (!cmdline.settings.remove && !cmdline.settings.save) {
+ /* Print setting value */
+ const gchar *value, *saved_value;
+ value = wp_metadata_find (settings, 0, cmdline.settings.key, NULL);
+ if (value) {
+ saved_value = wp_metadata_find (persistent_settings, 0,
+ cmdline.settings.key, NULL);
+ if (saved_value)
+ printf ("%s (saved: %s)\n", value, saved_value);
+ else
+ printf ("%s\n", value);
+ } else {
+ printf ("Setting %s not found\n", cmdline.settings.key);
+ }
+ } else if (!cmdline.settings.remove && cmdline.settings.save) {
+ /* Save setting */
+ const gchar *value, *type;
+ value = wp_metadata_find (settings, 0, cmdline.settings.key, &type);
+ if (value) {
+ wp_metadata_set (persistent_settings, 0, cmdline.settings.key, type,
+ value);
+ printf ("Updated and saved setting %s with current value %s\n",
+ cmdline.settings.key, value);
+ } else {
+ printf ("Setting %s not found\n", cmdline.settings.key);
+ }
+ } else if (cmdline.settings.remove && !cmdline.settings.save) {
+ /* Delete saved setting */
+ const gchar *value;
+ value = wp_metadata_find (persistent_settings, 0, cmdline.settings.key,
+ NULL);
+ if (value) {
+ wp_metadata_set (persistent_settings, 0, cmdline.settings.key, NULL,
+ NULL);
+ printf ("Deleted setting %s with value %s\n", cmdline.settings.key,
+ value);
+ } else {
+ printf ("Setting %s is not saved\n", cmdline.settings.key);
+ }
+ } else {
+ g_assert_not_reached ();
+ }
+ } else if (cmdline.settings.key && cmdline.settings.val) {
+ /* key and value */
+ if (!cmdline.settings.remove && !cmdline.settings.save) {
+ /* Set setting value */
+ wp_metadata_set (settings, 0, cmdline.settings.key, NULL,
+ cmdline.settings.val);
+ printf ("Updated setting %s with value %s\n", cmdline.settings.key,
+ cmdline.settings.val);
+ } else if (!cmdline.settings.remove && cmdline.settings.save) {
+ /* Save setting value */
+ wp_metadata_set (persistent_settings, 0, cmdline.settings.key, NULL,
+ cmdline.settings.val);
+ printf ("Updated and saved setting %s with current value %s\n",
+ cmdline.settings.key, cmdline.settings.val);
+ } else if (cmdline.settings.remove && !cmdline.settings.save) {
+ /* Remove saved setting */
+ const gchar *value;
+ value = wp_metadata_find (persistent_settings, 0, cmdline.settings.key,
+ NULL);
+ if (value) {
+ wp_metadata_set (persistent_settings, 0, cmdline.settings.key, NULL,
+ NULL);
+ printf ("Deleted setting %s with value %s\n", cmdline.settings.key,
+ value);
+ } else {
+ printf ("Setting %s is not saved\n", cmdline.settings.key);
+ }
+ } else {
+ g_assert_not_reached ();
+ }
+ } else {
+ g_assert_not_reached ();
+ }
wp_core_sync (self->core, NULL, (GAsyncReadyCallback) async_quit, self);
return;
@@ -1647,14 +1755,22 @@ static const struct subcommand {
.run = clear_default_run,
},
{
- .name = "clear-persistent",
- .positional_args = "[KEY]",
- .summary = "Clears the persistent setting (no KEY means 'all')",
+ .name = "settings",
+ .positional_args = "[KEY] [VAL]",
+ .summary = "Shows, changes or removes settings",
.description = NULL,
- .entries = { { NULL } },
- .parse_positional = clear_persistent_parse_positional,
- .prepare = clear_persistent_prepare,
- .run = clear_persistent_run,
+ .entries = {
+ { "delete", 'd', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE,
+ &cmdline.settings.remove,
+ "Deletes the saved setting value (no KEY means 'all')", NULL },
+ { "save", 's', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE,
+ &cmdline.settings.save,
+ "Saves the setting value (no KEY means 'all', no VAL means current value)", NULL },
+ { NULL }
+ },
+ .parse_positional = settings_parse_positional,
+ .prepare = settings_prepare,
+ .run = settings_run,
},
{
.name = "set-log-level",
--
GitLab

View File

@ -3,7 +3,7 @@
<service name="obs_scm" mode="manual">
<param name="scm">git</param>
<param name="url">https://gitlab.freedesktop.org/pipewire/wireplumber.git</param>
<param name="revision">refs/tags/0.4.17</param>
<param name="revision">refs/tags/0.4.82</param>
<param name="versionformat">@PARENT_TAG@</param>
<!--
<param name="revision">master</param>

View File

@ -1,28 +0,0 @@
From: Antonio Larrosa <alarrosa@suse.com>
Subject: Fix bsc#1219411
wireplumber enables the bluetooth support in pipewire by default but this
clashes with the bluetooth support in pulseaudio if audio is disabled in
pipewire so this patch disables bluetooth support unless the
90-enable-all.lua file is installed and we now move that file into the
wireplumber-audio package.
Index: wireplumber-0.4.17/src/config/bluetooth.lua.d/50-bluez-config.lua
===================================================================
--- wireplumber-0.4.17.orig/src/config/bluetooth.lua.d/50-bluez-config.lua
+++ wireplumber-0.4.17/src/config/bluetooth.lua.d/50-bluez-config.lua
@@ -1,4 +1,4 @@
-bluez_monitor.enabled = true
+bluez_monitor.enabled = false
bluez_monitor.properties = {
-- Enabled roles (default: [ a2dp_sink a2dp_source bap_sink bap_source hfp_hf hfp_ag ])
Index: wireplumber-0.4.17/src/config/bluetooth.lua.d/90-enable-all.lua
===================================================================
--- wireplumber-0.4.17.orig/src/config/bluetooth.lua.d/90-enable-all.lua
+++ wireplumber-0.4.17/src/config/bluetooth.lua.d/90-enable-all.lua
@@ -1,2 +1,4 @@
+bluez_monitor.enabled = true
+
bluez_monitor.enable()
bluez_midi_monitor.enable()

View File

@ -1,48 +1,43 @@
#!/usr/bin/python3
import hashlib
import sys
import re
def sha256_from_data(data):
hash_sha256 = hashlib.sha256()
hash_sha256.update(data)
return hash_sha256.hexdigest()
contents = open('90-enable-all.lua', 'r', encoding='utf-8').read()
lines = open('wireplumber.conf', 'r', encoding='utf-8').readlines()
sha256sum = sha256_from_data(contents.encode('utf-8'))
expected_sha256sum = '86888e9d3fcc952c41e778ab4edae4a0eb1f9f51b62ae0772befa9f0fdef611d'
if sha256sum != expected_sha256sum:
print('The script has to be updated for new changes in 90-enable-all.lua')
print(f'File sha256sum: {sha256sum}')
print(f'expected sha256sum: {expected_sha256sum}')
sys.exit(1)
content_sections = contents.split('\n\n')
sections = ['enable-metadata',
'default-access-policy',
'load-devices',
'track-user-choices-devices',
'track-user-choices-streams',
'link-nodes-by-roles',
'suspend-idle-nodes',
'allow-loading-objects-on-demand']
if len(content_sections) != len(sections):
print('The script has to be updated for new changes in 90-enable-all.lua')
sys.exit(1)
for i, (content, sec) in enumerate(zip(content_sections, sections)):
if sec == 'load-devices':
lines = content.split('\n')
open(f'90-{i}-1-enable-alsa.lua', 'w',
encoding='utf-8').write(lines[1])
open(f'90-{i}-2-enable-v4l2.lua', 'w',
encoding='utf-8').write(lines[2])
open(f'90-{i}-3-enable-libcamera.lua', 'w',
encoding='utf-8').write(lines[3])
is_in_device_monitor = False
main_config_content = ''
device_monitors_content = ''
for line in lines:
if re.match(' *## Device monitors$', line):
main_config_content += line
main_config_content += ' # Section moved to a device-monitors.conf file which is provided by the wireplumber-audio package\n\n'
is_in_device_monitor = True
continue
elif re.match(' *## ', line):
is_in_device_monitor = False
filename = f'90-{i}-{sec}.lua'
open(filename, 'w', encoding='utf-8').write(content)
if is_in_device_monitor:
device_monitors_content += line
else:
main_config_content += line
config_sha256 = sha256_from_data(device_monitors_content.encode('utf-8'))
verified_sha256 = 'bf33d018e5b924da71266636757fa264bc677b945c35e4dcd7f708da42731cc9'
if config_sha256 != verified_sha256:
print('The "Device monitors" section was modified, please verify that the contents are ok')
print('and if they are, modify the "verified_sha256" value in this script to')
print(f' {config_sha256}')
print('Current device monitors section is:')
print(device_monitors_content)
sys.exit(1)
device_monitors_content = 'wireplumber.components = [\n' + device_monitors_content + ']'
open('wireplumber.conf', 'w', encoding='utf-8').write(main_config_content)
open('wireplumber.conf.d/00-device-monitors.conf', 'w', encoding='utf-8').write(device_monitors_content)

BIN
wireplumber-0.4.17.obscpio (Stored with Git LFS)

Binary file not shown.

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cfb55189762e5b6de4f3fdcf53029a6da8fdfc04b524e171a82fad1b04aa33a6
size 2630668

View File

@ -1,3 +1,108 @@
-------------------------------------------------------------------
Mon Feb 19 07:29:52 UTC 2024 - Antonio Larrosa <alarrosa@suse.com>
- Add patch from upstream to remove the "clear-persistent"
sub-command and add a "settings" sub-command:
* 0001-wpctl-add-settings-subcomand-to-show_-delete-or-change.patch
-------------------------------------------------------------------
Thu Feb 15 07:23:41 UTC 2024 - Antonio Larrosa <alarrosa@suse.com>
- Update to version 0.4.82 (0.5.0 pre-release 2)
* Highlights:
- Bluetooth auto-switching is now implemented with a virtual
source node. When an application links to it, the actual
device switches to the HSP/HFP profile to provide the real
audio stream. This is a more robust solution that works with
more applications and is more user-friendly than the previous
application whitelist approach
- Added support for dynamic log level changes via the PipeWire
settings metadata. Also added support for log level patterns
in the configuration file
- The "persistent" (i.e. stored) settings approach has changed
to use two different metadata objects: sm-settings and
persistent-sm-settings. Changes in the former are applied in
the current session but not stored, while changes in the
latter are stored and restored at startup. Some work was also
done to expose a wpctl interface to read and change these
settings, but more is underway
- Several WirePlumber-specific node properties that used to be
called target.* have been renamed to node.* to match the
PipeWire convention of node.dont-reconnect. These are also
now fully documented
* Other changes:
- Many documentation updates
- Added support for SNAP container permissions
- Fixed multiple issues related to restoring the Route
parameter of devices, which includes volume state
- Smart filters can now be targetted by specific streams
directly when the filter.smart.targetable property is set
- Ported the mechanism to override device profile priorities in
the configuration, which is used to re-prioritize Bluetooth
codecs
- WpSettings is no longer a singleton class and there is a
built-in component to preload an instance of it
-------------------------------------------------------------------
Mon Feb 5 16:11:12 UTC 2024 - Antonio Larrosa <alarrosa@suse.com>
- Update to version 0.4.81
* Highlights:
- Lua scripts have been refactored to use the new event
dispatcher API, which allows them to be split into multiple
small fragments that react to events in a specified order.
This allows scripts to be more modular and easier to
maintain, as well as more predictable in terms of execution
order.
- The configuration system has been refactored to use a single
SPA-JSON file, like PipeWire does, with support for fragments
that can override options. This file is also now loaded using
PipeWire's configuration API, which effectively means that
the file is now loaded from the PipeWire configuration
directories, such as /etc/pipewire and
$XDG_CONFIG_HOME/pipewire.
- The configuration system now has the concept of profiles,
which are groups of components that can be loaded together,
with the ability to mark certain components as optional. This
allows having multiple configurations that can be loaded
using the same configuration file. Optional components also
allow loading the same profile gracefully on different
setups, where some components may not be available (ex,
loading of the session D-Bus plugin on a system-wide PipeWire
setup now does not fail).
- Many configuration options are now exposed in the sm-settings
metadata, which allows changing them at runtime. This can be
leveraged in the future to implement configuration tools that
can modify WirePlumber's behaviour dynamically, without
restarting.
- A new "filters" system has been implemented, which allows
specifying chains of "filter" nodes to be dynamically linked
in-between streams and devices. This is achieved with certain
properties and metadata that can be set on the filter nodes
themselves.
- The default linking policy now reads some more target.*
properties from nodes, which allows fine-tuning some aspects
of their linking behaviour, such as whether they are allowed
to be re-linked or whether an error should be sent to the
client if they cannot be linked.
- Some state files have been renamed and some have changed
format to use JSON for storing complex values, such as
arrays. This may cause some of the old state to be lost on
upgrade, as there is no transition path implemented.
- The libcamera and V4L2 monitors have a "device deduplication"
logic built-in, which means that for each physical camera
device, only one node will be created, either from libcamera
or V4L2, depending on which one is considered better for the
device. This is mainly to avoid having multiple nodes for the
same camera device, which can cause confusion when looking at
the list of available cameras in applications.
- Bump apiver to 0.5
- Rewrite split-config-file.py to work with the new config
subsystem
- Remove patch which isn't applying anymore and whose fix is
now handled by the split-config-file.py script:
* fix-bsc1219411.patch
-------------------------------------------------------------------
Mon Feb 5 06:46:58 UTC 2024 - Antonio Larrosa <alarrosa@suse.com>

View File

@ -1,4 +1,4 @@
name: wireplumber
version: 0.4.17
mtime: 1701626719
commit: d3eb77b292655cef333a8f4cab4e861415bc37c2
version: 0.4.82
mtime: 1707928830
commit: 5826a21456dbdb789dcef63f98e9b84d952eb3fa

View File

@ -16,13 +16,13 @@
#
%define pipewire_minimum_version 0.3.68
%define apiver 0.4
%define apiver_str 0_4
%define pipewire_minimum_version 0.3.75
%define apiver 0.5
%define apiver_str 0_5
%define sover 0
%define libwireplumber libwireplumber-%{apiver_str}-%{sover}
Name: wireplumber
Version: 0.4.17
Version: 0.4.82
Release: 0
Summary: Session / policy manager implementation for PipeWire
License: MIT
@ -30,8 +30,8 @@ Group: Development/Libraries/C and C++
URL: https://gitlab.freedesktop.org/pipewire/wireplumber
Source0: wireplumber-%{version}.tar.xz
Source1: split-config-file.py
# FIX-PATCH-SUSE fix-bsc1219411.patch alarrosa@suse.com -- Enable bluetooth only when audio support is enabled
Patch0: fix-bsc1219411.patch
# PATCH-FIX-UPSTREAM 0001-wpctl-add-settings-subcomand-to-show_-delete-or-change.patch
Patch0: 0001-wpctl-add-settings-subcomand-to-show_-delete-or-change.patch
# docs
BuildRequires: doxygen
BuildRequires: graphviz
@ -147,9 +147,8 @@ Optional dependency offering zsh completion for various wpctl parameters.
%prep
%autosetup -p1
pushd src/config/main.lua.d
pushd src/config
python3 %{SOURCE1}
rm 90-enable-all.lua
popd
%build
@ -216,31 +215,36 @@ fi
%{_bindir}/wpctl
%{_bindir}/wpexec
%dir %{_libdir}/wireplumber-%{apiver}
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-dbus-connection.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-default-nodes-api.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-default-nodes.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-default-profile.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-file-monitor-api.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-log-settings.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-logind.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-lua-scripting.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-metadata.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-mixer-api.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-portal-permissionstore.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-reserve-device.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-settings.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-si-audio-adapter.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-si-audio-endpoint.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-si-audio-virtual.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-si-node.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-si-standard-link.so
%{_libdir}/wireplumber-%{apiver}/libwireplumber-module-standard-event-source.so
%{_userunitdir}/wireplumber.service
%{_userunitdir}/wireplumber@.service
%{_datadir}/wireplumber
%exclude %{_datadir}/wireplumber/main.lua.d/90-2-1-enable-alsa.lua
%exclude %{_datadir}/wireplumber/bluetooth.lua.d/90-enable-all.lua
%dir %{_datadir}/doc/wireplumber
%dir %{_datadir}/doc/wireplumber/examples
%{_datadir}/doc/wireplumber/examples/wireplumber.conf.d
%{_datadir}/pipewire/wireplumber.conf
%dir %{_datadir}/pipewire/wireplumber.conf.d
%{_datadir}/pipewire/wireplumber.conf.d/alsa-vm.conf
%files lang -f %{name}.lang
%files audio
%{_datadir}/wireplumber/main.lua.d/90-2-1-enable-alsa.lua
%{_datadir}/wireplumber/bluetooth.lua.d/90-enable-all.lua
%{_datadir}/pipewire/wireplumber.conf.d/00-device-monitors.conf
%files devel
%{_includedir}/wireplumber-%{apiver}