-
-
Notifications
You must be signed in to change notification settings - Fork 261
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add playerctl module #2211
Add playerctl module #2211
Conversation
Does
I think it was brought up in the past and possibly coded, but not implemented.
Actually, I wanted to treat this as a loop of players, so all players that comes and go would appear on the bar along with its own buttons.
|
Yes, that works perfectly!
If desired, I can make a PR implementing this config option for every module. It would be similar to the
Sounds good. I'll make the change. How would buttons be done? None of the modules you shared had support for |
If you desire it, then go and make it.
Note: I made many things and some unreleased code / unmerged PRs may contain this. IIRC, essentially, it's done by making a composite first with ( In main method, you should create unique usable Inside Get a loop of players to work first, then it's a minimal fix to add This should work in |
@lasers, I finished your requested changes. The colors and indices work for each player separately. Should I document how to select the index? The index is the player name, not the player instance because playerctl does not track two of the same player (at least for browsers, so I assume every player). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not tested yet. Progress looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See git grep -A15 'class Meta' py3status/modules/loadavg.py
for amending :escape
to specific placeholder(s).
I decided to automatically add I also added support for Another important issue that I want to solve before this is officially added is the i3bar exiting unexpectedly when a browser instance is closed. I get the error |
Nice on adding
No particular reason other than fnmatch is being used in many modules already (and possibly not needed). If you need to negate something, then we can roll back. Not familiar with playerctld. I assume users would do no more than to target their favorite players or just ignore that one player (ie wanting all information from playerctl).
I see your issue. I wonder if it had to do something with Glib/Thread loop. I toyed with your module some in virtual machine. For me, it is chromium that crashes it. Firefox does it okay. I don't think it's worth creating individual buttons (like mpris) since clicking full player does the job and is friendly enough. This is going to be a nice module for many users... and we probably should remove I think we need to look at
Imho, I would add |
I fixed the crash that was happening by adding a very small delay ( I found out that the reason for this is because Playerctl is not given enough time to remove the player from the manager before this module retrieves tracked players. It would then error when getting Additionally, I removed the |
Hey @lasers, I believe I have addressed every one of your points. Please let me know if you have any other suggestions. Thanks very much for helping improve this module a lot! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did this get everything it can? (shuffle, loop, volume status, mute, et cetera).
Scrolling mouse on player to seek forward / backward?
Scrolling mouse to change volume?
Clicking to mute? Things like that.
Remember, we want to be better than mpris / player_control if we can. ;-)
Otherwise, it looks great to go after one or two more iterations.
Hey @lasers, I finished adding support for everything I think is possible with Playerctl. This includes displaying and changing the volume, shuffle mode, loop status, and seeking forward/backward with buttons. While doing this, I noticed a few odd behaviors. Cmus changes the volume and loop status (not shuffle) using playerctl, but playerctl does not respond to updates from the player, so it effectively does not work. For example, to increase the volume, the current volume is added to a I also looked into how to mute the players, but there is no specific functionality to mute using MPRIS. Setting the volume to 0 doesn't work because this module doesn't remember the previous volume (cmus also doesn't mute correctly natively). If you have any suggestions to do this, I would be happy to add them. However, it seems infeasible because it depends on the player's volume integrating well with playerctl and the volume before mute might need to persist even when py3status restarts. Last, I added a better caching algorithm so the module only updates when necessary. |
time.sleep(0.01) | ||
self.py3.update() | ||
|
||
def _loop_status_changed(self, player, loop_status, manager): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could point these event handlers (loop, volume, metadata, etc.) to the same function to simplify the code a little. However, that might not be best practice since the parameters are of different types (even though it is the same number of them). Additionally, it wouldn't allow extensibility in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it couldn't be helped with excessive buttons... Sometimes I wonder having excessive buttons in the modules is one of annoying thing about modules... and thought about making buttons = {"volume_up": 4, "volume_down": 5}
dict config to make it go from 12 down to 1. I think that could be not friendly for users too.
Everything playerctl offer now is supported by this module too.
Nice job. 🥇
You should make a PR to remove |
I wouldn't be opposed to adding a dictionary for the buttons. However, it doesn't follow the configuration of other modules so it might be more confusing to users than just having 12 button configuration values. |
There are a few other modules that could possibly be removed as well.
All of the above don't appear to provide any more data/functionality that this module can provide. I don't think Is there a process to removing modules, similar to deprecating configs? |
Not linking to unrelated pulls.
|
Meanwhile, I would be grateful if you could rebase your branch with current master (I changed quite a lot of things regarding to CI and build system). |
Now, all players tracked by playerctl will be displayed side by side, similar to how the bluetooth module displays multiple devices at once.
default Many titles (especially from browsers) have invalid characters which would cause them not to show up. Therefore, they will be escaped using `:escape` automatically. Also, `format_separator` was renamed to `format_player_separator`.
These issues were only seen on browsers. When a player closed, sometimes the module would update faster than it took Playerctl to remove the player. Therefore, a crash would happen because this module would try to access metadata for a player that didn't exist anymore. Now, a very slight delay before updating fixes this issue.
when no title exists When a new player appears, the timeout will be set from CACHE_FOREVER to self.cache_timeout, ensuring the module only updates when a player is actually being tracked. A couple of functions were reorganized to provide more logical grouping.
The `cache_timeout` config option is now removed and defaults to 1 second only if the user has the {position} placeholder in the format and players are being tracked. Otherwise, the module will be cached forever and will only update when players appear/disappear, status changes, or metadata changes.
In order for the module to update continuously, a couple of things need to happen: 1. The {position} placeholder needs to be used 2. At least one player needs to be playing AND have a valid position Also, the status strings were changed to represent the defaults provided by playerctl instead of doing a .lower() call. The cache_timeout is exposed as a valid configuration option, but it is hidden to give the users the impression that the module's updates are done automatically and not on an interval.
This commit adds functionality for a few more controls: 1. Cycling the loop status of the player (None, playlist, Track) 2. Seeking the playback back and forth 3. Toggling shuffle mode of the player 4. Changing the volume of the player Additionally, a few more player/track properties were added: loop_status, shuffle, trackNumber, and volume Some players don't support these features (e.g. web browsers). Also, some players, such as cmus, don't integrate well with shuffle, loop status, and volume changing. This is most likely due to a limitation of cmus and its communication with MPRIS rather than playerctl as controlling Spotify with this module works as expected for all controls.
Thanks @ultrabug. I rebased my branch, so let me know if anything else should be done. |
This is more of a configuration question (I didn't want to open a new issue for it. Maybe opening GitHub discussions could help users with similar questions), but how can I use multiple format specifiers? I want to escape the title and limit it to 15 characters, but my current configuration does not work even though it does in Python's f-string formatting (which this appears to be based off of). Here is what I tried: |
IIRC it's not from Python f-string formatting. Some things may behave like that. As for length, you may want |
Wrapping the title in a max_length block worked. Thanks! |
@ultrabug any updates to this? I’ve been using it for over a month now and it has worked very well for me. |
Thanks @ultrabug. The code QA commit did wrongly move an import from line 75 to 73 in this commit. When running the module in test mode ( Also, let me know if I should submit any PRs to deprecate modules that are similar to Playerctl's functionality but are old. I mentioned possible module deprecations here. |
@jdholtz indeed, CI was not happy about it. So if that doesn't break anything let's leave it.
It's hard to know which modules are used or not. I guess clementine and gpmdp are very old and unmaintained. I'm sure that spotify and mpris have a strong user base so I would not touch them. |
Fixes #2205.
This PR adds support for the playerctl module. It uses Playerctl's Python binding library to monitor and extract information from players. Most of the configuration options are the same as the
cmus
module. There are three more added:button_shift
,button_unshift
, andignored_players
.An important thing to note: If any text sent to i3bar contains an
&
, the text will not render. The&
is common in videos and therefore creates a problem. I also see this issue in thecmus
module, so it isn't directly an issue with this module, but should be solved to provide users with a better experience.There are two ways I see solving this:
str.replace("&", "and")
I also have a few more configuration options in mind but would like to get others' opinions:
max_width
option to render the text with an...
if it is too long. There are a lot of videos that span half the i3bar. However, I am not sure if this can be handled in Py3status's formatter or not.player_priority
option to initially select the active player. Currently, it selects the first one that playerctl selects. I don't think this option is necessary as I only see it being a factor during the post_config_hook (mostly only run when the user starts i3). After the initial start, active players will be cycled through by the most recent player to change status, metadata, or be opened. Additionally, configuration options are provided for the user to manually switch the active player (button_shift
andbutton_unshift
)This might remove the need for the
mpris
module, but more information about a player is provided in that module so that be good to still keep. Additionally, theplayer_control
module probably doesn't need to be kept as this module controls the same players.Any feedback is appreciated. I will be willing to maintain this module (fixing bugs, adding new features, refactoring, etc.).