reverse engineered Spotify Canvas API only available on iOS and Android displays short looping video for song in place of album when available
633 lines
23 KiB
Python
633 lines
23 KiB
Python
import spotipy
|
|
from spotipy.oauth2 import SpotifyOAuth
|
|
import tkinter as ttk
|
|
from tkinter import ttk as tk
|
|
import sv_ttk
|
|
import requests
|
|
import os
|
|
import syncedlyrics
|
|
from PIL import Image, ImageTk, ImageDraw, ImageFilter
|
|
from io import BytesIO
|
|
import math
|
|
from time import sleep, time
|
|
import threading
|
|
import queue
|
|
import numpy
|
|
from sys import exit
|
|
import _canvas as SpotifyCanvas
|
|
from _tkvideoplayer import TkinterVideo
|
|
from gc import collect as gc
|
|
|
|
# SpotifyGUI - Made by Brandon Brunson
|
|
|
|
# import speech_recognition as sr
|
|
if os.name == 'posix':
|
|
client_id = "df61ecadf09941eb87e693d37f3ad178"
|
|
client_secret = "ba97992d614e48d6b0d023998b2957cb"
|
|
os.system("xset -display :0 s 86400")
|
|
if os.path.isfile("updated.cfg"):
|
|
print("NEW VER")
|
|
os.remove("updated.cfg")
|
|
sleep(5)
|
|
else:
|
|
client_id = "69b82a34d0fb40be80b020eae8e80f25"
|
|
client_secret = "455575b0e3db44acbbfaa0c419bc3c10"
|
|
|
|
q = queue.Queue()
|
|
|
|
# import canvas
|
|
|
|
# development client id and secret (SpotifyGUI)
|
|
# client_id = "69b82a34d0fb40be80b020eae8e80f25"
|
|
# client_secret = "455575b0e3db44acbbfaa0c419bc3c10"
|
|
redirect_uri = "http://127.0.0.1:8888/callback"
|
|
|
|
# embeeded client id and secret (SpotifyGUI 2)
|
|
# client_id = "df61ecadf09941eb87e693d37f3ad178"
|
|
# client_secret = "ba97992d614e48d6b0d023998b2957cb"
|
|
|
|
# misc client id and secret (SpotifyGUI 3)
|
|
# client_id = "21ca0dc87c9441ceaf875a05d0199756"
|
|
# client_secret = "dd430e634ae94471aa70dfc22936be10"
|
|
|
|
# Set the user's Spotify username
|
|
username = "thebrandon45"
|
|
password = "Mariposa2502$"
|
|
|
|
# os.environ["DISPLAY"] = ":0"
|
|
|
|
# def setup():
|
|
# checkDisplay()
|
|
|
|
# def checkDisplay():
|
|
# while True:
|
|
# if os.name == 'posix':
|
|
# if "DISPLAY" in os.environ:
|
|
# break
|
|
# else:
|
|
# sleep(0.25)
|
|
# pass
|
|
# else:
|
|
# break
|
|
|
|
|
|
# Get the user's Spotify authorization token
|
|
scope = "user-read-playback-state,user-modify-playback-state,user-library-read,user-library-modify"
|
|
|
|
oauth = SpotifyOAuth(client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, scope=scope, requests_timeout=30)
|
|
|
|
# Create a Spotify object with the user's authorization token
|
|
spotify = spotipy.Spotify(auth_manager=oauth)
|
|
|
|
# access_token = SpotifyOAuth.get_access_token(spotify)
|
|
|
|
# print(SpotifyOAuth.refresh_access_token(refresh_token=access_token))
|
|
|
|
bg_color = "#000000"
|
|
count = 0
|
|
# wait_time = 6500
|
|
# hotword = "magical"
|
|
|
|
# sleep = False
|
|
|
|
# Create the tkinter window
|
|
root = ttk.Tk()
|
|
root.title("Media Controller")
|
|
root.geometry("1280x400")
|
|
root.attributes("-topmost", True)
|
|
if os.name == 'posix':
|
|
root.overrideredirect(1)
|
|
sv_ttk.use_dark_theme()
|
|
|
|
# Function to call the Spotify API to play the current track
|
|
def controlPlay():
|
|
spotify.start_playback()
|
|
|
|
# Function to call the Spotify API to pause the current track
|
|
def controlPause():
|
|
spotify.pause_playback()
|
|
|
|
def controlNext():
|
|
spotify.next_track()
|
|
|
|
def controlPrevious():
|
|
if track_progress < 5000:
|
|
spotify.previous_track()
|
|
else:
|
|
spotify.seek_track(0)
|
|
|
|
# def sleep():
|
|
# while not sleep:
|
|
# sleep(900000)
|
|
# kill(kill=sleep)
|
|
|
|
# development purposes
|
|
def kill(kill):
|
|
if kill is sleep:
|
|
exit(1)
|
|
|
|
def likeSong():
|
|
if spotify.current_user_saved_tracks_contains(tracks=[(spotify.current_playback()["item"]["id"])])[0] is False:
|
|
spotify.current_user_saved_tracks_add(tracks=[(spotify.current_playback()["item"]["id"])])
|
|
if isBright is True:
|
|
play_button.config(image=play_heart_img_black)
|
|
pause_button.config(image=pause_heart_img_black)
|
|
else:
|
|
play_button.config(image=play_heart_img)
|
|
pause_button.config(image=pause_heart_img)
|
|
else:
|
|
spotify.current_user_saved_tracks_delete(tracks=[(spotify.current_playback()["item"]["id"])])
|
|
if isBright is True:
|
|
play_button.config(image=play_img_black)
|
|
pause_button.config(image=pause_img_black)
|
|
else:
|
|
play_button.config(image=play_img)
|
|
pause_button.config(image=pause_img)
|
|
|
|
def colorUI(track_id, dominant_color):
|
|
if spotify.current_user_saved_tracks_contains(tracks=[track_id])[0] is True:
|
|
liked_song = True
|
|
else:
|
|
liked_song = False
|
|
if math.sqrt(0.299 * (dominant_color[0] ** 2) + 0.587 * (dominant_color[1] ** 2) + 0.114 * (dominant_color[2] ** 2)) > 170:
|
|
is_bright = True
|
|
if liked_song is True:
|
|
play_button.config(image=play_heart_img_black)
|
|
pause_button.config(image=pause_heart_img_black)
|
|
else:
|
|
play_button.config(image=play_img_black)
|
|
pause_button.config(image=pause_img_black)
|
|
song_label.config(foreground="black")
|
|
artist_label.config(foreground="black")
|
|
device_name_label.config(foreground="black")
|
|
lyrics_label.config(foreground="black")
|
|
next_button.config(image=next_img_black)
|
|
previous_button.config(image=previous_img_black)
|
|
else:
|
|
is_bright = False
|
|
if liked_song is True:
|
|
play_button.config(image=play_heart_img)
|
|
pause_button.config(image=pause_heart_img)
|
|
else:
|
|
play_button.config(image=play_img)
|
|
pause_button.config(image=pause_img)
|
|
song_label.config(foreground="white")
|
|
artist_label.config(foreground="white")
|
|
device_name_label.config(foreground="white")
|
|
lyrics_label.config(foreground="white")
|
|
next_button.config(image=next_img)
|
|
previous_button.config(image=previous_img)
|
|
return is_bright
|
|
|
|
def start_playback_on_device():
|
|
# global count
|
|
# global wait_time
|
|
# count = 0
|
|
# wait_time = 6500
|
|
device_selections = devices_list.curselection()
|
|
list_of_devices = spotify.devices()
|
|
device_id = list_of_devices["devices"][device_selections[0]]["id"]
|
|
spotify.transfer_playback(device_id=device_id)
|
|
|
|
def get_devices():
|
|
global count
|
|
# global count
|
|
# global wait_time0
|
|
# count +=1
|
|
# if count < 69:
|
|
# wait_time = 6500
|
|
# elif count >= 69:
|
|
# wait_time = 3600000
|
|
# count += 1
|
|
list_of_devices = spotify.devices()
|
|
|
|
# if list_of_devices == "{'devices': []}":
|
|
# unloadDevices_list()
|
|
# loadSearching_Devices()
|
|
# root.after(1000, get_devices)
|
|
# else:
|
|
# if count > 210:
|
|
# unloadDevices_list()
|
|
# loadSleep()
|
|
# root.after(3600, get_devices)
|
|
if spotify.current_playback() != None:
|
|
count = 0
|
|
# unloadSearching_Devices()
|
|
unloadDevices_list()
|
|
loadNow_playing()
|
|
root.after(800, update_song_label)
|
|
else:
|
|
count += 1
|
|
if count > 420:
|
|
kill(kill=sleep)
|
|
# unloadSearching_Devices()
|
|
# loadDevices_list()
|
|
else:
|
|
devices_list.delete(0, ttk.END)
|
|
list_of_devices = spotify.devices()
|
|
for num_of_device, garbage in enumerate(list_of_devices["devices"]):
|
|
# exec(f'dev_{num_of_device} = tk.Button(root, text=list_of_devices["devices"][num_of_device]["name"], command=start_playback_on_device(device_id=num_of_device))')
|
|
# exec(f'dev_{num_of_device}.grid(row={num_of_device}, column=1)')
|
|
devices_list.insert(num_of_device, list_of_devices["devices"][num_of_device]["name"])
|
|
root.after(8500, get_devices)
|
|
|
|
# def wakeup():
|
|
# global count
|
|
# count = 0
|
|
|
|
# def wakeup():
|
|
# global count
|
|
# global wait_time
|
|
# count = 0
|
|
# wait_time = 6500
|
|
|
|
def addCorners(im, rad):
|
|
circle = Image.new('L', (rad * 2, rad * 2), 0)
|
|
draw = ImageDraw.Draw(circle)
|
|
draw.ellipse((0, 0, rad * 2 - 1, rad * 2 - 1), fill=255)
|
|
alpha = Image.new('L', im.size, 255)
|
|
w, h = im.size
|
|
alpha.paste(circle.crop((0, 0, rad, rad)), (0, 0))
|
|
alpha.paste(circle.crop((0, rad, rad, rad * 2)), (0, h - rad))
|
|
alpha.paste(circle.crop((rad, 0, rad * 2, rad)), (w - rad, 0))
|
|
alpha.paste(circle.crop((rad, rad, rad * 2, rad * 2)), (w - rad, h - rad))
|
|
im.putalpha(alpha)
|
|
return im
|
|
|
|
# def addDropShadow( image, offset=(5,5), background=0xffffff, shadow=0x444444,
|
|
# border=8, iterations=3):
|
|
# """
|
|
# Add a gaussian blur drop shadow to an image.
|
|
|
|
# image - The image to overlay on top of the shadow.
|
|
# offset - Offset of the shadow from the image as an (x,y) tuple. Can be
|
|
# positive or negative.
|
|
# background - Background colour behind the image.
|
|
# shadow - Shadow colour (darkness).
|
|
# border - Width of the border around the image. This must be wide
|
|
# enough to account for the blurring of the shadow.
|
|
# iterations - Number of times to apply the filter. More iterations
|
|
# produce a more blurred shadow, but increase processing time.
|
|
# """
|
|
|
|
# # Create the backdrop image -- a box in the background colour with a
|
|
# # shadow on it.
|
|
# totalWidth = image.size[0] + abs(offset[0]) + 2*border
|
|
# totalHeight = image.size[1] + abs(offset[1]) + 2*border
|
|
# back = Image.new(image.mode, (totalWidth, totalHeight), background)
|
|
|
|
# # Place the shadow, taking into account the offset from the image
|
|
# shadowLeft = border + max(offset[0], 0)
|
|
# shadowTop = border + max(offset[1], 0)
|
|
# back.paste(shadow, [shadowLeft, shadowTop, shadowLeft + image.size[0],
|
|
# shadowTop + image.size[1]] )
|
|
|
|
# # Apply the filter to blur the edges of the shadow. Since a small kernel
|
|
# # is used, the filter must be applied repeatedly to get a decent blur.
|
|
# n = 0
|
|
# while n < iterations:
|
|
# back = back.filter(ImageFilter.BLUR)
|
|
# n += 1
|
|
|
|
# # Paste the input image onto the shadow backdrop
|
|
# imageLeft = border - min(offset[0], 0)
|
|
# imageTop = border - min(offset[1], 0)
|
|
# back.paste(image, (imageLeft, imageTop))
|
|
|
|
# return back
|
|
|
|
# def get_colors(image_file, resize=150):
|
|
# # Resize image to speed up processing
|
|
# image_file.thumbnail((resize, resize))
|
|
|
|
# max_count_index = numpy.argmax(numpy.unique(numpy.array(image_file).reshape(-1, numpy.array(image_file).shape[-1]), axis=0, return_counts=True)[1])
|
|
|
|
# # colors = list()
|
|
# # for i in range(numcolors):
|
|
# # palette_index = color_counts[i][1]
|
|
# # dominant_color = palette[palette_index*3:palette_index*3+3]
|
|
# # colors.append(tuple(dominant_color))
|
|
|
|
# return tuple(numpy.unique(numpy.array(image_file).reshape(-1, numpy.array(image_file).shape[-1]), axis=0, return_counts=True)[0][max_count_index])
|
|
|
|
def get_colors(image_file, resize=150):
|
|
# Resize image to speed up processing
|
|
image_file.thumbnail((resize, resize))
|
|
|
|
# Reduce to palette
|
|
numpy_array = numpy.array(image_file)
|
|
|
|
pixels = numpy_array.reshape(-1, numpy_array.shape[-1])
|
|
color_counts = numpy.unique(pixels, axis=0, return_counts=True)
|
|
max_count_index = numpy.argmax(color_counts[1])
|
|
|
|
# colors = list()
|
|
# for i in range(numcolors):
|
|
# palette_index = color_counts[i][1]
|
|
# dominant_color = palette[palette_index*3:palette_index*3+3]
|
|
# colors.append(tuple(dominant_color))
|
|
|
|
return tuple(color_counts[0][max_count_index])
|
|
|
|
# def get_colors(image_file, numcolors=1, resize=150):
|
|
# # Resize image to speed up processing
|
|
# image_file.thumbnail((resize, resize))
|
|
|
|
# # Reduce to palette
|
|
# paletted = image_file.convert('P', palette=Image.ADAPTIVE, colors=numcolors)
|
|
|
|
# # Find dominant colors
|
|
# palette = paletted.getpalette()
|
|
# # color_counts = sorted(paletted.getcolors(), reverse=True)
|
|
# dominant_color = (palette[0], palette[1], palette[2])
|
|
# # colors = list()
|
|
# # for i in range(numcolors):
|
|
# # palette_index = color_counts[i][1]
|
|
# # dominant_color = palette[palette_index*3:palette_index*3+3]
|
|
# # colors.append(tuple(dominant_color))
|
|
|
|
# return dominant_color
|
|
|
|
|
|
def getLyrics(artist_name, track_name):
|
|
global lrc
|
|
lrc = syncedlyrics.search("[" + track_name + "] [" + artist_name + "]")
|
|
|
|
|
|
# IT WONT DELETE
|
|
def getCanvas(track_id):
|
|
global videoplayer
|
|
videoplayer.stop()
|
|
videoplayer.grid_forget()
|
|
videoplayer.destroy()
|
|
gc()
|
|
try:
|
|
canvas_url = SpotifyCanvas.get_canvas_for_track(SpotifyCanvas.get_access_token(), track_id)
|
|
except AttributeError:
|
|
videoplayer = TkinterVideo(album_art_frame, scaled=True, background=bg_color, loop=True)
|
|
album_art_label.grid(sticky="w")
|
|
return None
|
|
else:
|
|
videoplayer = TkinterVideo(album_art_frame, scaled=True, background=bg_color, loop=True)
|
|
album_art_label.grid_forget()
|
|
videoplayer.load(canvas_url)
|
|
videoplayer.grid(sticky="w")
|
|
videoplayer.play()
|
|
videoplayer.bind("<Button-1>", lambda e:likeSong())
|
|
# def loop(e):
|
|
# videoplayer.play()
|
|
# videoplayer.bind("<<Ended>>", loop)
|
|
|
|
# def upNext():
|
|
# print(spotify.queue())
|
|
# up_next_label.config(text="Placeholder")
|
|
|
|
# def rgb_to_hex(r, g, b):
|
|
# return ('{:X}{:X}{:X}').format(r, g, b)
|
|
|
|
play_img = ttk.PhotoImage(file="icons/play.png")
|
|
pause_img = ttk.PhotoImage(file="icons/pause.png")
|
|
play_heart_img = ttk.PhotoImage(file="icons/play-heart.png")
|
|
pause_heart_img = ttk.PhotoImage(file="icons/pause-heart.png")
|
|
next_img = ttk.PhotoImage(file="icons/next.png")
|
|
previous_img = ttk.PhotoImage(file="icons/previous.png")
|
|
play_img_black = ttk.PhotoImage(file="icons/play-black.png")
|
|
pause_img_black = ttk.PhotoImage(file="icons/pause-black.png")
|
|
play_heart_img_black = ttk.PhotoImage(file="icons/play-heart-black.png")
|
|
pause_heart_img_black = ttk.PhotoImage(file="icons/pause-heart-black.png")
|
|
next_img_black = ttk.PhotoImage(file="icons/next-black.png")
|
|
previous_img_black = ttk.PhotoImage(file="icons/previous-black.png")
|
|
album_art_img = ""
|
|
|
|
|
|
frame_artist_song = ttk.Frame(root, width=(1280/3), height=400, bg=bg_color)
|
|
album_art_frame = ttk.Frame(root)
|
|
lyrics_label_frame = ttk.Frame(root, width=(1280/3), height=400, bg=bg_color)
|
|
lyrics_label_frame.grid_propagate(0)
|
|
sleep_frame = ttk.Frame(root, width=(1280/3), height=400, bg=bg_color)
|
|
|
|
root.grid_rowconfigure(0, weight=1)
|
|
root.grid_rowconfigure(1, weight=1)
|
|
root.grid_rowconfigure(2, weight=1)
|
|
root.grid_columnconfigure(0, weight=1)
|
|
root.grid_columnconfigure(1, weight=1)
|
|
|
|
root.configure(background=bg_color)
|
|
|
|
lyrics_label_frame.grid_rowconfigure(0, weight=1)
|
|
lyrics_label_frame.grid_columnconfigure(0, weight=1)
|
|
|
|
# Create the media control buttons and a text label
|
|
play_button = ttk.Label(root, image=play_img, borderwidth=0)
|
|
pause_button = ttk.Label(root, image=pause_img, borderwidth=0)
|
|
next_button = ttk.Label(root, image=next_img, borderwidth=0)
|
|
previous_button = ttk.Label(root, image=previous_img, borderwidth=0)
|
|
artist_label = tk.Label(frame_artist_song, text="", font=("Helvetica", 24), wraplength=(1280/3), justify=ttk.CENTER, background=bg_color)
|
|
song_label = tk.Label(frame_artist_song, text="", font=("Helvetica", 32), wraplength=(1280/3), justify=ttk.CENTER, background=bg_color)
|
|
get_devices_button = tk.Button(root, text="Get Devices", command=get_devices)
|
|
start_playback_on_device_button = tk.Button(root, text="Start Playback on Device", command=start_playback_on_device)
|
|
devices_list = ttk.Listbox(root, selectmode=ttk.SINGLE, font=("Helvetica", 18))
|
|
progress_bar = tk.Progressbar(root, orient=ttk.HORIZONTAL, length=1280)
|
|
searching_for_devices_label = tk.Label(root, text="Searching for Devices...", font=("Helvetica", 24))
|
|
device_name_label = tk.Label(frame_artist_song, text="", font=("Helvetica", 12))
|
|
lyrics_label = tk.Label(lyrics_label_frame, text="", font=("Helvetica", 32), wraplength=(1280/3), justify=ttk.CENTER, background=bg_color)
|
|
album_art_label = tk.Label(album_art_frame, image=album_art_img)
|
|
# up_next_label = tk.Label(frame_artist_song, text="", font=("Helvetica", 12), wraplength=(1280/3), justify=ttk.CENTER, background=bg_color)
|
|
videoplayer = TkinterVideo(album_art_frame, scaled=True, background=bg_color, loop=True)
|
|
|
|
|
|
play_button.bind("<Button-1>", lambda e:controlPlay())
|
|
pause_button.bind("<Button-1>", lambda e:controlPause())
|
|
next_button.bind("<Button-1>", lambda e:controlNext())
|
|
previous_button.bind("<Button-1>", lambda e:controlPrevious())
|
|
# previous_button.bind("<Double-Button-1>", lambda e:controlPrevious(double=True))
|
|
album_art_label.bind("<Button-1>", lambda e:likeSong())
|
|
|
|
# development restart script (will push to update.py)
|
|
song_label.bind("<Double-Button-1>", lambda e:kill())
|
|
devices_list.bind("<Double-Button-1>", lambda e:kill())
|
|
# sleep_frame.bind("<Button-1>", lambda e:wakeup())
|
|
# devices_list.bind("<Button-1>", lambda e:wakeup())
|
|
|
|
|
|
|
|
|
|
|
|
# Function to update the song label with the current track's name
|
|
def update_song_label():
|
|
try:
|
|
global lrc
|
|
global album_art_img
|
|
global isBright
|
|
global track_progress
|
|
# Get the current playback information
|
|
current_playback = spotify.current_playback()
|
|
# If there is no current playback, set the text of the song label to "No playback"
|
|
if current_playback is None:
|
|
unloadNow_playing()
|
|
loadDevices_list()
|
|
|
|
root.after(200, get_devices)
|
|
# Update the song label every 1 second
|
|
elif current_playback.get("item") is not None:
|
|
track_name = current_playback["item"]["name"]
|
|
track_progress = current_playback["progress_ms"]
|
|
playing_status = current_playback["is_playing"]
|
|
track_progress_min = track_progress//(1000*60)%60
|
|
track_progress_sec = (track_progress//1000)%60
|
|
if track_name == song_label.cget("text"):
|
|
track_progress_formatted = ("{}:{:02d}".format(track_progress_min, track_progress_sec))
|
|
progress_bar.config(value=track_progress)
|
|
for line in str(lrc).splitlines():
|
|
if track_progress_formatted in line:
|
|
lyric = line.split("]")[1]
|
|
lyrics_label.config(text=lyric)
|
|
# if track_progress < 5000:
|
|
# threading.Thread(target=upNext).start()
|
|
root.after(800, update_song_label)
|
|
else:
|
|
artist_name = current_playback["item"]["artists"][0]["name"]
|
|
threading.Thread(target=getLyrics, args=(artist_name, track_name)).start()
|
|
track_id = current_playback["item"]["id"]
|
|
threading.Thread(target=getCanvas, args=(track_id,)).start()
|
|
track_duration = current_playback["item"]["duration_ms"]
|
|
device_name = current_playback["device"]["name"]
|
|
album_art_url = current_playback["item"]["album"]["images"][0]["url"]
|
|
device_name_label.config(text=device_name)
|
|
song_label.config(text=track_name)
|
|
artist_label.config(text=artist_name)
|
|
progress_bar.config(maximum=track_duration)
|
|
lyrics_label.config(text="")
|
|
album_art_img_data = requests.get(album_art_url).content
|
|
album_art_img_open = Image.open(BytesIO(album_art_img_data))
|
|
# bg_color_img = album_art_img_open.resize((1,1), resample=0)
|
|
# bg_color_img_pixel = bg_color_img.getpixel((0,0))
|
|
# bg_color_rgb = get_colors(album_art_img_open)
|
|
dominant_color = get_colors(album_art_img_open)
|
|
bg_color = "#" + '%02x%02x%02x' % (dominant_color)
|
|
# print(bg_color)
|
|
album_art_img_with_corners = addCorners(album_art_img_open, 15)
|
|
# addDropShadow(album_art_img_with_corners)
|
|
album_art_img = ImageTk.PhotoImage(album_art_img_with_corners.resize((300,300)))
|
|
album_art_label.config(image=album_art_img, background=bg_color)
|
|
root.config(background=bg_color)
|
|
frame_artist_song.config(background=bg_color)
|
|
device_name_label.config(background=bg_color)
|
|
song_label.config(background=bg_color)
|
|
artist_label.config(background=bg_color)
|
|
play_button.config(background=bg_color)
|
|
pause_button.config(background=bg_color)
|
|
next_button.config(background=bg_color)
|
|
previous_button.config(background=bg_color)
|
|
lyrics_label_frame.config(background=bg_color)
|
|
lyrics_label.config(background=bg_color)
|
|
isBright = colorUI(track_id, dominant_color)
|
|
# print(oauth.get_cached_token()["access_token"])
|
|
# print(current_playback["item"]["id"])
|
|
# canvas_url = canvas.get_canvas_for_track(access_token=oauth.get_cached_token()["access_token"], track_id=current_playback["item"]["id"])
|
|
# print(canvas_url)
|
|
# lrc = q.get()
|
|
root.after(500, update_song_label)
|
|
if playing_status == True:
|
|
play_button.grid_forget()
|
|
pause_button.grid(row=3, column=1, pady=(0,30))
|
|
elif playing_status == False:
|
|
pause_button.grid_forget()
|
|
play_button.grid(row=3, column=1, pady=(0,30))
|
|
else:
|
|
pass
|
|
else:
|
|
root.after(1000, get_devices)
|
|
except Exception as e:
|
|
print(e)
|
|
root.after(5000, update_song_label)
|
|
|
|
def loadNow_playing():
|
|
frame_artist_song.grid(row=0, column=1, rowspan=3, pady=(30,0), sticky="n")
|
|
device_name_label.grid(row=0, column=1)
|
|
artist_label.grid(row=2, column=1)
|
|
song_label.grid(row=1, column=1)
|
|
# up_next_label.grid(row=3, column=1)
|
|
previous_button.grid(row=3, column=1, padx=(0,200), pady=(0,30))
|
|
play_button.grid(row=3, column=1, pady=(0,30))
|
|
next_button.grid(row=3, column=1, padx=(200,0), pady=(0,30))
|
|
progress_bar.grid(row=3, column=0, columnspan=3, sticky="wse")
|
|
album_art_frame.grid(row=0, column=0, rowspan=4)
|
|
album_art_label.grid(sticky="w")
|
|
lyrics_label_frame.grid(row=0, column=2, rowspan=4)
|
|
lyrics_label.grid()
|
|
|
|
def unloadNow_playing():
|
|
device_name_label.grid_forget()
|
|
artist_label.grid_forget()
|
|
song_label.grid_forget()
|
|
previous_button.grid_forget()
|
|
play_button.grid_forget()
|
|
next_button.grid_forget()
|
|
progress_bar.grid_forget()
|
|
lyrics_label.grid_forget()
|
|
album_art_label.grid_forget()
|
|
videoplayer.grid_forget()
|
|
|
|
def loadDevices_list():
|
|
devices_list.grid(row=1, column=1, pady=10)
|
|
start_playback_on_device_button.grid(row=0, column=1, ipadx=40, ipady=40)
|
|
|
|
def unloadDevices_list():
|
|
devices_list.grid_forget()
|
|
start_playback_on_device_button.grid_forget()
|
|
|
|
def loadSearching_Devices():
|
|
searching_for_devices_label.grid()
|
|
|
|
def unloadSearching_Devices():
|
|
searching_for_devices_label.grid_forget()
|
|
|
|
def loadSleep():
|
|
sleep_frame.grid()
|
|
|
|
|
|
|
|
# def recognize(recognizer, audio):
|
|
# try:
|
|
# words = r.recognize_sphinx(audio)
|
|
# print(words)
|
|
# if ("magical") in words:
|
|
# if (" play") in words:
|
|
# controlPlay()
|
|
# elif (" pause") in words:
|
|
# controlPause()
|
|
# elif (" next") in words:
|
|
# controlNext()
|
|
# elif (" previous") in words:
|
|
# controlPrevious()
|
|
# else:
|
|
# pass
|
|
# else:
|
|
# pass
|
|
# except sr.RequestError as e:
|
|
# print("Could not request results; {0}".format(e))
|
|
# except sr.UnknownValueError:
|
|
# print("Speech not understood")
|
|
|
|
# r = sr.Recognizer()
|
|
# m = sr.Microphone()
|
|
|
|
# with m as source:
|
|
# r.adjust_for_ambient_noise(source)
|
|
# print("Ambient Noise Calibration Complete")
|
|
|
|
|
|
# r.listen_in_background(m, recognize)
|
|
|
|
|
|
# Start updating the song label
|
|
# setup()
|
|
|
|
# Run the GUI
|
|
|
|
|
|
loadNow_playing()
|
|
update_song_label()
|
|
|
|
root.mainloop() |