Before starting to read this text based I want to point out that there is also video version. Click below 

Requirements for this project.

Python 3.x

Third party packages

i) pygame ( for music )
ii) mutagen ( for song metadata )
 

you can install these easily using

pip install pygame
pip install mutagen

We are going to build a function based music player that can be easily extended by adding more functions. I hope after following this through you can add your own functions in a similar matter and extend this. I will also embed my videos along the way to paint a clearer picture.

 

First let’s start off by creating the file and importing the packages, I’m going to name my file as music_player.py

Let’s import the packages

 

import os # to fetch songs and directories 
from tkinter.filedialog import askdirectory # for selecting our song directory
import pygame # for playing music
from mutagen.id3 import ID3 # For tagging the meta data to our songs
from tkinter import * # for UI

 

Well, Now we have our requirements done, Let’s create a basic window where we add our UI elements. That can be done by

root = Tk() # creates an Empty window
root.minsize(300,300) # set size as 300 x 300 wide, Change this accordingly

 

Now let us create 2 lists that we are going to use later.

listofsongs = []

realnames = []

To currently see which song is being played we need a label on our UI that updates as the song changes or updates. To do this we need to define  Label that gets it’s value from a StringVar().

v = StringVar()
songlabel = Label(root,textvariable=v,width=35)


Okay, Now we laid down the bricks let’s build some functions.

Starting off with our first function, This function opens up a directory and scans all the mp3 files then adds them to our listofsongs list. This is how it goes

 

def directorychooser():

    directory = askdirectory()
    os.chdir(directory)
    #Loop over all the files in that directory
    for file in os.listdir(directory):
        # only add them if they end with .mp3
        if file.endswith(".mp3"):
            realdir = os.path.realpath(file)
	# load the meta data of that song into audio variable. (A dictionary)
            audio = ID3(realdir)
	# TIT2 refers to the TITLE of the song, So let’s append that to realnames
            realnames.append(audio['TIT2'].text[0])
            listofsongs.append(file)
    
    # initialize pygame
    pygame.mixer.init()
    # load the first song
    pygame.mixer.music.load(listofsongs[0])
    #pygame.mixer.music.play()

 

Now let us make few functions which will modify the state of our song.

Here is the function to update our label as the song updates,

def updatelabel():
    global index # If you do not use global, new index variable will be defined
    global songname
    v.set(realnames[index]) # set our StringVar to the real name 
    #return songname

 

Now, To manipulate the song which is the player is playing we need 3 basic functions

i) To go to next song

ii) To go to previous song

iii) To stop the current song


You can keep adding as many functions as you need, Let us see how to do these 3 basic ones

For going to the next song, here is the function.

 

def nextsong(event):
    # get index from globals
    global index 
    # increment index
    index += 1 
    # get the next song from listofsongs
    pygame.mixer.music.load(listofsongs[index])
    # play it away
    pygame.mixer.music.play()
    # do not forget to update the label !
    updatelabel()

Similarly we are going to do it for previous song too. You might have already guessed what to do.

def prevsong(event):
   global index
   index -= 1
   pygame.mixer.music.load(listofsongs[index])
   pygame.mixer.music.play()
   updatelabel()

 

Simple as that !

You can combine the above functions if you’re feeling confident :)

Now to stop the song, That is pretty simple too.

 

def stopsong(event):
    # stop the current song which is playing
    pygame.mixer.music.stop()
    # set our Label to empty
    v.set("")
    #return songname

Okay, Looks like our backend is complete, Let us build a simple functional UI for our player.

Let us start off with the title for our UI
 

label = Label(root,text='Music Player') # set the heading
label.pack() # pack it inside root window

Now make a ListBox to store all our songs list. So that user can know what’s coming next 

listbox = Listbox(root)
listbox.pack()

 

We need to insert our songs, i.e our song names into this listbox. But there is a problem. The list box shows them in reverse. A simple workaround for this will be to reverse the list we giving to the lis box. This will make sure the list is ordered properly. Let us try that

realnames.reverse()

for items in realnames:
    listbox.insert(0,items)

realnames.reverse()

Now it’s time to plug in the buttons.

 

nextbutton = Button(root,text = 'Next Song')
nextbutton.pack()

previousbutton = Button(root,text = 'Previous Song')
previousbutton.pack()

stopbutton = Button(root,text='Stop Music')
stopbutton.pack()


Bind these buttons to the functions we’ve written above.\

nextbutton.bind("<Button-1>",nextsong)
previousbutton.bind("<Button-1>",prevsong)
stopbutton.bind("<Button-1>",stopsong)

Let’s not forget the song label 

songlabel.pack()

And Finally, Let’s start the window

root.mainloop()

And there we are. That’s it ! :D
 

Here's everything brought together.

import os
from tkinter.filedialog import askdirectory

import pygame
from mutagen.id3 import ID3
from tkinter import *

root = Tk()
root.minsize(300,300)


listofsongs = []
realnames = []

v = StringVar()
songlabel = Label(root,textvariable=v,width=35)

index = 0

def directorychooser():

    directory = askdirectory()
    os.chdir(directory)

    for files in os.listdir(directory):
        if files.endswith(".mp3"):

            realdir = os.path.realpath(files)
            audio = ID3(realdir)
            realnames.append(audio['TIT2'].text[0])


            listofsongs.append(files)


    pygame.mixer.init()
    pygame.mixer.music.load(listofsongs[0])
    #pygame.mixer.music.play()

directorychooser()

def updatelabel():
    global index
    global songname
    v.set(realnames[index])
    #return songname


def nextsong(event):
    global index
    index += 1
    pygame.mixer.music.load(listofsongs[index])
    pygame.mixer.music.play()
    updatelabel()

def prevsong(event):
    global index
    index -= 1
    pygame.mixer.music.load(listofsongs[index])
    pygame.mixer.music.play()
    updatelabel()


def stopsong(event):
    pygame.mixer.music.stop()
    v.set("")
    #return songname


label = Label(root,text='Music Player')
label.pack()

listbox = Listbox(root)
listbox.pack()

#listofsongs.reverse()
realnames.reverse()

for items in realnames:
    listbox.insert(0,items)

realnames.reverse()
#listofsongs.reverse()


nextbutton = Button(root,text = 'Next Song')
nextbutton.pack()

previousbutton = Button(root,text = 'Previous Song')
previousbutton.pack()

stopbutton = Button(root,text='Stop Music')
stopbutton.pack()

nextbutton.bind("<Button-1>",nextsong)
previousbutton.bind("<Button-1>",prevsong)
stopbutton.bind("<Button-1>",stopsong)

songlabel.pack()

root.mainloop()

 

blog comments powered by Disqus