diff --git a/kivyblocks/baseWidget.py b/kivyblocks/baseWidget.py index 9a4fece..112afbf 100755 --- a/kivyblocks/baseWidget.py +++ b/kivyblocks/baseWidget.py @@ -127,6 +127,14 @@ def ScatterBox(WidgetCSS, WidgetReady, ScatterLayout): def __init__(self, **kw): super().__init__(**kw) +class FBox(WidgetCSS, WidgetReady, FloatLayout): + def __init__(self, **kw): + try: + super(FBox, self).__init__(**kw) + except Exception as e: + print('Box(',kw,') Error') + raise e + class Box(WidgetCSS, WidgetReady, BoxLayout): def __init__(self, **kw): try: @@ -293,7 +301,8 @@ class Modal(VBox): self.dismiss() return True - return super().on_touch_down(touch) + super().on_touch_down(touch) + return True def on_target(self, o, target): w = Window diff --git a/kivyblocks/blocks.py b/kivyblocks/blocks.py index e813659..533d24b 100755 --- a/kivyblocks/blocks.py +++ b/kivyblocks/blocks.py @@ -455,6 +455,7 @@ x = ClassX{klass_cnt}() return Blocks.findWidget(desc.get('target'),from_widget=widget) def blocksAction(self, widget:Widget, desc, *args): + print('blocksACtion(),', desc) target = self.get_target(widget, desc) add_mode = desc.get('mode','replace') opts = desc.get('options').copy() diff --git a/kivyblocks/message.py b/kivyblocks/message.py index dd3396c..1656171 100755 --- a/kivyblocks/message.py +++ b/kivyblocks/message.py @@ -74,9 +74,11 @@ class Message(TimedModal): i18n=True, wrap=True, halign='left', + valign='center', size_hint=(1,1), font_size=CSize(1))) b.add_widget(b2) + # b.add_widget(VBox()) self.add_widget(b) class Error(Message): diff --git a/kivyblocks/register.py b/kivyblocks/register.py index 5c711e4..0f5f6f1 100755 --- a/kivyblocks/register.py +++ b/kivyblocks/register.py @@ -132,6 +132,7 @@ r('Title6',Title6) r('Modal',Modal) r('TimedModal',TimedModal) r('HBox',HBox) +r('FBox',FBox) r('VBox',VBox) r('SwipeBox',SwipeBox) r('ToggleItems',ToggleItems) diff --git a/kivyblocks/videobehavior.py b/kivyblocks/videobehavior.py index 8358384..6d59004 100755 --- a/kivyblocks/videobehavior.py +++ b/kivyblocks/videobehavior.py @@ -77,6 +77,7 @@ class VideoBehavior(object): return img def video_blocked(self, *args): + print('videobehavior.py:video_blocked() called') self._play_stop() self.on_v_src(None, None) @@ -133,6 +134,20 @@ class VideoBehavior(object): self._player.set_volume(self.volume) + def stop_timed_job(self): + if self._update_task: + self._update_task.cancel() + self._update_task = None + if self.vh_task: + self.vh_task.cancel() + self.vh_task = None + if self.start_task: + self.start_task.cancel() + self.start_task = None + if self.block_task: + self.block_task.cancel() + self.block_task = None + def on_status(self, *args): print('on_status called, ', self.status) if self._player is None: @@ -144,12 +159,14 @@ class VideoBehavior(object): Window.allow_screensaver = False self._player.set_pause(False) self.video_handle() - elif self.status == 'pause': - self._player.set_pause(True) - elif self.status == 'stop': - self._play_stop() else: - pass + self.stop_timed_job() + if self.status == 'pause': + self._player.set_pause(True) + elif self.status == 'stop': + self._play_stop() + else: + pass def stop_when_remove(self, *args): if self.parent: @@ -211,6 +228,7 @@ class VideoBehavior(object): self._player.request_channel('audio', action='cycle') def on_v_src(self, o, src): + print('videobehavior.py:on_v_src() called ...') self.status = 'stop' ff_opts = { 'pause':False @@ -268,18 +286,6 @@ class VideoBehavior(object): if self._player: self._player.close_player() self._player = None - if self._update_task: - self._update_task.cancel() - self._update_task = None - if self.vh_task: - self.vh_task.cancel() - self.vh_task = None - if self.start_task: - self.start_task.cancel() - self.start_task = None - if self.block_task: - self.block_task.cancel() - self.block_task = None self.next_frame = None self.duration = -1 self.position = 0 @@ -289,6 +295,7 @@ class VideoBehavior(object): if self.change_size_task: self.change_size_task.cancel() self.change_size_task = Clock.schedule_once(self._set_video_size, 0.1) + def _set_video_size(self, *args): if self._player is None: return @@ -411,6 +418,7 @@ class VideoBehavior(object): return frame, val = self._player.get_frame() if val == 'eof': + print('video_handler(),val="eof"') if self.repeat: self.seek(0) self.play() @@ -420,6 +428,7 @@ class VideoBehavior(object): self.last_val = None return if val == 'pause': + print('video_handle(), val="pause"') self.status = 'pause' self.last_val = None return @@ -442,11 +451,16 @@ class VideoBehavior(object): self._update_task = Clock.schedule_once(self.do_update, 0) def do_update(self, *args): + if self.status != 'play': + return + self.stop_timed_job() + """ if self.start_task: self.start_task.cancel() self.start_task = None if self.block_task: self.block_task.cancel() + """ if not self.playing: self.playing = True self._get_video_info() diff --git a/kivyblocks/videoplayer.py b/kivyblocks/videoplayer.py new file mode 100644 index 0000000..0242a21 --- /dev/null +++ b/kivyblocks/videoplayer.py @@ -0,0 +1,124 @@ + +from kivy.base import EventDispatcher +from kivy.properties import DictProperty, BooleanProperty +from kivyblocks.toolbar import Toolbar +from kivyblocks.baseWidget import FBox +from kivyblocks.ffpyplayer_video import FFVideo + +class VideoCtrls(FBox): + toolbar = DictProperty(None) + video = DictProperty({}) + show_toolbar_state = BooleanProperty(False) + def __init__(self, **kw): + super().__init__(**kw) + self.v_w = FFVideo(**self.video) + self.tb_w = None + self.add_widget(self.v_w) + if self.toolbar: + self.tb_w = Toolbar(**self.toolbar) + self.tb_w.bind(on_press = self.tool_press) + self.tb_w.center = self.center + self.add_widget(self.tb_w) + self.on_show_toolbar_state(w=None, v=None) + + self.actions = { + 'play':self.play_or_pause, + 'stop':self.play_stop, + 'mute':self.mute_or_voice, + 'forward':self.forward, + 'back':self.back, + 'switch_audio':self.switch_audio, + 'fullscreen':self.fullscreen, + 'next':self.play_next, + 'previous':self.play_previous, + 'voice_inc':self.voice_inc, + 'voice_dec':self.voice_dec + } + acts = self.actions.keys() + tools = self.toolbar['tools'] + for t in tools: + n = t['name'] + if n not in acts: + event_name = f'on_{n}' + setattr(self, event_name, self.default_action) + self.register_event_type(event_name) + kwargs = {event_name:self.default_action} + self.bind(**kwargs) + + self.v_w.bind(on_touch_down=self.on_press) + + def on_show_toolbar_state(self, w, v): + print('on_show_toolbar_state() called ...') + if self.tb_w is None: + return + if self.show_toolbar_state: + if not self.tb_w in self.children: + self.add_widget(self.tb_w) + else: + if self.tb_w in self.children: + self.remove_widget(self.tb_w) + + def play_next(self, w, v): + pass + + def play_previous(self, w, v): + pass + + def fullscreen(self, w, v): + self.fullscreen = not self.fullscreen + + def on_press(self, w, v): + print('on_press() called ...') + self.show_toolbar_state = not self.show_toolbar_state + + def tool_press(self, w, v): + eventname = f'on_{v["name"]}' + f = self.actions.get(v['name'], None) + if f: + return f(w, v) + self.dispatch(eventname,v) + + def default_action(self, w, v=None): + print('event fire', v) + + def play_or_pause(self, w, v): + if self.v_w.status == 'play': + self.v_w.pause() + else: + self.v_w.play() + + def play_stop(self, w, v): + print('VideoPlayer():play_stop() called ...') + self.v_w.status = 'stop' + + def forward(self, w, v): + pts = 0.03 * self.v_w.duration + self.position + if tps < self.v_w.duration: + self.v_w.seek(pts) + + def back(self, w, v): + pts = self.postion - 0.03 * self.v_w.duration + if tps >= 0: + self.v_w.seek(pts) + + def voice_inc(self, w, v): + if self.v_w.volume >= 1: + return + v = self.volume + 0.03 + if v < 1: + self.v_w.set_volume(v) + + def voice_dec(self, w, v): + if self.v_w.volume <= 0: + return + v - self.volume - 0.03 + if v > 0: + self.v_w.set_volume(v) + + def switch_audio(self, w, v=None): + self.v_w.switch_aduio() + + def mute_or_voice(self, w, v): + self.v_w.mute() + +