音频位置在 kivy 中没有改变

Audio position does not change in kivy

我正在使用 kivy.core.audio.Sounloader 在 kivy 中创建一个音乐播放器,我遇到了一个问题。当用户点击开始按钮时,我希望他们能够滑动滑块并更改歌曲的位置,但是,该功能不起作用。它也不会引发任何错误,只是不起作用。我也尝试用 music_obj.get_pos() 获取歌曲的位置,但它总是返回 0。我做了几次搜索,其他人似乎也有这个问题。我该如何解决这个问题?我的代码:

from kivy.app import App
from kivy.core.audio import SoundLoader
from kivy.uix.widget import Widget
from kivy.lang import Builder


Builder.load_string('''
<MyLayout>:
    BoxLayout:
        orientation: "vertical"
        size: root.width, root.height

        Label:
            id: song_title
            text: "Song title!"
            text_size: self.size
            font_size: 32
            valign: "middle"
            halign: "center"

        Slider:
            id: slider
            min: 0
            max: 1
            step: 1
            value: 0
            on_value: root.change_pos(self.value)

        Button:
            text: "Animate!"
            font_size: 32
            on_release: root.start_song()''')


class MyLayout(Widget):
    music_file = "pitbull-feat-kesha-pitbull-feat-keshatimber.mp3"
    music_obj = None

    def start_song(self):
        self.music_obj = SoundLoader.load(self.music_file)
        if self.music_obj:
            print(self.music_obj.source)
            print(self.music_obj.length)
            self.ids.song_title.text = self.music_obj.source
            self.ids.slider.max = self.music_obj.length
            self.music_obj.play()

    def change_pos(self, value):
        if self.music_obj is not None:
            self.music_obj.seek(value)


class Awesome(App):
    def build(self):
        self.title = "Hello!"
        return MyLayout()


if __name__ == "__main__":
    Awesome().run()

我试过 运行 您的代码,搜索栏在播放时工作正常。音乐停止后,搜索栏将停止工作。如果是你遇到的问题,建议你先播放一遍音频再求。

    def change_pos(self, value):
        if self.music_obj is not None:
            self.music_obj.play()
            self.music_obj.seek(value)

顺便用了Kivy 2.0.0和ffpyplayer 4.3.2

我正在使用 kivy 2.0.0。在我安装 ffpyplayer-4.3.2 之前,问题的代码无法运行。现在,它起作用了!

这是初始问题中提供的代码的改进版本。现在,随着 mp3 文件的播放,滑块位置会更新。这是在单独的线程中异步完成的。

from kivy.app import App
from kivy.core.audio import SoundLoader
from kivy.uix.widget import Widget
from kivy.lang import Builder

import os, time, threading

SLIDER_UPDATE_FRENQUENCY = 1

if os.name == 'posix':
    AUDIO_DIR = '/storage/emulated/0/Download/Audiobooks/Various/'
else:
    AUDIO_DIR = 'D:\Users\Jean-Pierre\Downloads\Audiobooks\Various\'

Builder.load_string('''
<MyLayout>:
    BoxLayout:
        orientation: "vertical"
        size: root.width, root.height

        Label:
            id: song_title
            text: "Song title!"
            text_size: self.size
            font_size: 32
            valign: "middle"
            halign: "center"

        Slider:
            id: slider
            min: 0
            max: 1
            step: 1
            value: 0
            on_value: root.change_pos(self.value)

        Button:
            text: "Animate!"
            font_size: 32
            on_release: root.start_song()''')


class AsynchSliderUpdater:
    def __init__(self, music_obj, slider):
        self.music_obj = music_obj
        self.slider = slider
    
    def updateSlider(self):
        music_length = self.music_obj.length
        stop = False
        
        while not stop:
            time.sleep(SLIDER_UPDATE_FRENQUENCY)
            music_pos = self.music_obj.get_pos()
            if music_pos < music_length:
                self.slider.value = music_pos
            else:
                stop = True

class MyLayout(Widget):
    """
    WARNING

    Only works if ffpyplayer is installed !
    (C:\Program Files\Python39> ./python -m pip install ffpyplayer
    Successfully installed ffpyplayer-4.3.2)
    
    NOT WORKING ON ANDROID SINCE INSTALLING FFPYPLAYER FAILS !
    """
    
    music_file = AUDIO_DIR + "Un résumé audio de ce qu'enseigne ' Le Cours en Miracles '.mp3"
    music_obj = None

    def start_song(self):
        self.music_obj = SoundLoader.load(self.music_file)
        if self.music_obj:
            print(self.music_obj.source)
            print(self.music_obj.length)
            self.ids.song_title.text = self.music_obj.source
            self.ids.slider.max = self.music_obj.length
            
            self.sliderAsynchUpdater = AsynchSliderUpdater(self.music_obj, self.ids.slider)
            t = threading.Thread(target=self.sliderAsynchUpdater.updateSlider, args=())
            t.daemon = True
            t.start()

            self.music_obj.play()

    def change_pos(self, value):
        if self.music_obj is not None:
            # test required to avoid mp3 playing perturbation
            if abs(self.music_obj.get_pos() - value) > SLIDER_UPDATE_FRENQUENCY:
                print(value)
                self.music_obj.seek(value)


class Awesome(App):
    def build(self):
        self.title = "Hello!"
        return MyLayout()


if __name__ == "__main__":
    Awesome().run()