'Showing audio progress by progress bar in KivyMD

I'm making a meditation app with kivymd, and I'm trying to figure out how to connect a audio file to a progress bar. There are not too many videos on how to do it, so any help would be greatly appreciated, thanks.

from kivy.lang import Builder 

from kivy.uix.screenmanager import ScreenManager

from kivymd.app import MDApp

from kivy.core.window import Window

Window.size = (400, 800)


class SecondWindow(Screen):
    def play_sound(self):
        sound = SoundLoader.load("audio2/mp3.mp3")
        if sound:
            sound.play()

sm = ScreenManager()
sm.add_widget(FirstWindow(name="First"))
sm.add_widget(SecondWindow(name="Second"))


class MainApp(MDApp):
    def build(self):
        self.theme_cls.theme_style = "Dark"
        self.theme_cls.primary_palette = "BlueGray"
        return Builder.load_file("thelab.kv")


MainApp().run()

kivy file -

<SecondWindow>:

    MDIconButton:
        id: my_sound
        icon: "play"
        user_font_size: 150
        pos: 100, 100
        on_press:
            root.play_sound()

    MDProgressBar:
        id: progress_bar
        size_hint: .8, .5
        pos: 90, 200
        min: 0
        max: 100


Solution 1:[1]

You have to handle it yourself. For that you can use Clock.schedule_interval to update the MDProgressBar.value.

  1. First create prop. in your SecondWindow to bind to the prop. of MDProgressBar. Then schedule a callback say, update_progress to update the current progress. I also included the end case when the audio stops playing.
class SecondWindow(Screen):
    length = NumericProperty(0.0)
    progress = NumericProperty(0.0)

    def play_sound(self):
        sound = SoundLoader.load("audio2/mp3.mp3")
        if sound:
            self.length = sound.length
            sound.play()
            # Now schedule and start updating after every 1.0 sec.
            # Use 'Clock.create_trigger' for more control.
            self.prog_ev = Clock.schedule_interval(self.update_progress, 1.0)

    def update_progress(self, dt):
        if self.progress < self.length:
            self.progress += 1 # Update value.
        else: # End case.
            self.progress = 0 # Reset value.
            self.prog_ev.cancel() # Stop updating.
  1. Now the binding work in kvlang; here also I added required logic to change icon automatically.
<SecondWindow>:

    MDIconButton:
        id: my_sound
        icon: "pause" if root.progress else "play" 
        user_font_size: 150
        pos: 100, 100
        on_press:
            root.play_sound()

    MDProgressBar:
        id: progress_bar
        size_hint: .8, .5
        pos: 90, 200
        min: 0
        max: root.length
        value: root.progress

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ApuCoder