I cant tell where the lag is coming from. in the function update_time
it sets the position of the time scale. The problem arises with the command in the function. set_time
is the function within the time scale, but it sets the time. that means every time update_time
is called it sets the time. I dont want that because it is creating lag. Could someone tell me how to get rid of this lag?
# Now you can increase or decrease the volume here, you can also select multiple songs at once and listen to your favorite songs, delete and add songs as needed.
# Remember only this files *.mp3;*.wav;*.ogg;*.mp4;*.avi;*.mkv;*.flv;*.mov;*.wmv;*.webm
import os
from os import environ
environ['PYGAME_HIDE_SUPPORT_PROMPT'] = '1'
import pygame
import librosa
import random
from tkinter import Tk, filedialog, messagebox
from tkinter import ttk
from tkinter import Listbox
from mutagen.mp3 import MP3
from threading import Timer
# Initialize the mixer
pygame.mixer.init()
# Create a Tkinter window to select media files
root = Tk()
root.withdraw()
# Global variables
s = 0
t = 0
length = 0
current_file = ""
playlist = []
current_index = 0
is_playing = False
music_time = 0.0 # Default time
volume = 0.5 # Default volume
# Function to select a file
def select_file():
file_path = filedialog.askopenfilenames(filetypes=[
("Audio/Video Files", "*.mp3;*.wav;")
])
#("Audio/Video Files", "*.mp3;*.wav;*.ogg;*.mp4;*.avi;*.mkv;*.flv;*.mov;*.wmv;*.webm")])
if file_path:
add_to_playlist(file_path)
# Function to add a file to the playlist
def add_to_playlist(file_path):
for files in file_path:
playlist.append(files)
playlist_box.insert("end", os.path.basename(files[:-4]))
# Find song length
def song_length(file_path):
'abuba.mp3'
if file_path[-4:] == '.mp3':
audio = MP3(file_path)
return audio.info.length
if file_path[-4:] == '.wav':
print(librosa.get_duration(path=file_path))
return librosa.get_duration(path=file_path)
#Function to stop the music and start it again from set position
def stop_start(music_pos):
pygame.mixer.music.stop()
pygame.mixer.music.play()
pygame.mixer.music.set_pos(music_pos)
# Function to remove a file from the playlist
def remove_from_playlist():
selected_index = playlist_box.curselection()
if is_playing:
if (current_index,) == selected_index:
stop_music()
if selected_index:
playlist.pop(selected_index[0])
playlist_box.delete(selected_index)
# Function to clear the playlist
def clear_playlist():
global current_index
playlist.clear()
playlist_box.delete(0, "end")
if is_playing:
stop_music()
current_index = 0
# Function to play the selected file or playlist
def play_music(file_path=None):
global current_file, current_index, is_playing, length, t
if not file_path:
selected_index = playlist_box.curselection()
if not selected_index:
messagebox.showinfo("Error", "No file selected.")
return
current_index = selected_index[0]
file_path = playlist[current_index]
pygame.mixer.music.load(file_path)
length = round(song_length(file_path), 3) * 1000
time_scale.set(10)
#time_scale.pack()
time_scale.config(to=(length/10))
pygame.mixer.music.play()
current_file = file_path
is_playing = True
t = Timer(((length/10) - music_time)/100, play_next)
t.start()
update_time()
update_status()
# Threading function that updates time of music constantly
def update_time():
global music_time
global s
music_time += 100
print(music_time)
print("its me hi im the problem")
time_scale.set(music_time)
if s != 0:
s.cancel()
s = Timer(1, update_time)
s.start()
# Function to pause/resume the music
def pause_resume_music():
global is_playing, t, s
if is_playing:
pygame.mixer.music.pause()
is_playing = False
t.cancel()
if s != 0:
s.cancel()
else:
pygame.mixer.music.unpause()
is_playing = True
t = Timer(((length/10) - music_time)/100 - pygame.mixer.music.get_pos()/1000, play_next)
t.start()
update_time()
update_status()
# Function to stop the music
def stop_music():
pygame.mixer.music.stop()
update_status()
play_pause_button.config(text="Play", command=play_music)
# Function to shuffle songs in playlist
def shuffle_playlist():
global playlist, t
randomized_playlist = random.sample(playlist, len(playlist))
clear_playlist()
if t != 0:
t.cancel()
for file_path in randomized_playlist:
playlist.append(file_path)
playlist_box.insert("end", os.path.basename(file_path[:-4]))
play_music(playlist[0])
# Function to play next song
def play_next():
global current_index
pygame.mixer.music.stop()
update_status()
if current_index + 1 <= len(playlist) - 1:
current_index += 1
else:
current_index = 0
play_music(playlist[current_index])
def play_previous():
global current_index
pygame.mixer.music.stop()
update_status()
if current_index + 1 <= len(playlist) - 1:
current_index += -1
else:
current_index = 0
play_music(playlist[current_index])
# Function to play next song
def play_next():
global current_index
pygame.mixer.music.stop()
update_status()
if current_index + 1 <= len(playlist) - 1:
current_index += 1
else:
current_index = 0
play_music(playlist[current_index])
# Function to set the volume
def set_volume(volume_level):
global volume
print(volume_level)
volume = float(volume_level)
pygame.mixer.music.set_volume(volume)
# Function to set the time
def set_time(music_time_level):
global music_time, t
music_time = float(music_time_level)
if is_playing:
stop_start(music_time/100)
if t != 0:
t.cancel()
t = Timer(((length/10) - music_time)/100, play_next)
t.start()
# Function to update the status label
def update_status():
global current_file, current_index, is_playing
if current_file:
status_label.config(text=f"Now playing: {os.path.basename(current_file)}")
else:
status_label.config(text="")
if music_time >= (length/10):
play_pause_button.config(text="Play", command=play_music)
elif is_playing:
play_pause_button.config(text="Pause", command=pause_resume_music)
else:
play_pause_button.config(text="Resume")
playlist_box.selection_clear(0, "end")
playlist_box.selection_set(current_index)
# Main GUI window
window = Tk()
window.title("Media Player")
# Create buttons
select_button = ttk.Button(window, text="Select File", command=select_file)
play_pause_button = ttk.Button(window,text="Play", command=play_music)
stop_button = ttk.Button(window, text="Stop", command=stop_music)
skip_button = ttk.Button(window, text="Skip", command=lambda: play_next())
rewind_button = ttk.Button(window, text="Rewind", command=lambda: play_previous())
# Create playlist controls
playlist_label = ttk.Label(window, text="Playlist")
playlist_box = Listbox(window, selectbackground="#3498db", selectforeground="white")
remove_button = ttk.Button(window, text="Remove", command=remove_from_playlist)
shuffle_button = ttk.Button(window, text="Shuffle", command=shuffle_playlist)
clear_button = ttk.Button(window, text="Clear", command=clear_playlist)
# Create volume control
volume_label = ttk.Label(window, text="Volume")
volume_scale = ttk.Scale(window, from_=0.0, to=1.0, orient="horizontal", command=set_volume)
volume_scale.set(volume) # Set initial volume value
# Create time control
time_label = ttk.Label(window, text="Time")
time_scale = ttk.Scale(window, from_=0.0, to=1.0, orient="horizontal", command=set_time)
time_scale.set(music_time) # Set initial volume value
# Create status label
status_label = ttk.Label(window, text="", anchor="center")
# Position the buttons and widgets
select_button.grid(row=0, column=0, padx=10, pady=10)
play_pause_button.grid(row=0, column=1, padx=10, pady=10)
stop_button.grid(row=0, column=2, padx=10, pady=10)
skip_button.grid(row=0, column=5, padx=10, pady=10)
rewind_button.grid(row=0, column=6, padx=10, pady=10)
playlist_label.grid(row=1, column=0, padx=10, pady=10, sticky="w")
playlist_box.grid(row=2, column=0, rowspan=4, columnspan=5, padx=10, pady=10, sticky="nsew")
remove_button.grid(row=2, column=5, padx=5, pady=10, sticky="w")
shuffle_button.grid(row=2, column=6, padx=5, pady=10, sticky="w")
clear_button.grid(row=5, column=5, padx=5, pady=10, sticky="w")
volume_label.grid(row=6, column=0, padx=10, pady=5, sticky="w")
volume_scale.grid(row=6, column=1, columnspan=4, padx=10, pady=5, sticky="we")
time_label.grid(row=7, column=0, padx=10, pady=5, sticky="w")
time_scale.grid(row=7, column=1, columnspan=4, padx=10, pady=5, sticky="we")
status_label.grid(row=8, column=0, columnspan=6, padx=10, pady=5, sticky="we")
# Configure grid weights
window.grid_rowconfigure(2, weight=1)
window.grid_columnconfigure(0, weight=1)
# Start the GUI event loop
window.mainloop()
# Quit the mixer
pygame.mixer.quit()