kaaholst / android-squeezer

Remote control for your Logitech Media Server ("Squeezeserver" etc) and players.
Apache License 2.0
75 stars 15 forks source link

Feature request: Add "Mute all" to actions when making a call #812

Closed SamInPgh closed 3 months ago

SamInPgh commented 4 months ago

Hi, Kurt! It's been awhile. 😊 Here's my request. As the number of players in my home grows, I find that the currently selected player in Squeezer might not be the one I'm nearest to when a phone call comes in and I have to take manual action to mute or pause it.

To be perfectly honest, I have also been using the Material Skin Android wrapper app lately, which has "Mute all active players" and "Pause all active players" options for phone calls. The problem is that the mute function stopped working reliably there and the developer has no interest in fixing it. Thus my request to add the option to Squeezer.

I appreciate all the work you continue to do on this great app, including some new features since the last time I used it. I also saw the issue that is being worked on to add more info, including bit depth and sampling rate, to the current track display and think that would be a major improvement.

Anyway, thanks for listening and I hope you are doing well.

kaaholst commented 4 months ago

Hi Sam, good to hear from you :smile:

When I first saw this, I thought you requested to mute the nearest player! While that may be theoretically possible, it would probably prove difficult and maybe unstable. However mute all player should be fairly straightforward, even if I should be careful using those words. I will definitely look into it.

To be fair, I think this would be difficult to implement in material skin, because it is not a native Android app, but a JavaScript app which runs in a WebView. And as such might not have access to native Android events for security or other reasons.

SamInPgh commented 4 months ago

Thanks, Kurt. I actually like your idea better though. Having every player advertise it's GPS coordinates would be a nice enhancement to LMS. 🤔😊

Regarding the Material Skin app's abilities, Craig actually has an Android 'wrapper' for it which he maintains separately. Here is the Github project for it:

https://github.com/CDrummond/lms-material-app

The module that handles the phone call state changes seems to be one called phonestatereceiver.java:

https://github.com/CDrummond/lms-material-app/blob/eaa4906878bb5245caa93c1cffb2168375d73cec/lms-material/src/main/java/com/craigd/lmsmaterial/app/PhoneStateReceiver.java

It seems to have multiple problems, as even muting just the current player no longer works. If you have any hints or suggestions for Craig, I would be happy to act as an intermediary or you could just create a pull request as he suggested I do. My problem is that I don't know anything about Java or Android internals (I guess that's actually two problems). 😉

Aside from helping Craig fix the phone logic in Material, adding the "mute/pause all players" feature to Squeezer would still be a nice addition.

As always, thanks for your help!

kaaholst commented 4 months ago

Thanks, Kurt. I actually like your idea better though. Having every player advertise it's GPS coordinates would be a nice enhancement to LMS. 🤔😊

I was thinking NFC tag. There have been some requests regarding the use of NFC to change the active player according to where you are, and also use it to let the currently playing music follow you around. I don't know anything about NFC tags or how they work on Android, or if it's even feasible. But interesting ideas if someone is interested in picking it up.

Regarding the Material Skin app's abilities, Craig actually has an Android 'wrapper' for it which he maintains separately. Here is the Github project for it: It seems to have multiple problems, as even muting just the current player no longer works. If you have any hints or suggestions for Craig, I would be happy to act as an intermediary or you could just create a pull request as he suggested I do. My problem is that I don't know anything about Java or Android internals (I guess that's actually two problems). 😉

I see, there is some java in the wrapper as well. Why the call handling is unreliable, I don't know. I see it sets up a broadcast receiver to receive and handle the phone state events from Android. This is different from what I do.

SamInPgh commented 4 months ago

I was thinking NFC tag. There have been some requests regarding the use of NFC to change the active player according to where you are, and also use it to let the currently playing music follow you around. I don't know anything about NFC tags or how they work on Android, or if it's even feasible. But interesting ideas if someone is interested in picking it up.

You piqued my interest with that comment so I did a quick search and found that NFC tags have a range of only 4 inches so it would require the listener to bring their phone that close to a radio (or a tag placed close by) to trigger the switch but it would definitely be doable in an Android app. Here is a good high-level discussion of them.

I see, there is some java in the wrapper as well. Why the call handling is unreliable, I don't know. I see it sets up a broadcast receiver to receive and handle the phone state events from Android. This is different from what I do.

If you have any tips on how to do it differently, it would be appreciated. My suspicion from googling around a bit is that Craig is using an older signalling method that is no longer supported. Whatever method you are using seems to work very well from my testing. It seems that in Material it works only once, after which clearing the app's cache is required for it to work again. I'm sure there is a clue there but, again, I don't know enough about Java or Android to make use of it.

kaaholst commented 4 months ago

The event it is listening for does not seem to be deprecated. I'm not sure if it's the Android events which are unreliable or other logic that fails. What we do in Squeezer is register a TelephonyManager.registerTelephonyCallback (or a TelephonyManager.listen in older Androids) from a service, if it's any help.

kaaholst commented 3 months ago

Mute all / pause all options are available in this apk.

If you would like to help test this, it will be appreciated.

SamInPgh commented 3 months ago

Preliminary testing looks good, Kurt. I will run some more comprehensive scenarios later today and report back.

While I have your attention, I have an unrelated question for you. I know from our work together in the past, and from the current behavior of Squeezer, that you had to come up with a way to handle the odd (and incorrect, in my opinion) way that LMS handles incremental volume changes to a player that is currently muted. As you might recall, LMS reacts to this condition by first setting the volume to 0, and then applying the incremental change. So, for instance, it the player volume was originally set to +45, a "mixer muting 1" command would change it to -45, effectively muting it while preserving the pre-mute volume setting so that a subsequent "mixer muting 0" unmute command can easily restore it. However, if a "mixer volume +/-N" command is received while the player is muted, instead of first restoring the pre-muted volume before applying the increment, LMS sets the volume to 0. So a "mixer volume +3" command to the muted player in my example sets the volume to 3 instead of 48. I had to deal with this in the Denon AVR Control plugin, which only registers to listen for volume/muting commands, making it difficult to handle because it is after the fact. In the case of Squeezer, or any client app, it should theoretically be easier to handle, as it can be compensated for before the incremental volume command is issued, My question is: "How is this done in Squeezer?". Do you query the volume of the player, or perhaps just set it to its absolute value, prior to issuing each incremental command? The reason I ask is that this situation is currently unhandled in the Material Skin client and I would like to be able to advise Craig Drummond how it is dealt with by Squeezer when I ask him to make a change there. Sorry for rambling on. I should probably have sent this in an email. 😉

kaaholst commented 3 months ago

You're probably right, the incremental volume handling should not pollute this thread, so I send a mail 😉

SamInPgh commented 3 months ago

Got the email. Thanks for the info. Now back to the issue at hand... 😉

I tested using three different players of different types and the new options work well. Unfortunately, though, it doesn't always work when Squeezer is running in the background, which is how I was hoping to use it. So, as far as a new Squeezer feature goes, it works as designed. I will continue to test and look for any clues as to the background behavior. Thanks again!

kaaholst commented 3 months ago

Call handling when Squeezer is in the background (but is connected to a server), for some reason works on my phone (Xiaomi 12 / Android 14). I didn't originally test that specific case, but I tested outgoing call, which means Squeezer is in the background. However now I also tried incoming call when the phone is sleeping.

Normally when I listen to music, though, I have Squeezer in the foreground and the screensaver clock option enabled.

SamInPgh commented 3 months ago

I think the key words in your response might be "but is connected to a server". I have been doing a lot of testing lately that involves restarting LMS and I recall having to manually reconnect Squeezer to the server after each restart. Is there an option to automatically try reconnecting to the last connected server at some predefined interval? If not, it would be a nice feature.

kaaholst commented 3 months ago

Currently, Squeezer attempts to reconnect when it loses the connection or when we get a Wi-Fi connection and Squeezer is in the foreground. It only attempts the auto-connection once per minute, to avoid looping in failed connection attempts. As long as Squeezer is connected, we keep a service running. It may be possible to have an option to have this service always running and, if not connected, periodically attempt to connect to a selected server. I think it's a valid use case, but to be honest not on the top of my list!

SamInPgh commented 3 months ago

Thanks, Kurt. As always, I appreciate your cooperation and willingness to act as a sounding board for ideas that are sometimes a little outside the box. I am satisfied that this new feature is working now and believe it will be a useful addition to the Squeezer app. Take care!

kaaholst commented 1 month ago

@SamInPgh if you monitor this thread, here's an apk which is able to reconnect when the server restarts. I was working on fixing some connection stability issues, and this is part of it. It works like this; if a working connection is broken, we attempt to reconnect periodically. If that doesn't succeed in 15 minutes, we give up, and does not try to reconnect until Squeezer is brought to the foreground.

SamInPgh commented 1 month ago

Thanks, Kurt! I'll give it a try.