0% found this document useful (0 votes)
7 views3 pages

MP3 Player Application in Python

The document describes a Python program that implements a simple MP3 player using the Tkinter library for the GUI and Pygame for audio playback. It allows users to load MP3 files, play, pause, stop, and shuffle through songs while displaying metadata and album art. The program also features a progress bar and time display for tracking playback duration.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views3 pages

MP3 Player Application in Python

The document describes a Python program that implements a simple MP3 player using the Tkinter library for the GUI and Pygame for audio playback. It allows users to load MP3 files, play, pause, stop, and shuffle through songs while displaying metadata and album art. The program also features a progress bar and time display for tracking playback duration.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd

import os

import io
import random
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from mutagen.mp3 import MP3
from mutagen.id3 import ID3
from pygame import mixer
from PIL import Image, ImageTk

class MP3Player:
def __init__(self, root):
[Link] = root
[Link]("MP3 Player")
[Link]("700x300")
[Link](bg="#2C2F33")

self.is_playing = False
self.is_paused = False
self.current_file = None
self.total_duration = 0

[Link] = [Link](root, text="Select MP3 Files To Play",


font=("StratumNo2", 14), fg="white", bg="#2C2F33")
[Link](pady=10)

self.metadata_label = [Link](root, text="", font=("Arial", 10),


fg="white", bg="#2C2F33")
self.metadata_label.pack(pady=5)

self.play_button = [Link](root, text="Open MP3 Files",


command=self.load_file)
self.play_button.pack(pady=5)

button_frame = [Link](root, bg="#2C2F33")


button_frame.pack(pady=10)

self.toggle_button = [Link](button_frame, text="Play",


command=self.toggle_play)
self.toggle_button.grid(row=0, column=0, padx=5)

self.stop_button = [Link](button_frame, text="Stop",


command=self.stop_music)
self.stop_button.grid(row=0, column=1, padx=5)

self.random_button = [Link](button_frame, text="Shuffle",


command=self.play_random)
self.random_button.grid(row=0, column=2, padx=5)

[Link] = [Link]()
[Link]("TProgressbar", troughcolor="#1E2124",
background="#7289DA", thickness=10)

[Link] = [Link](root, orient='horizontal', length=300,


mode='determinate', style="TProgressbar")
[Link](pady=5)

self.time_label = [Link](root, text="--:-- / --:--", font=("Arial", 10),


fg="white", bg="#2C2F33")
self.time_label.pack(pady=5)

self.album_art_label = [Link](root, bg="#2C2F33")


self.album_art_label.pack(pady=5)

[Link]()
[Link](1000, self.update_progress)

def load_file(self):
new_file = [Link](filetypes=[["MP3 files", "*.mp3"]])
if new_file:
self.stop_music()
self.current_file = new_file
[Link](text=[Link](self.current_file))
self.extract_metadata()
self.total_duration = MP3(self.current_file).[Link]
[Link]["value"] = 0

def extract_metadata(self):
try:
audio = MP3(self.current_file, ID3=ID3)
artist = [Link]("TPE1")
album = [Link]("TALB")
artist = [Link][0] if artist else "Unknown"
album = [Link][0] if album else "Unknown"
self.metadata_label.config(text=f"Artist: {artist}\nAlbum: {album}")

if 'APIC:' in [Link]:
image_data = [Link]['APIC:'].data
image = [Link]([Link](image_data))
[Link]((150, 150))
self.album_art = [Link](image)
self.album_art_label.config(image=self.album_art)
else:
self.album_art_label.config(image='')
except Exception as e:
[Link]("Error", f"Something went wrong on extract
metadata: {e}")

def toggle_play(self):
if self.current_file:
if not self.is_playing:
self.play_music()
else:
if self.is_paused:
[Link]()
self.is_paused = False
else:
[Link]()
self.is_paused = True
self.toggle_button.config(text="Resume" if self.is_paused else
"Pause")

def play_music(self):
[Link](self.current_file)
[Link]()
self.is_playing = True
self.is_paused = False
self.toggle_button.config(text="Pause")
[Link](1000, self.check_end)

def stop_music(self):
[Link]()
self.is_playing = False
self.is_paused = False
self.toggle_button.config(text="Play")
[Link]["value"] = 0

def update_progress(self):
if self.is_playing and not self.is_paused:
current_time = [Link].get_pos() / 1000
if current_time < self.total_duration:
[Link]["value"] = (current_time / self.total_duration) * 100
self.time_label.config(text=f"{self.format_time(current_time)} /
{self.format_time(self.total_duration)}")
else:
self.stop_music()
[Link](1000, self.update_progress)

def check_end(self):
if self.is_playing and not self.is_paused:
current_time = [Link].get_pos() / 1000
if current_time >= self.total_duration:
self.stop_music()
[Link](1000, self.check_end)

def format_time(self, seconds):


minutes = int(seconds // 60)
seconds = int(seconds % 60)
return f"{minutes:02}:{seconds:02}"

def play_random(self):
if self.current_file:
directory = [Link](self.current_file)
mp3_files = [f for f in [Link](directory) if [Link](".mp3")]
if mp3_files:
random_file = [Link](mp3_files)
self.current_file = [Link](directory, random_file)
[Link](text=[Link](self.current_file))
self.extract_metadata()
self.total_duration = MP3(self.current_file).[Link]
[Link]["value"] = 0
self.play_music()
else:
[Link]("Warning", "Cannot found Mp3 files on
folder.")

if __name__ == "__main__":
root = [Link]()
player = MP3Player(root)
[Link]()

Common questions

Powered by AI

The MP3Player's GUI indicates music playback state through the text of the 'toggle_button', which changes between 'Play', 'Pause', and 'Resume' based on the current status. During playing, 'toggle_button' displays 'Pause', switching to 'Resume' when music is paused, and returns to 'Play' when stopped. Furthermore, the progress bar visually indicates playback progress, and the time label displays elapsed and total time to offer ongoing feedback to the user .

The MP3Player class utilizes the tkinter library to create a GUI that includes several elements for user interaction and information display. It uses 'tk.Label' for displaying static text and metadata, 'ttk.Button' for interactive buttons like play, stop, and shuffle, 'tk.Frame' for organizing layout structures within the window, and 'ttk.Progressbar' for visualizing the progress of the track being played. 'messagebox' is used for displaying error and warning messages, while 'filedialog' is utilized to open the file selection dialog .

The MP3Player employs a conditional approach within the 'toggle_play' method to handle switching between playing, pausing, and resuming music. Initially, it checks if 'self.current_file' is not null to ensure a file is loaded. If music is not playing, 'play_music' is called to start playback. If music is playing and not paused, it pauses the music using 'mixer.music.pause()' and updates 'self.is_paused' to True. Conversely, if paused, it resumes playback with 'mixer.music.unpause()' and sets 'self.is_paused' to False. The play button's label is dynamically updated to either 'Pause' or 'Resume' based on the current state .

The MP3Player class handles failures in metadata extraction by using a try-except block around the extraction process in the 'extract_metadata' method. If an exception is caught, it shows an error message to the user using 'messagebox.showerror' with the message indicating that something went wrong along with the exception message .

The MP3Player class updates the displayed time of a song during playback using the 'update_progress' method, which is called every 1,000 milliseconds (1 second) via 'self.root.after(1000, self.update_progress)'. This method checks if the song is playing and not paused. If so, it calculates the 'current_time' using 'mixer.music.get_pos() / 1000' to convert the position from milliseconds to seconds. It then updates the progress bar's value based on the ratio of 'current_time' to 'self.total_duration'. Additionally, it updates the 'self.time_label' with formatted time strings for both the current position and total duration using the 'format_time' method .

The MP3Player ensures that non-MP3 files are not loaded by using a file dialog filter 'filetypes=[['MP3 files', '*.mp3']]' in the 'load_file' method. This filter limits the file selection window to only show and allow selection of files with a '.mp3' extension .

Album art is handled within the 'extract_metadata' method of the MP3Player application. The application checks if the 'APIC:' tag is present in the audio file's metadata, which contains image data for the album art. If found, the image data are extracted and converted into an image object using 'Image.open(io.BytesIO(image_data))'. The image is then resized to a thumbnail of 150x150 pixels for display. This thumbnail is converted into a format suitable for tkinter display using 'ImageTk.PhotoImage' and updated on 'self.album_art_label'. If no album art is present, the label is simply cleared .

The MP3Player uses both the 'update_progress' and 'check_end' methods for playback synchronization, ensuring that songs don't prematurely stop. The 'update_progress' method periodically updates the progress bar and time display by checking 'current_time' against 'self.total_duration'. If 'current_time' exceeds the total duration, it automatically calls 'stop_music'. Concurrently, 'check_end' periodically checks if the song has reached its conclusion by comparing 'current_time' and 'self.total_duration'. If true, it stops the music by invoking 'stop_music' .

The 'play_random' method allows for the playback of a random MP3 file from the directory of the currently loaded file. This method first checks if 'self.current_file' is not null. Then, it retrieves the directory path of the current file and lists all MP3 files in that directory. If there are MP3 files present, it selects a random file using 'random.choice(mp3_files)' and updates 'self.current_file' to this new file path. The metadata for this file is extracted using 'self.extract_metadata()' and the total duration is set. It resets the progress to 0 and starts playback using 'self.play_music()'. If no MP3 files are found, it displays a warning message .

The MP3Player employs the 'format_time' method to convert raw time in seconds into a more human-readable format of 'MM:SS'. This method calculates the number of minutes and seconds by dividing and using the modulus operation, respectively, followed by formatting these values into a string. This formatting is necessary to provide users with a clear and consistent representation of time rather than dealing with raw second values, which enhances user experience by aligning with common time display standards .

You might also like