I have been developing an app using python and kivymd
This is a simple music player app which finds all the music in the phone and show it as a list
And when we click on the song name it will play the song But the problem is that the songs overlaps and then it keep on overlapping
What I want is that when we click on any other song the previous one stops and the clicked one starts to play
My previous code in which there is no stop function-:
from kivy.lang import Builder
from kivymd.uix.list import OneLineListItem
from kivymd.app import MDApp
from kivy.core.audio import SoundLoader
import os
helper_string = """
Screen:
BoxLayout:
orientation: "vertical"
ScrollView:
MDList:
id: scroll
"""
class MainApp(MDApp):
def build(self):
screen = Builder.load_string(helper_string)
return screen
def on_start(self):
for root, dirs, files in os.walk('C:/'):
for file in files:
if file.endswith('.mp3'):
required_file = file
the_location = os.path.abspath(required_file)
self.root.ids.scroll.add_widget(OneLineListItem(text=required_file, on_release=self.play_song))
# print(required_file)
def play_song(self, onelinelistitem):
# print('play:', onelinelistitem.text)
the_song_path = os.path.abspath(onelinelistitem.text)
sound = SoundLoader.load(the_song_path)
if sound:
sound.play()
print(the_song_path)
MainApp().run()
My new code in which I tried a simple fix using the lists and it also did not worked -:
from kivy.lang import Builder
from kivymd.uix.list import OneLineListItem
from kivymd.app import MDApp
from kivy.core.audio import SoundLoader
import os
helper_string = """
Screen:
BoxLayout:
orientation: "vertical"
ScrollView:
MDList:
id: scroll
"""
class MainApp(MDApp):
def build(self):
screen = Builder.load_string(helper_string)
return screen
def on_start(self):
for root, dirs, files in os.walk('C:/'):
for file in files:
if file.endswith('.mp3'):
required_file = file
the_location = os.path.abspath(required_file)
self.root.ids.scroll.add_widget(OneLineListItem(text=required_file, on_release=self.play_song))
# print(required_file)
def play_song(self, onelinelistitem):
SongList = []
# print('play:', onelinelistitem.text)
the_song_path = onelinelistitem.secondary_text
SongList.append(the_song_path)
if len(SongList) == 1:
sound = SoundLoader.load(SongList[0])
if sound:
sound.play()
print(the_song_path)
if len(SongList) > 1:
SoundLoader.load(SongList[0]).stop()
sound = SoundLoader.load(SongList[1])
if sound:
sound.play()
print(the_song_path)
MainApp().run()
😅Yes I know that it was a very bad fix
So please can anyone help me out with this issue
Thank you Very Much in advance
Your SongList
is a local variable in method play_song()
and is set to []
every time play_song()
is called. So the condition:
if len(SongList) > 1:
will never be true. An easy way to handle this is to define an instance variable that holds the currently playing sound, lets call it it self.sound
. Initialize it in the build()
method:
def build(self):
self.sound = None
screen = Builder.load_string(helper_string)
return screen
And use it in the play_song()
method:
def play_song(self, onelinelistitem):
the_song_path = onelinelistitem.secondary_text
if self.sound:
self.sound.stop()
self.sound = SoundLoader.load(the_song_path)
if self.sound:
self.sound.play()
print(the_song_path)