summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2021-08-10 11:17:14 +0200
committerMax Kellermann <max@musicpd.org>2021-08-10 11:17:16 +0200
commit269583f5dd9949b106a86b11df7408e51fc34557 (patch)
treeabc217f8dd8a50bd749689a6fb889b90f146eaff
parent7c9f4f7e4f65aa8460ab5e585c67933149c3b01c (diff)
output/pipewire: allow specifying a target by its name
-rw-r--r--doc/plugins.rst6
-rw-r--r--src/output/plugins/PipeWireOutputPlugin.cxx20
2 files changed, 22 insertions, 4 deletions
diff --git a/doc/plugins.rst b/doc/plugins.rst
index 8573ae8a8..f97b78c5c 100644
--- a/doc/plugins.rst
+++ b/doc/plugins.rst
@@ -1080,8 +1080,10 @@ Connect to a `PipeWire <https://pipewire.org/>`_ server. Requires
* - Setting
- Description
- * - **target ID**
- - Link to the given target id.
+ * - **target NAME**
+ - Link to the given target. If not specified, let the PipeWire
+ manager select a target. To get a list of available targets,
+ type ``pw-cli dump short Node``
.. _pulse_plugin:
diff --git a/src/output/plugins/PipeWireOutputPlugin.cxx b/src/output/plugins/PipeWireOutputPlugin.cxx
index 37a81d2ad..cf623a1cb 100644
--- a/src/output/plugins/PipeWireOutputPlugin.cxx
+++ b/src/output/plugins/PipeWireOutputPlugin.cxx
@@ -25,6 +25,7 @@
#include "pcm/Silence.hxx"
#include "util/Domain.hxx"
#include "util/ScopeExit.hxx"
+#include "util/StringCompare.hxx"
#include "util/WritableBuffer.hxx"
#include "Log.hxx"
@@ -53,6 +54,8 @@ static constexpr Domain pipewire_output_domain("pipewire_output");
class PipeWireOutput final : AudioOutput {
const char *const name;
+ const char *const target;
+
struct pw_thread_loop *thread_loop = nullptr;
struct pw_stream *stream;
@@ -67,7 +70,7 @@ class PipeWireOutput final : AudioOutput {
using RingBuffer = boost::lockfree::spsc_queue<std::byte>;
RingBuffer *ring_buffer;
- const uint32_t target_id;
+ uint32_t target_id = PW_ID_ANY;
float volume = 1.0;
@@ -182,8 +185,19 @@ inline
PipeWireOutput::PipeWireOutput(const ConfigBlock &block)
:AudioOutput(FLAG_ENABLE_DISABLE),
name(block.GetBlockValue("name", "pipewire")),
- target_id(block.GetBlockValue("target", unsigned(PW_ID_ANY)))
+ target(block.GetBlockValue("target", nullptr))
{
+ if (target != nullptr) {
+ if (StringIsEmpty(target))
+ throw std::runtime_error("target must not be empty");
+
+ char *endptr;
+ const auto _target_id = strtoul(target, &endptr, 10);
+ if (endptr > target && *endptr == 0)
+ /* numeric value means target_id, not target
+ name */
+ target_id = (uint32_t)_target_id;
+ }
}
void
@@ -352,6 +366,8 @@ PipeWireOutput::Open(AudioFormat &audio_format)
PW_KEY_APP_NAME, "Music Player Daemon",
PW_KEY_NODE_NAME, "mpd",
nullptr);
+ if (target != nullptr && target_id == PW_ID_ANY)
+ pw_properties_setf(props, PW_KEY_NODE_TARGET, "%s", target);
const PipeWire::ThreadLoopLock lock(thread_loop);