diff --git a/.cache-thebrandon45 b/.cache-thebrandon45 index 8a0c033..8295222 100644 --- a/.cache-thebrandon45 +++ b/.cache-thebrandon45 @@ -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"} \ No newline at end of file +{"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"} \ No newline at end of file diff --git a/credentials.json b/credentials.json index c3a8ea4..c4e0fbe 100644 --- a/credentials.json +++ b/credentials.json @@ -1 +1 @@ -{"username": "thebrandon45", "credentials": "QVFEalQxYVlobUdHczYwd21NNERDcWgxMVhtUFBlU1dicWN6VW9PR0JraDNLa0NrUDU4YlFVSzNQUDRka2NTLUo3aHVtQlFrMHJYWGlnai1pc0RQNjY4a1dDSDFZYmR6NnB6ZGhRaFd0bkNaSjVpMVZLeXlWWlE2dEJiOW5zR3RwMy1IQlkxdEJ2RjhMQQ==", "type": "AUTHENTICATION_STORED_SPOTIFY_CREDENTIALS"} \ No newline at end of file +{"username": "thebrandon45", "credentials": "QVFCYUsxTG9xY0NOYlY4RnVBOThVRjdESTVMTnRvU05jTTJfSkNMZ1NCb1J0anFhQzFrdTFrZzc3VGxRUUVLZUxQMUU3ekx4Unp3am9DSHAwaTE3cDNKNDJLSENmbnhkNk1tb1pVSlNmUzhkUGlwRWlTRElPclp6QU9hRmFBX3BiZFlZd2NIYzk2UTNoQQ==", "type": "AUTHENTICATION_STORED_SPOTIFY_CREDENTIALS"} \ No newline at end of file diff --git a/icons/pause-circle-x2.png b/icons/pause-circle-x2.png new file mode 100644 index 0000000..3fc7457 Binary files /dev/null and b/icons/pause-circle-x2.png differ diff --git a/icons/play-circle-x2.png b/icons/play-circle-x2.png new file mode 100644 index 0000000..07e58e0 Binary files /dev/null and b/icons/play-circle-x2.png differ diff --git a/icons/skip-next-x2.png b/icons/skip-next-x2.png new file mode 100644 index 0000000..d24594b Binary files /dev/null and b/icons/skip-next-x2.png differ diff --git a/icons/skip-previous-x2.png b/icons/skip-previous-x2.png new file mode 100644 index 0000000..c9f868f Binary files /dev/null and b/icons/skip-previous-x2.png differ diff --git a/program-embedded.py b/program-embedded.py new file mode 100644 index 0000000..bb73e06 --- /dev/null +++ b/program-embedded.py @@ -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("", 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() \ No newline at end of file diff --git a/program-production.py b/program-production.py new file mode 100644 index 0000000..09a48f3 --- /dev/null +++ b/program-production.py @@ -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("", 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() \ No newline at end of file diff --git a/program.py b/program.py index 7113c19..b66d50e 100644 --- a/program.py +++ b/program.py @@ -38,7 +38,7 @@ spotify = spotipy.Spotify(auth=token) # Create the tkinter window root = ttk.Tk() root.title("Media Controller") -root.attributes("-topmost", True) +root.attributes("-fullscreen", True) root.overrideredirect(1) # root.geometry("380x160") 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="") -# root.grid_rowconfigure(1, weight=1) -# root.grid_columnconfigure(0) -# root.grid_columnconfigure(1) -# root.grid_columnconfigure(2) +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) # frame.pack() # frame2.pack() diff --git a/spotify-gui.zip b/spotify-gui.zip new file mode 100644 index 0000000..7a6ddca Binary files /dev/null and b/spotify-gui.zip differ diff --git a/testing.txt b/testing.txt new file mode 100644 index 0000000..46440df --- /dev/null +++ b/testing.txt @@ -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 +} diff --git a/todo.txt b/todo.txt new file mode 100644 index 0000000..4dff72a --- /dev/null +++ b/todo.txt @@ -0,0 +1,2 @@ +update volume slider from spotify every 10 seconds (probably going to need a new function for it) +add clause for if nothing is playing is returend from spotify then present list of devices to chose where to start playback on \ No newline at end of file