Skip to content

Don't automatically hide the volume control when ignore_volume_control is set. - #2272

Merged
mikebrady merged 1 commit into
mikebrady:developmentfrom
paintarm287:external-volume-control
Aug 31, 2026
Merged

mikebrady merged 1 commit into
mikebrady:developmentfrom
paintarm287:external-volume-control

Conversation

@paintarm287

@paintarm287 paintarm287 commented Aug 30, 2026

Copy link
Copy Markdown

Description

Fix the AirPlay 2 getInfo response so that ignore_volume_control no longer changes the volume capability advertised to the sender.

Previously, when ignore_volume_control = "yes", Shairport Sync reported:

volumeControlType = 0

This could cause the AirPlay sender's volume control to disappear.

Local arrangements for handling volume should not affect the capability reported to the sender. With this change, volumeControlType is always reported using the configured value, regardless of ignore_volume_control.

This keeps ignore_volume_control responsible only for local volume handling.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Code refactoring
  • Performance improvement
  • Build/CI configuration change

Testing

  • Tested on Linux
  • Tested on FreeBSD
  • Tested on OpenBSD
  • Tested with AirPlay 2
  • Tested with classic AirPlay

Test configuration:

  • Raspberry Pi 3B, aarch64
  • Debian Linux 6.18.39+rpt-rpi-v8
  • AirPlay 2
  • OpenSSL
  • Avahi
  • PipeWire / ALSA
  • soxr
  • convolution
  • metadata
  • D-Bus
  • MPRIS
  • MQTT

The change was rebuilt successfully from the current development branch with the full feature set above.

Live AirPlay 2 testing confirmed that with:

ignore_volume_control = "yes"

the sender-side volume control remains visible and usable.

The sender volume state also remained available through the existing Shairport Sync remote-control interface.

This PR intentionally does not change the existing local volume-handling semantics of ignore_volume_control.

Checklist

  • I have performed a self-review of my own code
  • I have commented the non-obvious area
  • The contribution builds successfully
  • I have tested the fix with AirPlay 2
  • The pull request targets the development branch

Additional Notes

This PR has been reduced from the original external-volume-control proposal following discussion in the PR.

The external-controller use case is separate from this bug fix and is not part of this change.

@mikebrady

Copy link
Copy Markdown
Owner

Thanks for this, but I am at a slight loss to understand to what it's for.

As things stand, one could set ignore_volume_control to "yes" and use the run_this_when_volume_is_set hook to control an external volume control -- the hook provides the airplay volume to the program or script.

@paintarm287

paintarm287 commented Aug 31, 2026

Copy link
Copy Markdown
Author

Thanks Mike — yes, I should probably have explained the distinction more clearly.

ignore_volume_control="yes" together with run_this_when_volume_is_set covers the sender → external-controller part of the use case.

The particular behaviour I needed was slightly different: I wanted the AirPlay volume control itself to remain advertised and live as a control/state coordinate, while Shairport Sync applies no local software attenuation or backend hardware volume/mute.

With ignore_volume_control, volumeControlType is currently omitted from the AirPlay 2 info response, so the sender-side volume control can disappear. In my use case I also use the existing remote-control path to write the canonical volume back to the sender, so I need that sender volume surface to remain active in both directions while the actual acoustic gain is owned externally.

That is the reason for separating external_volume_control from ignore_volume_control: it is essentially “keep normal AirPlay volume signalling/state, but don’t locally actuate it”, rather than “ignore volume control”.

If there is already a supported configuration which preserves the advertised sender volume control and its read/write state while guaranteeing unity local gain, I’d be very happy to use that instead and simplify or close this PR.

@mikebrady

Copy link
Copy Markdown
Owner

Thanks.

With ignore_volume_control, volumeControlType is currently omitted from the AirPlay 2 info response, so the sender-

So, you mean the getInfo response back to the player? If so, that's a bug!

I agree with what I think is the the sense of your argument, that any local arrangements for how volume is dealt with -- whether by software attenuator, by hardware attenuator, by external hardware, or not at all -- is no business of the sender, so it should receive the same information whether ignore_volume_control is set or not.

Did I get that right? If so, it's a bug.

@paintarm287

Copy link
Copy Markdown
Author

Yes, exactly — I’m referring to the getInfo response back to the player.

That’s the behaviour I ran into: with ignore_volume_control="yes", volumeControlType is omitted, and in my AirPlay 2 testing that can cause the sender-side volume control to disappear.

I agree with your interpretation completely: how the receiver implements the acoustic gain locally shouldn’t change what the sender sees.

If that omission is considered a bug, then fixing it may well remove the need for the separate external_volume_control option. My use case should then be achievable with ignore_volume_control="yes" plus run_this_when_volume_is_set, provided the sender volume remains advertised/readable/writable and the existing remote SetVolume path continues to work.

I’d be happy to rework this PR into the smaller bug fix and retest that configuration if you’d prefer.

@mikebrady

Copy link
Copy Markdown
Owner

Great, thanks. So, I think I was a bit too clever -- I may have added code so that if ignore_volume_control was set, the volumeControlType was arranged to make the player's volume control disappear (a nice idea when you think about it quickly...). If you'd like to rework the PR just to remove that "feature", that would be great, if you don't mind. I can do it here if you prefer.

Sometime later we should add a volumeControlType configuration setting, but not just now -- there is too much going on!

@paintarm287

Copy link
Copy Markdown
Author

Absolutely, happy to rework it — and thanks for clarifying.

I’ll reduce the PR to just removing the ignore_volume_control behaviour that suppresses the player’s volume control, and drop the separate external_volume_control option and associated changes.

I’ll also retest the resulting ignore_volume_control="yes" configuration with run_this_when_volume_is_set and the existing remote SetVolume path to confirm the sender control remains visible and works in both directions while local attenuation stays disabled.

Agreed on leaving a configurable volumeControlType for later.

Thanks Mike.

@paintarm287
paintarm287 force-pushed the external-volume-control branch from 7834d6b to f3a3dc4 Compare August 31, 2026 12:12
@mikebrady mikebrady changed the title Add external volume control mode Don't automatically hide the volume control when ignore_volume_control is set. Aug 31, 2026
@paintarm287

Copy link
Copy Markdown
Author

Thanks Mike — I’ve now tested the smaller fix live.

The volumeControlType change works as intended: with ignore_volume_control="yes" the AirPlay 2 sender volume control remains visible and usable, so the bug fix itself looks good.

I also tested whether that configuration could replace the separate external-volume mode in my use case. Unfortunately it can’t quite: while changing the sender volume, playback repeatedly staggered and Shairport logged sync errors, late packet drops and ALSA underruns. Restoring my previous external-volume implementation immediately restored smooth volume changes under the same test.

So I think there are two separate things here:

  1. this PR’s volumeControlType behaviour is a genuine bug fix and should remain the small one-file change;
  2. my external-controller use case still seems to need a mode where Shairport retains normal volume signalling/state but completely bypasses local/backend volume and mute actuation.

I’m going to isolate which part of that behaviour is actually necessary before proposing anything further rather than putting the larger patch back into this PR.

@mikebrady
mikebrady merged commit 6e98519 into mikebrady:development Aug 31, 2026
4 checks passed
@mikebrady

Copy link
Copy Markdown
Owner

I also tested whether that configuration could replace the separate external-volume mode in my use case. Unfortunately it can’t quite: while changing the sender volume, playback repeatedly staggered and Shairport logged sync errors, late packet drops and ALSA underruns. Restoring my previous external-volume implementation immediately restored smooth volume changes under the same test.

Could it be that whatever you have connected to the run_this_when_volume_is_set hook is taking a long time?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants