output/snapcast: Zeroconf support
This commit is contained in:
parent
e4fccc85c8
commit
7a68775e6c
|
@ -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')
|
||||||
|
|
||||||
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')
|
||||||
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')
|
||||||
'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 @@
|
||||||
#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 {
|
||||||
|
|
||||||
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 @@
|
||||||
#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)
|
||||||
// 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()
|
||||||
|
|
||||||
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
|
||||||
assert(!open);
|
assert(!open);
|
||||||
|
|
||||||
BlockingCall(GetEventLoop(), [this](){
|
BlockingCall(GetEventLoop(), [this](){
|
||||||
|
zeroconf_helper.reset();
|
||||||
|
|
||||||
ServerSocket::Close();
|
ServerSocket::Close();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue