import spotipy import spotipy.util import tkinter as ttk from tkinter import ttk as tk import random import json import sv_ttk # 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" # Get the user's Spotify authorization token scope = "user-read-playback-state,user-modify-playback-state" 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 spotify = spotipy.Spotify(auth=token) # Create the tkinter window root = ttk.Tk() root.title("Media Controller") root.geometry("480x320") root.attributes("-topmost", True) root.overrideredirect(1) sv_ttk.use_dark_theme() rootDevices = ttk.Tk() rootDevices.title("Media Controller") rootDevices.geometry("480x320") rootDevices.attributes("-topmost", True) rootDevices.overrideredirect(1) # 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() 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(): devices_list.delete(0, ttk.END) 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"]) get_devices_button.pack_forget() hide_devices_button.pack() devices_list.pack() start_playback_on_device_button.pack() def hide_devices(): get_devices_button.pack() devices_list.pack_forget() start_playback_on_device_button.pack_forget() hide_devices_button.pack_forget() 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") frame_artist_song = tk.Frame(root) frame_controls = tk.Frame(root) root.grid_rowconfigure(0, weight=1) root.grid_rowconfigure(1, weight=1) root.grid_rowconfigure(2, weight=1) root.grid_rowconfigure(3, weight=1) root.grid_columnconfigure(0, weight=1) root.grid_columnconfigure(1, weight=1) root.grid_columnconfigure(2, weight=1) # Create the media control buttons and a text label play_button = ttk.Button(frame_controls, image=play_img, command=play, borderwidth=0, relief=None) pause_button = ttk.Button(frame_controls, image=pause_img, command=pause, borderwidth=0) next_button = ttk.Button(frame_controls, image=next_img, command=next, borderwidth=0) previous_button = ttk.Button(frame_controls, image=previous_img, command=previous, 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)) song_label = tk.Label(frame_artist_song, text="", font=("Helvetica", 24)) 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) progress_bar = tk.Progressbar(root, orient=ttk.HORIZONTAL, length=480) volumeslider_button.grid(row=1, column=1, rowspan=3, sticky="e", padx=(0,20)) frame_artist_song.grid(row=1, column=1, pady=(20,5)) frame_controls.grid(row=2, column=1, pady=(20,0)) artist_label.grid() song_label.grid() previous_button.grid(row=0, column=0, padx=(0,10)) play_button.grid(row=0, column=1) next_button.grid(row=0, column=2, padx=(10,0)) progress_bar.grid(row=3, column=1, pady=(20,0)) root.bind("", search) # Function to update the song label with the current track's name def update_song_label(): # 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: # nothing_playing_obj = '{"item": {"artists": [{"name": "Nothing Playing"}],"duration_ms": 0,"name": "Nothing Playing"},"progress_ms": 0}' # current_playback = json.loads(nothing_playing_obj) track_name = "Nothing Playing" artist_name = "Nothing Playing" track_progress = 0 track_duration = 0 current_volume = 0 playing_status = False else: track_name = current_playback["item"]["name"] artist_name = current_playback["item"]["artists"][0]["name"] track_progress = current_playback["progress_ms"] track_duration = current_playback["item"]["duration_ms"] current_volume = current_playback["device"]["volume_percent"] playing_status = current_playback["is_playing"] # Set the text of the song label to the track's name song_label.config(text=track_name) artist_label.config(text=artist_name) 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 track_progress_label.config(text=("{}:{:02d}".format(track_progress_min, track_progress_sec))) track_duration_label.config(text=("{}:{:02d}".format(track_duration_min, track_duration_sec))) progress_bar.config(maximum=track_duration) progress_bar.config(value=track_progress) track_combined_label.config(text=("{}:{:02d} / {}:{:02d}".format(track_progress_min, track_progress_sec, track_duration_min, track_duration_sec))) if playing_status == True: play_button.grid_forget() pause_button.grid(row=0, column=1) elif playing_status == False: pause_button.grid_forget() play_button.grid(row=0, column=1) else: pass # Update the song label every 1 second root.after(1000, update_song_label) # Start updating the song label update_song_label() # Run the GUI root.mainloop()