led-matrix-player/main.py

261 lines
8.3 KiB
Python
Raw Permalink Normal View History

2020-12-19 20:13:22 +00:00
import sys
import spotipy
import spotipy.util as util
2020-12-19 20:34:44 +00:00
import config as cfg
2020-12-19 23:53:44 +00:00
from PIL import Image, ImageDraw, ImageFont
2020-12-19 21:32:34 +00:00
import asyncio
2020-12-19 21:08:07 +00:00
from rgbmatrix import RGBMatrix, RGBMatrixOptions
2020-12-19 21:41:21 +00:00
import threading
2020-12-19 20:13:22 +00:00
import requests
from io import BytesIO
2020-12-19 21:42:40 +00:00
import time
2020-12-20 20:27:31 +00:00
from datetime import datetime
2020-12-19 20:13:22 +00:00
2020-12-19 20:34:44 +00:00
client_id = cfg.client_id
client_secret = cfg.client_secret
redirect_uri = cfg.redirect_uri
username = cfg.username
2020-12-19 20:13:22 +00:00
scope = 'user-read-currently-playing'
2020-12-19 21:08:07 +00:00
options = RGBMatrixOptions()
options.rows = 32
options.cols = 64
options.chain_length = 6
options.parallel = 2
options.hardware_mapping = 'regular'
options.pixel_mapper_config = 'U-mapper'
options.limit_refresh_rate_hz = 240
options.gpio_slowdown = 4
2020-12-19 23:11:54 +00:00
options.brightness = 50
2020-12-20 01:33:05 +00:00
options.disable_hardware_pulsing = True
2020-12-19 22:37:17 +00:00
screen = RGBMatrix(options = options)
2020-12-19 21:08:07 +00:00
2020-12-19 23:25:53 +00:00
song_name=""
artist_name=""
2020-12-19 20:13:22 +00:00
2020-12-20 01:29:10 +00:00
cache_path="/home/pi/.cache-"+username
2020-12-20 01:27:54 +00:00
2020-12-20 00:14:55 +00:00
is_playing = False
2020-12-19 20:34:44 +00:00
2020-12-20 12:50:39 +00:00
is_scrolling_art = False
2020-12-20 12:19:49 +00:00
cover_art_offset_x = 0
cover_art_offset_y = 96
2020-12-20 13:27:43 +00:00
last_cover_art = Image.new('RGB',(32,32),color='white')
2020-12-20 13:34:09 +00:00
last_song = ''
2020-12-20 13:40:45 +00:00
last_artist = ''
2020-12-20 13:08:24 +00:00
2020-12-20 13:48:48 +00:00
current_cover_art = Image.new('RGB',(32,32),color='white')
current_song = ''
current_artist = ''
2020-12-20 01:14:12 +00:00
token = None #oauth2.SpotifyOAuth(username, scope, client_id, client_secret, redirect_uri)
#token = util.prompt_for_user_token(username, scope, client_id, client_secret, redirect_uri)
2020-12-19 20:13:22 +00:00
2020-12-19 23:56:40 +00:00
font = ImageFont.load_default()
2020-12-20 20:39:42 +00:00
clock_font = ImageFont.truetype(font='BebasNeue_Regular_1.otf', size=75)
2020-12-19 23:08:08 +00:00
2020-12-20 13:18:41 +00:00
2020-12-19 21:39:56 +00:00
def get_track():
2020-12-20 00:18:15 +00:00
print('getting current song info')
2020-12-19 20:13:22 +00:00
sp = spotipy.Spotify(auth=token)
2020-12-19 20:52:10 +00:00
track = sp.currently_playing()
2020-12-20 12:15:03 +00:00
if track is None:
2020-12-20 19:10:54 +00:00
return Image.new('RGB',(32,32),color='black')
2020-12-20 00:14:55 +00:00
global is_playing
is_playing = track['is_playing']
2020-12-19 23:25:53 +00:00
global song_name
2020-12-20 19:09:59 +00:00
if track is None:
2020-12-20 19:10:54 +00:00
return Image.new('RGB',(32,32),color='black')
2020-12-19 23:25:53 +00:00
song_name = track['item']['name']
global artist_name
2020-12-20 00:23:21 +00:00
artist_name = track['item']['artists'][0]['name']
for i in range(len(track['item']['artists'])-1):
2020-12-20 00:23:50 +00:00
artist_name +=', ' + track['item']['artists'][i+1]['name']
2020-12-20 09:59:44 +00:00
print('got info: ' + track['item']['name'] + ' - ' + track['item']['artists'][0]['name'])
2020-12-20 00:18:03 +00:00
#print('getting image')
2020-12-19 22:25:47 +00:00
image_url = track['item']['album']['images'][0]['url']
response = requests.get(image_url)
2020-12-19 22:26:03 +00:00
image = Image.open(BytesIO(response.content))
2020-12-20 00:18:34 +00:00
#print(image_url)
2020-12-19 22:32:57 +00:00
image = image.resize((32,32))
2020-12-19 23:08:08 +00:00
return image
2020-12-19 23:02:58 +00:00
def showImage(image, offset_x = 0, offset_y = 0):
2020-12-19 23:21:58 +00:00
image = image.convert('RGB')
2020-12-19 23:02:58 +00:00
width, height = image.size
for x in range(width):
for y in range(height):
2020-12-19 22:43:44 +00:00
r, g, b = image.getpixel((x, y))
2020-12-19 22:44:21 +00:00
screen.SetPixel(x+offset_x,y+offset_y,r,g,b)
2020-12-19 23:02:58 +00:00
2020-12-20 13:48:48 +00:00
def changeSong():
scrollDownSongInfo(song_name=last_song,artist_name=last_artist,cover_art=last_cover_art)
scrollUpSongInfo(song_name=current_song,artist_name=current_artist,cover_art=current_cover_art)
2020-12-19 21:27:06 +00:00
2020-12-19 23:08:08 +00:00
2020-12-19 23:19:07 +00:00
def drawCanvas():
2020-12-19 23:28:49 +00:00
canvas = Image.new('RGB', (192, 128), color = 'black')
2020-12-20 13:08:24 +00:00
global last_song
2020-12-20 13:40:45 +00:00
global last_artist
2020-12-20 12:30:53 +00:00
was_playing = is_playing
2020-12-20 13:08:24 +00:00
2020-12-20 00:15:58 +00:00
cover_art = get_track()
2020-12-20 13:08:24 +00:00
2020-12-20 12:50:39 +00:00
global is_scrolling_art
2020-12-20 12:51:16 +00:00
if (cover_art is None):
2020-12-20 11:17:56 +00:00
return
2020-12-20 13:40:45 +00:00
2020-12-20 13:08:24 +00:00
if not (last_song == song_name):
2020-12-20 13:48:48 +00:00
change_song_scroll = threading.Thread(target=changeSong)
2020-12-20 13:40:45 +00:00
change_song_scroll.start()
2020-12-20 13:48:48 +00:00
last_song=song_name
last_artist = artist_name
2020-12-20 13:50:33 +00:00
global last_cover_art
2020-12-20 13:31:20 +00:00
last_cover_art = cover_art
2020-12-20 13:48:48 +00:00
global current_cover_art
current_cover_art = cover_art
global current_song
current_song = song_name
global current_artist
current_artist = artist_name
2020-12-20 12:30:53 +00:00
if(was_playing and not is_playing):
2020-12-20 12:50:39 +00:00
is_scrolling_art = True
2020-12-20 12:31:55 +00:00
scroll = threading.Thread(target=scrollDownSongInfo)
scroll.start()
2020-12-20 12:50:39 +00:00
2020-12-20 12:44:57 +00:00
if(not was_playing and is_playing):
2020-12-20 12:50:39 +00:00
is_scrolling_art = True
2020-12-20 12:44:57 +00:00
scroll = threading.Thread(target=scrollUpSongInfo)
scroll.start()
2020-12-20 12:51:16 +00:00
if is_scrolling_art:
return
2020-12-20 00:14:55 +00:00
if(is_playing):
2020-12-20 12:30:53 +00:00
canvas.paste(cover_art,(cover_art_offset_x,cover_art_offset_y))
2020-12-20 00:13:57 +00:00
songinfo = ImageDraw.Draw(canvas)
songinfo_offset_x = 33
songinfo_offset_y = 101
2020-12-20 00:54:49 +00:00
songinfo.text((songinfo_offset_x,songinfo_offset_y+11), song_name)
2020-12-20 00:13:57 +00:00
songinfo.text((songinfo_offset_x,songinfo_offset_y), artist_name)
2020-12-19 23:46:17 +00:00
2020-12-20 00:13:57 +00:00
#scrolling_text(song_name,songinfo_offset_x, songinfo_offset_y+10)
2020-12-20 00:48:33 +00:00
if(font.getsize(song_name)[0]>160):
2020-12-20 00:54:49 +00:00
x = threading.Thread(target=scrolling_text,args=(song_name,songinfo_offset_x,songinfo_offset_y+11))
2020-12-20 00:13:57 +00:00
x.start()
print('scrolling text started')
2020-12-20 00:48:33 +00:00
if(font.getsize(artist_name)[0]>160):
2020-12-20 00:22:50 +00:00
2020-12-20 00:48:33 +00:00
y = threading.Thread(target=scrolling_text,args=(artist_name,songinfo_offset_x,songinfo_offset_y))
2020-12-20 00:13:57 +00:00
y.start()
2020-12-20 00:22:50 +00:00
2020-12-20 20:33:16 +00:00
#showImage(canvas)
2020-12-19 23:47:41 +00:00
2020-12-20 13:33:27 +00:00
def scrollDownSongInfo(offset_x=0,offset_y=96, song_name=song_name, artist_name=artist_name, cover_art=last_cover_art):
2020-12-20 12:50:39 +00:00
global is_scrolling_art
2020-12-20 13:08:24 +00:00
#cover_art = get_track()
2020-12-20 12:30:53 +00:00
if (cover_art is None):
return
2020-12-20 12:42:58 +00:00
for i in range(33):
2020-12-20 12:35:50 +00:00
song_info_canvas = Image.new('RGB', (192,32), color = 'black')
songinfo = ImageDraw.Draw(song_info_canvas)
2020-12-20 12:30:53 +00:00
songinfo_offset_x = 33
2020-12-20 12:54:19 +00:00
songinfo.text((songinfo_offset_x,15+i), song_name)
songinfo.text((songinfo_offset_x,4+i), artist_name)
2020-12-20 12:42:27 +00:00
song_info_canvas.paste(cover_art,(0,i))
2020-12-20 12:40:20 +00:00
showImage(song_info_canvas, offset_x, offset_y)
2020-12-20 12:48:27 +00:00
time.sleep(0.001)
2020-12-20 12:50:39 +00:00
is_scrolling_art = False
2020-12-20 12:30:53 +00:00
2020-12-20 13:33:27 +00:00
def scrollUpSongInfo(offset_x=0, offset_y=96, song_name=song_name, artist_name=artist_name, cover_art=last_cover_art):
2020-12-20 12:50:39 +00:00
global is_scrolling_art
2020-12-20 13:08:24 +00:00
#cover_art = get_track()
2020-12-20 12:44:57 +00:00
if (cover_art is None):
return
for i in range(33):
song_info_canvas = Image.new('RGB', (192,32), color = 'black')
songinfo = ImageDraw.Draw(song_info_canvas)
songinfo_offset_x = 33
2020-12-20 12:54:19 +00:00
songinfo.text((songinfo_offset_x,15+(33-i)), song_name)
songinfo.text((songinfo_offset_x,4+(33-i)), artist_name)
2020-12-20 12:55:07 +00:00
song_info_canvas.paste(cover_art,(0,(32-i)))
2020-12-20 12:44:57 +00:00
showImage(song_info_canvas, offset_x, offset_y)
2020-12-20 12:48:27 +00:00
time.sleep(0.001)
2020-12-20 12:50:39 +00:00
is_scrolling_art = False
2020-12-19 23:47:41 +00:00
2020-12-20 00:48:33 +00:00
def scrolling_text(text,offset_x=0,offset_y=0):
2020-12-20 20:26:08 +00:00
scroll_frame_time = (6/2)/(font.getsize(text)[0]-160)
2020-12-20 00:53:00 +00:00
#print(scroll_frame_time)
2020-12-20 11:31:47 +00:00
if(scroll_frame_time>0.03):
scroll_frame_time = 0.03
2020-12-20 11:23:21 +00:00
for i in range((font.getsize(text)[0]-160)):
2020-12-20 00:32:02 +00:00
scrolled_text_canvas = Image.new('RGB', (160, 11), color = 'black')
2020-12-20 00:08:31 +00:00
scrolled_text = ImageDraw.Draw(scrolled_text_canvas)
2020-12-20 11:23:21 +00:00
scrolled_text.text((-i,0), text)
2020-12-20 00:08:31 +00:00
showImage(scrolled_text_canvas, offset_x, offset_y)
2020-12-20 11:23:21 +00:00
time.sleep(scroll_frame_time)
2020-12-20 00:11:32 +00:00
#print('scrolled '+str(i)+' px')
2020-12-20 00:50:32 +00:00
if((5-(font.getsize(text)[0]-160)*2*scroll_frame_time)>0):
2020-12-20 00:48:33 +00:00
time.sleep(5-(font.getsize(text)[0]-160)*2*scroll_frame_time)
2020-12-20 00:08:31 +00:00
for i in range(font.getsize(text)[0]-160):
2020-12-20 00:32:02 +00:00
scrolled_text_canvas = Image.new('RGB', (160, 11), color = 'black')
2020-12-20 00:08:31 +00:00
scrolled_text = ImageDraw.Draw(scrolled_text_canvas)
2020-12-20 00:10:48 +00:00
scrolled_text.text(((-(font.getsize(text)[0]-160))+i+1,0), text)
2020-12-20 00:08:31 +00:00
showImage(scrolled_text_canvas, offset_x, offset_y)
2020-12-20 00:48:33 +00:00
time.sleep(scroll_frame_time)
2020-12-20 00:11:32 +00:00
#print('scrolled '+str(i)+' px')
2020-12-20 00:10:48 +00:00
2020-12-19 23:46:17 +00:00
2020-12-20 01:14:12 +00:00
def main():
get_access_token()
2020-12-20 20:26:08 +00:00
clock = threading.Thread(target=drawClock)
clock.start()
print('led-matrix-viewer started')
while True:
get_access_token()
drawCanvas()
time.sleep(10)
def drawClock():
while True:
2020-12-20 20:30:15 +00:00
canvas = Image.new('RGB', (128,64), color = 'black')
2020-12-20 20:26:33 +00:00
clock_text = ImageDraw.Draw(canvas)
2020-12-20 20:35:08 +00:00
clock_text.text((0,0), datetime.now().strftime("%H:%M"), font = clock_font, align = "center")
2020-12-20 20:26:33 +00:00
showImage(canvas, 32, 0)
2020-12-20 20:36:39 +00:00
time.sleep(20)
2020-12-20 20:26:08 +00:00
2020-12-20 01:14:12 +00:00
2020-12-20 13:32:21 +00:00
def get_access_token():
global token
sp_oauth = spotipy.SpotifyOAuth(
client_id,
client_secret,
redirect_uri,
scope=scope,
#cache_path=cache_path,
username=username,
open_browser=False
)
token_info = sp_oauth.get_cached_token()
2020-12-20 01:14:12 +00:00
2020-12-20 13:32:21 +00:00
if not token_info:
code = sp_oauth.get_auth_response()
token = sp_oauth.get_access_token(code, as_dict=False)
else:
if sp_oauth.is_token_expired(token_info):
token_info = refresh_access_token(token_info)
token = token_info["access_token"]
2020-12-20 01:14:12 +00:00
2020-12-20 13:20:06 +00:00
2020-12-19 22:24:11 +00:00
if __name__ == "__main__":
2020-12-20 01:14:12 +00:00
main()
2020-12-19 23:08:08 +00:00
2020-12-19 21:42:40 +00:00
2020-12-19 21:39:56 +00:00
2020-12-19 23:46:17 +00:00
2020-12-19 21:39:56 +00:00