├── ico.png ├── README.md └── main.py /ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JasonHinds13/KVMusicPlayer/HEAD/ico.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About KVMusicPlayer 2 | A music player application written in python-kivy. 3 | 4 | #Things to do 5 | * Find a good sound module to handle playing mp3 6 | * Make GUI more attractive 7 | 8 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | #If on Windows to avoid fullscreen, use the following two lines of code 2 | from kivy.config import Config 3 | Config.set('graphics', 'fullscreen', '0') 4 | 5 | from kivy.app import App 6 | from kivy.lang import Builder 7 | from kivy.uix.popup import Popup 8 | from kivy.uix.button import Button 9 | from kivy.uix.widget import Widget 10 | from kivy.core.audio import SoundLoader 11 | from kivy.properties import ObjectProperty 12 | from kivy.uix.gridlayout import GridLayout 13 | from kivy.uix.floatlayout import FloatLayout 14 | 15 | from os import listdir, path 16 | 17 | Builder.load_string(''' 18 | : 19 | 20 | canvas.before: 21 | Color: 22 | rgba: 0, 0, .1, 1 23 | Rectangle: 24 | pos: self.pos 25 | size: self.size 26 | 27 | TextInput: 28 | id: direct 29 | pos: 0,root.top-35 30 | size: root.width-200,35 31 | hint_text: 'Enter File Location or Leave Empty to Browse' 32 | Button: 33 | id: searchBtn 34 | text: 'Browse' 35 | size: 200,35 36 | background_color: 0,.5,1,1 37 | pos: root.width-200, root.top-35 38 | on_release: root.getSongs() 39 | 40 | ScrollView: 41 | size_hint: None, None 42 | size: root.width, root.height-135 43 | pos: 0, 100 44 | GridLayout: 45 | id: scroll 46 | cols: 2 47 | spacing: 10 48 | size_hint_y: None 49 | row_force_default: True 50 | row_default_height: 40 51 | 52 | GridLayout: 53 | rows: 1 54 | pos: 0, 50 55 | size: root.width, 50 56 | Button: 57 | text: '<--' 58 | background_color: 0,.5,1,1 59 | Button: 60 | text: '||' 61 | background_color: 0,.5,1,1 62 | Button: 63 | text: '-->' 64 | background_color: 0,.5,1,1 65 | Button: 66 | id: nowplay 67 | text: 'Now Playing' 68 | pos: 0,0 69 | size: root.width, 50 70 | background_color: 0,.5,1,1 71 | 72 | Label: 73 | id: status 74 | text: '' 75 | center: root.center 76 | 77 | : 78 | 79 | canvas.before: 80 | Color: 81 | rgba: 0, 0, .4, 1 82 | Rectangle: 83 | pos: self.pos 84 | size: self.size 85 | BoxLayout: 86 | size: root.size 87 | pos: root.pos 88 | orientation: "vertical" 89 | FileChooserIconView: 90 | id: filechooser 91 | 92 | BoxLayout: 93 | size_hint_y: None 94 | height: 30 95 | Button: 96 | text: "Cancel" 97 | background_color: 0,.5,1,1 98 | on_release: root.cancel() 99 | 100 | Button: 101 | text: "Select Folder" 102 | background_color: 0,.5,1,1 103 | on_release: root.select(filechooser.path) 104 | 105 | 106 | ''') 107 | 108 | class ChooseFile(FloatLayout): 109 | select = ObjectProperty(None) 110 | cancel = ObjectProperty(None) 111 | 112 | class MusicPlayer(Widget): 113 | 114 | directory = '' #location of songs folder 115 | nowPlaying = '' #Song that is currently playing 116 | 117 | def getpath(self): 118 | try: 119 | f = open("sav.dat","r") 120 | self.ids.direct.text = str(f.readline()) 121 | f.close() 122 | self.ids.searchBtn.text = "Scan" 123 | self.getSongs() 124 | except: 125 | self.ids.direct.text = '' 126 | 127 | def savepath(self, path): 128 | f = open("sav.dat","w") 129 | f.write(path) 130 | f.close() 131 | 132 | def dismiss_popup(self): 133 | self._popup.dismiss() 134 | 135 | def fileSelect(self): 136 | content = ChooseFile(select=self.select, 137 | cancel=self.dismiss_popup) 138 | 139 | self._popup = Popup(title="Select Folder", content=content, 140 | size_hint=(0.9, 0.9)) 141 | self._popup.open() 142 | 143 | def select(self, path): 144 | self.directory = path 145 | self.ids.direct.text = self.directory 146 | self.ids.searchBtn.text = "Scan" 147 | self.savepath(self.directory) 148 | self.getSongs() 149 | self.dismiss_popup() 150 | 151 | def getSongs(self): 152 | 153 | songs = [] #List to hold songs from music directory 154 | self.directory = self.ids.direct.text #Directory entered by the user 155 | 156 | if self.directory == '': 157 | self.fileSelect() 158 | 159 | #To make sure that the directory ends with a '/' 160 | if not self.directory.endswith('/'): 161 | self.directory += '/' 162 | 163 | #Check if directory exists 164 | if not path.exists(self.directory): 165 | self.ids.status.text = 'Folder Not Found' 166 | self.ids.status.color = (1,0,0,1) 167 | 168 | else: 169 | 170 | self.ids.status.text = '' 171 | 172 | self.ids.scroll.bind(minimum_height=self.ids.scroll.setter('height')) 173 | 174 | #get mp3 files from directory 175 | for fil in listdir(self.directory): 176 | if fil.endswith('.mp3'): 177 | songs.append(fil) 178 | 179 | #If there are no mp3 files in the chosen directory 180 | if songs == [] and self.directory != '': 181 | self.ids.status.text = 'No Music Found' 182 | self.ids.status.color = (1,0,0,1) 183 | 184 | songs.sort() 185 | 186 | for song in songs: 187 | 188 | def playSong(bt): 189 | try: 190 | self.nowPlaying.stop() 191 | except: 192 | pass 193 | finally: 194 | self.nowPlaying = SoundLoader.load(self.directory+bt.text+'.mp3') 195 | self.nowPlaying.play() 196 | self.ids.nowplay.text = bt.text 197 | 198 | btn = Button(text=song[:-4], on_press=playSong) 199 | icon = Button(size_hint_x=None, width=50, background_down="ico.png", background_normal="ico.png") 200 | 201 | #Color Buttons Alternatively 202 | if songs.index(song)%2 == 0: 203 | btn.background_color=(0,0,1,1) 204 | else: 205 | btn.background_color=(0,0,2,1) 206 | 207 | self.ids.scroll.add_widget(icon) #Add icon to layout 208 | self.ids.scroll.add_widget(btn) #Add btn to layout 209 | 210 | class KVMusicApp(App): 211 | 212 | def build(self): 213 | music = MusicPlayer() 214 | music.getpath() 215 | return music 216 | 217 | def on_pause(self): 218 | return True 219 | 220 | def on_resume(self): 221 | pass 222 | 223 | if __name__ == "__main__": 224 | KVMusicApp().run() 225 | --------------------------------------------------------------------------------