Created
March 2, 2023 22:58
-
-
Save p3nj/a76b2000f4cd324ce9a7e5584e531d49 to your computer and use it in GitHub Desktop.
monitor multiple players via playerctl with python script modified version
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import argparse | |
import logging | |
import sys | |
import signal | |
import gi | |
import json | |
gi.require_version('Playerctl', '2.0') | |
from gi.repository import Playerctl, GLib | |
logger = logging.getLogger(__name__) | |
def write_output(text, player): | |
logger.info('Writing output') | |
output = {'text': text, | |
'class': 'custom-' + player.props.player_name, | |
'alt': player.props.player_name} | |
sys.stdout.write(json.dumps(output) + '\n') | |
sys.stdout.flush() | |
def on_play(player, status, manager): | |
logger.info('Received new playback status') | |
on_metadata(player, player.props.metadata, manager) | |
def on_metadata(player, metadata, manager): | |
logger.info('Received new metadata') | |
track_info = '' | |
if player.props.player_name == 'spotify' and \ | |
'mpris:trackid' in metadata.keys() and \ | |
':ad:' in player.props.metadata['mpris:trackid']: | |
track_info = 'AD PLAYING' | |
elif player.get_artist() != '' and player.get_title() != '': | |
track_info = '{artist} - {title}'.format(artist=player.get_artist(), | |
title=player.get_title()) | |
else: | |
track_info = player.get_title() | |
if player.props.status != 'Playing' and track_info: | |
track_info = ' ' + track_info | |
else: | |
track_info = ' ' + track_info | |
write_output(track_info, player) | |
def on_player_appeared(manager, player, selected_player=None): | |
if player is not None and (selected_player is None or player.name == selected_player): | |
init_player(manager, player) | |
else: | |
logger.debug("New player appeared, but it's not the selected player, skipping") | |
def on_player_vanished(manager, player): | |
logger.info('Player has vanished') | |
sys.stdout.write('\n') | |
sys.stdout.flush() | |
def init_player(manager, name): | |
logger.debug('Initialize player: {player}'.format(player=name.name)) | |
player = Playerctl.Player.new_from_name(name) | |
player.connect('playback-status', on_play, manager) | |
player.connect('metadata', on_metadata, manager) | |
manager.manage_player(player) | |
on_metadata(player, player.props.metadata, manager) | |
def signal_handler(sig, frame): | |
logger.debug('Received signal to stop, exiting') | |
sys.stdout.write('\n') | |
sys.stdout.flush() | |
# loop.quit() | |
sys.exit(0) | |
def parse_arguments(): | |
parser = argparse.ArgumentParser() | |
# Increase verbosity with every occurrence of -v | |
parser.add_argument('-v', '--verbose', action='count', default=0) | |
# Define for which player we're listening | |
parser.add_argument('--player') | |
parser.add_argument('--ignore') | |
return parser.parse_args() | |
def main(): | |
arguments = parse_arguments() | |
# Initialize logging | |
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG, | |
format='%(name)s %(levelname)s %(message)s') | |
# Logging is set by default to WARN and higher. | |
# With every occurrence of -v it's lowered by one | |
logger.setLevel(max((3 - arguments.verbose) * 10, 0)) | |
# Log the sent command line arguments | |
logger.debug('Arguments received {}'.format(vars(arguments))) | |
manager = Playerctl.PlayerManager() | |
loop = GLib.MainLoop() | |
manager.connect('name-appeared', lambda *args: on_player_appeared(*args, arguments.player)) | |
manager.connect('player-vanished', on_player_vanished) | |
signal.signal(signal.SIGINT, signal_handler) | |
signal.signal(signal.SIGTERM, signal_handler) | |
signal.signal(signal.SIGPIPE, signal.SIG_DFL) | |
ignores = [] | |
players = [] | |
if arguments.player is not None: | |
players = arguments.player.split(',') | |
if arguments.ignore is not None: | |
ignores = arguments.ignore.split(',') | |
for player in manager.props.player_names: | |
if len(players) != 0 and player.name in players: | |
init_player(manager, player) | |
elif len(ignores) != 0 and player.name in ignores: | |
logger.debug('{player} is not the filtered player, skipping it' | |
.format(player=player.name)) | |
else: | |
init_player(manager, player) | |
loop.run() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment