INDEX
S no. CONTENTS PAGE NO.
1 ABSTRACT 2
2 FEASIBILITY STUDY 3
3 SYSTEM REQUIREMENT 4
4 ERROR AND ITS TYPES 5
5 TESTING 6
6 MAINTAINANCE 7
7 MODULES USED 8
8 FLOW CHART 10
9 CODING 11
10 SAMPLE OUTPUT 28
11 CONCLUSION 35
12 BIBILIOGRAPHY 36
1
1.ABSTRACT
This project implements a Simple Music Player with a graphical
user interface (GUI) using Tkinter, Pygame, and SQLite. The
application provides users with a platform to play, pause, resume,
and navigate through a playlist of audio tracks, all stored in a local
SQLite database.
Key features include:
Database Integration: Each user has a unique database
storing their playlist, allowing for personalized song
management.
Music Control: Users can play, pause, resume, skip, and
delete songs from the playlist.
Graphical Interface: The application features an
aesthetically appealing UI with background images, volume
sliders, and music progress bars.
2
2.FEASIBILITY STUDY
Feasibility study is a system proposal according to its work, ability,
impact on the operation ability to meet the needs of users and
efficient use of resources. An important outcome of preliminary
investigations the determination of that system requested feasible.
2.1 Economical Feasibility:
This mp3 player helps in playing mp3 songs without any
interruption.
It is free of cost and easily accessible. It asks for a username and
password to create an account, if account exist already you can
sign in directly. This player will itself look for your mp3 songs and
load it.
2.2 Technical Feasibility:
Simple user interface
Login and Signup
Load the songs
Save or change the playlist
Enjoy listening to songs
3
3.SYSTEM REQUIREMENTS
3.1 MINIMUM
Processor: Intel Core i3-2330M or (newer or equivalent)
Graphics Card: NVIDIA GeForce 410M
Disk: 100MB Storage
OS: Microsoft Windows 10
RAM: 8GB RAM
3.2 SOFTWARE:
Python (Version 3.11 or newer)
4
4. ERROR AND ITS TYPES
An error, some times called “A Bug” is anything in the code that
prevents a program from compiling and running correctly. There
are broadly three types of errors
4.1 Compile-time error: Errors that occur during compilation of
a program is called compile times error. It has two types as follows:
4.1.1 Syntax Error: It refers to formal rules governing the
construction of valid statements in a language.
4.1.2 Semantics Error: It refers to the set of rules which give
the meaning of a statement.
4.2 Runtime Error: Errors that occur during the execution of
program are runtime errors. These are harder to detect errors.
Some runtime errors stop the execution of program which is the
called program “Crashed”.
4.3 Logical Error: Sometimes, even if you don’t encounter any
error during compiling-time and runtime, your program does not
provide the correct result. This is because the programmer’s
mistaken analysis of the problem he/she is trying to solve. Such
errors are called logical errors.
5
5. TESTING
5.1 Alpha Testing: It is the most common type of testing used in
the software industry. The objective of this testing is to identify all
possible issues or defects before releasing it into the market or to
the user. It is conducted at the developer’s site.
5.2 Beta Testing: It is a formal type of software testing which is
carried out by the customers. It is performed in a real environment
before releasing the products into the market for the actual
endusers. It is carried out to ensure that there is no major failures
in the software or product and it satisfies the business requirement.
Beta Testing is successful when the customer accepts the software.
5.3 White Box Testing: White Box Testing is based on the
knowledge about the internal logic of an application’s code. It is
also known as Glass Box Testing. Internal software and code
working should be known for programming this type of testing.
These tests are based in the coverage of the code statements,
branches, paths, conditions, etc.
5.4 Black Box Testing: It is a software testing method in which
the internal structure or design of the item to be tested is not
known to the tester. This method of testing can be applied virtually
to every level of the software testing.
6
6. MAINTAINANCE
Programming maintenance refers to the modifications in the
program. After it has been completed, in order to meet changing
requirements or to take care of the errors that shown up. There
are four types of maintenance:
6.1 Corrective Maintenance: When the program after
compilation shows error because of some unexpected situations,
untested areas such errors are fixed up by Corrective
Maintenance.
6.2 Adaptive Maintenance: Changes in the environment in
which an information system operates may lead to system
management. To accommodate changing need time to time
maintenance is done and is called Adaptive Maintenance.
6.3 Preventive Maintenance: If possible the errors could be
anticipated before they actually occur; the maintenance is called
Preventive Maintenance.
6.4 Perfective Maintenance: In this rapidly growing world,
information technology is the fastest growing area. If the
existing system is maintained to keep tuned with the new
features, new facilities, new capabilities, it is said to be
Perfective Maintenance.
7
7.MODULES
7.1 Custom Tkinter: Its modern GUI of tkinter.
7.2 Tkinter: is the inbuilt python module that is used to create
GUI applications. It is one of the most commonly used modules
for creating GUI applications in Python as it is simple and easy to
work with. You don’t need to worry about the installation of the
Tkinter module separately as it comes with Python already.
7.3 pygame: is a set of Python modules designed for writing video
games and multimedia applications. It provides functionality for
handling graphics, sound, and input devices (such as keyboard,
mouse, and joystick), which makes it easier to create games and
interactive applications in Python.
Pygame is built on top of the SDL (Simple DirectMedia Layer)
library, which is a low-level multimedia library that provides
functions to access graphics, sound, and input devices across
different platforms (Windows, macOS, Linux). Pygame simplifies
the use of SDL by providing higher-level Python bindings.
7.4 mutagen: is a Python module used for reading, writing, and
manipulating audio metadata (such as MP3, FLAC, OGG, WAV, and
other audio formats). It is particularly useful for working with audio
file tags and metadata, including information like artist name,
album title, track number, and genre, which are stored in various
audio file formats.
8
7.5 sqlite3: module in Python provides an interface for interacting
with SQLite databases. SQLite is a lightweight, serverless, self-
contained, and zero-configuration SQL database engine. It is
widely used for embedded databases and local storage in
applications due to its simplicity and ease of use.
9
8. FLOW CHART
10
9.CODE
import tkinter as tk
from tkinter import filedialog, StringVar, ttk, messagebox
from pygame import mixer
from PIL import Image, ImageTk
import os
import sqlite3
import mutagen
# Initialize Pygame Mixer
mixer.init(buffer=4096)
# MusicDatabase class to interact with SQLite
class MusicDatabase:
def __init__(self, db_name="music_player.db"):
self.db_name = db_name
self.connection = sqlite3.connect(self.db_name)
self.cursor = self.connection.cursor()
# Ensure database exists and has the correct schema
if not self.check_schema_exists():
11
self.create_schema()
def check_schema_exists(self):
"""Check if the required tables exist in the database."""
self.cursor.execute("SELECT name FROM sqlite_master
WHERE type='table';")
tables = self.cursor.fetchall()
return any(table[0] in ['users', 'songs'] for table in tables)
def create_schema(self):
"""Create the necessary tables (users and songs) if they
don't exist."""
self.cursor.execute('''CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY
AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password TEXT NOT NULL)''')
self.cursor.execute('''CREATE TABLE IF NOT EXISTS songs (
id INTEGER PRIMARY KEY
AUTOINCREMENT,
title TEXT NOT NULL,
12
file_path TEXT NOT NULL,
duration INTEGER NOT NULL)''')
self.connection.commit()
def add_user(self, username, password):
"""Add a new user to the database."""
try:
self.cursor.execute("INSERT INTO users (username,
password) VALUES (?, ?)", (username, password))
self.connection.commit()
except sqlite3.IntegrityError:
return False
return True
def authenticate_user(self, username, password):
"""Authenticate the user by username and password."""
self.cursor.execute("SELECT * FROM users WHERE
username = ? AND password = ?", (username, password))
user = self.cursor.fetchone()
return user
def add_song(self, title, file_path, duration):
"""Add a song to the songs table."""
13
self.cursor.execute("INSERT INTO songs (title, file_path,
duration) VALUES (?, ?, ?)", (title, file_path, duration))
self.connection.commit()
def delete_song(self, song_id):
"""Delete a song from the songs table."""
self.cursor.execute("DELETE FROM songs WHERE id = ?",
(song_id,))
self.connection.commit()
def get_all_songs(self):
"""Retrieve all songs from the songs table."""
self.cursor.execute("SELECT id, title, file_path, duration
FROM songs")
return self.cursor.fetchall()
def close(self):
"""Close the database connection."""
self.connection.close()
def change_database(self, db_name):
"""Switch to a different database (used when changing
accounts)."""
self.close()
14
self.db_name = db_name
self.connection = sqlite3.connect(self.db_name)
self.cursor = self.connection.cursor()
if not self.check_schema_exists():
self.create_schema()
# Music Player Class
class SimpleMusicPlayer:
def __init__(self, root, db):
self.root = root
self.db = db
self.root.title("Simple Music Player")
self.root.geometry("1080x720")
# Load and set the background image
self.bg_image =
Image.open(r"C:\Users\class1230\Desktop\2.jpg") # Replace
with your image path
self.bg_image = ImageTk.PhotoImage(self.bg_image)
self.bg_label = tk.Label(root, image=self.bg_image)
self.bg_label.place(x=0, y=0, relwidth=1, relheight=1) #
Stretch to fit the window
15
self.track_name_var = StringVar()
self.playlist = []
self.current_track_index = -1
self.is_paused = False
self.track_duration = 0
# Track label (on top of the background)
self.track_label = ttk.Label(root,
textvariable=self.track_name_var, font=("Arial", 12))
self.track_label.pack(pady=10)
# Buttons
button_frame = ttk.Frame(root)
button_frame.pack(pady=10)
ttk.Button(button_frame, text="Load",
command=self.load_music).grid(row=0, column=0, padx=5)
ttk.Button(button_frame, text="Play",
command=self.play_music).grid(row=0, column=1, padx=5)
ttk.Button(button_frame, text="Pause",
command=self.pause_music).grid(row=0, column=2, padx=5)
ttk.Button(button_frame, text="Resume",
command=self.resume_music).grid(row=0, column=3, padx=5)
16
ttk.Button(button_frame, text="Next",
command=self.next_track).grid(row=0, column=4, padx=5)
ttk.Button(button_frame, text="Previous",
command=self.prev_track).grid(row=0, column=5, padx=5)
ttk.Button(button_frame, text="Delete",
command=self.delete_song).grid(row=0, column=6, padx=5)
# Playlist
self.playlist_box = tk.Listbox(root, width=100, height=20)
self.playlist_box.pack(pady=10)
self.playlist_box.bind('<<ListboxSelect>>',
self.on_playlist_select)
# Volume Control (Vertical)
self.volume_scale = ttk.Scale(root, from_=1, to=0,
orient=tk.VERTICAL, command=self.set_volume)
self.volume_scale.set(0.5) # Set default volume to 50%
self.volume_scale.pack(side=tk.RIGHT, padx=10, pady=10)
# Volume Label
self.volume_label = ttk.Label(root, text="%")
self.volume_label.pack(side=tk.RIGHT)
# Duration Bar (Centered at the bottom)
duration_frame = ttk.Frame(root)
17
duration_frame.pack(side=tk.BOTTOM, fill=tk.X, padx=10)
self.duration_scale = ttk.Scale(duration_frame, from_=0,
to=100, orient=tk.HORIZONTAL, command=self.set_position)
self.duration_scale.pack(fill=tk.X)
self.duration_label = ttk.Label(duration_frame, text="00:00
/ 00:00")
self.duration_label.pack(fill=tk.X)
# Load songs from the database into the playlist
self.load_playlist_from_db()
# Main loop (This was the missing part, it checks the music
status)
self.root.after(1000, self.check_music)
# Keyboard shortcuts
self.root.bind('<Control-k>', self.pause_music) # Ctrl+K to
pause
self.root.bind('<space>', self.play_music) # Space to play
self.root.bind('<Control-j>', self.resume_music) # Ctrl+J to
resume
def check_music(self):
"""Check and update the music player's state"""
18
if mixer.music.get_busy():
current_pos = mixer.music.get_pos() / 1000 # Get
current position in seconds
self.update_duration_label(current_pos)
self.duration_scale.set(current_pos)
if current_pos >= self.track_duration:
self.next_track()
self.root.after(1000, self.check_music) # Check every
100ms
def load_playlist_from_db(self):
"""Load all songs from the database into the playlist."""
self.playlist = self.db.get_all_songs() # Fetch all songs
from the database
self.playlist_box.delete(0, tk.END) # Clear the existing
playlist in the UI
for song in self.playlist:
self.playlist_box.insert(tk.END, song[1]) # Insert song
titles into the playlist box
def load_music(self):
files = filedialog.askopenfilenames(filetypes=[("Audio Files",
"*.mp3 *.wav *.flac *.ogg")])
19
if files:
for file in files:
title = os.path.basename(file)
duration = self.get_track_duration(file)
self.db.add_song(title, file, duration)
self.load_playlist_from_db()
def get_track_duration(self, file_path):
try:
from mutagen import File
audio = File(file_path)
return int(audio.info.length) # Return the duration in
seconds
except Exception as e:
messagebox.showerror("Error", f"Could not load track
duration: {str(e)}")
return 0
def on_playlist_select(self, event):
if self.playlist:
selected_index = self.playlist_box.curselection()
if selected_index:
20
self.current_track_index = selected_index[0]
self.play_music()
def play_music(self, event=None):
if self.playlist:
if self.current_track_index == -1:
self.current_track_index = 0
song = self.playlist[self.current_track_index]
mixer.music.load(song[2])
mixer.music.play()
self.track_name_var.set(song[1])
self.is_paused = False
self.update_playlist_selection()
self.track_duration = song[3]
self.duration_scale.config(to=self.track_duration)
self.duration_scale.set(0)
self.update_duration_label(0)
def pause_music(self, event=None):
if not self.is_paused:
mixer.music.pause()
21
self.is_paused = True
def resume_music(self, event=None):
if self.is_paused:
mixer.music.unpause()
self.is_paused = False
def next_track(self):
if self.playlist:
self.current_track_index = (self.current_track_index + 1)
% len(self.playlist)
self.play_music()
def prev_track(self):
if self.playlist:
self.current_track_index = (self.current_track_index - 1)
% len(self.playlist)
self.play_music()
def update_playlist_selection(self):
self.playlist_box.selection_clear(0, tk.END)
self.playlist_box.selection_set(self.current_track_index)
def set_position(self, position):
22
"""Set the music player's current position based on the
scale."""
mixer.music.set_pos(float(position))
def update_duration_label(self, position):
"""Update the duration label with the current position and
total track duration"""
minutes, seconds = divmod(int(position), 60)
current_time = f"{minutes:02d}:{seconds:02d}"
self.duration_label.config(text=f"{current_time} /
{self.format_duration(self.track_duration)}")
def set_volume(self, volume):
"""Set the volume for the music player."""
volume = float(volume)
mixer.music.set_volume(volume)
def format_duration(self, duration):
minutes = int(duration) // 60
seconds = int(duration) % 60
return f"{minutes:02d}:{seconds:02d}"
def delete_song(self):
23
if self.playlist:
selected_index = self.playlist_box.curselection()
if selected_index:
song_id = self.playlist[selected_index[0]][0]
self.db.delete_song(song_id)
self.load_playlist_from_db()
# Login Page Class
class LoginPage:
def __init__(self, root):
self.root = root
self.root.title("Login Page")
self.root.geometry("400x300")
# Load and set the background image
self.bg_image =
Image.open(r"C:\Users\class1230\Desktop\musicplayer
bgrnd.jpg") # Replace with your image path
self.bg_image = ImageTk.PhotoImage(self.bg_image)
self.bg_label = tk.Label(root, image=self.bg_image)
self.bg_label.place(x=0, y=0, relwidth=1, relheight=1) #
Stretch to fit the window
24
self.username_var = StringVar()
self.password_var = StringVar()
self.login_frame = ttk.Frame(root)
self.login_frame.place(relx=0.5, rely=0.5,
anchor=tk.CENTER) # Center the frame
ttk.Label(self.login_frame, text="Username:").grid(row=0,
column=0, pady=10)
self.username_entry = ttk.Entry(self.login_frame,
textvariable=self.username_var)
self.username_entry.grid(row=0, column=1)
ttk.Label(self.login_frame, text="Password:").grid(row=1,
column=0, pady=10)
self.password_entry = ttk.Entry(self.login_frame,
textvariable=self.password_var, show="*")
self.password_entry.grid(row=1, column=1)
ttk.Button(self.login_frame, text="Login",
command=self.login).grid(row=2, column=0, columnspan=2,
pady=10)
self.signup_button = ttk.Button(self.login_frame,
text="Sign Up", command=self.signup)
self.signup_button.grid(row=3, column=0, columnspan=2)
25
def login(self):
username = self.username_var.get()
password = self.password_var.get()
if username and password:
db_name = f"{username}_music.db"
db = MusicDatabase(db_name)
if db.authenticate_user(username, password):
self.root.destroy()
player_root = tk.Tk()
player = SimpleMusicPlayer(player_root, db)
player_root.mainloop()
else:
messagebox.showerror("Login Failed", "Invalid
username or password.")
else:
messagebox.showerror("Input Error", "Please enter both
username and password.")
def signup(self):
username = self.username_var.get()
password = self.password_var.get()
26
if username and password:
db_name = f"{username}_music.db"
db = MusicDatabase(db_name)
if db.add_user(username, password):
messagebox.showinfo("Sign Up", "Account created
successfully.")
else:
messagebox.showerror("Sign Up Failed", "Username
already exists.")
else:
messagebox.showerror("Input Error", "Please enter both
username and password.")
if __name__ == "__main__":
root = tk.Tk()
login_page = LoginPage(root)
root.mainloop()
27
10. OUTPUT
1. LOGIN PAGE
2. SIGNUP
28
3. DATABASE
4. LOGIN
29
5. LOAD DIRECTRY
30
6. LOAD
7. PLAY
31
8. PAUSE
9.NEXT
32
10.RESUME
11.PREVIOUS
33
12.DELETE
34
11. CONCLUSION
We conclude that our program is fully functionable and operable
with all the functions and modules shown in the previous page .
Further updation will be done with Javascript,HTML,CSS,Python to
create a friendly user interface where it will be further developed
into an application which user can install in any device user want.
Further the platform will be an online mp3 audio player in which
user can search any song they want and even download it to their
corresponding playlist, and they can control the flow of song
accordingly.
35
12.BIBLIOGRAPHY
12.1 List of sites, docs used for reference:
https://app.diagrams.net/
https://github.com/
https://www.geeksforgeeks.org/python-programming-
language-tutorial/
https://www.youtube.com/
https://www.canva.com/ai-image-generator/
12.2 List of books, docs used for reference:
Computer Science with Python(class 12)(SUMITA ARORA)
Computer Science with Python(class 12)(PREETHI ARORA)
36