From fcb3132d6a66a5fa8a0b895f282ab1517d4dbd0e Mon Sep 17 00:00:00 2001 From: Brandon4466 Date: Sat, 17 Dec 2022 02:53:07 -0800 Subject: [PATCH] - volume slider of device will be grabbed on start - if no music is playing, device list will appear that keeps searching --- .cache-thebrandon45 | 2 +- credentials.json | 2 +- icons/pause-circle-x2.png | Bin 0 -> 2193 bytes icons/play-circle-x2.png | Bin 0 -> 2442 bytes icons/skip-next-x2.png | Bin 0 -> 976 bytes icons/skip-previous-x2.png | Bin 0 -> 965 bytes program-embedded.py | 213 +++++++++++++++++ program-production.py | 186 +++++++++++++++ program.py | 13 +- spotify-gui.zip | Bin 0 -> 12636 bytes testing.txt | 477 +++++++++++++++++++++++++++++++++++++ todo.txt | 2 + 12 files changed, 888 insertions(+), 7 deletions(-) create mode 100644 icons/pause-circle-x2.png create mode 100644 icons/play-circle-x2.png create mode 100644 icons/skip-next-x2.png create mode 100644 icons/skip-previous-x2.png create mode 100644 program-embedded.py create mode 100644 program-production.py create mode 100644 spotify-gui.zip create mode 100644 testing.txt create mode 100644 todo.txt 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 0000000000000000000000000000000000000000..3fc7457eaae266514883bfb64fa0979af242ff34 GIT binary patch literal 2193 zcmV;C2yXX@P) zYjYGu6o%hr$&IYRgoHpKDU_QQh=5l>r7SHit@0Q6)qmw@e}LsDZ)G6}%0*Pf3n+mA zNiZf$Zsfjeb@5D`qS#E&_RLC>lA%frLN!^6YF!^6X);gE@X z;bO6vwoI~;nrI!8woBS6X+Y98NxhP`(4LT#lhh)qS<(jXQINDKXc}S`nsyPA-`9{bGBpsBrSJDmy-cDGz6HokAKf5{lG`CEa{&|2>4slZO9o*@?o_`fD!tO zwCB+Efm(PX$p={=uoHRg!xc%FBwdtrC#i?j0s$N8^}8e;lJpYI^!QfSn$QXhRFkm>KTG;n(gjI3TGd9ST2;COXh2h%nyT zHyG$dkQ4z~^yUeA{&C1y4=}1|PiQi@#0VI1^^lYx0Y><5NqQgQ??~vrwS=8?uqWy)_h8s03OGrI>iqAfGph zzQ#hi1eo~xQNjy*8cg^B+UR&ESzEYIC?giiCEzJZuQS{2PV}|v3q7c!`;3Ix1jNQF@TJI55qtHx`*~i2q zO#+G$Jtk^MyI${#95ULE%p%vlZ3yUKWoQSVY3A*0j377{F=}0}cSSao-PdiCYGXq{ zkgM5KMs`{wq6t}T$8m8cpdUsnoj6s`$RV@HRY9BKIDq;|Q}?eov?H@fBWy#!cHFC4 zOQfo0w33E%Kk7Hy5U>pb{LI%LZP$it=lq^ZBT)i! zv__8m$HfL@mdHGyooJs&Jha<*jy43edi7Hlnrzm}ZDT=R{lrJs#&NL`tQUUyh?Jcd zZk1s}Kw`P@4TwnD*$}YkNhk{|HkooZ1k95Y?-376$j+I7S$3Iw#KSB*^PLHpp?NiA zj{-7FWKDR2u&P%>_E0i$I7&NaGJV_*)MjYeH!vmi4Vo@Ns84!0cRC8k_4;yA zB=~j<8QrrD-NacDTSE9(&~tuf{68MBA>$WhWF0q)n=5a2pqwXPwAZJrtYQlFb0Kcw zj<^KmsjF%79-oB>kB6$ql)LbYNilNJn!G(}2YD4(DD^UHs+9(j^{El}ot58z_*DafQYNi!g zGiYW{*?P^mD>a5@0Om4E_<=o0avrce!?^;W#EKt$N6oiDM0&ZUf#+O&L+ zin1#ZaGdR}>jgp2H^ToE&nI%Z(FREoP{0R1hb>s5m|y=oSiqUb$Qo7qH6$cu-z>80EcRxpfMh*rQ262jy8a?Q{;wF`G1nx7S~y8>nbovWdRLIL zXI`*Bbc|I;1%68y;o}a6SWLM{OVrS=g=!q+){P1Z4stsfs>Ik^fljfEfxS*oze*%C z=p2b2)>Dfo=>;$ownvXL?1P+KiK7f{y{IBCbLT=r znP%N#8sSf3CvtdDrH-?m=AQY`akj&#m^=JE6FSb;!^6YF!^6YF!^6X)a**^Nc#s?# Tx5DII00000NkvXXu0mjf%h4a~ literal 0 HcmV?d00001 diff --git a/icons/play-circle-x2.png b/icons/play-circle-x2.png new file mode 100644 index 0000000000000000000000000000000000000000..07e58e0c271192ba5d759b063683fb69bbf8040a GIT binary patch literal 2442 zcmV;533c{~P) z`*Re>6@`zq=*6yuB_t$)rLqHv1Y_br635_}B&3{5D*tSL%)1;rc5FkO1lvh)0Go#p z2x&nQdTTe;Iv}IC~)W;Z>G$rXJNi&irB~3^=%6LIiMbdzzeo4Jtqb6xf(uSnxl9nYcG3F&b zlyq0p14(m|RwQjRcGG;go}T6+K9uIo9dSg`D4%1Jj$7lHq;dZLMTB2Q__YE7cBk6Gi0kN7g>R#e33M1DjJNh@ z473;cBA|rcyv)qM1R31`ql!*h!QeJ4;9NHrG8Q4C zE$^ru0tU(DTw!URu+qcbjA$iXCiOi}_H{E$0tWDpf5-|r9Z*^!3k;G3TFy@jWwG7_Ox0$!2yW1`(LuaDJP7)KR7WhEpgAgRvo z!_bq5gZWOSP#?O9yH&V_(pi-1>QIxEzzXmg&)u#R0g%O+1qTbmVRWG2gh znJ`V^LO?&>&n$sQmISC_3E!ZK!OXCq;EkPWp=Ky8RFKgbWcDO3I(8von4O^$d}is1 z^fvg_&zV_OJfvl2*{O_G<9;Yv)qP`Do@igV5D?XBjt4Z;9%GyzQ^WH%Y2wKMep?^1 znqmdaHT$v)0n;#=b>UPTo?r`>8Ed48L-3L+$jq$Nzc>4$3js5zpR9Gi3wA8;XpX(w z5WJ)^GV@}Dr_isV6;egmLJck9_J!aj4RY_NabI*HU=jkdh1U8|3%l?JUQ!xCX352Iam|Ky3ydAONz70t$b2QmXN#5HLEcag0xm1STP=J5IBZoh zTqMd*GrozHoeKe5T&UAm%MiO&SBVKCBb-)*zw1&d=R&{+HSwY5g5uCm6nvH=`b}kW(hy*R74G#c}YhvA^eb2 z(v3KVj~@v>>tx&(@kVST5LW_5xM=7EL|)DXUKY$N9qpBXc_PL20JkM=*j~XIn7{X^$6KDg$n_9d6-y>o&)mqa++b4>}%{>lr99^ zV{;+aqGyaey_`5iMFO#HZ(LQ-D21|{ff(Yvy_{y)L{<-d*??to=@0mv$gn!DMnoB* zYZdX!pa;SyF|NN3ygYr?>O;5eD;v7Y#lEnNURJ#zh9LY!?)wfzgt|xlm|eGsfY?r3 zE(Fxk!}C^m!C8cmc3Xm|@l&0b15c-Xzg7{w$M7{WdemUM_C=D-=xv05gRQ*T3})gK z?<1E2@^bdV8UbJvS zp8b8^Wp3#`=2k1hp27MkF6nRwl&|~78bQ~)bW@Cd7ho^6O28KVaXzN7X*jS}#A#z4 zujd17;@u>kkBxR}A~!8nG=%U^2HelV7iwfV|H`ws)Tk*!yG5y0dZyKJ7yF43y0zl2 zj_{4g^E)&^TL(b2OF#`nbe;TApVdRB+nV>)$Os#?^LuPy+pUa!m1RGoqwFpOTq0-F zEr@2m5&m!Rd}6m7UEqs=8b0uc*n(}6XVV>AQ5RtYBWqOcA0ffp0S~@kOt?=+*(JjB zw}_ZK^#zYD4t6jz{9VvB^oPMX+g&J!0e|S6Zu>!oGxRmAz z8b@jDY9HXxDShVdplaSH!S+?F2RP(;g2tlNPqWHOh+2A$2N<+%u%U8~BTU{y_;=FG zcV%^m<1+98LdBQ;ly2l)hL)*I&cO{|v*s(C+zSA)KVQV|Bc`XO--k2b{K!u^P_c zx7e_cJG{$g$~A^pL)#2_9OO2J3W^SLJ7;xboXB8O>|kKOwDxarTa&}h`59*3ODK1Uh4dQo*;$W0Pw>(&bs3&bopA>a%CeqfF=Y{ZDwk79)M_7tBJ>;*>$ zb4J7r?D5;{2>dw(QIP|%fXbV*M%5}GPqc%T6rFII>atbNU9p6+!oI@_!heRHsNg~E zcbx4C*Q{E{+0LP2?(_Fm>p0s21qu`>P@q780tE^b$PSYJ546QzINUPIegFUf07*qo IM6N<$f-xSIzyJUM literal 0 HcmV?d00001 diff --git a/icons/skip-next-x2.png b/icons/skip-next-x2.png new file mode 100644 index 0000000000000000000000000000000000000000..d24594bbd462edbd529b0598955b1949d0bc0fbb GIT binary patch literal 976 zcmV;>126oEP)l6ZOKxJ0Hq7@oh|uf{NoBR8YJ?aX~;7+)xn|F%?fI?SdG! zYpUDxC7qcIGV@QJs(-60Fvb{Tj4{R-V~jDz7-Nhv#u#IaF~(GmTG2mfVPWAU@B!%6 z^9GntWFU_NC-nL=Ue#)~-9;L(yvPq1;Rk#KUII^mN5G2+-}^hP0yY7yi~Q}{q78^4 zz+qrDupejxx`94mBEoksMQw>OSW&bAF$4&+Yn^6Vpjko;03%u%jp7sV_7~s%x@fy% z2#}96`y@bE4ObKst|sJ?q7y@aISqPXC9o6N2DAe$S{?nsDDWi}z02G*aDK@m{V#6Tt6qu>#n14ef1;_|4=#U0~FK}KfVo>!%rAa{m zH2b@>5;n*+h3shv7*n=VNm3CYqXRgmARRKMI&e-xd``o}e@kitpqbw)G1^p(hS&SR z^U&Q$z{Y<@iUMSGDqG4{L&%b@sg+R~QWgNMf)1^SEK9l}5uPPr-(Qou02w=#w(e2= za8b{A8s_~uWf7oBE@^A7d$|Um4U7h7`mL#U+hYBeO^$|$=4 z8S8-~z-GmTtb)Fyc6hQ>MF1p1SFVC?*85>#N^U8+o>G+r$OsL+qjF1O=k0>h)gcQI zkBxfTH1kJPJtw#0wk!b~{%fkb0$yv@_bDx%NHrK&QGh8`#@#w`kp+8yTvO+BB!KVTOyw^Yvx)l+h8M&CA+$oB&vYjg`qX3_j)eLG=#_i~c z%xiQ0GH}KlGVz$#X}Jd)bZ<#U=Alkf*S#qpmq`u&RUb=<&!}1nXLXk#JD61|QWPNE zn0cHltb8;vB9jWTy~=d5!?~3ld=e7iozlr$KAs+*x4IeAEtivB(5U?2(_jI@0FSGk z;44aznN`QKu2zCC=@rPT+(*wTsNVB6)vv@5AfLeuDXpw0a#6eC#1Ps=*jzj4{R-V~jDz7-Nhv#u#IaF~%5EI%-*WXmN4z8L)AM z*SCP1dZxfCpbNMNTn0L7wc3p=+tnVS(>s8*E4o&v?pj9W@ zW6Z+eWD9T-xC&ec`hbsF|I-)(yaP6^@NORX8lerX2%~-{a16Kv3`>Z>`>g+Y3;|N6 zTgI--=O2~JY>@fvtf~O(Waxg4`nrVZTJpV5SvRDL0(2_K4lCQ~ml#WpAB8Fj5R!o& z8NA-)>o?@tsHzAM`gstzpe*MsuuCx@_lA|3Hefq&Kt`|2=l7-3=dug1PuWc{`YA24 zdJ<^YPs%F5RvG_1Fan&D@sp#B0)$1?Y5Dp=`TlJQv};+)B*121w=$dHa;^YJ5-N2p zOIZZiDmPPCZhuI*ebUCK1OlvAI(Y&ZlJN%;tFX4D$O3e!fHoqR6Aa&5B;!+10Xmi2 z4`{@XNQhiY3I9sb1X!zzWh2NQSJtyWfwuh>MG;_)g6bia6D}+0Zcd+D2>E=qCJcS}v0ovr#gOT@Zv=3{6)tf;3{u`+ZutvW9tVaGBU{4ub&Qekppk3vI z;BKy|u2V`@m9=9fGKlO%8K7`Rfs+lmS*f86)C7FEx%CaXs1>6Q+15dmupAXaeOzF9xXX98( zl0ua6T+q0(r8k-lKA4pQQ~Jy_Wl27om;*0#&nw*2eB{Hq@%bi~G@*6FjADb2r$;8# zlg5;)j%!Bvf<|P%$oP#~QX@7rt|;X)8>)CmER-@H$Q_OT;*wtGRP~nRg31>Y5@J?+ z4~=W89r|A8C5@`z6Am%qt^)MfG8eVKXWf7p0<;QpT?q_=Ii;wRO)KbHnSQF^ON*%- zvXjLKZTKBRLGMmex;hxcJ~0G%-QwqJCS%-2{{!Z", 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 0000000000000000000000000000000000000000..7a6ddca1084471f9895e06a73cd56a555c872ec5 GIT binary patch literal 12636 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 literal 0 HcmV?d00001 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