- volume slider of device will be grabbed on start
- if no music is playing, device list will appear that keeps searching
This commit is contained in:
@@ -1 +1 @@
|
|||||||
{"access_token": "BQDGLDKMfiNe4CK2l9-RdoedRx2QfGqoYkmW21bEXH43BW2731XrUtwkQnomX472HG0U04FahklGSfPSFHJLl4052Bxdypf6I1LWmlEh9Y_pGYVWxK279xyUMrg6MUksj3QcxFfn44PCajOvkgCrSQU3gdaBxbUWvNStiaYZ6DgcE2ou9fJ-HYhm3EeCkA", "token_type": "Bearer", "expires_in": 3600, "scope": "user-modify-playback-state user-read-playback-state", "expires_at": 1671086161, "refresh_token": "AQAQRkRkmOxwR34lsJu_mpG4wxEFiNuJ1FIdmHYN5j0dClEEqMRqPPFX8jM3cQTQkRpeXXyi3xPQ8YImc7Fc-PH1CKTvyARy9VkMKXIes4-l6ijO9fVMyCNwbI0IGvpfrqE"}
|
{"access_token": "BQDi5JTAjQCSNArackjHJE8bQ3Gbb_MDBdIUHEbiKZRAzA0k3PSJRd-1IytW8Ez0OQSZnLczyhp3rl2ZB7vdklSz0lTn2b4yTYgLYe2jBrmznYsnTOHAkaNFWtYjy5skxrq6xV24MSoLsZocXFd96ozn-1Hc3752XMmq4hVkBFUR5I3WlTFc9IHdOjjCVA", "token_type": "Bearer", "expires_in": 3600, "scope": "user-modify-playback-state user-read-playback-state", "expires_at": 1671273275, "refresh_token": "AQAQRkRkmOxwR34lsJu_mpG4wxEFiNuJ1FIdmHYN5j0dClEEqMRqPPFX8jM3cQTQkRpeXXyi3xPQ8YImc7Fc-PH1CKTvyARy9VkMKXIes4-l6ijO9fVMyCNwbI0IGvpfrqE"}
|
||||||
@@ -1 +1 @@
|
|||||||
{"username": "thebrandon45", "credentials": "QVFEalQxYVlobUdHczYwd21NNERDcWgxMVhtUFBlU1dicWN6VW9PR0JraDNLa0NrUDU4YlFVSzNQUDRka2NTLUo3aHVtQlFrMHJYWGlnai1pc0RQNjY4a1dDSDFZYmR6NnB6ZGhRaFd0bkNaSjVpMVZLeXlWWlE2dEJiOW5zR3RwMy1IQlkxdEJ2RjhMQQ==", "type": "AUTHENTICATION_STORED_SPOTIFY_CREDENTIALS"}
|
{"username": "thebrandon45", "credentials": "QVFCYUsxTG9xY0NOYlY4RnVBOThVRjdESTVMTnRvU05jTTJfSkNMZ1NCb1J0anFhQzFrdTFrZzc3VGxRUUVLZUxQMUU3ekx4Unp3am9DSHAwaTE3cDNKNDJLSENmbnhkNk1tb1pVSlNmUzhkUGlwRWlTRElPclp6QU9hRmFBX3BiZFlZd2NIYzk2UTNoQQ==", "type": "AUTHENTICATION_STORED_SPOTIFY_CREDENTIALS"}
|
||||||
BIN
icons/pause-circle-x2.png
Normal file
BIN
icons/pause-circle-x2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
BIN
icons/play-circle-x2.png
Normal file
BIN
icons/play-circle-x2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
icons/skip-next-x2.png
Normal file
BIN
icons/skip-next-x2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 976 B |
BIN
icons/skip-previous-x2.png
Normal file
BIN
icons/skip-previous-x2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 965 B |
213
program-embedded.py
Normal file
213
program-embedded.py
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
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("<Return>", 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()
|
||||||
186
program-production.py
Normal file
186
program-production.py
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
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.attributes("-topmost", True)
|
||||||
|
root.overrideredirect(1)
|
||||||
|
sv_ttk.use_dark_theme()
|
||||||
|
|
||||||
|
# Function to call the Spotify API to play the current track
|
||||||
|
def play():
|
||||||
|
play_button.grid_forget()
|
||||||
|
pause_button.grid(row=0, column=1)
|
||||||
|
spotify.start_playback()
|
||||||
|
|
||||||
|
# Function to call the Spotify API to pause the current track
|
||||||
|
def pause():
|
||||||
|
pause_button.grid_forget()
|
||||||
|
play_button.grid(row=0, column=1)
|
||||||
|
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.png")
|
||||||
|
pause_img = ttk.PhotoImage(file="icons/pause-circle.png")
|
||||||
|
next_img = ttk.PhotoImage(file="icons/skip-next.png")
|
||||||
|
previous_img = ttk.PhotoImage(file="icons/skip-previous.png")
|
||||||
|
|
||||||
|
|
||||||
|
frame_artist_song = tk.Frame(root)
|
||||||
|
frame_controls = tk.Frame(root)
|
||||||
|
|
||||||
|
# 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, command=volumeslider)
|
||||||
|
#doaudio_analysis = tk.Button(root, text="Audio Analysis", command=doaudioanalysis)
|
||||||
|
artist_label = tk.Label(frame_artist_song, text="")
|
||||||
|
song_label = tk.Label(frame_artist_song, text="")
|
||||||
|
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=300)
|
||||||
|
volumeslider_button.grid(row=1, column=1, rowspan=3, sticky="e", padx=(0,5))
|
||||||
|
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,5))
|
||||||
|
|
||||||
|
root.bind("<Return>", 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)
|
||||||
|
# Get the current track's name
|
||||||
|
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"]
|
||||||
|
|
||||||
|
# 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)))
|
||||||
|
|
||||||
|
# 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()
|
||||||
13
program.py
13
program.py
@@ -38,7 +38,7 @@ spotify = spotipy.Spotify(auth=token)
|
|||||||
# Create the tkinter window
|
# Create the tkinter window
|
||||||
root = ttk.Tk()
|
root = ttk.Tk()
|
||||||
root.title("Media Controller")
|
root.title("Media Controller")
|
||||||
root.attributes("-topmost", True)
|
root.attributes("-fullscreen", True)
|
||||||
root.overrideredirect(1)
|
root.overrideredirect(1)
|
||||||
# root.geometry("380x160")
|
# root.geometry("380x160")
|
||||||
sv_ttk.use_dark_theme()
|
sv_ttk.use_dark_theme()
|
||||||
@@ -193,10 +193,13 @@ progress_bar = tk.Progressbar(root, orient=ttk.HORIZONTAL, length=300)
|
|||||||
#track_label = tk.Label(root, text="")
|
#track_label = tk.Label(root, text="")
|
||||||
|
|
||||||
|
|
||||||
# root.grid_rowconfigure(1, weight=1)
|
root.grid_rowconfigure(0, weight=1)
|
||||||
# root.grid_columnconfigure(0)
|
root.grid_rowconfigure(1, weight=1)
|
||||||
# root.grid_columnconfigure(1)
|
root.grid_rowconfigure(2, weight=1)
|
||||||
# root.grid_columnconfigure(2)
|
root.grid_rowconfigure(3, weight=1)
|
||||||
|
root.grid_columnconfigure(0, weight=1)
|
||||||
|
root.grid_columnconfigure(1, weight=1)
|
||||||
|
root.grid_columnconfigure(2, weight=1)
|
||||||
|
|
||||||
# frame.pack()
|
# frame.pack()
|
||||||
# frame2.pack()
|
# frame2.pack()
|
||||||
|
|||||||
BIN
spotify-gui.zip
Normal file
BIN
spotify-gui.zip
Normal file
Binary file not shown.
477
testing.txt
Normal file
477
testing.txt
Normal file
@@ -0,0 +1,477 @@
|
|||||||
|
{
|
||||||
|
"actions": {
|
||||||
|
"disallows": {
|
||||||
|
"resuming": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"context": {
|
||||||
|
"external_urls": {
|
||||||
|
"spotify": "https://open.spotify.com/collection/tracks"
|
||||||
|
},
|
||||||
|
"href": "https://api.spotify.com/v1/me/tracks",
|
||||||
|
"type": "collection",
|
||||||
|
"uri": "spotify:user:thebrandon45:collection"
|
||||||
|
},
|
||||||
|
"currently_playing_type": "track",
|
||||||
|
"device": {
|
||||||
|
"id": "3e20a2964c1151e118255b819e12e57836e32c1b",
|
||||||
|
"is_active": true,
|
||||||
|
"is_private_session": false,
|
||||||
|
"is_restricted": false,
|
||||||
|
"name": "SILVERHAND",
|
||||||
|
"type": "Computer",
|
||||||
|
"volume_percent": 31
|
||||||
|
},
|
||||||
|
"is_playing": true,
|
||||||
|
"item": {
|
||||||
|
"album": {
|
||||||
|
"album_type": "album",
|
||||||
|
"artists": [
|
||||||
|
{
|
||||||
|
"external_urls": {
|
||||||
|
"spotify": "https://open.spotify.com/artist/5edcHuf8pWH3I00WTorajM"
|
||||||
|
},
|
||||||
|
"href": "https://api.spotify.com/v1/artists/5edcHuf8pWH3I00WTorajM",
|
||||||
|
"id": "5edcHuf8pWH3I00WTorajM",
|
||||||
|
"name": "Kidd G",
|
||||||
|
"type": "artist",
|
||||||
|
"uri": "spotify:artist:5edcHuf8pWH3I00WTorajM"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"available_markets": [
|
||||||
|
"AD",
|
||||||
|
"AE",
|
||||||
|
"AG",
|
||||||
|
"AL",
|
||||||
|
"AM",
|
||||||
|
"AO",
|
||||||
|
"AR",
|
||||||
|
"AT",
|
||||||
|
"AU",
|
||||||
|
"AZ",
|
||||||
|
"BA",
|
||||||
|
"BB",
|
||||||
|
"BD",
|
||||||
|
"BE",
|
||||||
|
"BF",
|
||||||
|
"BG",
|
||||||
|
"BH",
|
||||||
|
"BI",
|
||||||
|
"BJ",
|
||||||
|
"BN",
|
||||||
|
"BO",
|
||||||
|
"BR",
|
||||||
|
"BS",
|
||||||
|
"BT",
|
||||||
|
"BW",
|
||||||
|
"BY",
|
||||||
|
"BZ",
|
||||||
|
"CA",
|
||||||
|
"CD",
|
||||||
|
"CG",
|
||||||
|
"CH",
|
||||||
|
"CI",
|
||||||
|
"CL",
|
||||||
|
"CM",
|
||||||
|
"CO",
|
||||||
|
"CR",
|
||||||
|
"CV",
|
||||||
|
"CW",
|
||||||
|
"CY",
|
||||||
|
"CZ",
|
||||||
|
"DE",
|
||||||
|
"DJ",
|
||||||
|
"DK",
|
||||||
|
"DM",
|
||||||
|
"DO",
|
||||||
|
"DZ",
|
||||||
|
"EC",
|
||||||
|
"EE",
|
||||||
|
"EG",
|
||||||
|
"ES",
|
||||||
|
"ET",
|
||||||
|
"FI",
|
||||||
|
"FJ",
|
||||||
|
"FM",
|
||||||
|
"FR",
|
||||||
|
"GA",
|
||||||
|
"GB",
|
||||||
|
"GD",
|
||||||
|
"GE",
|
||||||
|
"GH",
|
||||||
|
"GM",
|
||||||
|
"GN",
|
||||||
|
"GQ",
|
||||||
|
"GR",
|
||||||
|
"GT",
|
||||||
|
"GW",
|
||||||
|
"GY",
|
||||||
|
"HK",
|
||||||
|
"HN",
|
||||||
|
"HR",
|
||||||
|
"HT",
|
||||||
|
"HU",
|
||||||
|
"ID",
|
||||||
|
"IE",
|
||||||
|
"IL",
|
||||||
|
"IN",
|
||||||
|
"IQ",
|
||||||
|
"IS",
|
||||||
|
"IT",
|
||||||
|
"JM",
|
||||||
|
"JO",
|
||||||
|
"JP",
|
||||||
|
"KE",
|
||||||
|
"KG",
|
||||||
|
"KH",
|
||||||
|
"KI",
|
||||||
|
"KM",
|
||||||
|
"KN",
|
||||||
|
"KR",
|
||||||
|
"KW",
|
||||||
|
"KZ",
|
||||||
|
"LA",
|
||||||
|
"LB",
|
||||||
|
"LC",
|
||||||
|
"LI",
|
||||||
|
"LK",
|
||||||
|
"LR",
|
||||||
|
"LS",
|
||||||
|
"LT",
|
||||||
|
"LU",
|
||||||
|
"LV",
|
||||||
|
"LY",
|
||||||
|
"MA",
|
||||||
|
"MC",
|
||||||
|
"MD",
|
||||||
|
"ME",
|
||||||
|
"MG",
|
||||||
|
"MH",
|
||||||
|
"MK",
|
||||||
|
"ML",
|
||||||
|
"MN",
|
||||||
|
"MO",
|
||||||
|
"MR",
|
||||||
|
"MT",
|
||||||
|
"MU",
|
||||||
|
"MV",
|
||||||
|
"MW",
|
||||||
|
"MX",
|
||||||
|
"MY",
|
||||||
|
"MZ",
|
||||||
|
"NA",
|
||||||
|
"NE",
|
||||||
|
"NG",
|
||||||
|
"NI",
|
||||||
|
"NL",
|
||||||
|
"NO",
|
||||||
|
"NP",
|
||||||
|
"NR",
|
||||||
|
"NZ",
|
||||||
|
"OM",
|
||||||
|
"PA",
|
||||||
|
"PE",
|
||||||
|
"PG",
|
||||||
|
"PH",
|
||||||
|
"PK",
|
||||||
|
"PL",
|
||||||
|
"PS",
|
||||||
|
"PT",
|
||||||
|
"PW",
|
||||||
|
"PY",
|
||||||
|
"QA",
|
||||||
|
"RO",
|
||||||
|
"RS",
|
||||||
|
"RW",
|
||||||
|
"SA",
|
||||||
|
"SB",
|
||||||
|
"SC",
|
||||||
|
"SE",
|
||||||
|
"SG",
|
||||||
|
"SI",
|
||||||
|
"SK",
|
||||||
|
"SL",
|
||||||
|
"SM",
|
||||||
|
"SN",
|
||||||
|
"SR",
|
||||||
|
"ST",
|
||||||
|
"SV",
|
||||||
|
"SZ",
|
||||||
|
"TD",
|
||||||
|
"TG",
|
||||||
|
"TH",
|
||||||
|
"TJ",
|
||||||
|
"TL",
|
||||||
|
"TN",
|
||||||
|
"TO",
|
||||||
|
"TR",
|
||||||
|
"TT",
|
||||||
|
"TV",
|
||||||
|
"TW",
|
||||||
|
"TZ",
|
||||||
|
"UA",
|
||||||
|
"UG",
|
||||||
|
"US",
|
||||||
|
"UY",
|
||||||
|
"UZ",
|
||||||
|
"VC",
|
||||||
|
"VE",
|
||||||
|
"VN",
|
||||||
|
"VU",
|
||||||
|
"WS",
|
||||||
|
"XK",
|
||||||
|
"ZA",
|
||||||
|
"ZM",
|
||||||
|
"ZW"
|
||||||
|
],
|
||||||
|
"external_urls": {
|
||||||
|
"spotify": "https://open.spotify.com/album/4qJXgmxckQ2YDBurSy42AS"
|
||||||
|
},
|
||||||
|
"href": "https://api.spotify.com/v1/albums/4qJXgmxckQ2YDBurSy42AS",
|
||||||
|
"id": "4qJXgmxckQ2YDBurSy42AS",
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"height": 640,
|
||||||
|
"url": "https://i.scdn.co/image/ab67616d0000b273aa2ee84477ed05ab1ace526e",
|
||||||
|
"width": 640
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"height": 300,
|
||||||
|
"url": "https://i.scdn.co/image/ab67616d00001e02aa2ee84477ed05ab1ace526e",
|
||||||
|
"width": 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"height": 64,
|
||||||
|
"url": "https://i.scdn.co/image/ab67616d00004851aa2ee84477ed05ab1ace526e",
|
||||||
|
"width": 64
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "Down Home Boy",
|
||||||
|
"release_date": "2021-09-24",
|
||||||
|
"release_date_precision": "day",
|
||||||
|
"total_tracks": 14,
|
||||||
|
"type": "album",
|
||||||
|
"uri": "spotify:album:4qJXgmxckQ2YDBurSy42AS"
|
||||||
|
},
|
||||||
|
"artists": [
|
||||||
|
{
|
||||||
|
"external_urls": {
|
||||||
|
"spotify": "https://open.spotify.com/artist/5edcHuf8pWH3I00WTorajM"
|
||||||
|
},
|
||||||
|
"href": "https://api.spotify.com/v1/artists/5edcHuf8pWH3I00WTorajM",
|
||||||
|
"id": "5edcHuf8pWH3I00WTorajM",
|
||||||
|
"name": "Kidd G",
|
||||||
|
"type": "artist",
|
||||||
|
"uri": "spotify:artist:5edcHuf8pWH3I00WTorajM"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"available_markets": [
|
||||||
|
"AD",
|
||||||
|
"AE",
|
||||||
|
"AG",
|
||||||
|
"AL",
|
||||||
|
"AM",
|
||||||
|
"AO",
|
||||||
|
"AR",
|
||||||
|
"AT",
|
||||||
|
"AU",
|
||||||
|
"AZ",
|
||||||
|
"BA",
|
||||||
|
"BB",
|
||||||
|
"BD",
|
||||||
|
"BE",
|
||||||
|
"BF",
|
||||||
|
"BG",
|
||||||
|
"BH",
|
||||||
|
"BI",
|
||||||
|
"BJ",
|
||||||
|
"BN",
|
||||||
|
"BO",
|
||||||
|
"BR",
|
||||||
|
"BS",
|
||||||
|
"BT",
|
||||||
|
"BW",
|
||||||
|
"BY",
|
||||||
|
"BZ",
|
||||||
|
"CA",
|
||||||
|
"CD",
|
||||||
|
"CG",
|
||||||
|
"CH",
|
||||||
|
"CI",
|
||||||
|
"CL",
|
||||||
|
"CM",
|
||||||
|
"CO",
|
||||||
|
"CR",
|
||||||
|
"CV",
|
||||||
|
"CW",
|
||||||
|
"CY",
|
||||||
|
"CZ",
|
||||||
|
"DE",
|
||||||
|
"DJ",
|
||||||
|
"DK",
|
||||||
|
"DM",
|
||||||
|
"DO",
|
||||||
|
"DZ",
|
||||||
|
"EC",
|
||||||
|
"EE",
|
||||||
|
"EG",
|
||||||
|
"ES",
|
||||||
|
"ET",
|
||||||
|
"FI",
|
||||||
|
"FJ",
|
||||||
|
"FM",
|
||||||
|
"FR",
|
||||||
|
"GA",
|
||||||
|
"GB",
|
||||||
|
"GD",
|
||||||
|
"GE",
|
||||||
|
"GH",
|
||||||
|
"GM",
|
||||||
|
"GN",
|
||||||
|
"GQ",
|
||||||
|
"GR",
|
||||||
|
"GT",
|
||||||
|
"GW",
|
||||||
|
"GY",
|
||||||
|
"HK",
|
||||||
|
"HN",
|
||||||
|
"HR",
|
||||||
|
"HT",
|
||||||
|
"HU",
|
||||||
|
"ID",
|
||||||
|
"IE",
|
||||||
|
"IL",
|
||||||
|
"IN",
|
||||||
|
"IQ",
|
||||||
|
"IS",
|
||||||
|
"IT",
|
||||||
|
"JM",
|
||||||
|
"JO",
|
||||||
|
"JP",
|
||||||
|
"KE",
|
||||||
|
"KG",
|
||||||
|
"KH",
|
||||||
|
"KI",
|
||||||
|
"KM",
|
||||||
|
"KN",
|
||||||
|
"KR",
|
||||||
|
"KW",
|
||||||
|
"KZ",
|
||||||
|
"LA",
|
||||||
|
"LB",
|
||||||
|
"LC",
|
||||||
|
"LI",
|
||||||
|
"LK",
|
||||||
|
"LR",
|
||||||
|
"LS",
|
||||||
|
"LT",
|
||||||
|
"LU",
|
||||||
|
"LV",
|
||||||
|
"LY",
|
||||||
|
"MA",
|
||||||
|
"MC",
|
||||||
|
"MD",
|
||||||
|
"ME",
|
||||||
|
"MG",
|
||||||
|
"MH",
|
||||||
|
"MK",
|
||||||
|
"ML",
|
||||||
|
"MN",
|
||||||
|
"MO",
|
||||||
|
"MR",
|
||||||
|
"MT",
|
||||||
|
"MU",
|
||||||
|
"MV",
|
||||||
|
"MW",
|
||||||
|
"MX",
|
||||||
|
"MY",
|
||||||
|
"MZ",
|
||||||
|
"NA",
|
||||||
|
"NE",
|
||||||
|
"NG",
|
||||||
|
"NI",
|
||||||
|
"NL",
|
||||||
|
"NO",
|
||||||
|
"NP",
|
||||||
|
"NR",
|
||||||
|
"NZ",
|
||||||
|
"OM",
|
||||||
|
"PA",
|
||||||
|
"PE",
|
||||||
|
"PG",
|
||||||
|
"PH",
|
||||||
|
"PK",
|
||||||
|
"PL",
|
||||||
|
"PS",
|
||||||
|
"PT",
|
||||||
|
"PW",
|
||||||
|
"PY",
|
||||||
|
"QA",
|
||||||
|
"RO",
|
||||||
|
"RS",
|
||||||
|
"RW",
|
||||||
|
"SA",
|
||||||
|
"SB",
|
||||||
|
"SC",
|
||||||
|
"SE",
|
||||||
|
"SG",
|
||||||
|
"SI",
|
||||||
|
"SK",
|
||||||
|
"SL",
|
||||||
|
"SM",
|
||||||
|
"SN",
|
||||||
|
"SR",
|
||||||
|
"ST",
|
||||||
|
"SV",
|
||||||
|
"SZ",
|
||||||
|
"TD",
|
||||||
|
"TG",
|
||||||
|
"TH",
|
||||||
|
"TJ",
|
||||||
|
"TL",
|
||||||
|
"TN",
|
||||||
|
"TO",
|
||||||
|
"TR",
|
||||||
|
"TT",
|
||||||
|
"TV",
|
||||||
|
"TW",
|
||||||
|
"TZ",
|
||||||
|
"UA",
|
||||||
|
"UG",
|
||||||
|
"US",
|
||||||
|
"UY",
|
||||||
|
"UZ",
|
||||||
|
"VC",
|
||||||
|
"VE",
|
||||||
|
"VN",
|
||||||
|
"VU",
|
||||||
|
"WS",
|
||||||
|
"XK",
|
||||||
|
"ZA",
|
||||||
|
"ZM",
|
||||||
|
"ZW"
|
||||||
|
],
|
||||||
|
"disc_number": 1,
|
||||||
|
"duration_ms": 154792,
|
||||||
|
"explicit": false,
|
||||||
|
"external_ids": {
|
||||||
|
"isrc": "USUM72116258"
|
||||||
|
},
|
||||||
|
"external_urls": {
|
||||||
|
"spotify": "https://open.spotify.com/track/5TfoydH4YOOHFUxY85ysvK"
|
||||||
|
},
|
||||||
|
"href": "https://api.spotify.com/v1/tracks/5TfoydH4YOOHFUxY85ysvK",
|
||||||
|
"id": "5TfoydH4YOOHFUxY85ysvK",
|
||||||
|
"is_local": false,
|
||||||
|
"name": "Unknown Numbers",
|
||||||
|
"popularity": 32,
|
||||||
|
"preview_url": "https://p.scdn.co/mp3-preview/df76d6279328b0c0327068d1effe87af833c0da7?cid=69b82a34d0fb40be80b020eae8e80f25",
|
||||||
|
"track_number": 11,
|
||||||
|
"type": "track",
|
||||||
|
"uri": "spotify:track:5TfoydH4YOOHFUxY85ysvK"
|
||||||
|
},
|
||||||
|
"progress_ms": 39867,
|
||||||
|
"repeat_state": "off",
|
||||||
|
"shuffle_state": true,
|
||||||
|
"timestamp": 1671182621535
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user