Kivy Music Player with Python | Part -2

So this is Part 2 of the kivy music player series. In this part we will see

  • how to make Labels for song titles.
  • how to add album images to our music player.

So this is the last code that we write in our part 1

import os
import random
import kivy
kivy.require('2.0.0')
from kivy.app import App
from kivymd.uix.relativelayout import MDRelativeLayout
from kivymd.uix.button import MDIconButton
from kivymd.app import MDApp
from kivy.core.audio import SoundLoader
from kivy.core.window import Window
Window.size = (400,600)
class MyApp(MDApp):
    
    def build(self):
        layout = MDRelativeLayout(md_bg_color = [0,0.5,1,1])
        self.music_dir = 'F:/Project/Parts'
        music_files = os.listdir(self.music_dir)
        
        print(music_files)
        
        self.song_list = [x for x in music_files if x.endswith('mp3')]
        print(self.song_list)
        
        self.song_count = len(self.song_list)
        self.playbutton = MDIconButton(pos_hint={'center_x':0.4, 'center_y':0.05},
                                       icon="play.png",
                                       on_press = self.playaudio)
        
        self.stopbutton = MDIconButton(pos_hint={'center_x':0.55, 'center_y':0.05},
                                       icon="stop.png",
                                       on_press = self.stopaudio)
        layout.add_widget(self.playbutton)
        layout.add_widget(self.stopbutton)        
        
        return layout
    def playaudio(self,obj):
        self.song_title = self.song_list[random.randrange(0, self.song_count)]
        print(self.song_title)
        self.sound = SoundLoader.load('{}/{}'.format(self.music_dir, self.song_title))
        self.sound.play()
    def stopaudio(self,obj):
        self.sound.stop()
    
if __name__ == '__main__':
    MyApp().run()

Now from kivy library, import Label, Image UI elements, and Clock to schedule intervals.

from kivy.uix.label import Label
from kivy.uix.image import Image
from kivy.clock import Clock

Then add this code snippet in the build function to add label and image in music player

self.songlabel = Label(pos_hint={'center_x':0.5, 'center_y':.96},
                                size_hint=(1,1),
                                font_size=18)
self.albumimage = Image(pos_hint={'center_x':0.5, 'center_y':0.55},
                                size_hint=(.8,.75))

To add widgets in the layout, add below two lines in build function

layout.add_widget(self.songlabel)
layout.add_widget(self.albumimage)

To update your play function with these new lines of code, these lines are extracting the song name from the song title (like 1_SongOne.mp3 – make sure songs are saved in this format in our folder, you can check in the previous part).

so to show Song Name we remove “.mp3” and “1_” from the title of the song.

For the image, we are taking the 0th element from the song title (like 1_SongOne.mp3) so we are taking the only 0th using self.song_title[0] and adding extension .jpg to set image in album image.

def playaudio(self,obj):
    self.song_title = self.song_list[random.randrange(0, self.song_count)]
    print(self.song_title)
    self.sound = SoundLoader.load('{}/{}'.format(self.music_dir, self.song_title))
    self.songlabel.text = "===== Playing ~ "+self.song_title[2:-4] +" ====="
    self.albumimage.source = self.song_title[0]+".jpg"
    self.sound.play()

Now when you will run the code up to this point, then initially the image and song will now be loaded, you can check the below image.

Output

kivy music player song image

To solve this problem add one line in your build function.

Clock.schedule_once(self.playaudio)

so this line will execute the play audio function for the first time when the application will initiate, you can check in the below image.

Output

music player image

So now suppose if you will click on the play button multiple times then you can find multiple songs that will play at the same time because we did now handle button enable and disable feature up to this point.

To handle this problem we can do one thing, after a click on the play button we can disable our play button and enable the stop button so that the user cannot click on the play button multiple times and for the stop button does it’s reverse.

To do this task update your stop button code (when the app will start, it should be disabled) and also update the play and stop function.

self.stopbutton = MDIconButton(pos_hint={'center_x':0.55, 'center_y':0.05},
                                       icon="stop.png",
                                       on_press = self.stopaudio, disabled=True)
def playaudio(self,obj):
    self.playbutton.disabled = True
    self.stopbutton.disabled = False
    self.song_title = self.song_list[random.randrange(0, self.song_count)]
    print(self.song_title)
    self.songlabel.text = "===== Playing ~ "+self.song_title[2:-4] +" ====="
    self.sound = SoundLoader.load('{}/{}'.format(self.music_dir, self.song_title))
    self.albumimage.source = self.song_title[0]+".jpg"
    self.sound.play()
def stopaudio(self,obj):
    self.playbutton.disabled = False
    self.stopbutton.disabled = True
    self.sound.stop()

Final Code Upto this Point

import os
import random
import kivy
kivy.require('2.0.0')
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.image import Image
from kivymd.uix.relativelayout import MDRelativeLayout
from kivymd.uix.button import MDIconButton
from kivymd.app import MDApp
from kivy.core.audio import SoundLoader
from kivy.clock import Clock
from kivy.core.window import Window
Window.size = (400,600)
class MyApp(MDApp):
    
    def build(self):
        layout = MDRelativeLayout(md_bg_color = [0,0.5,1,1])
        self.music_dir = 'F:/Project/Parts'
        music_files = os.listdir(self.music_dir)
        
        print(music_files)
        
        self.song_list = [x for x in music_files if x.endswith('mp3')]
        print(self.song_list)
        
        self.song_count = len(self.song_list)
        self.songlabel = Label(pos_hint={'center_x':0.5, 'center_y':.96},
                               size_hint=(1,1),
                               font_size=18)
        self.albumimage = Image(pos_hint={'center_x':0.5, 'center_y':0.55},
                               size_hint=(.8,.75))
        self.playbutton = MDIconButton(pos_hint={'center_x':0.4, 'center_y':0.05},
                               icon="play.png",
                               on_press = self.playaudio)
        
        self.stopbutton = MDIconButton(pos_hint={'center_x':0.55, 'center_y':0.05},
                               icon="stop.png",
                               on_press = self.stopaudio, disabled=True)
        layout.add_widget(self.songlabel)
        layout.add_widget(self.albumimage)
        layout.add_widget(self.playbutton)
        layout.add_widget(self.stopbutton)        
        Clock.schedule_once(self.playaudio)
        
        return layout
    def playaudio(self,obj):
        self.playbutton.disabled = True
        self.stopbutton.disabled = False
        self.song_title = self.song_list[random.randrange(0, self.song_count)]
        print(self.song_title)
        self.songlabel.text = "===== Playing ~ "+self.song_title[2:-4] +" ====="
        self.sound = SoundLoader.load('{}/{}'.format(self.music_dir, self.song_title))
        self.albumimage.source = self.song_title[0]+".jpg"
        self.sound.play()
    def stopaudio(self,obj):
        self.playbutton.disabled = False
        self.stopbutton.disabled = True
        self.sound.stop()
    
if __name__ == '__main__':
    MyApp().run()
Shopping Basket