aboutsummaryrefslogtreecommitdiff
path: root/waybar/custom_modules/media-player-status.py
blob: df348c7e24754fee2e3de94f9db5847264a1973c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/usr/bin/env python

import html
import json
import gi
import sys
gi.require_version('Playerctl', '2.0')
from gi.repository import Playerctl, GLib  # noqa: E402

ARTIST = 'xesam:artist'
TITLE = 'xesam:title'
ICONS = {
    'spotify': '阮 ',
    'ncspot': '阮 ',
    'vlc': '嗢 ',
    'firefox': ' ',
    'default': '契 ',
    'paused': ' '
}

last_status = None


def find_active_player(manager, vanished_player):
    for player in manager.props.players:
        if player == vanished_player:
            continue
        if player.props.playback_status != Playerctl.PlaybackStatus.STOPPED:
            return player
    return None


def get_status(manager, vanished_player):
    player = find_active_player(manager, vanished_player)
    if player is None:
        return '', '', 'stopped'
    name = player.props.player_name
    metadata = player.props.metadata
    title = metadata[TITLE] if TITLE in metadata.keys() else None
    artist = metadata[ARTIST][0] if ARTIST in metadata.keys() else None
    if name == 'firefox' and title == 'Firefox' and artist == 'Mozilla':
        title = None
        artist = None
    if player.props.playback_status == Playerctl.PlaybackStatus.PAUSED:
        css_class = 'paused'
    else:
        css_class = 'playing'
    if title is None and artist is None:
        if css_class == 'paused':
            icon = ICONS['paused']
        else:
            icon = ICONS['default']
            app_icon = ICONS.get(name, None)
        if app_icon is None:
            label = icon
        else:
            label = f'{icon} {app_icon}'
        return label, f'{name.title()}: {css_class.title()}', css_class
    if css_class == 'paused':
        icon = ICONS['paused']
    else:
        # Added override for icon
        #icon = ICONS.get(name, ICONS['default'])
        icon = ICONS['default']
    if title is None or title == '':
        song = artist or name.title()
    elif artist is None or artist == '':
        song = f'{title}'
    else:
        song = f'{artist} – {title}'
    html_song = html.escape(song)
    return f'{icon} {html_song}', f'{name.title()}: {song}', css_class


def print_status(manager, vanished_player=None):
    text, tooltip, css_class = get_status(manager, vanished_player)
    status = json.dumps({'text': text, 'tooltip': tooltip, 'class': css_class})
    global last_status
    if last_status != status:
        print(status)
        sys.stdout.flush()
        last_status = status


def on_playback_status(player, status, manager):
    manager.move_player_to_top(player)
    print_status(manager)


def on_metadata(player, metadata, manager):
    manager.move_player_to_top(player)
    print_status(manager)


def init_player(manager, name):
    player = Playerctl.Player.new_from_name(name)
    player.connect('playback-status', on_playback_status, manager)
    player.connect('metadata', on_metadata, manager)
    manager.manage_player(player)


def on_name_appeared(manager, name, _):
    init_player(manager, name)
    print_status(manager)


def on_player_vanished(manager, player, _):
    print_status(manager, player)


def init_manager():
    manager = Playerctl.PlayerManager()
    manager.connect('name-appeared', on_name_appeared, manager)
    manager.connect('player-vanished', on_player_vanished, manager)
    for name in manager.props.player_names:
        init_player(manager, name)
    print_status(manager)


if __name__ == '__main__':
    init_manager()
    main = GLib.MainLoop()
    main.run()