A now playing script for MPRIS and OBS (to be run as a systemd user service). Change the file path, music player name, etc. to whatever works for you
This file contains 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 | |
from PIL import Image | |
from PIL import ImageDraw | |
from PIL import ImageFont | |
import gi | |
gi.require_version('Playerctl', '2.0') | |
from gi.repository import Playerctl, GLib | |
image_filename = "/home/logan/Documents/nowplaying.png" | |
player_names = ["Lollypop"] | |
manager = Playerctl.PlayerManager() | |
img_width=500 | |
img_height=100 | |
font = ImageFont.truetype(font="DejaVuSans-Bold", size=20, index=0, encoding='') | |
def generate_image(player): | |
meta = player.props.metadata | |
image = Image.new(mode = "RGBA", size = (img_width,img_height), color = (0,0,0,0)) | |
if player.props.status == "Playing" and (meta['mpris:artUrl'] != None or meta['mpris:artUrl'] != ""): | |
art = Image.open(meta['mpris:artUrl'][7:]).resize((img_height, img_height)).convert("RGBA") | |
image.paste(art, (0,0), art) | |
if player.props.status == "Playing" and (meta['xesam:title'] != None or meta['xesam:title'] != ""): | |
draw = ImageDraw.Draw(image) | |
text = f"{meta['xesam:title']}\n{meta['xesam:artist'][0]}\n{meta['xesam:album']}" | |
draw.text((img_height+20-1,10-1), text, font=font, fill=(0,0,0)) | |
draw.text((img_height+20+1,10-1), text, font=font, fill=(0,0,0)) | |
draw.text((img_height+20-1,10+1), text, font=font, fill=(0,0,0)) | |
draw.text((img_height+20+1,10+1), text, font=font, fill=(0,0,0)) | |
draw.text((img_height+20,10), text, font=font, fill=(255,255,255)) | |
image.save(image_filename) | |
def on_play(player, status, manager): | |
print('player is playing: {}'.format(player.props.player_name)) | |
generate_image(player) | |
def on_pause(player, status, manager): | |
print('player is paused: {}'.format(player.props.player_name)) | |
generate_image(player) | |
def on_metadata(player, metadata, manager): | |
keys = metadata.keys() | |
if 'xesam:artist' in keys and 'xesam:title' in keys: | |
print('{} - {}\n{}'.format(metadata['xesam:artist'][0], metadata['xesam:title'], metadata['mpris:artUrl'])) | |
generate_image(player) | |
def init_player(name): | |
# choose if you want to manage the player based on the name | |
if name.name in player_names: | |
player = Playerctl.Player.new_from_name(name) | |
player.connect('playback-status::playing', on_play, manager) | |
player.connect('playback-status::paused', on_pause, manager) | |
player.connect('metadata', on_metadata, manager) | |
manager.manage_player(player) | |
def on_name_appeared(manager, name): | |
init_player(name) | |
generate_image(player) | |
def on_player_vanished(manager, player): | |
print('player has exited: {}'.format(player.props.player_name)) | |
generate_image(player) | |
manager.connect('name-appeared', on_name_appeared) | |
manager.connect('player-vanished', on_player_vanished) | |
for name in manager.props.player_names: | |
init_player(name) | |
main = GLib.MainLoop() | |
main.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment