Request to add Music Attenuation support on Linux with/via MPRIS sources
Since this feature is available on Windows, wouldn't MPRIS on Linux provide the same functionality (to detect external audio sources)? At the very least, it's the current standard for modern media players.
This is something I was working on before this issue was submitted and although I'm unable to finish it off and PR it for today, I have got things I can say about this in the meantime.
Unlike Windows and macOS which have rather simple APIs specifically for this, on Linux you're inherently forced to connect to and communicate over D-Bus yourself. Not only does this complicate the amount of work you have to do to receive any information (especially because of how the APIs are like), it's also rather flawed in the way we wish it to be used.
With Windows, you can retrieve the active/most likely wanted player by calling GetCurrentSession. From my testing, a session typically lasts from when something first starts playing up to when it has finished, and the current session seems to be whichever session started first. Once the current session has finished, the current may now change to the next oldest session, sort of like a queue. This works fine.
On Linux however, if stuff was playing before your program connects to D-Bus, there's no way to determine what started playing first. It seems you very well just have to hope that the first MPRIS2 client you encounter in your ListNames call is the desired player, unless you also try and employ heuristics based on information such as elapsed time. As well as this, you'd also need to track new/disconnecting clients yourself, all to add to your own queue to acheive similar behaviour to Windows.
As it turns out though, playerctl comes with its own proxy daemon that seems to overcome most of these issues for us. This being present unfortunately cannot be relied on though, as its seemingly unlikely most users would have this installed. Even if that were chose to be a requirement, installation of that could also be an inconvenience to SteamOS users, as presumably because of the immutability of the system you'd have to go through the steps to reinstall it every system update.
With my current implementation I implemented a queue, but if playerctld is present on start it takes priority. Library ended up being glib's, which irked me a bit to have to use at first but it should be fine as every desktop system comes with it and is considerably more sane to use than libdbus. All in all ends up about 300 lines more than the WinRT implementation.
Have I thought too much into this? Absolutely. About all I said above would've ended up in the PR anyway just so people know what I'm even thinking though.
Design question, why only care about what is considers the "main" or "current" session? Why not just check all players to see if any of them are currently playing audio, as opposed to just whatever the "main" one is?
I thought about this because behaviour with stuff like browsers. Some piece of media in a tab could have its own MPRIS2 session, or some long enough notification sound. Just as I'm typing this, for some reason Firefox has an MPRIS2 session with a PlaybackStatus of Playing, despite nothing being played.
That does seem like an issue...
But even in the case where only g_activePlayers.front() is checked, if I just decide to just not open a music app, that firefox issue you described would still happen?
That seems to only fix the niche case that I open Spotify/whatever but not listen to music?
Hmm, it's been a while since I've wrote this now so I don't remember exactly all the issues and details I was thinking of.
I just tried Firefox stuff again and it appears this issue only happens with Discord, thankfully. Playing media on other sites reports them as being paused correctly. That and Discord Firefox on Linux users I'd think to be a minority assuming most people just use the desktop app.
AFAIK KDE determines what it deems the active player in a similar way, so if somebody were to experience this issue then it hopefully wouldn't be hard to troubleshoot and close the affected tab, as you can see the current player from both a button on the panel and the lock screen.
I think this is a rather tricky situation to handle well. Maybe setting status to the most recent change could be more robust in some situations, but then in theory having your music paused but then a notification sound plays could give unwanted behaviour.
I don't think this is a situation you can truly win, and it seems having a queue is better than nothing.
(On another note, further discussion I'd think should really be moved to the PR, as we're talking about my implementation...)