Python 3.10媒体播放器:AB循环与调速按钮失效及格式支持需求
问题解决:Kivy媒体播放器AB循环与速度调节失效及格式支持扩展
一、功能失效问题修复
1. 播放速度滑块失效修复
Kivy的VideoPlayer是容器组件,实际播放核心是内部的video属性,直接设置self.video.playback_rate不会生效,需访问内部视频对象:
修改set_speed方法:
def set_speed(self, instance, value): # 确保视频组件已初始化 if hasattr(self.video, 'video') and self.video.video: self.video.video.playback_rate = value # 更新速度显示文本 self.speed_label.text = f'Speed: {round(value, 2)}x'
2. AB循环功能失效修复
原逻辑判断条件有误,且未校验A点时间早于B点,导致循环异常。调整set_a、set_b和on_update方法:
修改set_a和set_b方法:
def set_a(self, instance): if self.video.source and self.video.position >= 0: self.a_time = self.video.position print(f'Set A at {round(self.a_time, 2)}s') def set_b(self, instance): if self.video.source and self.video.position >= 0: self.b_time = self.video.position print(f'Set B at {round(self.b_time, 2)}s')
修改on_update方法:
def on_update(self, dt): if self.loop_enabled and self.a_time is not None and self.b_time is not None: # 确保A点早于B点,否则关闭循环并提示 if self.a_time >= self.b_time: print('A time must be earlier than B time!') self.loop_enabled = False return # 播放到B点后跳回A点 if self.video.position >= self.b_time: self.video.position = self.a_time
二、扩展视频格式支持
Kivy视频播放依赖FFmpeg,默认支持格式有限,安装官方FFmpeg依赖包即可支持MP4、MKV、AVI、MOV等主流格式:
执行命令安装:
pip install kivy-deps.ffmpeg
完整修改后的代码
import kivy from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button from kivy.uix.label import Label from kivy.uix.slider import Slider from kivy.uix.filechooser import FileChooserListView from kivy.uix.popup import Popup from kivy.uix.videoplayer import VideoPlayer kivy.require('2.0.0') class MediaPlayer(BoxLayout): def __init__(self, **kwargs): super().__init__(**kwargs) self.orientation = 'vertical' self.video = VideoPlayer(source='', state='stop') self.add_widget(self.video) self.controls = BoxLayout(size_hint_y=None, height='50dp') self.add_widget(self.controls) self.play_button = Button(text='Play/Pause') self.play_button.bind(on_press=self.toggle_play) self.controls.add_widget(self.play_button) self.a_button = Button(text='Set A') self.a_button.bind(on_press=self.set_a) self.controls.add_widget(self.a_button) self.b_button = Button(text='Set B') self.b_button.bind(on_press=self.set_b) self.controls.add_widget(self.b_button) self.loop_button = Button(text='Toggle Loop') self.loop_button.bind(on_press=self.toggle_loop) self.controls.add_widget(self.loop_button) self.speed_label = Label(text='Speed: 1.0x') self.controls.add_widget(self.speed_label) self.speed_slider = Slider(min=0.4, max=1.2, value=1.0) self.speed_slider.bind(value=self.set_speed) self.controls.add_widget(self.speed_slider) self.browse_button = Button(text='Browse') self.browse_button.bind(on_press=self.browse_file) self.controls.add_widget(self.browse_button) self.a_time = None self.b_time = None self.loop_enabled = False def toggle_play(self, instance): if self.video.state == 'play': self.video.state = 'pause' else: self.video.state = 'play' def set_a(self, instance): if self.video.source and self.video.position >= 0: self.a_time = self.video.position print(f'Set A at {round(self.a_time, 2)}s') def set_b(self, instance): if self.video.source and self.video.position >= 0: self.b_time = self.video.position print(f'Set B at {round(self.b_time, 2)}s') def toggle_loop(self, instance): self.loop_enabled = not self.loop_enabled print(f'Loop enabled: {self.loop_enabled}') def set_speed(self, instance, value): if hasattr(self.video, 'video') and self.video.video: self.video.video.playback_rate = value self.speed_label.text = f'Speed: {round(value, 2)}x' def browse_file(self, instance): content = BoxLayout(orientation='vertical') filechooser = FileChooserListView() content.add_widget(filechooser) select_button = Button(text='Select') content.add_widget(select_button) popup = Popup(title='Select a video file', content=content, size_hint=(0.9, 0.9)) def on_file_select(instance): if filechooser.selection: self.video.source = filechooser.selection[0] self.video.state = 'play' popup.dismiss() select_button.bind(on_press=on_file_select) popup.open() def on_update(self, dt): if self.loop_enabled and self.a_time is not None and self.b_time is not None: if self.a_time >= self.b_time: print('A time must be earlier than B time!') self.loop_enabled = False return if self.video.position >= self.b_time: self.video.position = self.a_time class MediaPlayerApp(App): def build(self): player = MediaPlayer() kivy.clock.Clock.schedule_interval(player.on_update, 1 / 30.0) return player if __name__ == '__main__': MediaPlayerApp().run()
内容的提问来源于stack exchange,提问作者newGIS
相关产品推荐
相关产品推荐

