class Player: def __init__(self, master): self.master = master pygame.init() pygame.mixer.init() #===Empty thread list=====# self.threads = [] #=====show an icon for the player===# def get_icon(): self.winicon = PhotoImage(file="best (2).png") master.iconphoto(False, self.winicon) #=====run the get_icon on a different thread from the gui=====# def icon(): mythreads = threading.Thread(target=get_icon) self.threads.append(mythreads) mythreads.start() icon() #=======all Button symbols and variables======# PLAY = "►" PAUSE = "║║" RWD = "⏮" FWD = "⏭" STOP = "■" UNPAUSE = "||" mute = "🔇" unmute = u"\U0001F50A" vol_mute = 0.0 vol_unmute = 1 #==========music playlist listbox=========# self.scroll = Scrollbar(master) self.play_list = Listbox(master, font="Sansarif 12 bold", bd=5, bg="white", width=37, height=19, selectbackground="black") self.play_list.place(x=600, y=77) self.scroll.place(x=946, y=80, height=389, width=15) self.scroll.config(command=self.play_list.yview) self.play_list.config(yscrollcommand=self.scroll.set) files = 'best (2).png' self.img1 = Image.open(files) self.img1 = self.img1.resize((600, 470), Image.ANTIALIAS) self.img = ImageTk.PhotoImage(self.img1) self.lab = Label(master) self.lab.grid(row=0, column=0) self.lab["compound"] = LEFT self.lab["image"] = self.img #=====show the song playing==========# self.var = StringVar() self.var.set( ".............................................................................." ) self.song_title = Label(master, font="Helvetica 12 bold", bg="black", fg="white", width=60, textvariable=self.var) self.song_title.place(x=3, y=0) # =====add a music list to the listbox======" def append_listbox(): global song_list try: directory = askdirectory() os.chdir(directory) # it permits to change the current dir song_list = os.listdir() song_list.reverse() for item in song_list: # it returns the list of files song pos = 0 self.play_list.insert(pos, item) pos += 1 global size index = 0 size = len(song_list) self.play_list.selection_set(index) self.play_list.see(index) self.play_list.activate(index) self.play_list.selection_anchor(index) except: showerror("File selected error", "Please choose a file correctly") # =====run the append_listbox function on separate thread====== # def add_songs_playlist(): mythreads = threading.Thread(target=append_listbox) self.threads.append(mythreads) mythreads.start() #=====show music time=========# def get_time(): current_time = pygame.mixer.music.get_pos() / 1000 formated_time = time.strftime("%H:%M:%S", time.gmtime(current_time)) next_one = self.play_list.curselection() song = self.play_list.get(next_one) song_timer = MP3(song) song_length = int(song_timer.info.length) format_for_length = time.strftime("%H:%M:%S", time.gmtime(song_length)) self.label_time.config( text=f"{ format_for_length} / {formated_time}") self.progress["maximum"] = song_length self.progress["value"] = int(current_time) master.after(100, get_time) #=====play the music====# def Play_music(): try: track = self.play_list.get(ACTIVE) pygame.mixer.music.load(track) self.var.set(track) pygame.mixer.music.play() get_time() # iterate through all the songs in the playlist # there is a bug when closing the window except: showerror("No Music", "Please load the music you want to play") def playAll(): try: index = 0 for i in range(size): self.play_list.select_clear(0, END) self.play_list.selection_set(index, last=None) self.play_list.see(index) self.play_list.activate(index) self.play_list.selection_anchor(index) track = self.play_list.get(index) pygame.mixer.music.load(track) self.var.set(track) pygame.mixer.music.play() current_song = self.play_list.curselection() song = self.play_list.get(current_song) song_timer = MP3(song) song_length = int(song_timer.info.length) * 1000 get_time() index += 1 except: showerror("No songs in playlist", "Please add music") def play_all(): mythreads = threading.Thread(target=playAll) self.threads.append(mythreads) mythreads.start() # ===pause and unpause == # def pause_unpause(): if self.button_pause['text'] == PAUSE: pygame.mixer.music.pause() self.button_pause['text'] = UNPAUSE elif self.button_pause['text'] == UNPAUSE: pygame.mixer.music.unpause() self.button_pause['text'] = PAUSE # ==play the music on a diffent thread from the gui == # def play_thread(): mythreads = threading.Thread(target=Play_music) self.threads.append(mythreads) mythreads.start() master.bind("<space>", lambda x: play_thread()) # ===stop=== def stop(): pygame.mixer.music.stop() #====increase and decrease volume when slider is moved()==# def volume(x): pygame.mixer.music.set_volume(self.volume_slider.get()) # ====mute and unmute the song while the song plays== # def muted(): if self.button_mute['text'] == unmute: pygame.mixer.music.set_volume(vol_mute) self.volume_slider.set(vol_mute) self.button_mute['fg'] = "red" self.button_mute['text'] = mute elif self.button_mute['text'] == mute: pygame.mixer.music.set_volume(vol_unmute) self.volume_slider.set(vol_unmute) self.button_mute['fg'] = "white" self.button_mute['text'] = unmute #===move to the next song===# def nextSong(): try: next_one = self.play_list.curselection() next_one = next_one[0] + 1 song = self.play_list.get(next_one) pygame.mixer.music.load(song) pygame.mixer.music.play() self.play_list.select_clear(0, END) self.play_list.activate(next_one) self.play_list.selection_set(next_one, last=None) self.var.set(song) get_time() self.play_list.see(next_one) except: showerror("No Next Song", "Please press the previous button") def next(): mythreads = threading.Thread(target=nextSong) self.threads.append(mythreads) mythreads.start() #===move to the previous song===# def prevSong(): try: next_one = self.play_list.curselection() next_one = next_one[0] - 1 song = self.play_list.get(next_one) pygame.mixer.music.load(song) pygame.mixer.music.play() self.play_list.select_clear(0, END) self.play_list.activate(next_one) self.play_list.selection_set(next_one, last=None) self.var.set(song) get_time() self.play_list.see(next_one) except: showerror("No previous Song", "Please press the Next button") def prev(): mythreads = threading.Thread(target=prevSong) self.threads.append(mythreads) mythreads.start() self.master.bind('<Left>', lambda x: prev()) self.master.bind('<Right>', lambda x: next()) #=====exit the application=====# def exit(): MsgBox = askquestion( 'Exit Application', 'Are you sure you want to exit the music player.', icon='warning') if MsgBox == 'yes': master.quit() master.after(100, exit) else: showinfo('Return', 'Continue playing your awesome music') return #=====Help window=====# def help(): top = Toplevel() top.title("Help") top.geometry("350x554+500+80") top.resizable(width=0, height=0) user_manual = [ " MUSIC PLAYER USER MANUAL: \n", "1. play button = ( ► )", "2. pause button = ║║ ", "3. unpause symbol = ||", "4. next button = ⏭ ", "5. previous button = ⏮", "6. mute button = '\U0001F50A' ", "7. unmute symbol = 🔇", "8. stop button = ■ ", "\n\n| Made by manucho | Copyright @ 2021 |\n" ] for i in user_manual: manual = Label(top, text=i, width=50, height=3, font="Helvetica, 11", bg="black", fg="white") manual.pack(side=TOP, fill=BOTH) #==============================================================================================# # THis part contains the menu, volume slider , music playlist label and the volume slider # #===============================================================================================# self.menu = Menu( self.lab, font="helvetica, 3", ) master.config(menu=self.menu) self.menu.add_command(label="HELP", command=help) self.menu.add_command(label="EXIT", command=exit) self.separator = ttk.Separator(self.lab, orient='horizontal') self.separator.place(relx=0, rely=0.87, relwidth=1, relheight=1) self.button_play = Button(master, text=PLAY, width=5, bd=5, bg="black", fg="white", font="Helvetica, 15", command=play_thread) self.button_play.place(x=150, y=415) self.button_stop = Button(master, text=STOP, width=5, bd=5, font="Helvetica, 15", bg="black", fg="white", command=stop) self.button_stop.place(x=225, y=415) self.button_prev = Button(master, text=FWD, width=5, bd=5, font="Helvetica, 15", bg="black", fg="white", command=next) self.button_prev.place(x=300, y=415) self.buttonPlayall = Button(self.master, text='\U0001F500', bg='black', fg='white', font='Helvetica, 15', bd=5, width=3, command=play_all) self.buttonPlayall.place(x=375, y=415) self.button_next = Button(master, text=RWD, width=5, bd=5, bg="black", fg="white", font="Helvetica, 15", command=prev) self.button_next.place(x=10, y=415) self.button_pause = Button(master, text=PAUSE, width=4, bd=5, font="Helvetica, 15", bg="black", fg="white", command=pause_unpause) self.button_pause.place(x=85, y=415) self.button_mute = Button(master, text=unmute, width=2, bd=5, font="Helvetica, 15", bg="black", fg="white", command=muted) self.button_mute.place(x=430, y=415) self.label_playlist = Label(master, text=u"♫ Music Playlist ♫ ", width=31, font="Helvetica, 15") self.label_playlist.place(x=610, y=5) self.button_load_music = Button( master, text="♫ Click Here To Load The Music ♫", width=43, bd=5, font="Helvetica, 10", bg="black", fg="white", command=add_songs_playlist) self.button_load_music.place(x=605, y=45) self.style = ttk.Style() self.style.configure("myStyle.Horizontal.TScale", background="#505050") self.volume_slider = ttk.Scale(self.lab, from_=0, to=1, orient=HORIZONTAL, value=1, length=120, command=volume, style="myStyle.Horizontal.TScale") self.volume_slider.place(x=475, y=424) self.progress = ttk.Progressbar(self.lab, orient=HORIZONTAL, value=0, length=453, mode='determinate') self.progress.place(x=0, y=385) self.label_time = Label(master, text="00:00:00 / 00:00:00", width=17, font="Helvetica, 10", bg="black", fg="white") self.label_time.place(x=460, y=387)