Skip to content

Commit

Permalink
Better music control when multiple players
Browse files Browse the repository at this point in the history
  • Loading branch information
fortes committed Nov 20, 2023
1 parent d3b511c commit 3f6b6d6
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 77 deletions.
161 changes: 161 additions & 0 deletions stowed-files/playerctl/.local/bin/music-control
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#!/usr/bin/python3
# Usage: music-control [toggle] [previous] [next]

# Note: Must be run from distro python, since venv doesn't work with PythonGObject

import gi
import os
import subprocess
import sys

# Must call this before importing Playerctl
gi.require_version("Playerctl", "2.0")
from gi.repository import Playerctl

def select_option(options, prompt="Player: "):
if len(options) == 1:
return options[0]

if os.environ.get("WAYLAND_DISPLAY"):
result = subprocess.run(
[
"fuzzel",
"--dmenu",
"--lines=%s" % (len(options) + 1),
"--prompt=%s" % prompt,
],
encoding="utf-8",
input=("\n".join(options) + "\n"),
text=True,
stdout=subprocess.PIPE,
)
else:
result = subprocess.run(
["fzf", "--prompt=%s" % prompt],
encoding="utf-8",
input=("\n".join(options) + "\n"),
stdout=subprocess.PIPE,
text=True,
)
if result.returncode != 0:
print("Non-zero FZF return code")
sys.exit(1)
selected_option = result.stdout.strip()
return selected_option


def get_track_info(player):
keys = player.props.metadata.keys()
if "xesam:albumArtist" in keys:
return "%s - %s" % (
player.props.metadata["xesam:albumArtist"][0],
player.get_title(),
)
elif "xesam:artist" in keys:
return "%s - %s" % (
player.props.metadata["xesam:artist"][0],
player.get_title(),
)
else:
return player.get_title()


# In priority order, use: `notify-send`, `tmux`, shell output
def notify(msg, opts={}):
title = opts.get("title", None) or 'Music'
if os.environ.get("WAYLAND_DISPLAY"):
app_name = opts.get("app_name", None) or "Music"
icon = opts.get("icon", None) or "audio-headphones-symbolic"
urgency = opts.get("urgency", None) or "low"
subprocess.run(
[
"notify-send",
"--app-name=%s" % app_name,
"--urgency=%s" % urgency,
"--icon=%s" % icon,
title,
msg,
]
)
elif os.environ.get("TMUX"):
subprocess.run(
[
"tmux",
"display-message",
"%s: %s"
% (
title,
msg,
)
if title
else msg,
]
)
else:
print(
"%s: %s"
% (
title,
msg,
)
if title
else msg
)


def main():
player_list = Playerctl.list_players()

all_players = [Playerctl.Player.new_from_name(player) for player in player_list]

players = [player for player in all_players if player.props.status == "Playing"]
player_state = "playing"
if len(players) == 0:
players = [player for player in all_players if player.props.status == "Paused"]
player_state = "paused"

if len(players) == 0:
notify("No active players", {"app_name": "Music", "urgency": "normal"})
sys.exit()

# Prompt for which player to pause
selected_name = select_option([player.props.player_name for player in players])
selected_player = [
player for player in players if player.props.player_name == selected_name
][0]
selected_status = selected_player.props.status

action = sys.argv[1] if len(sys.argv) > 1 else "toggle"

# Perform the requested action
if action == "toggle":
selected_player.play_pause()
notify(
get_track_info(selected_player),
{
"app_name": selected_name,
"title": "Paused" if selected_status == "Playing" else "Playing",
},
)
elif action == "previous" or action == "next":
if player_state == "paused":
selected_player.play()
if action == "previous":
selected_player.previous()
else:
selected_player.next()

notify(
get_track_info(selected_player),
{
"app_name": selected_name,
"title": action.capitalize(),
},
)
else:
notify("Invalid argument %s. Use 'play/pause', 'previous', or 'next'." % action)
sys.exit(1)


if __name__ == "__main__":
main()
68 changes: 0 additions & 68 deletions stowed-files/playerctl/.local/bin/music-pause

This file was deleted.

8 changes: 4 additions & 4 deletions stowed-files/playerctl/.local/bin/tmux-music-menu
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ main() {
local artist
local album

play_status=$(playerctl status 2>&1 || echo)
play_status=$(playerctl -p cmus status 2>&1 || echo)
if echo "${play_status}" | grep -qiE '(no players found|stopped)'; then
tmux display-message "Not playing music"
return
Expand All @@ -35,9 +35,9 @@ main() {
"-Album #[nodim align=right]${album:0:60}" "" "" \
"-Genre #[nodim align=right]${genre:0:60}" "" "" \
"" \
"Previous" "z" "run-shell -b 'playerctl previous'" \
"${verb}" "c" "run-shell -b 'playerctl play-pause'" \
"Next" "b" "run-shell -b 'playerctl next'" \
"Previous" "z" "run-shell -b 'music-control previous'" \
"${verb}" "c" "run-shell -b 'music-control toggle'" \
"Next" "b" "run-shell -b 'music-control next'" \
"" \
"Close" "q" ""
}
Expand Down
6 changes: 3 additions & 3 deletions stowed-files/sway/.config/sway/config
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ bindsym XF86AudioLowerVolume exec wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
bindsym XF86AudioMute exec wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
# And music control
# TODO: Detect multiple players, also show notification
bindsym XF86AudioPrev exec playerctl previous
bindsym XF86AudioPlay exec playerctl play-pause
bindsym XF86AudioNext exec playerctl next
bindsym XF86AudioPrev exec music-control previous
bindsym XF86AudioPlay exec music-control toggle
bindsym XF86AudioNext exec music-control next

# Screen capture
# Plain print screen captures active window
Expand Down
4 changes: 2 additions & 2 deletions stowed-files/tmux/.config/tmux/tmux.conf
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,10 @@ if-shell 'test -n "${IS_DOCKER}"' {
if-shell 'command -v playerctl' {
# Pause music via 'u', or click on right status
bind-key -N "Pause music" u {
run-shell -b "music-pause -t"
run-shell -b "music-control"
}
bind-key -N "Pause music" -Troot MouseUp1StatusRight {
run-shell -b "music-pause -q"
run-shell -b "music-control"
}
# Music menu via 'U' or right click on right status
Expand Down

0 comments on commit 3f6b6d6

Please sign in to comment.