Exemple #1
0
    def get_video(self, path=None, is_random=False, paused=False, eos="stop", player=None,volume=0):
        path = "Videos/" + path
        if is_random:
            files = os.listdir(path)
            video_path = path + "/" + random.choice(files)
        else:
            print(path)
            video_path = path

        if player is not None:

            player.source=video_path
            player.state="stop" if paused else "play"
            player.eos=eos
            player.volume=volume

            return player

        s = {
            "source": video_path,
            "state": "stop" if paused else "play",
            "options": {"allow_stretch": True},
            "volume":volume,
            "size":self.screen.size,
            "eos":eos
        }

        player = Video(**s)
        player.bind(on_eos=self.on_video_end)
        return player
class VideoApp(App):
    def build(self):
        self.v = Video(source=sys.argv[1], state='play')
        self.v.bind(state=self.update_state)
        return self.v

    def update_state(self, *args):
        if self.v.state == 'stop':
            outlet.push_sample([2], time.time())
            exit()
class ScreenThree(Screen):
    def __init__(self, **kwargs):
        super(ScreenThree, self).__init__(**kwargs)
        self.video1 = Video(source=os.path.join(original_dir, "cityCC0.mpg"))
        float_layout = FloatLayout()
        self.label1 = Label(text="Just a place holder video",
                            opacity=0,
                            pos_hint={
                                "x": 0,
                                "bottom": 1
                            },
                            size_hint=[0.2, 0.1])
        # self.label2 = Label(text="loading video", opacity=0)
        # pos_hint = {"x": 0, "bottom": 1}, size_hint=[0.2, 0.1]
        self.add_widget(float_layout)
        float_layout.add_widget(self.label1, index=0)
        # float_layout.add_widget(self.label2)
        float_layout.add_widget(self.video1, index=1)
        self.video1.opacity = 0

    def video1_play(self, *dt):
        do_nothing(dt)
        self.video1.state = "play"
        # self.event1 = Clock.schedule_interval(partial(print, self.video1.loaded), 0.5)
        self.label1.opacity = 1
        self.video1.opacity = 1
        # self.label2.opacity = 0
        self.video1.volume = 1

    def on_video1_eos(self, *dt):
        do_nothing(dt, self)
        global audio_playback
        # print(self.video1.loaded)
        # Clock.schedule_once(self.video1_play)
        audio_playback = False
        change_screen_to('screen_two')
        # self.event1.cancel()

    def on_enter(self):
        self.video1.allow_stretch = True
        self.video1.state = "play"
        self.label1.opacity = 1
        self.video1.bind(eos=self.on_video1_eos)
        # self.label2.opacity = 1
        Clock.schedule_once(self._adjust_opacity, 1)
        # self.event1 = Clock.schedule_interval(self._check_loaded, 0.5)

    # def _check_loaded(self, *dt):
    #     if self.video1.loaded:
    #         self.video1.play = True
    #     do_nothing(dt, self.video1.loaded)

    def _adjust_opacity(self, *dt):
        do_nothing(dt)
        self.video1.opacity = 1
Exemple #4
0
 def build(self):
     if len(argv) > 1:
         filename = argv[1]
     else:
         curdir = dirname(__file__)
         filename = join(curdir, 'softboy.avi')
     video = Video(source=filename, play=True)
     scatter = Scatter()
     video.bind(texture_size=scatter.setter('size'))
     scatter.add_widget(video)
     return scatter
Exemple #5
0
 def build(self):
     if len(argv) > 1:
         filename = argv[1]
     else:
         curdir = dirname(__file__)
         filename = join(curdir, 'softboy.avi')
     video = Video(source=filename, play=True)
     scatter = Scatter()
     video.bind(texture_size=scatter.setter('size'))
     scatter.add_widget(video)
     return scatter
class VideoApp(App):
    def build(self):
        self.v = Video(source=sys.argv[1], state='play')
        self.v.bind(state=self.replay)
        return self.v

    def replay(self, *args):
        if self.v.state == 'stop':
            self.v.state = 'stop'
            time.sleep(1)
            exit()
 def setup_ui(self):
     layout = BoxLayout(orientation='vertical')
     # 请注意,由于 kivy 的官方实现 video 是有 bug 的
     # 所以官方文档也是错的,你要按照我给的这样的例子来写才行,这是我看源码扒出来的可行方法
     # 自动播放的写法
     v = Video(source='demo.mp4', state='play')
     self.video = v
     # on_loaded 函数会在视频载入成功后被调用
     v.bind(texture_size=self.on_loaded)
     # on_position_change 函数会在视频播放的时候不断调用,具体你播放一下就好了
     v.bind(position=self.on_position_change)
     layout.add_widget(v)
     return layout
Exemple #8
0
class VideoScreen(Screen):
    def __init__(self, **kwargs):
        super(VideoScreen, self).__init__(**kwargs)
        self.video = Video(source='test.mkv', state='stop')

        # Specific function that switches to EscapeRoom screen
        def switch(self, kwargs):
            sm.switch_to(PasswordScreen())

        # Bind a callback to eos event. Eos is when the video ends
        self.video.bind(eos=switch)
        self.add_widget(self.video)

    # When the screen enters view, play the video
    def on_enter(self, *args):
        self.video.state = 'play'
Exemple #9
0
 def test_video_unload(self):
     # fix issue https://github.com/kivy/kivy/issues/2275
     # AttributeError: 'NoneType' object has no attribute 'texture'
     from kivy.uix.video import Video
     from kivy.clock import Clock
     from kivy.base import runTouchApp, stopTouchApp
     from os.path import join, dirname
     here = dirname(__file__)
     source = join(here, "..", "..", "examples", "widgets", "softboy.avi")
     video = Video(source=source, play=True)
     Clock.schedule_once(lambda x: stopTouchApp(), 1)
     def unload_video(video, position):
         if position > 0.01:
             video.unload()
             Clock.schedule_once(lambda x: stopTouchApp(), 0.1)
     video.bind(position=unload_video)
     runTouchApp(video)
Exemple #10
0
    def test_video_unload(self):
        # fix issue https://github.com/kivy/kivy/issues/2275
        # AttributeError: 'NoneType' object has no attribute 'texture'
        from kivy.uix.video import Video
        from kivy.clock import Clock
        from kivy.base import runTouchApp, stopTouchApp
        from os.path import join, dirname
        here = dirname(__file__)
        source = join(here, "..", "..", "examples", "widgets", "softboy.avi")
        video = Video(source=source, play=True)
        Clock.schedule_once(lambda x: stopTouchApp(), 1)

        def unload_video(video, position):
            if position > 0.01:
                video.unload()
                Clock.schedule_once(lambda x: stopTouchApp(), 0.1)

        video.bind(position=unload_video)
        runTouchApp(video)
Exemple #11
0
    def test_video_unload(self):
        # fix issue https://github.com/kivy/kivy/issues/2275
        # AttributeError: 'NoneType' object has no attribute 'texture'
        from kivy.uix.video import Video
        from kivy.clock import Clock
        from kivy.base import runTouchApp, stopTouchApp
        from kivy import kivy_examples_dir
        from os.path import join, dirname, abspath
        source = abspath(join(kivy_examples_dir, "widgets", "cityCC0.mpg"))
        video = Video(source=source, play=True)
        Clock.schedule_once(lambda x: stopTouchApp(), 1)

        def unload_video(video, position):
            if position > 0.01:
                video.unload()
                Clock.schedule_once(lambda x: stopTouchApp(), 0.1)

        video.bind(position=unload_video)
        runTouchApp(video)
Exemple #12
0
    def __init__(self, **kwargs):
        # 父类构造方法
        super().__init__(**kwargs)

        # 进度位置变化
        def on_position_change(instance, value):
            # 打印文本
            print('进度位置变化', value)

        # 持续时间变化
        def on_duration_change(instance, value):
            # 打印文本
            print('持续时间变化', value)

        # 视频
        video = Video(source='34.mp4', state='play')
        # 视频信号与槽
        video.bind(position=on_position_change, duration=on_duration_change)

        # 加组件(视频)
        self.add_widget(video)
Exemple #13
0
class VideoPlayer(GridLayout):
    '''VideoPlayer class. See module documentation for more information.
    '''

    source = StringProperty('')
    '''Source of the video to read.

    :attr:`source` is a :class:`~kivy.properties.StringProperty` and
    defaults to ''.

    .. versionchanged:: 1.4.0
    '''

    thumbnail = StringProperty('')
    '''Thumbnail of the video to show. If None, VideoPlayer will try to find
    the thumbnail from the :attr:`source` + '.png'.

    :attr:`thumbnail` a :class:`~kivy.properties.StringProperty` and defaults
    to ''.

    .. versionchanged:: 1.4.0
    '''

    duration = NumericProperty(-1)
    '''Duration of the video. The duration defaults to -1 and is set to the
    real duration when the video is loaded.

    :attr:`duration` is a :class:`~kivy.properties.NumericProperty` and
    defaults to -1.
    '''

    position = NumericProperty(0)
    '''Position of the video between 0 and :attr:`duration`. The position
    defaults to -1 and is set to the real position when the video is loaded.

    :attr:`position` is a :class:`~kivy.properties.NumericProperty` and
    defaults to -1.
    '''

    volume = NumericProperty(1.0)
    '''Volume of the video in the range 0-1. 1 means full volume and 0 means
    mute.

    :attr:`volume` is a :class:`~kivy.properties.NumericProperty` and defaults
    to 1.
    '''

    state = OptionProperty('stop', options=('play', 'pause', 'stop'))
    '''String, indicates whether to play, pause, or stop the video::

        # start playing the video at creation
        video = VideoPlayer(source='movie.mkv', state='play')

        # create the video, and start later
        video = VideoPlayer(source='movie.mkv')
        # and later
        video.state = 'play'

    :attr:`state` is an :class:`~kivy.properties.OptionProperty` and defaults
    to 'play'.
    '''

    play = BooleanProperty(False)
    '''
    .. deprecated:: 1.4.0
        Use :attr:`state` instead.

    Boolean, indicates whether the video is playing or not. You can start/stop
    the video by setting this property::

        # start playing the video at creation
        video = VideoPlayer(source='movie.mkv', play=True)

        # create the video, and start later
        video = VideoPlayer(source='movie.mkv')
        # and later
        video.play = True

    :attr:`play` is a :class:`~kivy.properties.BooleanProperty` and defaults
    to False.
    '''

    image_overlay_play = StringProperty(
        'atlas://data/images/defaulttheme/player-play-overlay')
    '''Image filename used to show a "play" overlay when the video has not yet
    started.

    :attr:`image_overlay_play` is a
    :class:`~kivy.properties.StringProperty` and
    defaults to 'atlas://data/images/defaulttheme/player-play-overlay'.

    '''

    image_loading = StringProperty('data/images/image-loading.gif')
    '''Image filename used when the video is loading.

    :attr:`image_loading` is a :class:`~kivy.properties.StringProperty` and
    defaults to 'data/images/image-loading.gif'.
    '''

    image_play = StringProperty(
        'atlas://data/images/defaulttheme/media-playback-start')
    '''Image filename used for the "Play" button.

    :attr:`image_play` is a :class:`~kivy.properties.StringProperty` and
    defaults to 'atlas://data/images/defaulttheme/media-playback-start'.
    '''

    image_stop = StringProperty(
        'atlas://data/images/defaulttheme/media-playback-stop')
    '''Image filename used for the "Stop" button.

    :attr:`image_stop` is a :class:`~kivy.properties.StringProperty` and
    defaults to 'atlas://data/images/defaulttheme/media-playback-stop'.
    '''

    image_pause = StringProperty(
        'atlas://data/images/defaulttheme/media-playback-pause')
    '''Image filename used for the "Pause" button.

    :attr:`image_pause` is a :class:`~kivy.properties.StringProperty` and
    defaults to 'atlas://data/images/defaulttheme/media-playback-pause'.
    '''

    image_volumehigh = StringProperty(
        'atlas://data/images/defaulttheme/audio-volume-high')
    '''Image filename used for the volume icon when the volume is high.

    :attr:`image_volumehigh` is a :class:`~kivy.properties.StringProperty` and
    defaults to 'atlas://data/images/defaulttheme/audio-volume-high'.
    '''

    image_volumemedium = StringProperty(
        'atlas://data/images/defaulttheme/audio-volume-medium')
    '''Image filename used for the volume icon when the volume is medium.

    :attr:`image_volumemedium` is a :class:`~kivy.properties.StringProperty`
    and defaults to 'atlas://data/images/defaulttheme/audio-volume-medium'.
    '''

    image_volumelow = StringProperty(
        'atlas://data/images/defaulttheme/audio-volume-low')
    '''Image filename used for the volume icon when the volume is low.

    :attr:`image_volumelow` is a :class:`~kivy.properties.StringProperty`
    and defaults to 'atlas://data/images/defaulttheme/audio-volume-low'.
    '''

    image_volumemuted = StringProperty(
        'atlas://data/images/defaulttheme/audio-volume-muted')
    '''Image filename used for the volume icon when the volume is muted.

    :attr:`image_volumemuted` is a :class:`~kivy.properties.StringProperty`
    and defaults to 'atlas://data/images/defaulttheme/audio-volume-muted'.
    '''

    annotations = StringProperty('')
    '''If set, it will be used for reading annotations box.

    :attr:`annotations` is a :class:`~kivy.properties.StringProperty`
    and defaults to ''.
    '''

    fullscreen = BooleanProperty(False)
    '''Switch to fullscreen view. This should be used with care. When
    activated, the widget will remove itself from its parent, remove all
    children from the window and will add itself to it. When fullscreen is
    unset, all the previous children are restored and the widget is restored to
    its previous parent.

    .. warning::

        The re-add operation doesn't care about the index position of it's
        children within the parent.

    :attr:`fullscreen` is a :class:`~kivy.properties.BooleanProperty`
    and defaults to False.
    '''

    allow_fullscreen = BooleanProperty(True)
    '''By default, you can double-tap on the video to make it fullscreen. Set
    this property to False to prevent this behavior.

    :attr:`allow_fullscreen` is a :class:`~kivy.properties.BooleanProperty`
    defaults to True.
    '''

    options = DictProperty({})
    '''Optional parameters can be passed to a :class:`~kivy.uix.video.Video`
    instance with this property.

    :attr:`options` a :class:`~kivy.properties.DictProperty` and
    defaults to {}.
    '''

    # internals
    container = ObjectProperty(None)

    def __init__(self, **kwargs):
        self._video = None
        self._image = None
        self._annotations = ''
        self._annotations_labels = []
        super(VideoPlayer, self).__init__(**kwargs)
        self._load_thumbnail()
        self._load_annotations()

        if self.source:
            self._trigger_video_load()

    def _trigger_video_load(self, *largs):
        Clock.unschedule(self._do_video_load)
        Clock.schedule_once(self._do_video_load, -1)

    def on_source(self, instance, value):
        # we got a value, try to see if we have an image for it
        self._load_thumbnail()
        self._load_annotations()
        if self._video is not None:
            self._video.unload()
            self._video = None

    def _load_thumbnail(self):
        if not self.container:
            return
        self.container.clear_widgets()
        # get the source, remove extension, and use png
        thumbnail = self.thumbnail
        if not thumbnail:
            filename = self.source.rsplit('.', 1)
            thumbnail = filename[0] + '.png'
        self._image = VideoPlayerPreview(source=thumbnail, video=self)
        self.container.add_widget(self._image)

    def _load_annotations(self):
        if not self.container:
            return
        self._annotations_labels = []
        annotations = self.annotations
        if not annotations:
            filename = self.source.rsplit('.', 1)
            annotations = filename[0] + '.jsa'
        if exists(annotations):
            with open(annotations, 'r') as fd:
                self._annotations = load(fd)
        if self._annotations:
            for ann in self._annotations:
                self._annotations_labels.append(
                    VideoPlayerAnnotation(annotation=ann))

    def on_state(self, instance, value):
        if self._video is not None:
            self._video.state = value

    def _set_state(self, instance, value):
        self.state = value

    def _do_video_load(self, *largs):
        self._video = Video(source=self.source, state=self.state,
                            volume=self.volume, pos_hint={'x': 0, 'y': 0},
                            **self.options)
        self._video.bind(texture=self._play_started,
                         duration=self.setter('duration'),
                         position=self.setter('position'),
                         volume=self.setter('volume'),
                         state=self._set_state)

    def on_play(self, instance, value):
        value = 'play' if value else 'stop'
        return self.on_state(instance, value)

    def on_volume(self, instance, value):
        if not self._video:
            return
        self._video.volume = value

    def on_position(self, instance, value):
        labels = self._annotations_labels
        if not labels:
            return
        for label in labels:
            start = label.start
            duration = label.duration
            if start > value or (start + duration) < value:
                if label.parent:
                    label.parent.remove_widget(label)
            elif label.parent is None:
                self.container.add_widget(label)

    def seek(self, percent):
        '''Change the position to a percentage of the duration. Percentage must
        be a value between 0-1.

        .. warning::

            Calling seek() before video is loaded has no effect.
        '''
        if not self._video:
            return
        self._video.seek(percent)

    def _play_started(self, instance, value):
        self.container.clear_widgets()
        self.container.add_widget(self._video)

    def on_touch_down(self, touch):
        if not self.collide_point(*touch.pos):
            return False
        if touch.is_double_tap and self.allow_fullscreen:
            self.fullscreen = not self.fullscreen
            return True
        return super(VideoPlayer, self).on_touch_down(touch)

    def on_fullscreen(self, instance, value):
        window = self.get_parent_window()
        if not window:
            Logger.warning('VideoPlayer: Cannot switch to fullscreen, '
                           'window not found.')
            if value:
                self.fullscreen = False
            return
        if not self.parent:
            Logger.warning('VideoPlayer: Cannot switch to fullscreen, '
                           'no parent.')
            if value:
                self.fullscreen = False
            return

        if value:
            self._fullscreen_state = state = {
                'parent': self.parent,
                'pos': self.pos,
                'size': self.size,
                'pos_hint': self.pos_hint,
                'size_hint': self.size_hint,
                'window_children': window.children[:]}

            # remove all window children
            for child in window.children[:]:
                window.remove_widget(child)

            # put the video in fullscreen
            if state['parent'] is not window:
                state['parent'].remove_widget(self)
            window.add_widget(self)

            # ensure the video widget is in 0, 0, and the size will be
            # reajusted
            self.pos = (0, 0)
            self.size = (100, 100)
            self.pos_hint = {}
            self.size_hint = (1, 1)
        else:
            state = self._fullscreen_state
            window.remove_widget(self)
            for child in state['window_children']:
                window.add_widget(child)
            self.pos_hint = state['pos_hint']
            self.size_hint = state['size_hint']
            self.pos = state['pos']
            self.size = state['size']
            if state['parent'] is not window:
                state['parent'].add_widget(self)
class VideoPlayer(GridLayout):
    '''VideoPlayer class. See module documentation for more information.
    '''

    source = StringProperty('')
    '''Source of the video to read.

    :attr:`source` is a :class:`~kivy.properties.StringProperty` and
    defaults to ''.

    .. versionchanged:: 1.4.0
    '''

    thumbnail = StringProperty('')
    '''Thumbnail of the video to show. If None, VideoPlayer will try to find
    the thumbnail from the :attr:`source` + '.png'.

    :attr:`thumbnail` a :class:`~kivy.properties.StringProperty` and defaults
    to ''.

    .. versionchanged:: 1.4.0
    '''

    duration = NumericProperty(-1)
    '''Duration of the video. The duration defaults to -1 and is set to the
    real duration when the video is loaded.

    :attr:`duration` is a :class:`~kivy.properties.NumericProperty` and
    defaults to -1.
    '''

    position = NumericProperty(0)
    '''Position of the video between 0 and :attr:`duration`. The position
    defaults to -1 and is set to the real position when the video is loaded.

    :attr:`position` is a :class:`~kivy.properties.NumericProperty` and
    defaults to -1.
    '''

    volume = NumericProperty(1.0)
    '''Volume of the video in the range 0-1. 1 means full volume and 0 means
    mute.

    :attr:`volume` is a :class:`~kivy.properties.NumericProperty` and defaults
    to 1.
    '''

    state = OptionProperty('stop', options=('play', 'pause', 'stop'))
    '''String, indicates whether to play, pause, or stop the video::

        # start playing the video at creation
        video = VideoPlayer(source='movie.mkv', state='play')

        # create the video, and start later
        video = VideoPlayer(source='movie.mkv')
        # and later
        video.state = 'play'

    :attr:`state` is an :class:`~kivy.properties.OptionProperty` and defaults
    to 'stop'.
    '''

    play = BooleanProperty(False, deprecated=True)
    '''
    .. deprecated:: 1.4.0
        Use :attr:`state` instead.

    Boolean, indicates whether the video is playing or not. You can start/stop
    the video by setting this property::

        # start playing the video at creation
        video = VideoPlayer(source='movie.mkv', play=True)

        # create the video, and start later
        video = VideoPlayer(source='movie.mkv')
        # and later
        video.play = True

    :attr:`play` is a :class:`~kivy.properties.BooleanProperty` and defaults
    to False.
    '''

    image_overlay_play = StringProperty(
        'atlas://data/images/defaulttheme/player-play-overlay')
    '''Image filename used to show a "play" overlay when the video has not yet
    started.

    :attr:`image_overlay_play` is a
    :class:`~kivy.properties.StringProperty` and
    defaults to 'atlas://data/images/defaulttheme/player-play-overlay'.

    '''

    image_loading = StringProperty('data/images/image-loading.gif')
    '''Image filename used when the video is loading.

    :attr:`image_loading` is a :class:`~kivy.properties.StringProperty` and
    defaults to 'data/images/image-loading.gif'.
    '''

    image_play = StringProperty(
        'atlas://data/images/defaulttheme/media-playback-start')
    '''Image filename used for the "Play" button.

    :attr:`image_play` is a :class:`~kivy.properties.StringProperty` and
    defaults to 'atlas://data/images/defaulttheme/media-playback-start'.
    '''

    image_stop = StringProperty(
        'atlas://data/images/defaulttheme/media-playback-stop')
    '''Image filename used for the "Stop" button.

    :attr:`image_stop` is a :class:`~kivy.properties.StringProperty` and
    defaults to 'atlas://data/images/defaulttheme/media-playback-stop'.
    '''

    image_pause = StringProperty(
        'atlas://data/images/defaulttheme/media-playback-pause')
    '''Image filename used for the "Pause" button.

    :attr:`image_pause` is a :class:`~kivy.properties.StringProperty` and
    defaults to 'atlas://data/images/defaulttheme/media-playback-pause'.
    '''

    image_volumehigh = StringProperty(
        'atlas://data/images/defaulttheme/audio-volume-high')
    '''Image filename used for the volume icon when the volume is high.

    :attr:`image_volumehigh` is a :class:`~kivy.properties.StringProperty` and
    defaults to 'atlas://data/images/defaulttheme/audio-volume-high'.
    '''

    image_volumemedium = StringProperty(
        'atlas://data/images/defaulttheme/audio-volume-medium')
    '''Image filename used for the volume icon when the volume is medium.

    :attr:`image_volumemedium` is a :class:`~kivy.properties.StringProperty`
    and defaults to 'atlas://data/images/defaulttheme/audio-volume-medium'.
    '''

    image_volumelow = StringProperty(
        'atlas://data/images/defaulttheme/audio-volume-low')
    '''Image filename used for the volume icon when the volume is low.

    :attr:`image_volumelow` is a :class:`~kivy.properties.StringProperty`
    and defaults to 'atlas://data/images/defaulttheme/audio-volume-low'.
    '''

    image_volumemuted = StringProperty(
        'atlas://data/images/defaulttheme/audio-volume-muted')
    '''Image filename used for the volume icon when the volume is muted.

    :attr:`image_volumemuted` is a :class:`~kivy.properties.StringProperty`
    and defaults to 'atlas://data/images/defaulttheme/audio-volume-muted'.
    '''

    annotations = StringProperty('')
    '''If set, it will be used for reading annotations box.

    :attr:`annotations` is a :class:`~kivy.properties.StringProperty`
    and defaults to ''.
    '''

    fullscreen = BooleanProperty(False)
    '''Switch to fullscreen view. This should be used with care. When
    activated, the widget will remove itself from its parent, remove all
    children from the window and will add itself to it. When fullscreen is
    unset, all the previous children are restored and the widget is restored to
    its previous parent.

    .. warning::

        The re-add operation doesn't care about the index position of its
        children within the parent.

    :attr:`fullscreen` is a :class:`~kivy.properties.BooleanProperty`
    and defaults to False.
    '''

    allow_fullscreen = BooleanProperty(True)
    '''By default, you can double-tap on the video to make it fullscreen. Set
    this property to False to prevent this behavior.

    :attr:`allow_fullscreen` is a :class:`~kivy.properties.BooleanProperty`
    defaults to True.
    '''

    options = DictProperty({})
    '''Optional parameters can be passed to a :class:`~kivy.uix.video.Video`
    instance with this property.

    :attr:`options` a :class:`~kivy.properties.DictProperty` and
    defaults to {}.
    '''

    # internals
    container = ObjectProperty(None)

    _video_load_ev = None

    def __init__(self, **kwargs):
        self._video = None
        self._image = None
        self._annotations = ''
        self._annotations_labels = []
        super(VideoPlayer, self).__init__(**kwargs)
        self._load_thumbnail()
        self._load_annotations()

        if self.source:
            self._trigger_video_load()

    def _trigger_video_load(self, *largs):
        ev = self._video_load_ev
        if ev is None:
            ev = self._video_load_ev = Clock.schedule_once(
                self._do_video_load, -1)
        ev()

    def on_source(self, instance, value):
        # we got a value, try to see if we have an image for it
        self._load_thumbnail()
        self._load_annotations()
        if self._video is not None:
            self._video.unload()
            self._video = None
        if value:
            self._trigger_video_load()

    def on_image_overlay_play(self, instance, value):
        self._image.image_overlay_play = value

    def on_image_loading(self, instance, value):
        self._image.image_loading = value

    def _load_thumbnail(self):
        if not self.container:
            return
        self.container.clear_widgets()
        # get the source, remove extension, and use png
        thumbnail = self.thumbnail
        if not thumbnail:
            filename = self.source.rsplit('.', 1)
            thumbnail = filename[0] + '.png'
            if not exists(thumbnail):
                thumbnail = ''
        self._image = VideoPlayerPreview(source=thumbnail, video=self)
        self.container.add_widget(self._image)

    def _load_annotations(self):
        if not self.container:
            return
        self._annotations_labels = []
        annotations = self.annotations
        if not annotations:
            filename = self.source.rsplit('.', 1)
            annotations = filename[0] + '.jsa'
        if exists(annotations):
            with open(annotations, 'r') as fd:
                self._annotations = load(fd)
        if self._annotations:
            for ann in self._annotations:
                self._annotations_labels.append(
                    VideoPlayerAnnotation(annotation=ann))

    def on_state(self, instance, value):
        if self._video is not None:
            self._video.state = value

    def _set_state(self, instance, value):
        self.state = value

    def _do_video_load(self, *largs):
        self._video = Video(source=self.source,
                            state=self.state,
                            volume=self.volume,
                            pos_hint={
                                'x': 0,
                                'y': 0
                            },
                            **self.options)
        self._video.bind(texture=self._play_started,
                         duration=self.setter('duration'),
                         position=self.setter('position'),
                         volume=self.setter('volume'),
                         state=self._set_state)

    def on_play(self, instance, value):
        value = 'play' if value else 'stop'
        return self.on_state(instance, value)

    def on_volume(self, instance, value):
        if not self._video:
            return
        self._video.volume = value

    def on_position(self, instance, value):
        labels = self._annotations_labels
        if not labels:
            return
        for label in labels:
            start = label.start
            duration = label.duration
            if start > value or (start + duration) < value:
                if label.parent:
                    label.parent.remove_widget(label)
            elif label.parent is None:
                self.container.add_widget(label)

    def seek(self, percent, precise=True):
        '''Change the position to a percentage of duration.

        :Parameters:
            `percent`: float or int
                Position to seek, must be between 0-1.
            `precise`: bool, defaults to True
                Precise seeking is slower, but seeks to exact requested
                percent.

        .. warning::
            Calling seek() before the video is loaded has no effect.

        .. versionadded:: 1.2.0

        .. versionchanged:: 1.10.1
            The `precise` keyword argument has been added.
        '''
        if not self._video:
            return
        self._video.seek(percent, precise=precise)

    def _play_started(self, instance, value):
        self.container.clear_widgets()
        self.container.add_widget(self._video)

    def on_touch_down(self, touch):
        if not self.collide_point(*touch.pos):
            return False
        if touch.is_double_tap and self.allow_fullscreen:
            self.fullscreen = not self.fullscreen
            return True
        return super(VideoPlayer, self).on_touch_down(touch)

    def on_fullscreen(self, instance, value):
        window = self.get_parent_window()
        if not window:
            Logger.warning('VideoPlayer: Cannot switch to fullscreen, '
                           'window not found.')
            if value:
                self.fullscreen = False
            return
        if not self.parent:
            Logger.warning('VideoPlayer: Cannot switch to fullscreen, '
                           'no parent.')
            if value:
                self.fullscreen = False
            return

        if value:
            self._fullscreen_state = state = {
                'parent': self.parent,
                'pos': self.pos,
                'size': self.size,
                'pos_hint': self.pos_hint,
                'size_hint': self.size_hint,
                'window_children': window.children[:]
            }

            # remove all window children
            for child in window.children[:]:
                window.remove_widget(child)

            # put the video in fullscreen
            if state['parent'] is not window:
                state['parent'].remove_widget(self)
            window.add_widget(self)

            # ensure the video widget is in 0, 0, and the size will be
            # readjusted
            self.pos = (0, 0)
            self.size = (100, 100)
            self.pos_hint = {}
            self.size_hint = (1, 1)
        else:
            state = self._fullscreen_state
            window.remove_widget(self)
            for child in state['window_children']:
                window.add_widget(child)
            self.pos_hint = state['pos_hint']
            self.size_hint = state['size_hint']
            self.pos = state['pos']
            self.size = state['size']
            if state['parent'] is not window:
                state['parent'].add_widget(self)
Exemple #15
0
class SlideAndVideoShow(App):
    def __init__(self):
        super(SlideAndVideoShow, self).__init__()
        self.INSTAGRAM_ACCESS_TOKEN = "put your access token here"
        self.MOST_RECENT_PHOTOS_AND_VIDEOS_URL = "https://api.instagram.com/v1/users/self/media/recent/?access_token={}".format(
            self.INSTAGRAM_ACCESS_TOKEN)
        self.LOCAL_PHOTO_AND_VIDEO_DIRECTORY_PATH = "./instagram_photos_and_videos/"
        self.INI_FILE = "./instagram_slide_and_video_show.ini"
        self.title = "Instagram Slide and Video Show"
        self.HOUR_IN_SECONDS = 60 * 60
        # default configuration settings, used to create instagram_slide_and_video_show.ini if it doesn't already exist
        self.SECONDS_BEFORE_CHANGING_PHOTO = 15
        self.PHOTO_AND_VIDEO_DISPLAY_ORDER_DIRECTORY = "directory"
        self.PHOTO_AND_VIDEO_DISPLAY_ORDER_RANDOM = "random"
        self.PHOTO_AND_VIDEO_DISPLAY_ORDER_SORTED = "sorted"
        self.PHOTO_AND_VIDEO_DISPLAY_ORDER = self.PHOTO_AND_VIDEO_DISPLAY_ORDER_RANDOM
        self.SOUND_ON = 1
        self.SOUND_OFF = 0
        self.VIDEO_VOLUME_ON_OR_OFF = self.SOUND_ON
        # get stored configuration settings
        self.get_preferences_from_ini_file()
        # download any new photos or videos
        self.download_any_new_instagram_photos_or_videos()
        # get the filenames of all newly and/or previously-downloaded photos and videos
        self.photos_and_videos = self.get_photo_and_video_filenames()
        self.current_image_index = -1

    def get_preferences_from_ini_file(self):
        if os.path.isfile(self.INI_FILE):
            # if the .ini file exists, read in the configuration settings
            config = ConfigParser.RawConfigParser()
            config.read(self.INI_FILE)
            self.PHOTO_AND_VIDEO_DISPLAY_ORDER = config.get(
                "DisplaySettings", "photo_and_video_display_order")
            self.SECONDS_BEFORE_CHANGING_PHOTO = int(
                config.get("DisplaySettings", "seconds_before_changing_photo"))
            self.VIDEO_VOLUME_ON_OR_OFF = int(
                config.get("DisplaySettings", "video_volume_on_or_off"))
        else:
            # or if it doesn't exist, create it with the default settings
            self.create_ini_file()

    def create_ini_file(self):
        # create the ini file with the default settings the first time you run the program
        config = ConfigParser.RawConfigParser(allow_no_value=True)
        ini_file = open(self.INI_FILE, 'w')
        config.add_section("DisplaySettings")
        config.set(
            'DisplaySettings',
            '; Valid display order settings are directory, random, or sorted')
        config.set("DisplaySettings", "photo_and_video_display_order",
                   self.PHOTO_AND_VIDEO_DISPLAY_ORDER)
        config.set("DisplaySettings", "seconds_before_changing_photo",
                   self.SECONDS_BEFORE_CHANGING_PHOTO)
        config.set("DisplaySettings", "video_volume_on_or_off",
                   self.VIDEO_VOLUME_ON_OR_OFF)
        config.write(ini_file)
        ini_file.close()

    def download_any_new_instagram_photos_or_videos(self, value=None):
        # create the instagram_photos_and_videos subdirectory if it doesn't already exist
        if not os.path.isdir(self.LOCAL_PHOTO_AND_VIDEO_DIRECTORY_PATH):
            os.mkdir(self.LOCAL_PHOTO_AND_VIDEO_DIRECTORY_PATH)

        print(
            "Checking for any new Instagram photos or videos at {} ...".format(
                datetime.now()))
        internet_connection = True

        # get URLs, captions, etc. on the 20 most recent Instagram photos and videos
        try:
            json_data = json.loads(
                requests.get(self.MOST_RECENT_PHOTOS_AND_VIDEOS_URL).text)
        except:
            internet_connection = False
            print(
                "Unable to reach Instagram ... check your Internet connection. Showing stored photos and videos."
            )

        if internet_connection:
            new_photos_and_videos_downloaded = False

            # and check to see whether or not they have already been downloaded
            try:
                for photo_or_video in json_data["data"]:
                    if "videos" in photo_or_video:
                        photo_or_video_url = photo_or_video["videos"][
                            "standard_resolution"]["url"]
                    else:
                        photo_or_video_url = photo_or_video["images"][
                            "standard_resolution"]["url"]

                    photo_or_video_filename = photo_or_video_url[
                        photo_or_video_url.rindex("/") + 1:]
                    if not os.path.isfile(
                            self.LOCAL_PHOTO_AND_VIDEO_DIRECTORY_PATH +
                            photo_or_video_filename):
                        new_photos_and_videos_downloaded = True
                        if photo_or_video["caption"]:
                            print('Downloading and saving "{}"'.format(
                                photo_or_video["caption"]["text"].encode("utf8"
                                                                         )
                                if photo_or_video["caption"] else "..."))
                        else:
                            print('Downloading and saving "{}"'.format(
                                photo_or_video_filename))
                        photo_or_video_file = requests.get(
                            photo_or_video_url).content
                        with open(
                                self.LOCAL_PHOTO_AND_VIDEO_DIRECTORY_PATH +
                                photo_or_video_filename, 'wb') as handler:
                            handler.write(photo_or_video_file)
            except:
                print("Instagram error:", json_data)

            if new_photos_and_videos_downloaded:
                # update the list of filenames in the instagram_photos_and_videos subdirectory
                self.get_photo_and_video_filenames()
            else:
                print("No new photos or videos found.")

        # check for new photos and videos once an hour
        Clock.schedule_once(self.download_any_new_instagram_photos_or_videos,
                            self.HOUR_IN_SECONDS)

    def on_position_change(self, instance, value):
        # I'm doing it this way because eos wasn't always firing at the end of a video,
        # plus position isn't updated often enough to get all the way to the duration value.
        # If the program hangs at the end of a video you may need to increase the .3 value
        # (which means .3 of a second) a little more.
        if value > self.video_duration - .3:
            self.video.state = "stop"
            self.next_photo_or_video()

    def on_duration_change(self, instance, value):
        self.video_duration = value

    def on_texture_change(self, instance, value):
        # I'm doing it this way because I couldn't get loaded or on_load to actually fire,
        # but texture has reliably only been there only after a video finishes loading.
        if self.video.texture:
            self.video.opacity = 1
            self.photo.opacity = 0

    def build(self):
        # This line is for running under Windows but crashes things on the Raspberry Pi
        # Window.fullscreen = "auto"
        Window.show_cursor = False
        self.photo = Image()
        self.photo.allow_stretch = True
        # Without this line the Raspberry Pi starts blacking out photos after a few images.
        self.photo.nocache = True
        self.video = Video(allow_stretch=True,
                           options={
                               'eos': 'stop',
                               'autoplay': True
                           })
        self.video.bind(position=self.on_position_change,
                        duration=self.on_duration_change,
                        texture=self.on_texture_change)
        self.video.opacity = 0
        self.video.allow_stretch = True
        self.video.nocache = True
        self.video.volume = self.VIDEO_VOLUME_ON_OR_OFF
        self.screen = FloatLayout()
        self.screen.add_widget(self.photo)
        self.screen.add_widget(self.video)
        Clock.schedule_once(self.next_photo_or_video, 1)
        return self.screen

    def next_photo_or_video(self, value=None):
        if self.PHOTO_AND_VIDEO_DISPLAY_ORDER in [
                self.PHOTO_AND_VIDEO_DISPLAY_ORDER_DIRECTORY,
                self.PHOTO_AND_VIDEO_DISPLAY_ORDER_SORTED
        ]:
            self.current_image_index = (self.current_image_index + 1) % len(
                self.photos_and_videos)
        elif self.PHOTO_AND_VIDEO_DISPLAY_ORDER == self.PHOTO_AND_VIDEO_DISPLAY_ORDER_RANDOM:
            self.current_image_index = random.randint(
                0,
                len(self.photos_and_videos) - 1)

        next = self.LOCAL_PHOTO_AND_VIDEO_DIRECTORY_PATH + self.photos_and_videos[
            self.current_image_index]
        if next.endswith(".jpg"):
            self.photo.source = next
            self.video.opacity = 0
            self.photo.opacity = 1
            Clock.schedule_once(self.next_photo_or_video,
                                self.SECONDS_BEFORE_CHANGING_PHOTO)
        else:
            self.video.source = next
            self.video.state = "play"

    def get_photo_and_video_filenames(self):
        # get all the jpg and mp4 filenames in the instagram_photos_and_videos subdirectory
        photo_and_video_filenames = [
            file
            for file in os.listdir(self.LOCAL_PHOTO_AND_VIDEO_DIRECTORY_PATH)
            if file.endswith(".jpg") or file.endswith(".mp4")
        ]
        if self.PHOTO_AND_VIDEO_DISPLAY_ORDER == self.PHOTO_AND_VIDEO_DISPLAY_ORDER_SORTED:
            photo_and_video_filenames.sort()

        if not photo_and_video_filenames:
            # If there are no stored photos and/or videos, and the program was not able to download any,
            # you need to fix your Internet connection and/or Instagram Access Token.
            print("No stored photos or videos found. Make sure that you're")
            print("(1) connected to the Internet, and")
            print(
                "(2) that you've obtained an Instagram Access Token for the Instagram account you want to use, and entered it correctly as the self.INSTAGRAM_ACCESS_TOKEN value at the beginning of the code,"
            )
            print("and then try again.")
            exit()

        return photo_and_video_filenames
class MainScreen(Screen):
    foldername      = ""
    filename        = ""
    frame_per_sec   = ""

    sr              = None
    ss              = None
    video           = None
    logger          = None
    def __init__(self, **kwargs):
        self.name = 'MainScreen'
        super(MainScreen, self).__init__()
        from kivy.app import App
        app = App.get_running_app()
        self.ids.select_folder_label.text    = app.config.get("CustSettings", "defaultFolder")
        self.ids.frame_per_sec.text          = app.config.get("CustSettings", "framePerSec")
        self.ids.file_name.text              = app.config.get("CustSettings", "defaultFileName")

        MSToolbar = self.ids.MainScreen_Toolbar
        MSToolbar.left_action_items  = [["play"              ,self.play_video]]
        MSToolbar.right_action_items = [["file-search"       ,self.file_manager_open]
                                       ,["camera"            ,self.start_recording]
                                       ,["camera-party-mode" ,self.stop_recording ]]


        self.ss = SettingsClass()
        self.ids.screen_resolution.text = str(self.ss.get_screen_resolution())

    #def build(self):
    #    return Builder.load_string(mainscreen_kv)

    def file_manager_open(self, widget):
        raw_path = filechooser.choose_dir()
        if raw_path:
            self.ids.select_folder_label.text = raw_path[0]

    def start_recording(self,widget):
        self.foldername     = self.ids.select_folder_label.text
        self.filename       = self.ids.file_name.text
        self.frame_per_sec  = self.ids.frame_per_sec.text

        if self.foldername is None or self.foldername == "":
           Toast().toast("Please select a valid folder...")

        if self.filename is None or self.filename == "":
           Toast().toast("Please select a valid filename...")

        if self.frame_per_sec is None or self.frame_per_sec == "":
           Toast().toast("Please select a valid rate of frame per seconds...")

        try:
            if not self.sr:
               self.sr = RecordClass(foldername = self.foldername
                                    ,filename = self.filename
                                    ,frame_per_sec = self.frame_per_sec)

            self.sr.start_recording()
        except Exception as e:
            print("Error: ", __name__, " Exception ", e)
            applogger().logger.error('{ModuleName} - Error = {Exception}'.format(ModuleName=__name__, Exception = e))

    def stop_recording(self,widget):
        try:
            if self.sr:
               self.sr.stop_recording()
        except Exception as e:
            print("Error: ", __name__, " Exception ", e)
            applogger().logger.error('{ModuleName} - Error = {Exception}'.format(ModuleName=__name__, Exception = e))

    def play_video(self,widget):
        try:
            self.foldername     = self.ids.select_folder_label.text
            self.filename       = self.ids.file_name.text

            if self.foldername is None or self.foldername == "":
                Toast().toast("Please select a valid folder...")

            if self.filename is None or self.filename == "":
                Toast().toast("Please select a valid filename...")

            self.filename = os.path.join(self.foldername, self.filename)

            if self.video:
               self.ids.videoContainer.remove_widget(self.video)
               self.video = None

            self.video = Video()
            self.video.source = self.filename
            self.video.state = 'play'
            #self.video.options = {'eos':'stop'}
            self.video.bind(eos=self.VideoDone)
            self.video.allow_stretch = True
            self.ids.videoContainer.add_widget(self.video)
        except Exception as e:
            print("Error: ", __name__, " Exception ", e)
            applogger().logger.error('{ModuleName} - Error = {Exception}'.format(ModuleName=__name__, Exception = e))

    def VideoDone(self,value,value2):
        #print("video Done",value,value2)
        self.video.state = 'stop'
        self.video.unload()
        applogger().logger.info('{ModuleName} - {Message}'.format(ModuleName=__name__,Message="video completed successfully"))
Exemple #17
0
class VideoPlayer(GridLayout):
    '''VideoPlayer class, see module documentation for more information.
    '''

    source = StringProperty(None)
    '''Source of the video to read

    :data:`source` a :class:`~kivy.properties.StringProperty`, default to None.
    '''

    thumbnail = StringProperty(None)
    '''Thumbnail of the video to show. If None, it will try to search the
    thumbnail from the :data:`source` + .png.

    :data:`thumbnail` a :class:`~kivy.properties.StringProperty`, default to
    None.
    '''

    duration = NumericProperty(-1)
    '''Duration of the video. The duration is default to -1, and set to real
    duration when the video is loaded.

    :data:`duration` is a :class:`~kivy.properties.NumericProperty`, default to
    -1.
    '''

    position = NumericProperty(0)
    '''Position of the video between 0 and :data:`duration`. The position is
    default to -1, and set to real position when the video is loaded.

    :data:`position` is a :class:`~kivy.properties.NumericProperty`, default to
    -1.
    '''

    volume = NumericProperty(1.0)
    '''Volume of the video, in the range 0-1. 1 mean full volume, 0 mean mute.

    :data:`volume` is a :class:`~kivy.properties.NumericProperty`, default to
    1.
    '''

    play = BooleanProperty(False)
    '''Boolean, indicates if the video is playing.
    You can start/stop the video by setting this property. ::

        # start playing the video at creation
        video = VideoPlayer(source='movie.mkv', play=True)

        # create the video, and start later
        video = VideoPlayer(source='movie.mkv')
        # and later
        video.play = True

    :data:`play` is a :class:`~kivy.properties.BooleanProperty`, default to
    False.
    '''

    image_overlay_play = StringProperty(
        'atlas://data/images/defaulttheme/player-play-overlay')
    '''Image filename used to show an "play" overlay when the video is not yet
    started.

    :data:`image_overlay_play` a :class:`~kivy.properties.StringProperty`
    '''

    image_loading = StringProperty('data/images/image-loading.gif')
    '''Image filename used when the video is loading.

    :data:`image_loading` a :class:`~kivy.properties.StringProperty`
    '''

    image_play = StringProperty(
        'atlas://data/images/defaulttheme/media-playback-start')
    '''Image filename used for the "Play" button.

    :data:`image_loading` a :class:`~kivy.properties.StringProperty`
    '''

    image_pause = StringProperty(
        'atlas://data/images/defaulttheme/media-playback-pause')
    '''Image filename used for the "Pause" button.

    :data:`image_pause` a :class:`~kivy.properties.StringProperty`
    '''

    image_volumehigh = StringProperty(
        'atlas://data/images/defaulttheme/audio-volume-high')
    '''Image filename used for the volume icon, when the volume is high.

    :data:`image_volumehigh` a :class:`~kivy.properties.StringProperty`
    '''

    image_volumemedium = StringProperty(
        'atlas://data/images/defaulttheme/audio-volume-medium')
    '''Image filename used for the volume icon, when the volume is medium.

    :data:`image_volumemedium` a :class:`~kivy.properties.StringProperty`
    '''

    image_volumelow = StringProperty(
        'atlas://data/images/defaulttheme/audio-volume-low')
    '''Image filename used for the volume icon, when the volume is low.

    :data:`image_volumelow` a :class:`~kivy.properties.StringProperty`
    '''

    image_volumemuted = StringProperty(
        'atlas://data/images/defaulttheme/audio-volume-muted')
    '''Image filename used for the volume icon, when the volume is muted.

    :data:`image_volumemuted` a :class:`~kivy.properties.StringProperty`
    '''

    annotations = StringProperty(None)
    '''If set, it will be used for reading annotations box.
    '''

    fullscreen = BooleanProperty(False)
    '''Switch to a fullscreen view. This must be used with care. When activated,
    the widget will remove itself from its parent, remove all children from the
    window and add itself to it. When fullscreen is unset, all the previous
    children are restored, and the widget is readded to its previous parent.

    .. warning::

        The re-add operation doesn't care about it's children index position
        within the parent.

    :data:`fullscreen` a :class:`~kivy.properties.BooleanProperty`, default to
    False
    '''

    allow_fullscreen = BooleanProperty(True)
    '''By default, you can double-tap on the video to make it fullscreen. Set
    this property to False to prevent this behavior.

    :data:`allow_fullscreen` a :class:`~kivy.properties.BooleanProperty`,
    default to True
    '''

    options = DictProperty({})
    '''Optionals parameters can be passed to :class:`~kivy.uix.video.Video`
    instance with this property.

    :data:`options` a :class:`~kivy.properties.DictProperty`,
    default to {}
    '''

    # internals
    container = ObjectProperty(None)

    def __init__(self, **kwargs):
        self._video = None
        self._image = None
        self._annotations = None
        self._annotations_labels = []
        super(VideoPlayer, self).__init__(**kwargs)
        self._load_thumbnail()
        self._load_annotations()

    def on_source(self, instance, value):
        # we got a value, try to see if we have an image for it
        self._load_thumbnail()
        self._load_annotations()

    def _load_thumbnail(self):
        if not self.container:
            return
        self.container.clear_widgets()
        # get the source, remove extension, and use png
        thumbnail = self.thumbnail
        if thumbnail is None:
            filename = self.source.rsplit('.', 1)
            thumbnail = filename[0] + '.png'
        self._image = VideoPlayerPreview(source=thumbnail, video=self)
        self.container.add_widget(self._image)

    def _load_annotations(self):
        if not self.container:
            return
        self._annotations_labels = []
        annotations = self.annotations
        if annotations is None:
            filename = self.source.rsplit('.', 1)
            annotations = filename[0] + '.jsa'
        if exists(annotations):
            with open(annotations, 'r') as fd:
                self._annotations = load(fd)
        if self._annotations:
            for ann in self._annotations:
                self._annotations_labels.append(
                    VideoPlayerAnnotation(annotation=ann))

    def on_play(self, instance, value):
        if self._video is None:
            self._video = Video(source=self.source,
                                play=True,
                                volume=self.volume,
                                pos_hint={
                                    'x': 0,
                                    'y': 0
                                },
                                **self.options)
            self._video.bind(texture=self._play_started,
                             duration=self.setter('duration'),
                             position=self.setter('position'),
                             volume=self.setter('volume'))
        self._video.play = value

    def on_volume(self, instance, value):
        if not self._video:
            return
        self._video.volume = value

    def on_position(self, instance, value):
        labels = self._annotations_labels
        if not labels:
            return
        for label in labels:
            start = label.start
            duration = label.duration
            if start > value or (start + duration) < value:
                if label.parent:
                    label.parent.remove_widget(label)
            elif label.parent is None:
                self.container.add_widget(label)

    def seek(self, percent):
        '''Change the position to a percentage of duration. Percentage must be a
        value between 0-1.

        .. warning::

            Calling seek() before video is loaded have no impact.
        '''
        if not self._video:
            return
        self._video.seek(percent)

    def _play_started(self, instance, value):
        self.container.clear_widgets()
        self.container.add_widget(self._video)

    def on_touch_down(self, touch):
        if not self.collide_point(*touch.pos):
            return False
        if touch.is_double_tap and self.allow_fullscreen:
            self.fullscreen = not self.fullscreen
            return True
        return super(VideoPlayer, self).on_touch_down(touch)

    def on_fullscreen(self, instance, value):
        window = self.get_parent_window()
        if not window:
            Logger.warning('VideoPlayer: Cannot switch to fullscreen, '
                           'window not found.')
            if value:
                self.fullscreen = False
            return
        if not self.parent:
            Logger.warning('VideoPlayer: Cannot switch to fullscreen, '
                           'no parent.')
            if value:
                self.fullscreen = False
            return

        if value:
            self._fullscreen_state = state = {
                'parent': self.parent,
                'pos': self.pos,
                'size': self.size,
                'pos_hint': self.pos_hint,
                'size_hint': self.size_hint,
                'window_children': window.children[:]
            }

            # remove all window children
            for child in window.children[:]:
                window.remove_widget(child)

            # put the video in fullscreen
            if state['parent'] is not window:
                state['parent'].remove_widget(self)
            window.add_widget(self)

            # ensure the video widget is in 0, 0, and the size will be reajusted
            self.pos = (0, 0)
            self.size = (100, 100)
            self.pos_hint = {}
            self.size_hint = (1, 1)
        else:
            state = self._fullscreen_state
            window.remove_widget(self)
            for child in state['window_children']:
                window.add_widget(child)
            self.pos_hint = state['pos_hint']
            self.size_hint = state['size_hint']
            self.pos = state['pos']
            self.size = state['size']
            if state['parent'] is not window:
                state['parent'].add_widget(self)
Exemple #18
0
class Karaotool(FloatLayout):
    
    def __init__(self, **kwargs):
        super(Karaotool, self).__init__(**kwargs)
        
        self.source = kwargs.get('source', None)
        
        
        if self.source == None:
            self.selecttextfile = Popup(title='Select the lirycs')
            self.selecttextfile.content = BoxLayout(orientation='vertical')
            self.selecttextfile.content.add_widget(Button(text='Seleccionar archivo') )
            self.selecttextfile.content.add_widget(Button(text='Insertar texto') )
            self.selecttextfile.open()
            
        else:
        
            self.base_filename = os.path.splitext(self.source)[0]
           
            with open(self.base_filename + '.kot') as f:    #open karaotool text file
                self.content = f.readlines()
        
        self.line = 0;
        
        
        self.video = Video(source=self.source, state='play', allow_stretch=True, keep_ratio=False)
        
        self.video.bind(on_loaded=self.on_loaded)
        
        self.kar_english = LabelShadow(text='KARAOKELAND', 
                                    size_hint_y=None,
                                    color=(0,0,0,1),
                                    font_size=32 )
                                
                                
        self.add_widget(self.video)
        self.add_widget(self.kar_english)    
        
        #si existe el archivo con los tiempos
        if os.path.exists(self.base_filename + '.kos'):            
                
            self.kar_spanish = LabelShadow(text='KARAOKELAND ESP', 
                                        size_hint_y=1,
                                        color=(0,0,0,1),
                                        font_size=32 ) 
                                        
            self.add_widget(self.kar_spanish)
            
            self.fsteps = open(self.base_filename + '.kos') #steps
            self.steps = self.fsteps.readlines()
            
            try:
                self.efsteps = open(self.base_filename + '.koe') #subtitulos en lenguaje traducido
                self.esteps = self.efsteps.readlines()
            except:
                pass
            
            #Clock.schedule_interval(self.stepchecker, .1)
            
            
            self.video.bind(position=self.on_position)
            
            self.cursteptime = self.steps[self.line]
            
        else:
            
            self.btn_stepline = Button(text='Iniciar !', 
                                        #size_hint=(1,None),
                                        on_press=self.nextline
                                        )
            self.add_widget(self.btn_stepline, index=len(self.children) )
            
            
            #open for steps creation
            self.fsteps = open(self.base_filename + '.kos', 'w+')  #karaotool steps
            
            
    def on_loaded(self, w):
        print("Iniciando video")
        
    def on_position(self, w, val):
        
        if val > float(self.cursteptime):

            try:
                
                if hasattr(self, "old_kar_english"):
                    self.remove_widget(self.old_kar_english)
                    
                self.old_kar_english = self.kar_english
                    
                #subir titulo
                Animation(y=self.old_kar_english.y+50, opacity=.5, duration=.5).start(self.old_kar_english)
                #self.kar_english.y += 80
                
                        
                self.kar_english = LabelShadow(text=self.content[self.line], 
                                            size_hint_y=None,
                                            color=(0,0,0,1),
                                            font_size=32 )
                
                self.add_widget(self.kar_english)
                
                try:
                    self.kar_spanish.text = self.esteps[self.line]
                except:
                    pass

                
                
                self.line += 1
                
                #print "Step: ", self.video.position
                
                self.cursteptime = self.steps[self.line]
            except:
                self.kar_english.text = "END"
                self.kar_spanish.text = "FIN"
                
        
    def nextline(self, w):
        try:
            #advance one line
            self.kar_english.text = self.content[self.line]
            self.line += 1
            
            #self.kar_english.pos.y += 200
            
            self.fsteps.write(str(self.video.position) + '\n')
        except:
            self.kar_english.text = "FIN"
Exemple #19
0
    def phone(self):

        button = Button(text='挂断',
                        size_hint=(0.3, 0.15),
                        pos_hint={
                            'x': .35,
                            'y': .05
                        })

        #button.pos_x = 370
        #label = Label(text='内容',size_hint=(None, None),size=(300,500))

        #初始化摄像头,此时Play=False
        camera = Camera(id='camera',
                        resolution=(480, 640),
                        play=False,
                        pos=(0, -80))
        phoneTime = Label(text="00:00", pos_hint={'x': .15, 'y': .55})

        #filename = 'E:\\PythonProjects\\project_kivy\\venv\\share\\kivy-examples\\widgets\\cityCC0.mpg'
        #filename = 'http://192.168.0.100:8080/'
        #filename = 'udp://@:192.168.0.100:1234'
        #filename = 'rtsp://192.168.0.100:8554/play'

        filename = 'rtsp://192.168.0.100:8554/play'
        #filename = 'http://192.168.0.100:6060'
        '''
            当两次连接时,可以正常看视频,当有视频出现,显示视频纹理
            size默认值为(100,100)
            ?添加部件通话时长
            连接成功后,得到视频数据时,显示(如何判断)
            VLC RTSP通过UDP实现,Gstream通过什么?
        '''
        video = Video(source=filename, play='True', pos=(0, 120), volume=0.8)
        #通话时间
        count = 0

        relaytiveLayout = RelativeLayout(id='phone')
        relaytiveLayout.add_widget(camera)
        relaytiveLayout.add_widget(phoneTime)
        relaytiveLayout.add_widget(video)
        relaytiveLayout.add_widget(button)

        # label = Label(text='内容',size_hint=(None, None))
        # floatLayout = FloatLayout(size_hint=(None, None),size=(400, 600))
        # floatLayout.add_widget(label)
        # floatLayout.add_widget(relaytiveLayout)

        #覆盖整个窗口
        popup = Popup(title='正在与谁通话',
                      content=relaytiveLayout,
                      size_hint=(None, None),
                      size=(300, 500),
                      auto_dismiss=False)

        #self.proxy_ref.add_widget(popup)
        #print(popup.parent)

        popup.id = 'popup'

        #button.pos_x = popup.center_x + (popup.size[0] - button.size[0])/2
        #print(camera.size)

        #print(self.children[0].children)
        #print(self.ids.popup)

        #print(camera.properties())

        #print(self.id['camera'])
        #print(type(self.id['popup']))

        #print(popup.proxy_ref)
        '''
            摄像头没有释放,因为属性play值为True
        '''
        button.bind(on_press=popup.dismiss)

        #button.bind(on_touch_down=cv2.)

        #button.bind(on_press=)
        #popup.bind(on_dismiss=self.play)

        popup.open()

        for widget in self.walk():
            print('{} -> {}'.format(widget, widget.id))
            # if isinstance(widget,RelativeLayout):
            #     #print('{} -> {}'.format(widget,widget.id))
            #     for child in widget.walk():
            #         print('{} -> {}'.format(child, child.id))

        #为什么需要obj,其他值也可以,或许需要它来绑定事件的对象
        def closeCamera(obj):
            print(camera.play)
            #print(str(obj))
            camera.play = False
            print(camera.play)

        def closeVideo(obj):
            video.play = False
            video.unload()
            Clock.unschedule(phone_time_callback)

        def displayPhoneTime(*largs):
            # obj is float
            # print('obj is',type(largs))
            # print(largs)
            nonlocal count
            count = count + 1
            #print(count)
            #true
            #print(str(video.duration))
            phoneTime.text = str(s2t(count))

        phone_time_callback = Clock.schedule_interval(displayPhoneTime, 1.)
        video.bind(on_play=phone_time_callback)
        #video.bind(play=phone_time_callback)

        button.bind(on_press=closeCamera)
        button.bind(on_press=closeVideo)

        # 稍后启动摄像头
        camera.play = True
class TestApp(App):
    def build(self):

        # open config.ini to access the user's settings

        self.config = configparser.ConfigParser()
        self.config.read(os.environ['HOME'] + "/.config_showoff.ini")

        # ******************* DECIDE WINDOW SIZE *******************
        # in fullscreen is enable go full screen; otherwise use width and height provided
        if ConfigStuff.get_config_video_fullscreen(self.config):
            Window.fullscreen = "auto"
        else:
            # set the width and height from config.ini
            Window.size = (
            ConfigStuff.get_config_video_width(self.config), ConfigStuff.get_config_video_height(self.config))

        # ******************* DECIDE WHAT VIDEO IS PLAYED *******************
        # set the directory where the videos will be taken from
        self.video_directory = ConfigStuff.get_config_video_directory(self.config)

        # get the list of video files found
        self.video_list = PlaylistFromDir.create_playlist(self.video_directory)
        # the number of the file form video_list currently played
        self.curr_video_iterator = -1

        # todo: [ERROR  ] [Image       ] Error loading texture , try to deal with it at some point
        self.video1 = Video(source="./1_Second_of_Blank.mp4", state="play", volume=0)
        self.video1.fullscreen = True
        self.video1.allow_stretch = True
        self.video1.image_loading = "./GUI/loading.png"

        self.video1.pos_hint = {"center_x": .5, "center_y": .5}
        # when the video reaches its end, on_eos is called (eos= end of stream)
        self.video1.bind(position=self.on_position_change, eos=self.on_eos)

        # ******************* DEAL UI STUFF *******************
        self.label_help = Label(
            text="Approach your hand to control the Billboard. Hover over a button for 2s to activate it.",
            color=(1, 0, 0, 1))
        self.label_help.pos_hint = {"center_x": .5, "center_y": 0.98}

        self.button_loop = Button(text="Reset", background_normal="./GUI/loop.png", border=(0, 0, 0, 0),
                                  size_hint=(.2, .2), color=(1, 0, 0, 1))
        self.button_loop.pos_hint = {"center_x": 0.85, "center_y": 0.2}
        self.button_loop.opacity = 0.5
        self.button_loop.bind(on_press=self.callback_button_loop)

        self.button_next = Button(text="NEXT", background_normal="./GUI/arrow_next.png", border=(0, 0, 0, 0),
                                  size_hint=(.2, .2), color=(1, 0, 0, 1))
        self.button_next.pos_hint = {"center_x": 0.85, "center_y": 0.5}
        self.button_next.opacity = 0.5
        self.button_next.bind(on_press=self.callback_button_next)

        self.button_previous = Button(text="PREVIOUS", background_normal="./GUI/arrow_previous.png",
                                      border=(0, 0, 0, 0), size_hint=(.2, .2), color=(1, 0, 0, 1))
        self.button_previous.pos_hint = {"center_x": 0.15, "center_y": 0.5}
        self.button_previous.opacity = 0.5
        self.button_previous.bind(on_press=self.callback_button_previous)

        self.button_next_ppt = Button(text="NEXT SLIDE", background_normal="./GUI/arrow_next_2.png",
                                      border=(0, 0, 0, 0), size_hint=(.2, .2), color=(1, 0, 0, 1))
        self.button_next_ppt.pos_hint = {"center_x": 0.85, "center_y": 0.7}
        self.button_next_ppt.opacity = 0.5
        self.button_next_ppt.bind(on_press=self.callback_button_next_ppt)

        self.button_previous_ppt = Button(text="PREVIOUS SLIDE", background_normal="./GUI/arrow_previous_2.png",
                                          border=(0, 0, 0, 0), size_hint=(.2, .2), color=(1, 0, 0, 1))
        self.button_previous_ppt.pos_hint = {"center_x": 0.15, "center_y": 0.7}
        self.button_previous_ppt.opacity = 0.5
        self.button_previous_ppt.bind(on_press=self.callback_button_previous_ppt)

        self.label_help_ppt = Label(text="The power point will pause if you approach your hand", color=(1, 0, 0, 1))
        self.label_help_ppt.pos_hint = {"center_x": .5, "center_y": 0.02}

        # ******************* DEAL WITH LAYOUT *******************
        self.root = FloatLayout(size=Window.size)
        self.root_video = FloatLayout(size=Window.size)
        self.root_UI = FloatLayout(size=Window.size)
        self.root_UI.opacity=0.8

        if ConfigStuff.get_config_kinect_enable(self.config):
            self.faceAndEmotionAnalyser = apiFaceAndEmotion.apiFaceDetectAndClassifier()
            self.handTracking = HandTracking.MyHandTrackingApp()
            self.handTracking.pos_hint = {"center_x": .5, "center_y": .5}
            self.root_UI.add_widget(self.label_help)

        self.root_video.add_widget(self.video1)

        self.root.add_widget(self.root_video)
        self.root.add_widget(self.root_UI)

        # ******************* VIDEO MANAGEMENT ATTRIBUTES *******************
        self.playlist_management_event = None
        # ******************* PPT MANAGEMENT ATTRIBUTES *******************
        self.list_of_correct_extension_image = (".jpg", ".png")
        self.delay_image = ConfigStuff.get_config_image_delay(self.config)
        self.playing_ppt = False
        self.bool_ppt_UI_shown = False
        self.next_slide = False
        self.previous_slide = False
        self.bool_show_UI = False
        self.event_ppt = None  # used to cancel several power point management at the same time
        self.iterator_check_if_click = 0
        self.time_limit_beetween_clicks = 2  # in seconds

        # ******************* USER MANAGEMENT ATTRIBUTES *******************
        self.seen_users = set()
        self.current_people = None
        self.smart_video_choice = ConfigStuff.get_config_smart_video_enable(
            self.config) and ConfigStuff.get_config_kinect_enable(self.config)

        # ******************* CALL LOOPS *******************
        Clock.schedule_interval(self.check_mouse_position, 1)
        Clock.schedule_interval(self.hide_mouse_if_unmoved, 10)
        return self.root

    def callback_button_loop(self, instance):
        print("button loop")
        if(self.video1.source.endswith(self.list_of_correct_extension_image)):
            filename, file_extension = os.path.splitext(self.video1.source)
            # extract image number
            number_old = re.search('(\d+)$', filename).group(0)
            number_new = 1
            # replace the current image number to the next one
            filename = re.sub(str(number_old) + "$", str(number_new), filename)
            self.video1.source = filename + file_extension
            self.video1.reload()
            self.set_ppt_event(Clock.schedule_once(self.play_next_image, self.delay_image))
        else:
            self.video1.seek(0)

    def callback_button_next(self, instance):
        print("from button next")
        self.set_playlist_management_event(Clock.schedule_once(partial(self.playlist_management_next), 0))

    def callback_button_previous(self, instance):
        print("from button previous")
        self.set_playlist_management_event(Clock.schedule_once(partial(self.playlist_management_previous), 0))

    def callback_button_next_ppt(self, instance):
        self.next_slide = True
        self.set_ppt_event(Clock.schedule_once(self.play_next_image, 0))

    def callback_button_previous_ppt(self, instance):
        self.previous_slide = True
        self.set_ppt_event(Clock.schedule_once(self.play_next_image, 0))

    def check_users(self):
        self.current_people = self.faceAndEmotionAnalyser.check_who_it_is()
        for name in self.current_people:
            if name not in self.seen_users:
                self.seen_users.add(name)
                self.show_greetings("Hi " + name, 400, (1, 0, 0, 1))
        self.faceAndEmotionAnalyser.quitAndSave()
        self.faceAndEmotionAnalyser = apiFaceAndEmotion.apiFaceDetectAndClassifier()

    def check_users_watching_habits(self):
        # sort the list in accordance to what they have seen
        # print("Before:", self.video_list)
        list_video_with_score = []
        for video in self.video_list:
            list_video_with_score.append([video, 0])
        # print("Before 0:", list_video_with_score)
        # for all the people in front
        for person in self.current_people:
            parser = configparser.ConfigParser()
            parser.read("./pics/" + person + '.ini')
            # for all the videos found
            for i in range(len(self.video_list)):
                # if the video has been seen
                if parser.has_option("WATCHING_HABITS", self.video_list[i]):
                    # add a score base on how many time it was seen, and when was the last time
                    # todo: maybe think of a better formula
                    list_video_with_score[i] = (list_video_with_score[i][0],
                                                list_video_with_score[i][1] + parser.getint("WATCHING_HABITS",
                                                                                            self.video_list[i]) / (
                                                time.time() - parser.getfloat("WATCHING_HABITS_TIME_TICKS",
                                                                              self.video_list[i])))

                    # for all the video
                    # sort based on their score
        # print("Before1:", list_video_with_score)
        list_video_with_score = sorted(list_video_with_score, key=lambda score: score[1])  # sort by score
        # print("After 1:", list_video_with_score)
        # put the previously shown video at the end
        index = -1
        for i in range(len(list_video_with_score)):
            if (list_video_with_score[i][0] == self.video1.source):
                index = i
                break
        if (index != -1):
            list_video_with_score.append(list_video_with_score.pop(index))
        self.video_list = []
        for video in list_video_with_score:
            self.video_list.append(video[0])
            # print("After 2:", self.video_list)

    def update_users_watching_habits(self):
        if (not self.video1.source == "./1_second_of_blank.mp4"):
            # for all the people in front
            for person in self.current_people:
                parser = configparser.ConfigParser()
                parser.read("./pics/" + person + '.ini')
                # if the person has already seen the video
                if (parser.has_section("WATCHING_HABITS")):
                    try:
                        parser.set("WATCHING_HABITS", self.video1.source,
                                   str(parser.getint("WATCHING_HABITS", self.video1.source) + 1))

                    except:
                        parser.set("WATCHING_HABITS", self.video1.source, str(1))
                    # set it to the current time
                    parser.set("WATCHING_HABITS_TIME_TICKS", self.video1.source, str(time.time()))
                    parser.set("WATCHING_HABITS_TIME_DATE", self.video1.source,
                               str(time.asctime(time.localtime(time.time()))))

                else:
                    # create the section
                    parser.add_section("WATCHING_HABITS")
                    parser.add_section("WATCHING_HABITS_TIME_TICKS")
                    parser.add_section("WATCHING_HABITS_TIME_DATE")
                    parser.set("WATCHING_HABITS", self.video1.source, str(1))
                    # set it to the current time
                    parser.set("WATCHING_HABITS_TIME_TICKS", self.video1.source, str(time.time()))
                    parser.set("WATCHING_HABITS_TIME_DATE", self.video1.source,
                               str(time.asctime(time.localtime(time.time()))))
                # print("writing in:",person+'.ini' )
                with open("./pics/" + person + '.ini', "w") as config_file:
                    parser.write(config_file)

    # decide which video is played next
    def playlist_management_next(self, dt=None):
        if (self.playing_ppt or self.video1.source.endswith(self.list_of_correct_extension_image)):
            self.root_UI.remove_widget(self.label_help_ppt)
            if (self.bool_show_UI):
                self.root_UI.remove_widget(self.button_next_ppt)
                self.root_UI.remove_widget(self.button_previous_ppt)
                self.bool_ppt_UI_shown = False
            self.playing_ppt = False

            filename, file_extension = os.path.splitext(self.video1.source)
            # extract image number
            number_old = re.search('(\d+)$', filename).group(0)
            number_new = 1
            # replace the current image number to the next one
            filename = re.sub(str(number_old) + "$", str(number_new), filename)
            self.video1.source = filename + file_extension
            # print("new:", self.video1.source)

        self.video1.state = 'pause'
        self.video_list = PlaylistFromDir.create_playlist(self.video_directory)

        if not self.video_list:
            print("no video to play")
            self.video1.source = "./1_Second_of_Blank.mp4"
            self.video1.state = 'play'
        else:

            # todo check users activity with App and adjust list
            if (self.smart_video_choice):
                # check who is there
                self.check_users()
                if(self.current_people):
                    # check what the people there have seen and choose a content
                    self.check_users_watching_habits()
                    self.video1.source = self.video_list[0]  # the most appropriate is the first one
                    # for those there, add the chosen content to their watching habits
                    self.update_users_watching_habits()

            if(not self.current_people):
                self.curr_video_iterator = self.video_list.index(
                    self.video1.source) if self.video1.source in self.video_list else 0
                self.curr_video_iterator += 1
                if (len(self.video_list) == self.curr_video_iterator):
                    self.curr_video_iterator = 0
                self.video1.source = self.video_list[self.curr_video_iterator]

            if (self.video1.source.endswith(self.list_of_correct_extension_image)):
                self.video1.source = self.video1.source
                self.playing_ppt = True
                self.root_UI.add_widget(self.label_help_ppt)
                if (self.bool_show_UI):
                    self.root_UI.add_widget(self.button_next_ppt)
                    self.root_UI.add_widget(self.button_previous_ppt)
                    self.bool_ppt_UI_shown = True
                self.set_ppt_event(Clock.schedule_once(self.play_next_image, self.delay_image))
            else:
                self.video1.state = 'play'
        print("Playing:", self.video1.source)

    # decide which video is played next
    def playlist_management_previous(self, dt=None):
        if (self.playing_ppt):
            self.root_UI.remove_widget(self.label_help_ppt)
            if (self.bool_show_UI):
                self.root_UI.remove_widget(self.button_next_ppt)
                self.root_UI.remove_widget(self.button_previous_ppt)
                self.bool_ppt_UI_shown = False
            self.playing_ppt = False
            filename, file_extension = os.path.splitext(self.video1.source)
            # extract image number
            number_old = re.search('(\d+)$', filename).group(0)
            number_new = 1
            # replace the current image number to the next one
            filename = re.sub(str(number_old) + "$", str(number_new), filename)
            self.video1.source = filename + file_extension

        self.video1.state = 'pause'
        self.video_list = PlaylistFromDir.create_playlist(self.video_directory)

        if not self.video_list:
            print("no video to play")
            self.video1.source = "./1_Second_of_Blank.mp4"
            self.video1.state = 'play'
        else:
            self.curr_video_iterator = self.video_list.index(
                self.video1.source) if self.video1.source in self.video_list else 0
            self.curr_video_iterator -= 1
            if (self.curr_video_iterator < 0):
                self.curr_video_iterator = len(self.video_list) - 1
            self.video1.source = self.video_list[self.curr_video_iterator]

            # todo check users activity with App and adjust list
            if (self.smart_video_choice):
                # check who is there
                self.check_users()
                if(self.current_people):
                    # for those there, add the chosen content to their watching habits
                    self.update_users_watching_habits()

            # if ppt treat it accordingly
            if (self.video1.source.endswith(self.list_of_correct_extension_image)):
                self.video1.source = self.video1.source
                self.playing_ppt = True
                self.root_UI.add_widget(self.label_help_ppt)
                if (self.bool_show_UI):
                    self.root_UI.add_widget(self.button_next_ppt)
                    self.root_UI.add_widget(self.button_previous_ppt)
                    self.bool_ppt_UI_shown = True
                self.set_ppt_event(Clock.schedule_once(self.play_next_image, self.delay_image))
            else:
                self.video1.state = 'play'
        print("Playing:", self.video1.source)

    def set_ppt_event(self, event):
        if (self.event_ppt != None):
            self.event_ppt.cancel()
        self.event_ppt = event

    def set_playlist_management_event(self, event):
        if (self.playlist_management_event != None):
            self.playlist_management_event.cancel()
        self.playlist_management_event = event

    def play_next_image(self, dt):
        print("Entering play_next_image")
        if (self.playing_ppt):
            if (self.previous_slide):
                # print("play next")
                # get name and extension
                filename, file_extension = os.path.splitext(self.video1.source)
                # extract image number
                number_old = re.search('(\d+)$', filename).group(0)
                number_new = int(number_old) - 1

                # print("before :",filename)
                # replace the current image number to the next one
                filename = re.sub(str(number_old) + "$", str(number_new), filename)

                # print("after :", filename)
                # if the file does no exist we pass to the video/powerpoint
                if (os.path.isfile(filename + file_extension)):
                    # if it exist we update the image drawn
                    new_source = filename + file_extension
                    # print(self.video1.source," new image is :",new_source)
                    self.video1.source = new_source
                    self.previous_slide = False
                    self.next_slide = False
                    self.set_ppt_event(Clock.schedule_once(self.play_next_image, self.delay_image))

            elif (self.next_slide):
                # print("play next")
                # get name and extension
                filename, file_extension = os.path.splitext(self.video1.source)
                # extract image number
                number_old = re.search('(\d+)$', filename).group(0)
                number_new = int(number_old) + 1

                # print("before :",filename)
                # replace the current image number to the next one
                filename = re.sub(str(number_old) + "$", str(number_new), filename)

                # print("after :", filename)
                # if the file does no exist we pass to the video/powerpoint
                if (os.path.isfile(filename + file_extension)):
                    # if it exist we update the image drawn
                    new_source = filename + file_extension
                    # print(self.video1.source," new image is :",new_source)
                    self.video1.source = new_source
                    self.previous_slide = False
                    self.next_slide = False
                    self.set_ppt_event(Clock.schedule_once(self.play_next_image, self.delay_image))
            else:
                # print("play next")
                # get name and extension
                filename, file_extension = os.path.splitext(self.video1.source)
                # extract image number
                number_old = re.search('(\d+)$', filename).group(0)
                number_new = int(number_old) + 1

                # print("before :",filename)
                # replace the current image number to the next one
                filename = re.sub(str(number_old) + "$", str(number_new), filename)

                # print("after :", filename)
                # if the file does no exist we pass to the video/powerpoint
                if (not os.path.isfile(filename + file_extension)):
                    print("from play_next_image")
                    self.set_playlist_management_event(Clock.schedule_once(partial(self.playlist_management_next), 0))
                else:
                    # if it exist we update the image drawn
                    new_source = filename + file_extension
                    # print(self.video1.source," new image is :",new_source)
                    self.video1.source = new_source
                    self.previous_slide = False
                    self.next_slide = False
                    self.set_ppt_event(Clock.schedule_once(self.play_next_image, self.delay_image))

    def show_overlay(self):
        if (self.bool_show_UI == False):
            self.root_UI.add_widget(self.handTracking.painter)
            self.root_UI.add_widget(self.button_next)
            self.root_UI.add_widget(self.button_previous)
            self.root_UI.add_widget(self.button_loop)
            if (not self.bool_ppt_UI_shown and self.playing_ppt):
                self.root_UI.add_widget(self.button_next_ppt)
                self.root_UI.add_widget(self.button_previous_ppt)
                self.bool_ppt_UI_shown = True
            self.bool_show_UI = True

            self.check_users()

    def hide_overlay(self):
        if (self.bool_show_UI == True):
            self.root_UI.remove_widget(self.handTracking.painter)
            self.root_UI.remove_widget(self.button_next)
            self.root_UI.remove_widget(self.button_previous)
            self.root_UI.remove_widget(self.button_loop)
            if (self.bool_ppt_UI_shown):
                self.root_UI.remove_widget(self.button_next_ppt)
                self.root_UI.remove_widget(self.button_previous_ppt)
                self.bool_ppt_UI_shown = False
            self.bool_show_UI = False

    # move the mouse to the middle of the window and hide fullscreen (works best when full screen)
    def hide_mouse_if_unmoved(self, dt):
        if (Window.mouse_pos[0] == self.last_mouse_pose[0] and Window.mouse_pos[1] == self.last_mouse_pose[
            1] and self.bool_show_UI == False):
            pyautogui.moveTo(Window.width / 2, Window.height / 2)
            Window.show_cursor = False

    # check the mouse position, if situated on the right, the grid is show
    def check_mouse_position(self, dt):
        # show mouse cursor if hidden and not in the center of the screen
        x = Window.mouse_pos[0]
        y = Window.mouse_pos[1]
        if (x != Window.width / 2 and y != Window.height / 2 and Window.show_cursor == False):
            Window.show_cursor = True
        # todo: check if mouse over widget for click
        if (self.bool_show_UI):
            if (self.iterator_check_if_click == self.time_limit_beetween_clicks):
                self.check_if_click(0)
                self.iterator_check_if_click = 0
            else:
                self.iterator_check_if_click += 1
        self.last_mouse_pose = (Window.mouse_pos[0], Window.mouse_pos[1])
        # print(Window.mouse_pos)

    def check_if_click(self, dt):

        x = Window.mouse_pos[0]
        y = Window.mouse_pos[1]
        if (self.button_next.collide_point(x, y)):
            self.callback_button_next(None)

        if (self.button_previous.collide_point(x, y)):
            self.callback_button_previous(None)

        if (self.button_loop.collide_point(x, y)):
            self.callback_button_loop(None)

        if (self.bool_ppt_UI_shown):
            if (self.button_next_ppt.collide_point(x, y)):
                self.callback_button_next_ppt(None)

            if (self.button_previous_ppt.collide_point(x, y)):
                self.callback_button_previous_ppt(None)

    # todo: that may be a bit heavy on processing
    def on_position_change(self, instance, value):
        if (value > 30):
            print("from 30 sec !")
            self.set_playlist_management_event(Clock.schedule_once(partial(self.playlist_management_next), 0))

    def show_greetings(self, text, size=200, color=(1, 1, 1, 1)):
        label_hello = Label(
            text=text
        )
        self.root_UI.add_widget(label_hello)
        # Animate and fade out the message
        anim = Animation(font_size=size,
                         color=color, t='in_quad', s=1 / 30)
        anim.start(label_hello)

        def tick_hello_anim(dt):
            label_hello.canvas.ask_update()
            Clock.schedule_once(tick_hello_anim)

            tick_hello_anim(0)

        def end_hello_anim(dt):
            self.root_UI.remove_widget(label_hello)
            Clock.unschedule(end_hello_anim)

        Clock.schedule_once(end_hello_anim, 1)

    # on end of stream, playlist_management is shown
    def on_eos(self, instance, value):
        if (not self.video1.source.endswith(self.list_of_correct_extension_image)):
            print("from eos", self.video1.source)
            self.set_playlist_management_event(Clock.schedule_once(partial(self.playlist_management_next), 0))

    def __init__(self, **kwargs):
        super(TestApp, self).__init__(**kwargs)
        self._keyboard = Window.request_keyboard(self._keyboard_closed, self)
        self._keyboard.bind(on_key_down=self._on_keyboard_down)
        self._keyboard.bind(on_key_up=self._on_keyboard_up)

    def _keyboard_closed(self):
        self._keyboard.unbind(on_key_down=self._on_keyboard_down)
        self._keyboard = None

    def _on_keyboard_down(self, *args):
        # print ('down', args)
        if args[1][1] == 'f':
            Window.fullscreen = "auto"
        if args[1][1] == 'right':
            print("from right")
            self.set_playlist_management_event(Clock.schedule_once(partial(self.playlist_management_next), 0))
        if args[1][1] == 'left':
            print("from left")
            self.set_playlist_management_event(Clock.schedule_once(partial(self.playlist_management_previous), 0))
        if args[1][1] == 'enter':
            self.show_greetings("Hi Yoann")
        if args[1][1] == 's':
            self.faceAndEmotionAnalyser.quitAndSave()
            self.faceAndEmotionAnalyser = apiFaceAndEmotion.apiFaceDetectAndClassifier()
        if args[1][1] == 'c':
            self.faceAndEmotionAnalyser.changeName("36", "Yoann", self.faceAndEmotionAnalyser.personsDB)

    def _on_keyboard_up(self, *args):
        print(args[1][1])