'Music Player by Python
I wrote this music player code and when I hit the next button and then I work with slider the time Elapsed in the status bar resets to zero. and also all music that I play have the same Total lenght.But if I select the music and hit play button the total lenght change.but slider doesnt work properly.The ONLY way all things work correctly is when I hit stop and then select the music and hit play.
import tkinter.messagebox
from tkinter import *
import pygame
from pygame import mixer
from tkinter import filedialog
import re
import time
from mutagen.mp3 import MP3
from tkinter import ttk as ttk
# initializing the window...............................
window = Tk()
window.minsize(700, 450)
mixer.init() # initializing the pygame mixer module
# songlist box.............................................................
song_box = Listbox(window, bg="dim gray", fg="black", selectbackground="firebrick",
selectforeground="black", width=31, height=10)
song_box.place(x=255, y=78)
# Browse file for Open Menu...........................................................
def browse_files():
global songs_list
songs_list = filedialog.askopenfilenames(initialdir="c:/Users/ali/Downloads/Music",
title="Choose Songs", filetypes=(("mp3 File", "*.mp3"),))
for item in songs_list:
# getting just the name of song not the whole directory
pattern = "(.*\/.*\/)(.*)"
item = re.match(pattern, item).group(2)
song_box.insert(END, item)
song_box.select_set(0)
def show_song_time():
if stopped:
return
# Getting the current song Elapsed time in seconds
current_time = pygame.mixer.music.get_pos() / 1000
# Convert to time format
converted_currnet_time = time.strftime("%M:%S", time.gmtime(current_time))
# Getting what song is playing
i = song_box.curselection()
get_active_song = song_box.get(i)
first_list_item = songs_list[0]
pattern = "(.*\/.*\/)(.*)"
directory = re.match(pattern, first_list_item).group(1)
# directory + the name of the song
active_song = f"{directory}{get_active_song}"
if active_song == song:
# Grab the length with Mutagen
song_mutagen = MP3(active_song)
global song_lenght
song_lenght = song_mutagen.info.length
# Conver to time format
global converted_song_length
converted_song_length = time.strftime("%M:%S", time.gmtime(song_lenght))
status_bar.config(text=f"Time Elapsed {converted_currnet_time} of {converted_song_length}")
current_time += 1
# for end the counting at the end of song
if int(slider.get()) == int(song_lenght):
status_bar.config(text=f"Time Elapsed {converted_song_length}")
elif int(slider.get()) == int(current_time):
slider_position = int(song_lenght)
slider.config(to=slider_position, value=int(current_time))
elif pause_situation:
pass
else:
# Updating the slider position
slider_position = int(song_lenght)
slider.config(to=slider_position, value=int(slider.get()))
# Convert to time format
converted_currnet_time = time.strftime("%M:%S", time.gmtime(int(slider.get())))
status_bar.config(text=f"Time Elapsed {converted_currnet_time} of {converted_song_length}")
next_time = int(slider.get()) + 1
slider.config(value=next_time)
# else:
# slider_position = int(song_lenght)
# slider.config(to=slider_position, value=int(slider.get()))
else:
status_bar.config(text=f"Time Elapsed {converted_currnet_time} of {converted_song_length}")
# making this function running
# slider.config(value=int(current_time))
status_bar.after(1000, show_song_time)
# functions..............................................
def play():
global song
global song_box
global song_number_in_list
global pause_situation
try:
global stopped
stopped = False
if not pause_situation:
item = songs_list[0]
pattern = "(.*\/.*\/)(.*)"
directory = re.match(pattern, item).group(1)
# selected song by clicking
selected_song = song_box.get(ACTIVE)
# directory + the name of the song
song = f"{directory}{selected_song}"
mixer.music.load(song)
mixer.music.play(loops=0)
song_number_in_list = song_box.curselection()
show_song_time()
else:
mixer.music.unpause()
pause_situation = False
except (pygame.error, NameError) as e:
tkinter.messagebox.showerror("Open Error", e)
pause_situation = False
def pause(is_paused):
global pause_situation
pause_situation = is_paused
if pause_situation:
mixer.music.unpause()
pause_situation = False
else:
mixer.music.pause()
pause_situation = True
stopped = False
def stop():
# Reset slider and status bar
status_bar.config(text="")
slider.config(value=0)
# Stop song
mixer.music.stop()
song_box.selection_clear(ACTIVE)
# pause_situation = False
global stopped
stopped = True
def next_song():
try:
status_bar.config(text="")
slider.config(value=0)
next_one = 0
# Get the current number of the song_box
next_one = song_box.curselection()
# Add one to the current song to get the next one number
next_music = next_one[0] + 1
# Get the song title from song_box
song = song_box.get(next_music)
# Add full directory to song
i = songs_list[0]
pattern = "(.*\/.*\/)(.*)"
directory = re.match(pattern, i).group(1)
# directory + the name of the song
song = f"{directory}{song}"
mixer.music.load(song)
mixer.music.play(loops=0)
# Clear Active bar in song_box
song_box.selection_clear(0, END)
# Active new song bar
song_box.activate(next_music)
# set the acctive bar for next song
song_box.select_set(next_music, last=None)
# for stop song when hit next and then remove it
global next_song_number
next_song_number = song_box.curselection()
except (pygame.error, IndexError):
pass
def previous_song():
try:
status_bar.config(text="")
slider.config(value=0)
next_one = 0
# Get the current number of the song_box
next_one = song_box.curselection()
# Add one to the current song to get the next one number
next_music = next_one[0] - 1
# Get the song title from song_box
song = song_box.get(next_music)
# Add full directory to song
i = songs_list[0]
pattern = "(.*\/.*\/)(.*)"
directory = re.match(pattern, i).group(1)
# directory + the name of the song
song = f"{directory}{song}"
mixer.music.load(song)
mixer.music.play(loops=0)
# Clear Active bar in song_box
song_box.selection_clear(0, END)
# Active new song bar
song_box.activate(next_music)
# set the acctive bar for next song
song_box.select_set(next_music, last=None)
# for stop song when hit next and then remove it
global next_song_number
next_song_number = song_box.curselection()
except (pygame.error, IndexError):
pass
# Create Status Bar......................................................
status_bar = Label(window, text="", bd=1, relief=GROOVE, anchor=E)
status_bar.pack(fill=X, side=BOTTOM, pady=2)
# Slide function................................................................
def slide(X):
try:
mixer.music.load(song)
mixer.music.play(loops=0, start=int(slider.get()))
except NameError as e:
tkinter.messagebox.showerror("Error", e)
# Creating a slider..............................................................
slider = ttk.Scale(window, from_=0, to=100, orient=HORIZONTAL, length=375, value=0, command=slide)
slider.place(x=160, y=320)
# Buttons......................................................................................
play_button = Button(window, text="play", command=play)
play_button.place(x=200, y=250)
pause_button = Button(window, text="pause", command=lambda: pause(pause_situation))
pause_button.place(x=250, y=250)
stop_button = Button(window, text="stop", command=stop)
stop_button.place(x=300, y=250)
next_button = Button(window, text="next", command=next_song)
next_button.place(x=300, y=250)
previous_button = Button(window, text="previous", command=previous_song)
previous_button.place(x=350, y=250)
open_button = Button(window, text="open", command=browse_files)
open_button.place(x=430, y=250)
window.mainloop()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
