output/Control: Support always_off
outputs that are never used for playback
Add an `always_off` option to outputs that causes them to never start playback even if they're enabled. This allows placeholder `null` outputs to be defined for the purpose of having an external client react to the enabled state without the side effects of real outputs. Like an external mixer, the client can perform some action when an output is enabled. Normally `null` outputs can be used for playback so it's possible for MPD to continue playback silently if a problem occurs with all the real outputs (or there are none enabled).
This commit is contained in:
parent
90c3fe22f5
commit
ab196f7afc
@ -517,6 +517,11 @@ The following table lists the audio_output options valid for all plugins:
|
||||
- If set to no, then :program:`MPD` will not send tags to this output. This is only useful for output plugins that can receive tags, for example the httpd output plugin.
|
||||
* - **always_on yes|no**
|
||||
- If set to yes, then :program:`MPD` attempts to keep this audio output always open. This may be useful for streaming servers, when you don't want to disconnect all listeners even when playback is accidentally stopped.
|
||||
* - **always_off yes|no**
|
||||
- If set to yes, then :program:`MPD` never uses this audio output for
|
||||
playback even if it's enabled. This can be used with the null output
|
||||
plugin to create placeholder outputs for other software to react to
|
||||
the enabled state without affecting playback.
|
||||
* - **mixer_type hardware|software|null|none**
|
||||
- Specifies which mixer should be used for this audio output: the
|
||||
hardware mixer (available for ALSA :ref:`alsa_plugin`, OSS
|
||||
|
@ -25,6 +25,7 @@ AudioOutputControl::AudioOutputControl(std::unique_ptr<FilteredAudioOutput> _out
|
||||
thread(BIND_THIS_METHOD(Task)),
|
||||
tags(block.GetBlockValue("tags", true)),
|
||||
always_on(block.GetBlockValue("always_on", false)),
|
||||
always_off(block.GetBlockValue("always_off", false)),
|
||||
enabled(block.GetBlockValue("enabled", true))
|
||||
{
|
||||
}
|
||||
@ -36,7 +37,8 @@ AudioOutputControl::AudioOutputControl(AudioOutputControl &&src,
|
||||
client(_client),
|
||||
thread(BIND_THIS_METHOD(Task)),
|
||||
tags(src.tags),
|
||||
always_on(src.always_on)
|
||||
always_on(src.always_on),
|
||||
always_off(src.always_off)
|
||||
{
|
||||
}
|
||||
|
||||
@ -176,6 +178,9 @@ AudioOutputControl::EnableAsync()
|
||||
if (!output)
|
||||
return;
|
||||
|
||||
if (always_off)
|
||||
return;
|
||||
|
||||
if (!thread.IsDefined()) {
|
||||
if (!output->SupportsEnableDisable()) {
|
||||
/* don't bother to start the thread now if the
|
||||
|
@ -143,6 +143,11 @@ class AudioOutputControl {
|
||||
*/
|
||||
const bool always_on;
|
||||
|
||||
/**
|
||||
* Should this output never play anything, even when enabled?
|
||||
*/
|
||||
const bool always_off;
|
||||
|
||||
/**
|
||||
* Has the user enabled this device?
|
||||
*/
|
||||
@ -274,6 +279,10 @@ public:
|
||||
return !output;
|
||||
}
|
||||
|
||||
bool AlwaysOff() const noexcept {
|
||||
return always_off;
|
||||
}
|
||||
|
||||
/**
|
||||
* Caller must lock the mutex.
|
||||
*/
|
||||
|
@ -215,6 +215,10 @@ MultipleOutputs::Open(const AudioFormat audio_format)
|
||||
for (const auto &ao : outputs) {
|
||||
const std::scoped_lock<Mutex> lock(ao->mutex);
|
||||
|
||||
/* can't play on this device even if it's enabled */
|
||||
if (ao->AlwaysOff())
|
||||
continue;
|
||||
|
||||
if (ao->IsEnabled())
|
||||
enabled = true;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user