python - 绑定滑块以适应音频位置而不会导致性能下降
问题描述
我有一个用python 和 kivy制作的 mp3 播放器应用程序,我想创建一个滑块,使其值适应歌曲位置。
我已经有了一些解决方案,但所有解决方案的问题在于它们使音频播放变得不愉快和故障。
目前我使用Clock每隔一秒运行一次功能,但正如我之前提到的,它使音频非常滞后且无法收听。
我的代码:
import os
os.environ["KIVY_AUDIO"] = "ffpyplayer"
from kivy.lang import Builder
from kivy.core.audio import SoundLoader
from kivy.app import App
class MainApp(App):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.path = "C:/Users/Family/Downloads/10_poker_face.mp3"
self.song = SoundLoader.load(self.path)
self.kv = Builder.load_string('''
#:kivy 2.0.0
#:import Clock kivy.clock.Clock
BoxLayout:
orientation: "vertical"
Label:
text: app.path
font_size: 32
Slider:
id: song_slider
min: 0
max: app.song.length
on_value: app.song.seek(self.value)
Button:
text: "Play"
font_size: 32
on_release:
Clock.schedule_interval(app.update_slider, 1)
app.song.play()
''')
def build(self):
return self.kv
def update_slider(self, dt):
self.kv.ids.song_slider.value = self.song.get_pos()
if __name__ == "__main__":
MainApp().run()
我什至尝试了一个线程替代方案,但这比时钟方法更糟糕:
import os
os.environ["KIVY_AUDIO"] = "ffpyplayer"
from threading import Thread
from time import time
from kivy.lang import Builder
from kivy.core.audio import SoundLoader
from kivy.app import App
class MainApp(App):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.path = "C:/Users/Family/Downloads/10_poker_face.mp3"
self.song = SoundLoader.load(self.path)
self.start_time = None
self.kv = Builder.load_string('''
#:kivy 2.0.0
BoxLayout:
orientation: "vertical"
Label:
text: app.path
font_size: 32
Slider:
id: song_slider
min: 0
max: app.song.length
on_value: app.song.seek(self.value)
Button:
text: "Play"
font_size: 32
on_release: app.start_song()
''')
def build(self):
return self.kv
def start_song(self):
self.start_time = time()
Thread(target=self.update_slider, daemon=True).start()
self.song.play()
def update_slider(self):
while True:
now = time()
if now - self.start_time >= 1:
self.start_time = now
self.kv.ids.song_slider.value = self.song.get_pos()
if __name__ == "__main__":
MainApp().run()
如何绑定滑块以适应歌曲的音频位置而不会导致性能问题?
解决方案
我可以提供这样的解决方案,它独立于KIVY_AUDIO
论点起作用。
import os
os.environ["KIVY_AUDIO"] = "ffpyplayer"
from kivy.lang import Builder
from kivy.core.audio import SoundLoader
from kivy.clock import Clock
from kivy.app import App
KV = '''
BoxLayout:
padding: 10
orientation: 'vertical'
Label:
text: app.path
halign: 'center'
font_size: sp(32)
text_size: self.width, None
size_hint: 1, None
height: self.texture_size[1]
Slider:
id: song_slider
min: 0
max: 100
Button:
id: btn
text: 'Play'
font_size: sp(32)
on_release: app.start_song()
'''
class MainApp(App):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.path = 'music.mp3'
self.song = SoundLoader.load(self.path)
self.clock_event = None
self.kv = Builder.load_string(KV)
def build(self):
return self.kv
def start_song(self):
if self.song.state == 'stop':
self.song.play()
self.clock_event = Clock.schedule_interval(self.update_slider, self.song.length / 60)
self.kv.ids.btn.text = 'Stop'
else:
self.clock_event.cancel()
self.song.stop()
self.kv.ids.song_slider.value = 0
self.kv.ids.btn.text = 'Play'
def update_slider(self, *args):
if self.kv.ids.song_slider.value < 100:
self.kv.ids.song_slider.value += 1
if __name__ == '__main__':
MainApp().run()
推荐阅读
- c++ - 为什么允许 std::unordered_map::rehash() 使迭代器无效?
- mongodb - 从 localhost 到 cosmosDb 的 Mongorestore 失败并显示“通过指定“retrywrites=false”禁用可重试写入
- python - python webdriver获取每个子文本
- python - 我如何在 django 上编辑其他用户的个人资料
- r - 使用 dplyr rename(across(
- r - 使用 dplyr 计算数据框中的梯度
- hadoop - 如何在 MR 框架(HADOOP)中对只有数字的文件进行排序
- php - 如何使用 Stripe 和 PHP 为未来的付款创建表单?
- docker-compose - 我正在尝试在 Dockerfile 上运行 docker-compose up -d
- verilog - vivado仿真报错:达到迭代限制10000