Commit 7a68775e authored by Max Kellermann's avatar Max Kellermann

output/snapcast: Zeroconf support

parent e4fccc85
...@@ -1167,6 +1167,9 @@ connect to it and receive audio data from MPD. ...@@ -1167,6 +1167,9 @@ connect to it and receive audio data from MPD.
- Binds the Snapcast server to the specified address. Multiple - Binds the Snapcast server to the specified address. Multiple
addresses in parallel are not supported. The default is to addresses in parallel are not supported. The default is to
bind on all addresses on port :samp:`1704`. bind on all addresses on port :samp:`1704`.
* - **zeroconf yes|no**
- Publish the Snapcast server as service type ``_snapcast._tcp``
via Zeroconf (Avahi or Bonjour). Default is :samp:`yes`.
solaris solaris
......
...@@ -369,6 +369,8 @@ subdir('src/lib/yajl') ...@@ -369,6 +369,8 @@ subdir('src/lib/yajl')
subdir('src/lib/crypto') subdir('src/lib/crypto')
subdir('src/zeroconf')
subdir('src/fs') subdir('src/fs')
subdir('src/config') subdir('src/config')
subdir('src/tag') subdir('src/tag')
...@@ -384,7 +386,6 @@ subdir('src/decoder') ...@@ -384,7 +386,6 @@ subdir('src/decoder')
subdir('src/encoder') subdir('src/encoder')
subdir('src/song') subdir('src/song')
subdir('src/playlist') subdir('src/playlist')
subdir('src/zeroconf')
if curl_dep.found() if curl_dep.found()
sources += 'src/RemoteTagCache.cxx' sources += 'src/RemoteTagCache.cxx'
......
...@@ -119,7 +119,7 @@ if get_option('snapcast') ...@@ -119,7 +119,7 @@ if get_option('snapcast')
'snapcast/SnapcastOutputPlugin.cxx', 'snapcast/SnapcastOutputPlugin.cxx',
'snapcast/Client.cxx', 'snapcast/Client.cxx',
] ]
output_plugins_deps += [ event_dep, net_dep, yajl_dep ] output_plugins_deps += [ event_dep, net_dep, yajl_dep, zeroconf_dep ]
output_features.set('HAVE_YAJL', yajl_dep.found()) output_features.set('HAVE_YAJL', yajl_dep.found())
......
...@@ -30,14 +30,21 @@ ...@@ -30,14 +30,21 @@
#include "util/AllocatedArray.hxx" #include "util/AllocatedArray.hxx"
#include "util/IntrusiveList.hxx" #include "util/IntrusiveList.hxx"
#include "config.h" // for HAVE_ZEROCONF
#include <memory> #include <memory>
struct ConfigBlock; struct ConfigBlock;
class SnapcastClient; class SnapcastClient;
class PreparedEncoder; class PreparedEncoder;
class Encoder; class Encoder;
class ZeroconfHelper;
class SnapcastOutput final : AudioOutput, ServerSocket { class SnapcastOutput final : AudioOutput, ServerSocket {
#ifdef HAVE_ZEROCONF
unsigned zeroconf_port = 0;
#endif
/** /**
* True if the audio output is open and accepts client * True if the audio output is open and accepts client
* connections. * connections.
...@@ -46,6 +53,10 @@ class SnapcastOutput final : AudioOutput, ServerSocket { ...@@ -46,6 +53,10 @@ class SnapcastOutput final : AudioOutput, ServerSocket {
InjectEvent inject_event; InjectEvent inject_event;
#ifdef HAVE_ZEROCONF
std::unique_ptr<ZeroconfHelper> zeroconf_helper;
#endif
/** /**
* The configured encoder plugin. * The configured encoder plugin.
*/ */
......
...@@ -32,6 +32,10 @@ ...@@ -32,6 +32,10 @@
#include "util/DeleteDisposer.hxx" #include "util/DeleteDisposer.hxx"
#include "config/Net.hxx" #include "config/Net.hxx"
#ifdef HAVE_ZEROCONF
#include "zeroconf/Helper.hxx"
#endif
#ifdef HAVE_YAJL #ifdef HAVE_YAJL
#include "lib/yajl/Gen.hxx" #include "lib/yajl/Gen.hxx"
#endif #endif
...@@ -49,8 +53,14 @@ SnapcastOutput::SnapcastOutput(EventLoop &_loop, const ConfigBlock &block) ...@@ -49,8 +53,14 @@ SnapcastOutput::SnapcastOutput(EventLoop &_loop, const ConfigBlock &block)
// TODO: support other encoder plugins? // TODO: support other encoder plugins?
prepared_encoder(encoder_init(wave_encoder_plugin, block)) prepared_encoder(encoder_init(wave_encoder_plugin, block))
{ {
const unsigned port = block.GetBlockValue("port", 1704U);
ServerSocketAddGeneric(*this, block.GetBlockValue("bind_to_address"), ServerSocketAddGeneric(*this, block.GetBlockValue("bind_to_address"),
block.GetBlockValue("port", 1704U)); port);
#ifdef HAVE_ZEROCONF
if (block.GetBlockValue("zeroconf", true))
zeroconf_port = port;
#endif
} }
SnapcastOutput::~SnapcastOutput() noexcept = default; SnapcastOutput::~SnapcastOutput() noexcept = default;
...@@ -62,6 +72,13 @@ SnapcastOutput::Bind() ...@@ -62,6 +72,13 @@ SnapcastOutput::Bind()
BlockingCall(GetEventLoop(), [this](){ BlockingCall(GetEventLoop(), [this](){
ServerSocket::Open(); ServerSocket::Open();
#ifdef HAVE_ZEROCONF
if (zeroconf_port > 0)
zeroconf_helper = std::make_unique<ZeroconfHelper>
(GetEventLoop(), "Music Player Daemon",
"_snapcast._tcp", zeroconf_port);
#endif
}); });
// TODO: Zeroconf integration // TODO: Zeroconf integration
...@@ -73,6 +90,8 @@ SnapcastOutput::Unbind() noexcept ...@@ -73,6 +90,8 @@ SnapcastOutput::Unbind() noexcept
assert(!open); assert(!open);
BlockingCall(GetEventLoop(), [this](){ BlockingCall(GetEventLoop(), [this](){
zeroconf_helper.reset();
ServerSocket::Close(); ServerSocket::Close();
}); });
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment