greshake / i3status-rust

Very resourcefriendly and feature-rich replacement for i3status, written in pure Rust
GNU General Public License v3.0
2.88k stars 475 forks source link

music block: prioritized media players , OR exclude media players? #808

Closed Dieterbe closed 4 years ago

Dieterbe commented 4 years ago

Hello, first of all. nice project, thank you. i'm in the process of switching over from a conky based setup to i3status-rust and it's looking really nice.

My situation is the following: I use multiple media players (spotify and cmus), and i also tend to have some paused youtube videos in my chrome browser.

typically i'll play music through one of the players, or watch a video (rarely do i watch a video with my music playing in the background)

with the music block, it seems it assumes spotify when spotify is running. When i close it, it assumes a tab with a youtube video. even when i start playing music in cmus and restart the bar, it'll control the youtube video, not my music. if i want to prefer cmus over youtube, i can use player = "cmus" but of course then i can't control spotify anymore.

So how about we turn this option into an array of players, ordered by preference? I would then set something like player = ["spotify", "cmus"]. if neither of these apps is running it can then assume control over youtube.

Alternatively we could also have an exclusion list to always ignore youtube, but that doesn't seem as good of a solution.

ammgws commented 4 years ago

Looks (partly) doable by modifying the get_first_available_player function. However you probably also need to do some work in the update function and perhaps other places in order to make it prioritise the correct player in all cases.

ammgws commented 4 years ago

I am currently refactoring the music block code and can probably attempt to solve this while I am there. I think we could add both an array of preferred players and also an ignore list. However since a tradition has been set of not breaking user's configs then need to think about how to accept both a string and array for the player config. Perhaps introduce a new config param called players and mark player as deprecated and remove it in the future.

Also, how do we want the block to behave when there are multiple preferred players currently outputting at the same time?

For example, in this scenario with player = ["spotify", "cmus"]:

Since spotify has a higher priority in the array, should the block switch straight away from cmus to spotify? Or only switch once cmus is closed or playback is paused/stopped?

Dieterbe commented 4 years ago

it seems rare that someone would play music from 2 players at the same time, but it's an interesting point nonetheless. perhaps if a user wants to accommodate this, they could instantiate 2 music blocks, one for each player (or more specifically, each block could be configured with a distinct (non-overlapping) set of players, for example, one for cmus, the other for spotify, youtube or anything else). this also solves the other problems with this kind of approach (e.g. you'd probably want to visualize both songs that are playing, or be able to control both players separately) this then allows any music block to "focus" on the player that it considers to be highest prio, and is playing music.

there are some other special cases thoughe. eg with ["spotify","cmus"] if you start with cmus, pause it through the bar, you can't unpause a song in spotify, you have to do it through the spotify app, and likewise, you can pause in spotify but not unpause cmus from the bar. I think this is reasonable though. typically when you want to switch between players, you don't just want to unpause the last song. I see switching players as a new "session" in which the user probably wants to pick a new artist/album anyway, and thus will want to use the app anyway. (if this is not the case, then the dual-block approach should solve it)

BTW is there still a use for an ignore list if we already have the players array? i don't see it.

ammgws commented 4 years ago

BTW is there still a use for an ignore list if we already have the players array? i don't see it.

Currently if you specify a player in the config and the block cannot find it, it will instead choose the first one it finds on the bus. This behaviour would be the same even with the players array. While testing I found it sometimes attaching to my phone via kdeconnect's MPRIS interface, which lead me to understand the use-case so I ended up adding an ignore list in #888.

Dieterbe commented 4 years ago

I see. so in your case it sounds like you never want to control your phone through i3status-rust. For me, there is no player that I "never want to see". I merely have players (e.g. youtube) that i consider to be "least important" (only show if nothing else is active)

would it be possible to have a button in a music block to make it expand/collapse? in that case perhaps we should just scrap the idea of a list of prioritized players per block. it seems more robust and cleaner to define multiple blocks, one for each player, and blocks can be collapsed either if the player is not up, or manually

ammgws commented 4 years ago

For example this is the current block when there is no player found: image

Is your idea that you would click on the icon to make it collapse to this state even when it is playing something? Or to hide the block completely when there is no player like some other blocks do?

Dieterbe commented 4 years ago

Definitely the first. I'm not sure about the 2nd. While it seems cleaner to completely hide the block if the player is not running, it also removes all contact surface which could otherwise be used to start the player by means of a click handler. personally that wouldn't bother me so much as i can easily start my player(s) through other means (e.g. dmenu)

PS my collapsed block looks like this. perhaps i'm missing an icon or something? (all other icons work fine though, see full bar below) music bar

ammgws commented 4 years ago

Currently if you specify a player in the config and the block cannot find it, it will instead choose the first one it finds on the bus.

Actually I think I'm wrong. Have been messing around with the code too much but looks like it originally only auto discovers if you never specify a player in the config

ammgws commented 4 years ago

After #906 is merged, we will be able to correctly track all current players. Further work could be then be done to allow the block to cycle between players by right clicking on the block, which will allow you to control whatever players you want from the same block.

Dieterbe commented 4 years ago

oh that's an interesting idea as well! comparing it to the idea of multiple blocks, it becomes a tradeoff between space usage of the block(s) vs clicks needed to do/see what you want.