def _fadeWorker(self, start, end, fade_time_millis):
        volWidth = end - start

        func = end > start and min or max

        duration = fade_time_millis / 1000.0
        endTime = time.time() + duration
        vol = start
        left = duration

        DEBUG_LOG('Fade: START ({0}) - {1}ms'.format(start, fade_time_millis))
        while time.time() < endTime and not kodiutil.wait(0.1):
            while xbmc.getCondVisibility('Player.Paused') and not kodiutil.wait(0.1):
                endTime = time.time() + left

            if xbmc.abortRequested or not xbmc.getCondVisibility('Player.Playing') or self.abortFlag.isSet() or self._stop():
                DEBUG_LOG(
                    'Fade ended early({0}): {1}'.format(vol, not xbmc.getCondVisibility('Player.Playing') and 'NOT_PLAYING' or 'ABORT')
                )
                return
            left = endTime - time.time()
            vol = func(end, int(start + (((duration - left) / duration) * volWidth)))
            self._set(vol)

        DEBUG_LOG('Fade: END ({0})'.format(vol))
    def _fadeWorker(self, start, end, fade_time_millis):
        volWidth = end - start

        func = end > start and min or max

        duration = fade_time_millis / 1000.0
        endTime = time.time() + duration
        vol = start
        left = duration

        DEBUG_LOG('Fade: START ({0}) - {1}ms'.format(start, fade_time_millis))
        while time.time() < endTime and not kodiutil.wait(0.1):
            while xbmc.getCondVisibility(
                    'Player.Paused') and not kodiutil.wait(0.1):
                endTime = time.time() + left

            if xbmc.abortRequested or not xbmc.getCondVisibility(
                    'Player.Playing') or self.abortFlag.isSet() or self._stop(
                    ):
                DEBUG_LOG('Fade ended early({0}): {1}'.format(
                    vol, not xbmc.getCondVisibility('Player.Playing')
                    and 'NOT_PLAYING' or 'ABORT'))
                return
            left = endTime - time.time()
            vol = func(
                end, int(start + (((duration - left) / duration) * volWidth)))
            self._set(vol)

        DEBUG_LOG('Fade: END ({0})'.format(vol))
    def showImage(self, image):
        try:
            if image.fade:
                self.window.setTransition('fadesingle', image.fade)

            self.window.setImage(image.path)

            stop = time.time() + image.duration
            fadeStop = image.fade and stop - (image.fade / 1000) or 0

            while not kodiutil.wait(0.1) and (time.time() < stop
                                              or self.window.paused()):
                if fadeStop and time.time(
                ) >= fadeStop and not self.window.paused():
                    fadeStop = None
                    self.window.fadeOut()

                if not self.window.isOpen:
                    return False
                elif self.window.action:
                    if self.window.next():
                        return 'NEXT'
                    elif self.window.prev():
                        return 'PREV'
                    elif self.window.skip():
                        return 'SKIP'
                    elif self.window.back():
                        return 'BACK'
                    elif self.window.resume():
                        stop += self.window.pauseDuration()
                        self.window.finishPause()

            return True
        finally:
            self.window.clear()
    def showImageFromQueue(self, image, info, first=None):
        self.window.setImage(image.path)

        stop = time.time() + image.duration

        while not kodiutil.wait(0.1) and (time.time() < stop or self.window.paused()):
            if not self.window.isOpen:
                return False

            if info.musicEnd and time.time() >= info.musicEnd and not self.window.paused():
                info.musicEnd = None
                self.stopMusic(info.imageQueue)
            elif self.window.action:
                if self.window.next():
                    return 'NEXT'
                elif self.window.prev():
                    return 'PREV'
                if self.window.bigNext():
                    return 'BIG_NEXT'
                elif self.window.bigPrev():
                    return 'BIG_PREV'
                elif self.window.skip():
                    return 'SKIP'
                elif self.window.back():
                    return 'BACK'
                elif self.window.resume():
                    stop += self.window.pauseDuration()
                    self.window.finishPause()

            if xbmcgui.getCurrentWindowId() != self.window._winID:  # Prevent switching to another window as it's not a good idea
                self.window.show()

        return True
    def showImage(self, image):
        try:
            if image.fade:
                self.window.setTransition('fadesingle', image.fade)

            self.window.setImage(image.path)

            stop = time.time() + image.duration
            fadeStop = image.fade and stop - (image.fade/1000) or 0

            while not kodiutil.wait(0.1) and (time.time() < stop or self.window.paused()):
                if fadeStop and time.time() >= fadeStop and not self.window.paused():
                    fadeStop = None
                    self.window.fadeOut()

                if not self.window.isOpen:
                    return False
                elif self.window.action:
                    if self.window.next():
                        return 'NEXT'
                    elif self.window.prev():
                        return 'PREV'
                    elif self.window.skip():
                        return 'SKIP'
                    elif self.window.back():
                        return 'BACK'
                    elif self.window.resume():
                        stop += self.window.pauseDuration()
                        self.window.finishPause()

            return True
        finally:
            self.window.clear()
    def stopMusic(self, image_queue=None):
        try:
            rpc.Playlist.Clear(playlistid=xbmc.PLAYLIST_MUSIC)

            if image_queue and image_queue.music:
                self.volume.set(1, fade_time=int(image_queue.musicFadeOut*1000))
                while self.volume.fading() and not self.abortFlag.isSet() and not kodiutil.wait(0.1):
                    if self.window.hasAction() and self.window.action != 'RESUME':
                        break

            kodiutil.DEBUG_LOG('Stopping music')
            self.stop()
            self.waitForPlayStop()
            self.playStatus = self.NOT_PLAYING
        finally:
            self.volume.restore(delay=500)
    def waitLoop(self):
        while not kodiutil.wait(0.1) and self.window.isOpen:
            if self.processor.atEnd():
                break

            if self.isPlayingMinimized():
                DEBUG_LOG('Fullscreen video closed - stopping')
                self.stop()
        else:
            if not self.processor.atEnd():
                self.onAbort()

        DEBUG_LOG('[ -- Finished -------------------------------------------------------------- ]\n.')
        self.window.doClose()
        rpc.Playlist.Clear(playlistid=xbmc.PLAYLIST_VIDEO)
        self.stop()
    def waitLoop(self):
        while not kodiutil.wait(0.1) and self.window.isOpen:
            if self.processor.atEnd():
                break

            if self.isPlayingMinimized():
                DEBUG_LOG('Fullscreen video closed - stopping')
                self.stop()
        else:
            if not self.processor.atEnd():
                self.onAbort()

        DEBUG_LOG(
            '[ -- Finished -------------------------------------------------------------- ]\n.'
        )
        self.window.doClose()
        rpc.Playlist.Clear(playlistid=xbmc.PLAYLIST_VIDEO)
        self.stop()
    def stopMusic(self, image_queue=None):
        try:
            rpc.Playlist.Clear(playlistid=xbmc.PLAYLIST_MUSIC)

            if image_queue and image_queue.music:
                self.volume.set(1,
                                fade_time=int(image_queue.musicFadeOut * 1000))
                while self.volume.fading(
                ) and not self.abortFlag.isSet() and not kodiutil.wait(0.1):
                    if self.window.hasAction(
                    ) and self.window.action != 'RESUME':
                        break

            kodiutil.DEBUG_LOG('Stopping music')
            self.stop()
            self.waitForPlayStop()
            self.playStatus = self.NOT_PLAYING
        finally:
            self.volume.restore(delay=500)
    def showImageFromQueue(self, image, info, first=None):
        self.window.setImage(image.path)

        stop = time.time() + image.duration

        while not kodiutil.wait(0.1) and (time.time() < stop
                                          or self.window.paused()):
            if not self.window.isOpen:
                return False

            if info.musicEnd and time.time(
            ) >= info.musicEnd and not self.window.paused():
                info.musicEnd = None
                self.stopMusic(info.imageQueue)
            elif self.window.action:
                if self.window.next():
                    return 'NEXT'
                elif self.window.prev():
                    return 'PREV'
                if self.window.bigNext():
                    return 'BIG_NEXT'
                elif self.window.bigPrev():
                    return 'BIG_PREV'
                elif self.window.skip():
                    return 'SKIP'
                elif self.window.back():
                    return 'BACK'
                elif self.window.resume():
                    stop += self.window.pauseDuration()
                    self.window.finishPause()

            if xbmcgui.getCurrentWindowId(
            ) != self.window._winID:  # Prevent switching to another window as it's not a good idea
                self.window.show()

        return True
 def join(self):
     while not kodiutil.wait(0.1) and not self.abortFlag.isSet():
         if self.initialized:
             return
 def join(self):
     while not kodiutil.wait(0.1) and not self.abortFlag.isSet():
         if self.initialized:
             return