not sure what changes i made tbh
This commit is contained in:
1
.cache
Normal file
1
.cache
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"access_token": "BQB6UF8iw-WD97zuAcBy3j1JRn-HI3CUOYi-cFI0CG72nxPGXPkHdzOse6jAIVBrkkGgzDlqdgbGJWoEqzLFr60Ri9dKwIPjfOzDMrghO4Qm86r_ks81plxBDTqbmmJCpv518cFsu_w5JFEhGa6AruwxzYWrLhcZAPkAGCFGub-nj0gaWZnHGEyRBTdU5w", "token_type": "Bearer", "expires_in": 3600, "scope": "user-modify-playback-state user-read-playback-state", "expires_at": 1674288882, "refresh_token": "AQANdyTU2KRSkgJSsueOmP3-n3VFXKSeh90xje6HINu6becuKHhx0tauC4ruB7v6GbtRd45wkF13AsUXjGDHxRMSvGFky2KBhck6sEZTSJID0qd4pmsWoC8xOvzFzsAlaeA"}
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"access_token": "BQBDvdX_R5Ytk8IWYKvSfQ-xvTD3fJHLEXy5-EwVm6ukngDvG5Hlz6F0LWdjLuUMVmcJi24IYljaF2l396aeE0kcnX8X12rYcyMpy6kIUH3i_jL1xg4egPSZ8Lr41l7xHIw7BJQkuXN-yewbNo2quC_i32BtpYncurovWcSKYjLjfO8LC9_L7Z3IWhu1bw", "token_type": "Bearer", "expires_in": 3600, "scope": "user-modify-playback-state user-read-playback-state", "expires_at": 1673754361, "refresh_token": "AQBb9zPnT-MmK7H70IzzenfZBz1VV-0eZWhD73x2br6xQPx1jctO-uuGZu38EvvXapCpdJZ8oLAk4Z4Ci2gmZGGfMsmsofMNVB402gjRrSzfV94BpkuYJtyV0fS5bSK5Nrg"}
|
|
||||||
24
install.sh
Normal file
24
install.sh
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
echo "Downloading Spotify GUI"
|
||||||
|
curl http://files.bbrunson.com/spotify-gui/install.zip -o install.zip
|
||||||
|
echo "This installation requires sudo privileges"
|
||||||
|
sudo ls
|
||||||
|
echo "Installing Python 3"
|
||||||
|
sudo apt-get install -y python3 python3-distutils python3-tk
|
||||||
|
echo "Installing Pip 3"
|
||||||
|
curl -s https://bootstrap.pypa.io/get-pip.py | python3
|
||||||
|
echo "Installing spotify-gui to /opt"
|
||||||
|
sudo mkdir -p /opt/spotify-gui
|
||||||
|
sudo unzip -o install.zip -d /opt
|
||||||
|
sudo chmod +x /opt/spotify-gui/update.py
|
||||||
|
echo "Installing dependencies"
|
||||||
|
echo -e "librespot\nPillow\nPyAutoGUI\nrequests\nspotipy\nsv_ttk\nsyncedlyrics" > requirements.txt
|
||||||
|
sudo mv requirements.txt /opt/spotify-gui/requirements.txt
|
||||||
|
sudo pip3 install -r /opt/spotify-gui/requirements.txt
|
||||||
|
echo "Creating systemd service"
|
||||||
|
echo -e "[Unit]\nDescription=Spotify GUI\nAfter=network-online.target\nWants=network-online.target\n[Service]\nType=simple\nUser=pi\nWorkingDirectory=/opt/spotify-gui\nExecStart=xinit ./start.sh $* -- :0 vt$XDG_VTNR -nocursor\n[Install]\nWantedBy=multi-user.target" > spotify-gui.service
|
||||||
|
sudo mv spotify-gui.service /etc/systemd/system/spotify-gui.service
|
||||||
|
sudo chmod +x /etc/systemd/system/spotify-gui.service
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable spotify-gui.service
|
||||||
|
echo "Installation complete. Updating and starting Spotify GUI."
|
||||||
|
sudo service spotify-gui start
|
||||||
472
program-embedded-util.py
Normal file
472
program-embedded-util.py
Normal file
@@ -0,0 +1,472 @@
|
|||||||
|
import spotipy
|
||||||
|
import spotipy.util
|
||||||
|
import tkinter as ttk
|
||||||
|
from tkinter import ttk as tk
|
||||||
|
import sv_ttk
|
||||||
|
import requests
|
||||||
|
import os
|
||||||
|
import syncedlyrics
|
||||||
|
from PIL import Image, ImageTk
|
||||||
|
from io import BytesIO
|
||||||
|
import math
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
# Set the Spotify app's client ID and client secret
|
||||||
|
client_id = "69b82a34d0fb40be80b020eae8e80f25"
|
||||||
|
client_secret = "455575b0e3db44acbbfaa0c419bc3c10"
|
||||||
|
redirect_uri = "http://127.0.0.1:8888/callback"
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
|
||||||
|
# def wait_for_display():
|
||||||
|
# while True:
|
||||||
|
# try:
|
||||||
|
# test = ttk.Tk()
|
||||||
|
# test.destroy()
|
||||||
|
# return True
|
||||||
|
# except:
|
||||||
|
# pass
|
||||||
|
|
||||||
|
# Get the user's Spotify authorization token
|
||||||
|
scope = "user-read-playback-state,user-modify-playback-state"
|
||||||
|
|
||||||
|
# if len(sys.argv) == 1:
|
||||||
|
# pass
|
||||||
|
# elif sys.argv[1] == "--setup":
|
||||||
|
# try:
|
||||||
|
# os.remove(".cache-" + username)
|
||||||
|
# except OSError:
|
||||||
|
# pass
|
||||||
|
# elif sys.argv[1] == "--clear":
|
||||||
|
# os.remove(".cache-" + username)
|
||||||
|
# sys.exit("Deleting token from cache and exiting...")
|
||||||
|
# elif sys.argv[1] == "--clearChromeCache":
|
||||||
|
# if os.name() == "posix":
|
||||||
|
# os.system("rm -rf ~/.cache/chromium")
|
||||||
|
# os.system("rm -rf ~/.config/chromium")
|
||||||
|
# sys.exit("Deleting Chrome cache and exiting...")
|
||||||
|
|
||||||
|
# def oauthLogin():
|
||||||
|
# if os.path.isfile(".cache-" + username) == False:
|
||||||
|
# sleep(25)
|
||||||
|
# pyautogui.press('tab')
|
||||||
|
# pyautogui.press('tab')
|
||||||
|
# pyautogui.press('tab')
|
||||||
|
# pyautogui.press('tab')
|
||||||
|
# pyautogui.write(username)
|
||||||
|
# pyautogui.press('tab')
|
||||||
|
# pyautogui.write(password)
|
||||||
|
# pyautogui.press('enter')
|
||||||
|
# sleep(90)
|
||||||
|
# if platform.system() == "Linux":
|
||||||
|
# os.system("killall chromium-browser")
|
||||||
|
|
||||||
|
# threading.Thread(target=oauthLogin).start()
|
||||||
|
|
||||||
|
# oauthLogin()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Create a Spotify object with the user's authorization token
|
||||||
|
def createToken():
|
||||||
|
token = spotipy.util.prompt_for_user_token(username, scope, client_id, client_secret, redirect_uri)
|
||||||
|
spotify = spotipy.Spotify(auth=token)
|
||||||
|
return spotify
|
||||||
|
|
||||||
|
spotify = createToken()
|
||||||
|
|
||||||
|
bg_color = "#000000"
|
||||||
|
|
||||||
|
# Create the tkinter window
|
||||||
|
root = ttk.Tk()
|
||||||
|
root.title("Media Controller")
|
||||||
|
root.geometry("1280x400")
|
||||||
|
root.attributes("-topmost", True)
|
||||||
|
root.overrideredirect(1)
|
||||||
|
sv_ttk.use_dark_theme()
|
||||||
|
|
||||||
|
# Function to call the Spotify API to play the current track
|
||||||
|
def play():
|
||||||
|
spotify.start_playback()
|
||||||
|
|
||||||
|
# Function to call the Spotify API to pause the current track
|
||||||
|
def pause():
|
||||||
|
spotify.pause_playback()
|
||||||
|
|
||||||
|
def next():
|
||||||
|
spotify.next_track()
|
||||||
|
|
||||||
|
def previous():
|
||||||
|
spotify.previous_track()
|
||||||
|
|
||||||
|
# def maxvolume():
|
||||||
|
# spotify.volume(100)
|
||||||
|
|
||||||
|
# def minvolume():
|
||||||
|
# spotify.volume(0)
|
||||||
|
|
||||||
|
# def randomvolume():
|
||||||
|
# spotify.volume(random.randint(0,100))
|
||||||
|
|
||||||
|
# def volumeslider(self):
|
||||||
|
# spotify.volume(int(volumeslider_button.get()))
|
||||||
|
|
||||||
|
# def search(event):
|
||||||
|
# searched = track_search.get()
|
||||||
|
# if searched.startswith(":t"):
|
||||||
|
# track_searched_isolated = searched.replace(":t", "")
|
||||||
|
# track_search_results = spotify.search(q='track:' + track_searched_isolated, type='track')
|
||||||
|
# searched_track_id = track_search_results["tracks"]["items"][0]["id"]
|
||||||
|
# spotify.start_playback(uris=["spotify:track:" + searched_track_id])
|
||||||
|
# if searched.startswith(":a"):
|
||||||
|
# artist_searched_isolated = searched.replace(":a", "")
|
||||||
|
# artist_search_results = spotify.search(q='artist:' + artist_searched_isolated, type='artist')
|
||||||
|
# searched_artist_id = artist_search_results["artists"]["items"][0]["uri"]
|
||||||
|
# spotify.start_playback(context_uri=searched_artist_id)
|
||||||
|
# if searched.startswith(":l"):
|
||||||
|
# album_searched_isolated = searched.replace(":l", "")
|
||||||
|
# album_search_results = spotify.search(q='album:' + album_searched_isolated, type='album')
|
||||||
|
# searched_album_id = album_search_results["albums"]["items"][0]["uri"]
|
||||||
|
# spotify.start_playback(context_uri=searched_album_id)
|
||||||
|
# if searched.startswith(":p"):
|
||||||
|
# playlist_searched_isolated = searched.replace(":p", "")
|
||||||
|
# playlist_search_results = spotify.search(q='playlist:' + playlist_searched_isolated, type='playlist')
|
||||||
|
# searched_playlist_id = playlist_search_results["playlists"]["items"][0]["uri"]
|
||||||
|
# spotify.start_playback(context_uri=searched_playlist_id)
|
||||||
|
|
||||||
|
def start_playback_on_device():
|
||||||
|
device_selections = devices_list.curselection()
|
||||||
|
try:
|
||||||
|
list_of_devices = spotify.devices()
|
||||||
|
except (spotipy.exceptions.SpotifyException, requests.exceptions.HTTPError):
|
||||||
|
createToken()
|
||||||
|
pass
|
||||||
|
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():
|
||||||
|
list_of_devices = spotify.devices()
|
||||||
|
unloadNow_playing()
|
||||||
|
if list_of_devices == "{'devices': []}":
|
||||||
|
unloadDevices_list()
|
||||||
|
loadSearching_Devices()
|
||||||
|
root.after(1000, get_devices)
|
||||||
|
else:
|
||||||
|
current_playback = spotify.current_playback()
|
||||||
|
if current_playback != None:
|
||||||
|
unloadSearching_Devices()
|
||||||
|
unloadDevices_list()
|
||||||
|
loadNow_playing()
|
||||||
|
update_song_label()
|
||||||
|
else:
|
||||||
|
unloadSearching_Devices()
|
||||||
|
loadDevices_list()
|
||||||
|
devices_list.delete(0, ttk.END)
|
||||||
|
try:
|
||||||
|
list_of_devices = spotify.devices()
|
||||||
|
except (spotipy.exceptions.SpotifyException, requests.exceptions.HTTPError):
|
||||||
|
createToken()
|
||||||
|
pass
|
||||||
|
list_of_devices = spotify.devices()
|
||||||
|
for num_of_device, garbage in enumerate(list_of_devices["devices"]):
|
||||||
|
devices_list.insert(num_of_device, list_of_devices["devices"][num_of_device]["name"])
|
||||||
|
root.after(6500, get_devices)
|
||||||
|
|
||||||
|
# def loadLyrics_pressed():
|
||||||
|
# unloadNow_playing()
|
||||||
|
# loadLyrics()
|
||||||
|
|
||||||
|
# def unloadLyrics_pressed():
|
||||||
|
# unloadLyrics()
|
||||||
|
# loadNow_playing()
|
||||||
|
|
||||||
|
|
||||||
|
# def hide_devices():
|
||||||
|
# get_devices_button.grid()
|
||||||
|
# devices_list.grid_remove()
|
||||||
|
# start_playback_on_device_button.grid_remove()
|
||||||
|
# hide_devices_button.grid_remove()
|
||||||
|
|
||||||
|
|
||||||
|
play_img = ttk.PhotoImage(file="icons/play-circle-x2.png")
|
||||||
|
pause_img = ttk.PhotoImage(file="icons/pause-circle-x2.png")
|
||||||
|
next_img = ttk.PhotoImage(file="icons/skip-next-x2.png")
|
||||||
|
previous_img = ttk.PhotoImage(file="icons/skip-previous-x2.png")
|
||||||
|
play_img_black = ttk.PhotoImage(file="icons/play-circle-x2-black.png")
|
||||||
|
pause_img_black = ttk.PhotoImage(file="icons/pause-circle-x2-black.png")
|
||||||
|
next_img_black = ttk.PhotoImage(file="icons/skip-next-x2-black.png")
|
||||||
|
previous_img_black = ttk.PhotoImage(file="icons/skip-previous-x2-black.png")
|
||||||
|
# lyrics_img = ttk.PhotoImage(file="icons/lyrics.png")
|
||||||
|
album_art_img = ""
|
||||||
|
# album_art_img = ttk.PhotoImage(file="album_art.png")
|
||||||
|
|
||||||
|
# canvas = ttk.Canvas(root, width=480, height=320)
|
||||||
|
# canvas.create_image(0, 0, image=album_art_img, anchor="nw")
|
||||||
|
# canvas.grid()
|
||||||
|
|
||||||
|
# canvas = ttk.Canvas(root, width=480, height=320)
|
||||||
|
|
||||||
|
frame_artist_song = ttk.Frame(root, width=(1280/3), height=400, bg=bg_color)
|
||||||
|
# frame_controls = tk.Frame(root)
|
||||||
|
# lyrics_button = tk.Frame(root)
|
||||||
|
album_art_frame = ttk.Frame(root, bg=bg_color)
|
||||||
|
lyrics_label_frame = ttk.Frame(root, width=(1280/3), height=400, bg=bg_color)
|
||||||
|
lyrics_label_frame.grid_propagate(0)
|
||||||
|
|
||||||
|
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.grid_columnconfigure(2, 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(frame_artist_song, image=play_img, borderwidth=0)
|
||||||
|
pause_button = ttk.Label(frame_artist_song, image=pause_img, borderwidth=0)
|
||||||
|
next_button = ttk.Label(frame_artist_song, image=next_img, borderwidth=0)
|
||||||
|
previous_button = ttk.Label(frame_artist_song, image=previous_img, borderwidth=0)
|
||||||
|
# maxvolume_button = tk.Button(root, text="Max Volume", command=maxvolume)
|
||||||
|
# minvolume_button = tk.Button(root, text="Min Volume", command=minvolume)
|
||||||
|
# randomvolume_button = tk.Button(root, text="Random Volume", command=randomvolume)
|
||||||
|
# volumeslider_button = tk.Scale(root, from_=100, to=0, orient=ttk.VERTICAL, length=240, command=volumeslider)
|
||||||
|
#doaudio_analysis = tk.Button(root, text="Audio Analysis", command=doaudioanalysis)
|
||||||
|
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)
|
||||||
|
# track_progress_label = tk.Label(root, text="")
|
||||||
|
# track_duration_label = tk.Label(root, text="")
|
||||||
|
# track_combined_label = tk.Label(root, text="")
|
||||||
|
# track_search = tk.Entry(root, text="")
|
||||||
|
# track_search_button = tk.Button(root, text="Search", command=search)
|
||||||
|
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)
|
||||||
|
# hide_devices_button = tk.Button(root, text="Hide Devices", command=hide_devices)
|
||||||
|
# username_label = tk.Label(root, text="Username: " + spotify.me()["display_name"])
|
||||||
|
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))
|
||||||
|
# background_image_label = tk.Label(root, image=album_art_img)
|
||||||
|
lyrics_label = tk.Label(lyrics_label_frame, text="", font=("Helvetica", 32), wraplength=(1280/3), justify=ttk.CENTER, background=bg_color)
|
||||||
|
# loadLyrics_button = ttk.Button(lyrics_button, image=lyrics_img, command=loadLyrics_pressed, borderwidth=0)
|
||||||
|
# album_art_canvas = ttk.Canvas(root)
|
||||||
|
# album_art_canvas_create_image = album_art_canvas.create_image(0, 0, image=album_art_img)
|
||||||
|
album_art_label = tk.Label(album_art_frame, image=album_art_img)
|
||||||
|
|
||||||
|
# root.bind("<Return>", search)
|
||||||
|
# lyrics_label.bind("<Button-1>", lambda e:unloadLyrics_pressed())
|
||||||
|
play_button.bind("<Button-1>", lambda e:play())
|
||||||
|
pause_button.bind("<Button-1>", lambda e:pause())
|
||||||
|
next_button.bind("<Button-1>", lambda e:next())
|
||||||
|
previous_button.bind("<Button-1>", lambda e:previous())
|
||||||
|
|
||||||
|
# Function to update the song label with the current track's name
|
||||||
|
def update_song_label():
|
||||||
|
global lrc
|
||||||
|
global album_art_img
|
||||||
|
# Get the current playback information
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
current_playback = spotify.current_playback()
|
||||||
|
break
|
||||||
|
except (spotipy.exceptions.SpotifyException, requests.exceptions.HTTPError, requests.exceptions.ReadTimeout):
|
||||||
|
createToken()
|
||||||
|
sleep(0.25)
|
||||||
|
# If there is no current playback, set the text of the song label to "No playback"
|
||||||
|
if current_playback is None:
|
||||||
|
# nothing_playing_obj = '{"item": {"artists": [{"name": "Nothing Playing"}],"duration_ms": 0,"name": "Nothing Playing"},"progress_ms": 0}'
|
||||||
|
# current_playback = json.loads(nothing_playing_obj)
|
||||||
|
get_devices()
|
||||||
|
# Update the song label every 1 second
|
||||||
|
else:
|
||||||
|
track_name = current_playback["item"]["name"]
|
||||||
|
artist_name = current_playback["item"]["artists"][0]["name"]
|
||||||
|
track_duration = current_playback["item"]["duration_ms"]
|
||||||
|
track_progress = current_playback["progress_ms"]
|
||||||
|
# current_volume = current_playback["device"]["volume_percent"]
|
||||||
|
playing_status = current_playback["is_playing"]
|
||||||
|
device_name = current_playback["device"]["name"]
|
||||||
|
album_art_url = current_playback["item"]["album"]["images"][0]["url"]
|
||||||
|
track_progress_min = track_progress//(1000*60)%60
|
||||||
|
track_progress_sec = (track_progress//1000)%60
|
||||||
|
# track_duration_min = track_duration//(1000*60)%60
|
||||||
|
# track_duration_sec = (track_duration//1000)%60
|
||||||
|
# open_url = urlopen(album_art_url)
|
||||||
|
# raw_image_data = open_url.read()
|
||||||
|
# open_url.close()
|
||||||
|
# album_art = ImageTk.PhotoImage(data=raw_image_data)
|
||||||
|
# background_image_label.config(image=album_art)
|
||||||
|
# print(background_image_label.cget("image"))
|
||||||
|
# if raw_image_data == background_image_label.cget("image"):
|
||||||
|
# print("this is the same image")
|
||||||
|
# else:
|
||||||
|
# pass
|
||||||
|
# loadNow_playing()
|
||||||
|
if track_name == song_label.cget("text"):
|
||||||
|
track_progress_formatted = ("{}:{:02d}".format(track_progress_min, track_progress_sec))
|
||||||
|
# track_progress_label.config(text=track_progress_formatted)
|
||||||
|
progress_bar.config(maximum=track_duration)
|
||||||
|
progress_bar.config(value=track_progress)
|
||||||
|
for line in str(lrc).splitlines():
|
||||||
|
if track_progress_formatted in line:
|
||||||
|
lyric = line.split("]")[1]
|
||||||
|
# wrapped_lyric = textwrap.fill(lyric, 21)
|
||||||
|
lyrics_label.config(text=lyric)
|
||||||
|
root.after(800, update_song_label)
|
||||||
|
else:
|
||||||
|
# album_art_data = Image.open(requests.get(album_art_url, stream=True).raw)
|
||||||
|
# album_art_data.save("album_art.jpg")
|
||||||
|
device_name_label.config(text=device_name)
|
||||||
|
song_label.config(text=track_name)
|
||||||
|
artist_label.config(text=artist_name)
|
||||||
|
# track_duration_label.config(text=("{}:{:02d}".format(track_duration_min, track_duration_sec)))
|
||||||
|
# volumeslider_button.set(value=current_volume)
|
||||||
|
lyrics_label.config(text="")
|
||||||
|
lrc = syncedlyrics.search("[" + track_name + "] [" + artist_name + "]")
|
||||||
|
album_art_img_data = requests.get(album_art_url).content
|
||||||
|
album_art_img_open = Image.open(BytesIO(album_art_img_data))
|
||||||
|
album_art_img = ImageTk.PhotoImage(album_art_img_open.resize((300,300)))
|
||||||
|
album_art_label.config(image=album_art_img)
|
||||||
|
bg_color_img = album_art_img_open.resize((1,1), resample=0)
|
||||||
|
bg_color_img_pixel = bg_color_img.getpixel((0,0))
|
||||||
|
bg_color = "#" + '%02x%02x%02x' % (bg_color_img_pixel)
|
||||||
|
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)
|
||||||
|
if math.sqrt(0.299 * (bg_color_img_pixel[0] ** 2) + 0.587 * (bg_color_img_pixel[1] ** 2) + 0.114 * (bg_color_img_pixel[2] ** 2)) > 170:
|
||||||
|
song_label.config(foreground="black")
|
||||||
|
artist_label.config(foreground="black")
|
||||||
|
device_name_label.config(foreground="black")
|
||||||
|
lyrics_label.config(foreground="black")
|
||||||
|
play_button.config(image=play_img_black)
|
||||||
|
pause_button.config(image=pause_img_black)
|
||||||
|
next_button.config(image=next_img_black)
|
||||||
|
previous_button.config(image=previous_img_black)
|
||||||
|
else:
|
||||||
|
song_label.config(foreground="white")
|
||||||
|
artist_label.config(foreground="white")
|
||||||
|
device_name_label.config(foreground="white")
|
||||||
|
lyrics_label.config(foreground="white")
|
||||||
|
play_button.config(image=play_img)
|
||||||
|
pause_button.config(image=pause_img)
|
||||||
|
next_button.config(image=next_img)
|
||||||
|
previous_button.config(image=previous_img)
|
||||||
|
# album_art_label.grid_forget()
|
||||||
|
# album_art_label.grid()
|
||||||
|
root.after(500, update_song_label)
|
||||||
|
# if album_art_url == "12345":
|
||||||
|
# open_url = urlopen(album_art_url)
|
||||||
|
# raw_image_data = open_url.read()
|
||||||
|
# open_url.close()
|
||||||
|
# album_art = ImageTk.PhotoImage(data=raw_image_data)
|
||||||
|
# background_image_label.config(image=album_art)
|
||||||
|
# else:
|
||||||
|
# pass
|
||||||
|
if playing_status == True:
|
||||||
|
play_button.grid_forget()
|
||||||
|
pause_button.grid(row=3, column=1, pady=(100,0))
|
||||||
|
elif playing_status == False:
|
||||||
|
pause_button.grid_forget()
|
||||||
|
play_button.grid(row=3, column=1, pady=(100,0))
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def loadNow_playing():
|
||||||
|
# background_image_label.place(x=0, y=0)
|
||||||
|
# volumeslider_button.grid(row=1, column=1, rowspan=3, sticky="e", padx=(0,20))
|
||||||
|
# lyrics_button.grid(row=1, column=1, padx=(0,380))
|
||||||
|
frame_artist_song.grid(row=0, column=1, rowspan=3, pady=(20,0))
|
||||||
|
# frame_controls.grid(row=2, column=1)
|
||||||
|
# loadLyrics_button.grid()
|
||||||
|
device_name_label.grid(row=0, column=1)
|
||||||
|
artist_label.grid(row=2, column=1)
|
||||||
|
song_label.grid(row=1, column=1)
|
||||||
|
previous_button.grid(row=3, column=1, padx=(0,200), pady=(100,0))
|
||||||
|
play_button.grid(row=3, column=1, pady=(100,0))
|
||||||
|
next_button.grid(row=3, column=1, padx=(200,0), pady=(100,0))
|
||||||
|
progress_bar.grid(row=3, column=0, columnspan=3)
|
||||||
|
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():
|
||||||
|
# volumeslider_button.grid_forget()
|
||||||
|
# frame_artist_song.grid_forget()
|
||||||
|
# frame_controls.grid_forget()
|
||||||
|
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()
|
||||||
|
# loadLyrics_button.grid_forget()
|
||||||
|
# lyrics_label_frame.grid_forget()
|
||||||
|
lyrics_label.grid_forget()
|
||||||
|
album_art_label.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 loadLyrics():
|
||||||
|
# album_art_frame.grid(row=0, column=1)
|
||||||
|
# album_art_label.grid()
|
||||||
|
# lyrics_label.grid(row=0, column=1)
|
||||||
|
|
||||||
|
# def unloadLyrics():
|
||||||
|
# album_art_frame.grid_forget()
|
||||||
|
# album_art_label.grid_forget()
|
||||||
|
# lyrics_label.grid_forget()
|
||||||
|
|
||||||
|
# Start updating the song label
|
||||||
|
setup()
|
||||||
|
loadNow_playing()
|
||||||
|
update_song_label()
|
||||||
|
|
||||||
|
# Run the GUI
|
||||||
|
root.mainloop()
|
||||||
@@ -1,19 +1,15 @@
|
|||||||
import spotipy
|
import spotipy
|
||||||
import spotipy.util
|
from spotipy.oauth2 import SpotifyOAuth
|
||||||
import tkinter as ttk
|
import tkinter as ttk
|
||||||
from tkinter import ttk as tk
|
from tkinter import ttk as tk
|
||||||
import random
|
|
||||||
import sv_ttk
|
import sv_ttk
|
||||||
from urllib.request import urlopen
|
|
||||||
import requests
|
import requests
|
||||||
from time import sleep
|
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
import platform
|
|
||||||
import syncedlyrics
|
import syncedlyrics
|
||||||
from PIL import Image, ImageTk
|
from PIL import Image, ImageTk
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
import math
|
import math
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
# Set the Spotify app's client ID and client secret
|
# Set the Spotify app's client ID and client secret
|
||||||
client_id = "69b82a34d0fb40be80b020eae8e80f25"
|
client_id = "69b82a34d0fb40be80b020eae8e80f25"
|
||||||
@@ -24,70 +20,31 @@ redirect_uri = "http://127.0.0.1:8888/callback"
|
|||||||
username = "thebrandon45"
|
username = "thebrandon45"
|
||||||
password = "Mariposa2502$"
|
password = "Mariposa2502$"
|
||||||
|
|
||||||
def wait_for_connection():
|
# os.environ["DISPLAY"] = ":0"
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
urlopen('http://142.250.189.174', timeout=1)
|
|
||||||
return True
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# def wait_for_display():
|
# def setup():
|
||||||
|
# checkDisplay()
|
||||||
|
|
||||||
|
# def checkDisplay():
|
||||||
# while True:
|
# while True:
|
||||||
# try:
|
# if os.name == 'posix':
|
||||||
# test = ttk.Tk()
|
# if "DISPLAY" in os.environ:
|
||||||
# test.destroy()
|
# break
|
||||||
# return True
|
# else:
|
||||||
# except:
|
# sleep(0.25)
|
||||||
# pass
|
# pass
|
||||||
|
# else:
|
||||||
|
# break
|
||||||
|
|
||||||
|
|
||||||
# Get the user's Spotify authorization token
|
# Get the user's Spotify authorization token
|
||||||
scope = "user-read-playback-state,user-modify-playback-state"
|
scope = "user-read-playback-state,user-modify-playback-state"
|
||||||
if len(sys.argv) == 1:
|
|
||||||
pass
|
|
||||||
elif sys.argv[1] == "--setup":
|
|
||||||
try:
|
|
||||||
os.remove(".cache-" + username)
|
|
||||||
except OSError:
|
|
||||||
pass
|
|
||||||
elif sys.argv[1] == "--clear":
|
|
||||||
os.remove(".cache-" + username)
|
|
||||||
sys.exit("Deleting token from cache and exiting...")
|
|
||||||
elif sys.argv[1] == "--clearChromeCache":
|
|
||||||
if platform.system() == "Linux":
|
|
||||||
os.system("rm -rf ~/.cache/chromium")
|
|
||||||
os.system("rm -rf ~/.config/chromium")
|
|
||||||
sys.exit("Deleting Chrome cache and exiting...")
|
|
||||||
|
|
||||||
# def oauthLogin():
|
|
||||||
# if os.path.isfile(".cache-" + username) == False:
|
|
||||||
# sleep(25)
|
|
||||||
# pyautogui.press('tab')
|
|
||||||
# pyautogui.press('tab')
|
|
||||||
# pyautogui.press('tab')
|
|
||||||
# pyautogui.press('tab')
|
|
||||||
# pyautogui.write(username)
|
|
||||||
# pyautogui.press('tab')
|
|
||||||
# pyautogui.write(password)
|
|
||||||
# pyautogui.press('enter')
|
|
||||||
# sleep(90)
|
|
||||||
# if platform.system() == "Linux":
|
|
||||||
# os.system("killall chromium-browser")
|
|
||||||
|
|
||||||
# threading.Thread(target=oauthLogin).start()
|
|
||||||
|
|
||||||
# oauthLogin()
|
|
||||||
|
|
||||||
token = spotipy.util.prompt_for_user_token(username, scope, client_id, client_secret, redirect_uri)
|
|
||||||
|
|
||||||
# Create a Spotify object with the user's authorization token
|
# Create a Spotify object with the user's authorization token
|
||||||
def createToken():
|
spotify = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, scope=scope, requests_timeout=30))
|
||||||
spotify = spotipy.Spotify(auth=token)
|
|
||||||
return spotify
|
|
||||||
|
|
||||||
spotify = createToken()
|
|
||||||
|
|
||||||
bg_color = "#000000"
|
bg_color = "#000000"
|
||||||
|
count = 0
|
||||||
|
|
||||||
# Create the tkinter window
|
# Create the tkinter window
|
||||||
root = ttk.Tk()
|
root = ttk.Tk()
|
||||||
@@ -111,54 +68,19 @@ def next():
|
|||||||
def previous():
|
def previous():
|
||||||
spotify.previous_track()
|
spotify.previous_track()
|
||||||
|
|
||||||
def maxvolume():
|
|
||||||
spotify.volume(100)
|
|
||||||
|
|
||||||
def minvolume():
|
|
||||||
spotify.volume(0)
|
|
||||||
|
|
||||||
def randomvolume():
|
|
||||||
spotify.volume(random.randint(0,100))
|
|
||||||
|
|
||||||
def volumeslider(self):
|
|
||||||
spotify.volume(int(volumeslider_button.get()))
|
|
||||||
|
|
||||||
def search(event):
|
|
||||||
searched = track_search.get()
|
|
||||||
if searched.startswith(":t"):
|
|
||||||
track_searched_isolated = searched.replace(":t", "")
|
|
||||||
track_search_results = spotify.search(q='track:' + track_searched_isolated, type='track')
|
|
||||||
searched_track_id = track_search_results["tracks"]["items"][0]["id"]
|
|
||||||
spotify.start_playback(uris=["spotify:track:" + searched_track_id])
|
|
||||||
if searched.startswith(":a"):
|
|
||||||
artist_searched_isolated = searched.replace(":a", "")
|
|
||||||
artist_search_results = spotify.search(q='artist:' + artist_searched_isolated, type='artist')
|
|
||||||
searched_artist_id = artist_search_results["artists"]["items"][0]["uri"]
|
|
||||||
spotify.start_playback(context_uri=searched_artist_id)
|
|
||||||
if searched.startswith(":l"):
|
|
||||||
album_searched_isolated = searched.replace(":l", "")
|
|
||||||
album_search_results = spotify.search(q='album:' + album_searched_isolated, type='album')
|
|
||||||
searched_album_id = album_search_results["albums"]["items"][0]["uri"]
|
|
||||||
spotify.start_playback(context_uri=searched_album_id)
|
|
||||||
if searched.startswith(":p"):
|
|
||||||
playlist_searched_isolated = searched.replace(":p", "")
|
|
||||||
playlist_search_results = spotify.search(q='playlist:' + playlist_searched_isolated, type='playlist')
|
|
||||||
searched_playlist_id = playlist_search_results["playlists"]["items"][0]["uri"]
|
|
||||||
spotify.start_playback(context_uri=searched_playlist_id)
|
|
||||||
|
|
||||||
def start_playback_on_device():
|
def start_playback_on_device():
|
||||||
device_selections = devices_list.curselection()
|
device_selections = devices_list.curselection()
|
||||||
try:
|
list_of_devices = spotify.devices()
|
||||||
list_of_devices = spotify.devices()
|
|
||||||
except (spotipy.exceptions.SpotifyException, requests.exceptions.HTTPError):
|
|
||||||
createToken()
|
|
||||||
pass
|
|
||||||
list_of_devices = spotify.devices()
|
list_of_devices = spotify.devices()
|
||||||
device_id = list_of_devices["devices"][device_selections[0]]["id"]
|
device_id = list_of_devices["devices"][device_selections[0]]["id"]
|
||||||
spotify.transfer_playback(device_id=device_id)
|
spotify.transfer_playback(device_id=device_id)
|
||||||
|
|
||||||
|
|
||||||
def get_devices():
|
def get_devices():
|
||||||
|
# count +=1
|
||||||
|
# if count >= 277:
|
||||||
|
|
||||||
list_of_devices = spotify.devices()
|
list_of_devices = spotify.devices()
|
||||||
unloadNow_playing()
|
unloadNow_playing()
|
||||||
if list_of_devices == "{'devices': []}":
|
if list_of_devices == "{'devices': []}":
|
||||||
@@ -176,30 +98,11 @@ def get_devices():
|
|||||||
unloadSearching_Devices()
|
unloadSearching_Devices()
|
||||||
loadDevices_list()
|
loadDevices_list()
|
||||||
devices_list.delete(0, ttk.END)
|
devices_list.delete(0, ttk.END)
|
||||||
try:
|
|
||||||
list_of_devices = spotify.devices()
|
|
||||||
except (spotipy.exceptions.SpotifyException, requests.exceptions.HTTPError):
|
|
||||||
createToken()
|
|
||||||
pass
|
|
||||||
list_of_devices = spotify.devices()
|
list_of_devices = spotify.devices()
|
||||||
for num_of_device, garbage in enumerate(list_of_devices["devices"]):
|
for num_of_device, garbage in enumerate(list_of_devices["devices"]):
|
||||||
devices_list.insert(num_of_device, list_of_devices["devices"][num_of_device]["name"])
|
devices_list.insert(num_of_device, list_of_devices["devices"][num_of_device]["name"])
|
||||||
root.after(6500, get_devices)
|
root.after(6500, get_devices)
|
||||||
|
|
||||||
def loadLyrics_pressed():
|
|
||||||
unloadNow_playing()
|
|
||||||
loadLyrics()
|
|
||||||
|
|
||||||
def unloadLyrics_pressed():
|
|
||||||
unloadLyrics()
|
|
||||||
loadNow_playing()
|
|
||||||
|
|
||||||
|
|
||||||
# def hide_devices():
|
|
||||||
# get_devices_button.grid()
|
|
||||||
# devices_list.grid_remove()
|
|
||||||
# start_playback_on_device_button.grid_remove()
|
|
||||||
# hide_devices_button.grid_remove()
|
|
||||||
|
|
||||||
|
|
||||||
play_img = ttk.PhotoImage(file="icons/play-circle-x2.png")
|
play_img = ttk.PhotoImage(file="icons/play-circle-x2.png")
|
||||||
@@ -210,19 +113,10 @@ play_img_black = ttk.PhotoImage(file="icons/play-circle-x2-black.png")
|
|||||||
pause_img_black = ttk.PhotoImage(file="icons/pause-circle-x2-black.png")
|
pause_img_black = ttk.PhotoImage(file="icons/pause-circle-x2-black.png")
|
||||||
next_img_black = ttk.PhotoImage(file="icons/skip-next-x2-black.png")
|
next_img_black = ttk.PhotoImage(file="icons/skip-next-x2-black.png")
|
||||||
previous_img_black = ttk.PhotoImage(file="icons/skip-previous-x2-black.png")
|
previous_img_black = ttk.PhotoImage(file="icons/skip-previous-x2-black.png")
|
||||||
# lyrics_img = ttk.PhotoImage(file="icons/lyrics.png")
|
|
||||||
album_art_img = ""
|
album_art_img = ""
|
||||||
# album_art_img = ttk.PhotoImage(file="album_art.png")
|
|
||||||
|
|
||||||
# canvas = ttk.Canvas(root, width=480, height=320)
|
|
||||||
# canvas.create_image(0, 0, image=album_art_img, anchor="nw")
|
|
||||||
# canvas.grid()
|
|
||||||
|
|
||||||
canvas = ttk.Canvas(root, width=480, height=320)
|
|
||||||
|
|
||||||
frame_artist_song = ttk.Frame(root, width=(1280/3), height=400, bg=bg_color)
|
frame_artist_song = ttk.Frame(root, width=(1280/3), height=400, bg=bg_color)
|
||||||
# frame_controls = tk.Frame(root)
|
|
||||||
# lyrics_button = tk.Frame(root)
|
|
||||||
album_art_frame = ttk.Frame(root, bg=bg_color)
|
album_art_frame = ttk.Frame(root, bg=bg_color)
|
||||||
lyrics_label_frame = ttk.Frame(root, width=(1280/3), height=400, bg=bg_color)
|
lyrics_label_frame = ttk.Frame(root, width=(1280/3), height=400, bg=bg_color)
|
||||||
lyrics_label_frame.grid_propagate(0)
|
lyrics_label_frame.grid_propagate(0)
|
||||||
@@ -232,7 +126,6 @@ root.grid_rowconfigure(1, weight=1)
|
|||||||
root.grid_rowconfigure(2, weight=1)
|
root.grid_rowconfigure(2, weight=1)
|
||||||
root.grid_columnconfigure(0, weight=1)
|
root.grid_columnconfigure(0, weight=1)
|
||||||
root.grid_columnconfigure(1, weight=1)
|
root.grid_columnconfigure(1, weight=1)
|
||||||
# root.grid_columnconfigure(2, weight=1)
|
|
||||||
|
|
||||||
root.configure(background=bg_color)
|
root.configure(background=bg_color)
|
||||||
|
|
||||||
@@ -244,35 +137,18 @@ play_button = ttk.Label(frame_artist_song, image=play_img, borderwidth=0)
|
|||||||
pause_button = ttk.Label(frame_artist_song, image=pause_img, borderwidth=0)
|
pause_button = ttk.Label(frame_artist_song, image=pause_img, borderwidth=0)
|
||||||
next_button = ttk.Label(frame_artist_song, image=next_img, borderwidth=0)
|
next_button = ttk.Label(frame_artist_song, image=next_img, borderwidth=0)
|
||||||
previous_button = ttk.Label(frame_artist_song, image=previous_img, borderwidth=0)
|
previous_button = ttk.Label(frame_artist_song, image=previous_img, borderwidth=0)
|
||||||
maxvolume_button = tk.Button(root, text="Max Volume", command=maxvolume)
|
artist_label = tk.Label(frame_artist_song, text="", font=("Helvetica", 24), wraplength=(1280/3), justify=ttk.CENTER, background=bg_color)
|
||||||
minvolume_button = tk.Button(root, text="Min Volume", command=minvolume)
|
song_label = tk.Label(frame_artist_song, text="", font=("Helvetica", 32), wraplength=(1280/3), justify=ttk.CENTER, background=bg_color)
|
||||||
randomvolume_button = tk.Button(root, text="Random Volume", command=randomvolume)
|
|
||||||
volumeslider_button = tk.Scale(root, from_=100, to=0, orient=ttk.VERTICAL, length=240, command=volumeslider)
|
|
||||||
#doaudio_analysis = tk.Button(root, text="Audio Analysis", command=doaudioanalysis)
|
|
||||||
artist_label = tk.Label(frame_artist_song, text="", font=("Helvetica", 32), wraplength=(1280/3), justify=ttk.CENTER, background=bg_color)
|
|
||||||
song_label = tk.Label(frame_artist_song, text="", font=("Helvetica", 24), wraplength=(1280/3), justify=ttk.CENTER, background=bg_color)
|
|
||||||
track_progress_label = tk.Label(root, text="")
|
|
||||||
track_duration_label = tk.Label(root, text="")
|
|
||||||
# track_combined_label = tk.Label(root, text="")
|
|
||||||
track_search = tk.Entry(root, text="")
|
|
||||||
track_search_button = tk.Button(root, text="Search", command=search)
|
|
||||||
get_devices_button = tk.Button(root, text="Get Devices", command=get_devices)
|
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)
|
start_playback_on_device_button = tk.Button(root, text="Start Playback on Device", command=start_playback_on_device)
|
||||||
# hide_devices_button = tk.Button(root, text="Hide Devices", command=hide_devices)
|
|
||||||
username_label = tk.Label(root, text="Username: " + spotify.me()["display_name"])
|
|
||||||
devices_list = ttk.Listbox(root, selectmode=ttk.SINGLE, font=("Helvetica", 18))
|
devices_list = ttk.Listbox(root, selectmode=ttk.SINGLE, font=("Helvetica", 18))
|
||||||
progress_bar = tk.Progressbar(root, orient=ttk.HORIZONTAL, length=1280)
|
progress_bar = tk.Progressbar(root, orient=ttk.HORIZONTAL, length=1280)
|
||||||
searching_for_devices_label = tk.Label(root, text="Searching for Devices...", font=("Helvetica", 24))
|
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))
|
device_name_label = tk.Label(frame_artist_song, text="", font=("Helvetica", 12))
|
||||||
# background_image_label = tk.Label(root, image=album_art_img)
|
|
||||||
lyrics_label = tk.Label(lyrics_label_frame, text="", font=("Helvetica", 32), wraplength=(1280/3), justify=ttk.CENTER, background=bg_color)
|
lyrics_label = tk.Label(lyrics_label_frame, text="", font=("Helvetica", 32), wraplength=(1280/3), justify=ttk.CENTER, background=bg_color)
|
||||||
# loadLyrics_button = ttk.Button(lyrics_button, image=lyrics_img, command=loadLyrics_pressed, borderwidth=0)
|
|
||||||
# album_art_canvas = ttk.Canvas(root)
|
|
||||||
# album_art_canvas_create_image = album_art_canvas.create_image(0, 0, image=album_art_img)
|
|
||||||
album_art_label = tk.Label(album_art_frame, image=album_art_img)
|
album_art_label = tk.Label(album_art_frame, image=album_art_img)
|
||||||
|
|
||||||
root.bind("<Return>", search)
|
|
||||||
lyrics_label.bind("<Button-1>", lambda e:unloadLyrics_pressed())
|
|
||||||
play_button.bind("<Button-1>", lambda e:play())
|
play_button.bind("<Button-1>", lambda e:play())
|
||||||
pause_button.bind("<Button-1>", lambda e:pause())
|
pause_button.bind("<Button-1>", lambda e:pause())
|
||||||
next_button.bind("<Button-1>", lambda e:next())
|
next_button.bind("<Button-1>", lambda e:next())
|
||||||
@@ -283,16 +159,9 @@ def update_song_label():
|
|||||||
global lrc
|
global lrc
|
||||||
global album_art_img
|
global album_art_img
|
||||||
# Get the current playback information
|
# Get the current playback information
|
||||||
while True:
|
current_playback = spotify.current_playback()
|
||||||
try:
|
|
||||||
current_playback = spotify.current_playback()
|
|
||||||
break
|
|
||||||
except (spotipy.exceptions.SpotifyException, requests.exceptions.HTTPError):
|
|
||||||
createToken()
|
|
||||||
# If there is no current playback, set the text of the song label to "No playback"
|
# If there is no current playback, set the text of the song label to "No playback"
|
||||||
if current_playback is None:
|
if current_playback is None:
|
||||||
# nothing_playing_obj = '{"item": {"artists": [{"name": "Nothing Playing"}],"duration_ms": 0,"name": "Nothing Playing"},"progress_ms": 0}'
|
|
||||||
# current_playback = json.loads(nothing_playing_obj)
|
|
||||||
get_devices()
|
get_devices()
|
||||||
# Update the song label every 1 second
|
# Update the song label every 1 second
|
||||||
else:
|
else:
|
||||||
@@ -300,44 +169,24 @@ def update_song_label():
|
|||||||
artist_name = current_playback["item"]["artists"][0]["name"]
|
artist_name = current_playback["item"]["artists"][0]["name"]
|
||||||
track_duration = current_playback["item"]["duration_ms"]
|
track_duration = current_playback["item"]["duration_ms"]
|
||||||
track_progress = current_playback["progress_ms"]
|
track_progress = current_playback["progress_ms"]
|
||||||
current_volume = current_playback["device"]["volume_percent"]
|
|
||||||
playing_status = current_playback["is_playing"]
|
playing_status = current_playback["is_playing"]
|
||||||
device_name = current_playback["device"]["name"]
|
device_name = current_playback["device"]["name"]
|
||||||
album_art_url = current_playback["item"]["album"]["images"][0]["url"]
|
album_art_url = current_playback["item"]["album"]["images"][0]["url"]
|
||||||
track_progress_min = track_progress//(1000*60)%60
|
track_progress_min = track_progress//(1000*60)%60
|
||||||
track_progress_sec = (track_progress//1000)%60
|
track_progress_sec = (track_progress//1000)%60
|
||||||
track_duration_min = track_duration//(1000*60)%60
|
|
||||||
track_duration_sec = (track_duration//1000)%60
|
|
||||||
# open_url = urlopen(album_art_url)
|
|
||||||
# raw_image_data = open_url.read()
|
|
||||||
# open_url.close()
|
|
||||||
# album_art = ImageTk.PhotoImage(data=raw_image_data)
|
|
||||||
# background_image_label.config(image=album_art)
|
|
||||||
# print(background_image_label.cget("image"))
|
|
||||||
# if raw_image_data == background_image_label.cget("image"):
|
|
||||||
# print("this is the same image")
|
|
||||||
# else:
|
|
||||||
# pass
|
|
||||||
# loadNow_playing()
|
|
||||||
if track_name == song_label.cget("text"):
|
if track_name == song_label.cget("text"):
|
||||||
track_progress_formatted = ("{}:{:02d}".format(track_progress_min, track_progress_sec))
|
track_progress_formatted = ("{}:{:02d}".format(track_progress_min, track_progress_sec))
|
||||||
track_progress_label.config(text=track_progress_formatted)
|
|
||||||
progress_bar.config(maximum=track_duration)
|
progress_bar.config(maximum=track_duration)
|
||||||
progress_bar.config(value=track_progress)
|
progress_bar.config(value=track_progress)
|
||||||
for line in str(lrc).splitlines():
|
for line in str(lrc).splitlines():
|
||||||
if track_progress_formatted in line:
|
if track_progress_formatted in line:
|
||||||
lyric = line.split("]")[1]
|
lyric = line.split("]")[1]
|
||||||
# wrapped_lyric = textwrap.fill(lyric, 21)
|
|
||||||
lyrics_label.config(text=lyric)
|
lyrics_label.config(text=lyric)
|
||||||
root.after(800, update_song_label)
|
root.after(800, update_song_label)
|
||||||
else:
|
else:
|
||||||
# album_art_data = Image.open(requests.get(album_art_url, stream=True).raw)
|
|
||||||
# album_art_data.save("album_art.jpg")
|
|
||||||
device_name_label.config(text=device_name)
|
device_name_label.config(text=device_name)
|
||||||
song_label.config(text=track_name)
|
song_label.config(text=track_name)
|
||||||
artist_label.config(text=artist_name)
|
artist_label.config(text=artist_name)
|
||||||
track_duration_label.config(text=("{}:{:02d}".format(track_duration_min, track_duration_sec)))
|
|
||||||
volumeslider_button.set(value=current_volume)
|
|
||||||
lyrics_label.config(text="")
|
lyrics_label.config(text="")
|
||||||
lrc = syncedlyrics.search("[" + track_name + "] [" + artist_name + "]")
|
lrc = syncedlyrics.search("[" + track_name + "] [" + artist_name + "]")
|
||||||
album_art_img_data = requests.get(album_art_url).content
|
album_art_img_data = requests.get(album_art_url).content
|
||||||
@@ -358,7 +207,7 @@ def update_song_label():
|
|||||||
previous_button.config(background=bg_color)
|
previous_button.config(background=bg_color)
|
||||||
lyrics_label_frame.config(background=bg_color)
|
lyrics_label_frame.config(background=bg_color)
|
||||||
lyrics_label.config(background=bg_color)
|
lyrics_label.config(background=bg_color)
|
||||||
if math.sqrt(0.299 * (bg_color_img_pixel[0] ** 2) + 0.587 * (bg_color_img_pixel[1] ** 2) + 0.114 * (bg_color_img_pixel[2] ** 2)) > 186:
|
if math.sqrt(0.299 * (bg_color_img_pixel[0] ** 2) + 0.587 * (bg_color_img_pixel[1] ** 2) + 0.114 * (bg_color_img_pixel[2] ** 2)) > 170:
|
||||||
song_label.config(foreground="black")
|
song_label.config(foreground="black")
|
||||||
artist_label.config(foreground="black")
|
artist_label.config(foreground="black")
|
||||||
device_name_label.config(foreground="black")
|
device_name_label.config(foreground="black")
|
||||||
@@ -376,17 +225,7 @@ def update_song_label():
|
|||||||
pause_button.config(image=pause_img)
|
pause_button.config(image=pause_img)
|
||||||
next_button.config(image=next_img)
|
next_button.config(image=next_img)
|
||||||
previous_button.config(image=previous_img)
|
previous_button.config(image=previous_img)
|
||||||
# album_art_label.grid_forget()
|
|
||||||
# album_art_label.grid()
|
|
||||||
root.after(500, update_song_label)
|
root.after(500, update_song_label)
|
||||||
# if album_art_url == "12345":
|
|
||||||
# open_url = urlopen(album_art_url)
|
|
||||||
# raw_image_data = open_url.read()
|
|
||||||
# open_url.close()
|
|
||||||
# album_art = ImageTk.PhotoImage(data=raw_image_data)
|
|
||||||
# background_image_label.config(image=album_art)
|
|
||||||
# else:
|
|
||||||
# pass
|
|
||||||
if playing_status == True:
|
if playing_status == True:
|
||||||
play_button.grid_forget()
|
play_button.grid_forget()
|
||||||
pause_button.grid(row=3, column=1, pady=(100,0))
|
pause_button.grid(row=3, column=1, pady=(100,0))
|
||||||
@@ -397,15 +236,10 @@ def update_song_label():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def loadNow_playing():
|
def loadNow_playing():
|
||||||
# background_image_label.place(x=0, y=0)
|
|
||||||
# volumeslider_button.grid(row=1, column=1, rowspan=3, sticky="e", padx=(0,20))
|
|
||||||
# lyrics_button.grid(row=1, column=1, padx=(0,380))
|
|
||||||
frame_artist_song.grid(row=0, column=1, rowspan=3, pady=(20,0))
|
frame_artist_song.grid(row=0, column=1, rowspan=3, pady=(20,0))
|
||||||
# frame_controls.grid(row=2, column=1)
|
|
||||||
# loadLyrics_button.grid()
|
|
||||||
device_name_label.grid(row=0, column=1)
|
device_name_label.grid(row=0, column=1)
|
||||||
artist_label.grid(row=1, column=1)
|
artist_label.grid(row=2, column=1)
|
||||||
song_label.grid(row=2, column=1)
|
song_label.grid(row=1, column=1)
|
||||||
previous_button.grid(row=3, column=1, padx=(0,200), pady=(100,0))
|
previous_button.grid(row=3, column=1, padx=(0,200), pady=(100,0))
|
||||||
play_button.grid(row=3, column=1, pady=(100,0))
|
play_button.grid(row=3, column=1, pady=(100,0))
|
||||||
next_button.grid(row=3, column=1, padx=(200,0), pady=(100,0))
|
next_button.grid(row=3, column=1, padx=(200,0), pady=(100,0))
|
||||||
@@ -416,16 +250,15 @@ def loadNow_playing():
|
|||||||
lyrics_label.grid()
|
lyrics_label.grid()
|
||||||
|
|
||||||
def unloadNow_playing():
|
def unloadNow_playing():
|
||||||
volumeslider_button.grid_forget()
|
device_name_label.grid_forget()
|
||||||
frame_artist_song.grid_forget()
|
|
||||||
# frame_controls.grid_forget()
|
|
||||||
artist_label.grid_forget()
|
artist_label.grid_forget()
|
||||||
song_label.grid_forget()
|
song_label.grid_forget()
|
||||||
previous_button.grid_forget()
|
previous_button.grid_forget()
|
||||||
play_button.grid_forget()
|
play_button.grid_forget()
|
||||||
next_button.grid_forget()
|
next_button.grid_forget()
|
||||||
progress_bar.grid_forget()
|
progress_bar.grid_forget()
|
||||||
# loadLyrics_button.grid_forget()
|
lyrics_label.grid_forget()
|
||||||
|
album_art_label.grid_forget()
|
||||||
|
|
||||||
def loadDevices_list():
|
def loadDevices_list():
|
||||||
devices_list.grid(row=1, column=1, pady=10)
|
devices_list.grid(row=1, column=1, pady=10)
|
||||||
@@ -441,18 +274,9 @@ def loadSearching_Devices():
|
|||||||
def unloadSearching_Devices():
|
def unloadSearching_Devices():
|
||||||
searching_for_devices_label.grid_forget()
|
searching_for_devices_label.grid_forget()
|
||||||
|
|
||||||
def loadLyrics():
|
|
||||||
album_art_frame.grid(row=0, column=1)
|
|
||||||
album_art_label.grid()
|
|
||||||
lyrics_label.grid(row=0, column=1)
|
|
||||||
|
|
||||||
def unloadLyrics():
|
|
||||||
album_art_frame.grid_forget()
|
|
||||||
album_art_label.grid_forget()
|
|
||||||
lyrics_label.grid_forget()
|
|
||||||
|
|
||||||
# Start updating the song label
|
# Start updating the song label
|
||||||
wait_for_connection()
|
# setup()
|
||||||
loadNow_playing()
|
loadNow_playing()
|
||||||
update_song_label()
|
update_song_label()
|
||||||
|
|
||||||
|
|||||||
11
spotify-gui.service
Normal file
11
spotify-gui.service
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Spotify GUI
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=pi
|
||||||
|
WorkingDirectory=/opt/spotify-gui
|
||||||
|
ExecStart=xinit ./start.sh $* -- :0 vt$XDG_VTNR -nocursor
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
18
todo.txt
18
todo.txt
@@ -9,3 +9,21 @@ selection resets after 1 second on devices list; need to remove root.after in up
|
|||||||
|
|
||||||
01/14/23:
|
01/14/23:
|
||||||
smooth progress bar
|
smooth progress bar
|
||||||
|
|
||||||
|
01/15/23:
|
||||||
|
turns off screen and stops polling api after inactivity, reauthenticates when
|
||||||
|
screen is turned back on
|
||||||
|
|
||||||
|
01/18/23:
|
||||||
|
turn off screen when holding down on album art.
|
||||||
|
|
||||||
|
01/20/2023:
|
||||||
|
background gradient
|
||||||
|
|
||||||
|
01/21/2023:
|
||||||
|
it errors on "track_name = current_playback["item"]["name"]"
|
||||||
|
'TypeError: NoneType', current_playback is None basically... even though there is already an if statement checking if it is None.
|
||||||
|
ERROR HAPPENS ON SOME KIDZ BOP SONGS???
|
||||||
|
|
||||||
|
01/21/2023:
|
||||||
|
add canvas videos to background if available. USE: https://github.com/Delitefully/spotify-canvas-downloader/blob/master/src/canvas.py
|
||||||
18
update.py
Normal file
18
update.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import urllib
|
||||||
|
from urllib.request import urlopen
|
||||||
|
from zipfile import ZipFile
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
urlopen('http://bbrunson.com', timeout=1)
|
||||||
|
break
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
with ZipFile(BytesIO((urlopen('http://files.bbrunson.com/spotify-gui/update.zip')).read())) as zipObj:
|
||||||
|
zipObj.extractall()
|
||||||
|
except urllib.error.HTTPError:
|
||||||
|
pass
|
||||||
|
exec(open('program-embedded.py').read())
|
||||||
Reference in New Issue
Block a user