Exemple #1
0
    def __init__(self, session, updateObjImpl, autoStart=True):
        printDBG(
            "IPTVUpdateMainWindow.__init__ -------------------------------")
        Screen.__init__(self, session)
        self.autoStart = autoStart

        self.updateObjImpl = updateObjImpl
        self.updateObjImpl.setStepFinishedCallBack(self.stepFinished)

        self.setup_title = self.updateObjImpl.getSetupTitle()
        self["sub_title"] = Label(_(" "))
        self["console"] = Label(_("> Press OK to start <"))
        self["actions"] = ActionMap(["SetupActions", "ColorActions"], {
            "cancel": self.keyExit,
            "ok": self.keyOK,
        }, -2)
        self.list = []
        self["list"] = IPTVUpdateList(
            [GetIPTVDMImgDir(x) for x in IPTVUpdateWindow.ICONS])
        self.currStep = 0
        self.onLayoutFinish.append(self.layoutFinished)
        self.onClose.append(self.__onClose)
        self.status = None

        self.messages = {}
        self.messages['not_interrupt'] = _(
            "During processing, please do not interrupt.")
        self.messages['please_wait'] = _("During processing, please wait.")
        self.messages['not_aborted'] = _(
            "Step [%s] cannot be aborted. Please wait.")
Exemple #2
0
    def __init__(self, session, updateObjImpl, autoStart=True):
        printDBG(
            "IPTVUpdateMainWindow.__init__ -------------------------------")
        Screen.__init__(self, session)
        self.autoStart = autoStart

        self.updateObjImpl = updateObjImpl
        self.updateObjImpl.setStepFinishedCallBack(self.stepFinished)

        self.setup_title = self.updateObjImpl.getSetupTitle()
        self["sub_title"] = Label(_(" "))
        self["console"] = Label(_("> Press OK to start <"))
        self["actions"] = ActionMap(["SetupActions", "ColorActions"], {
            "cancel": self.keyExit,
            "ok": self.keyOK,
        }, -2)
        self.list = []
        self["list"] = IPTVUpdateList(
            [GetIPTVDMImgDir(x) for x in IPTVUpdateWindow.ICONS])
        self.currStep = 0
        self.onLayoutFinish.append(self.layoutFinished)
        self.onClose.append(self.__onClose)
        self.status = None
Exemple #3
0
class E2iPlayerBufferingWidget(Screen):
    NUM_OF_ICON_FRAMES = 8
    #######################
    #       SIZES
    #######################
    # screen size
    # we do not want borders, so make the screen lager than a desktop
    sz_w = getDesktop(0).size().width()
    sz_h = getDesktop(0).size().height()
    # icon
    i_w = 128
    i_h = 128
    # percentage
    p_w = 120
    p_h = 120
    # console
    c_w = sz_w
    c_h = 80
    # addinfo
    a_w = sz_w - 10
    a_h = 80
    #######################
    #     POSITIONS
    #######################
    start_y = (sz_h - (i_h + c_h)) / 2
    # icon
    i_x = (sz_w - i_w) / 2
    i_y = start_y
    # percentage
    p_x = (sz_w - p_w) / 2
    p_y = start_y + (i_h - p_h) / 2
    # console
    c_x = 0
    c_y = i_y + i_h
    # addinfo
    a_x = 10
    a_y = sz_h - 160
    #button
    b_x = sz_w - 10 - 35 * 3
    b_y = sz_h - 10 - 25

    printDBG("[E2iPlayerBufferingWidget] desktop size %dx%d" % (sz_w, sz_h))
    skin = """
        <screen name="E2iPlayerBufferingWidget"  position="center,center" size="%d,%d" title="E2iStream buffering...">
         <widget name="percentage" size="%d,%d"   position="%d,%d"  zPosition="5" valign="center" halign="center"  font="Regular;21" backgroundColor="black" transparent="1" /> #foregroundColor="white" shadowColor="black" shadowOffset="-1,-1"
         <widget name="console"    size="%d,%d"   position="%d,%d"  zPosition="5" valign="center" halign="center"  font="Regular;21" backgroundColor="black" transparent="1" />
         <widget name="icon"       size="%d,%d"   position="%d,%d"  zPosition="4" transparent="1" alphatest="blend" />
         <widget name="addinfo"    size="%d,%d"   position="%d,%d"  zPosition="5" valign="center" halign="center"  font="Regular;21" backgroundColor="black" transparent="1" />
         
         <widget name="ok_button"        position="%d,%d"                     size="35,25"   zPosition="8" pixmap="%s" transparent="1" alphatest="blend" />
         <widget name="rec_button"       position="%d,%d"                     size="35,25"   zPosition="8" pixmap="%s" transparent="1" alphatest="blend" />
         <widget name="exit_button"      position="%d,%d"                     size="35,25"   zPosition="8" pixmap="%s" transparent="1" alphatest="blend" />
        </screen>""" % (
        sz_w,
        sz_h,  # screen
        p_w,
        p_h,
        p_x,
        p_y,  # percentage
        c_w,
        c_h,
        c_x,
        c_y,  # console
        i_w,
        i_h,
        i_x,
        i_y,  # icon
        a_w,
        a_h,
        a_x,
        a_y,  # addinfo
        b_x,
        b_y,
        GetIPTVDMImgDir("key_ok.png"),  # OK
        b_x + 35,
        b_y,
        GetIPTVDMImgDir("key_rec.png"),  # REC
        b_x + 70,
        b_y,
        GetIPTVDMImgDir("key_exit.png"),  # EXIT
    )

    def __init__(self,
                 session,
                 url,
                 pathForBuffering,
                 pathForDownloading,
                 movieTitle,
                 activMoviePlayer,
                 requestedBuffSize,
                 playerAdditionalParams={},
                 downloadManager=None,
                 fileExtension=''):
        self.session = session
        Screen.__init__(self, session)
        self.onStartCalled = False

        self.downloadingPath = pathForDownloading
        self.bufferingPath = pathForBuffering
        self.filePath = pathForBuffering + '/.iptv_buffering.flv'
        self.url = url
        self.movieTitle = movieTitle
        self.downloadManager = downloadManager
        self.fileExtension = fileExtension

        self.currentService = self.session.nav.getCurrentlyPlayingServiceReference(
        )
        self.activMoviePlayer = activMoviePlayer

        self.onClose.append(self.__onClose)
        #self.onLayoutFinish.append(self.doStart)
        self.onShow.append(self.onWindowShow)
        #self.onHide.append(self.onWindowHide)

        self["actions"] = ActionMap(
            [
                "IPTVAlternateVideoPlayer", "WizardActions",
                "MoviePlayerActions"
            ], {
                "ok": self.ok_pressed,
                "back": self.back_pressed,
                "leavePlayer": self.back_pressed,
                "record": self.record_pressed,
            }, -1)

        self["console"] = Label()
        self["percentage"] = Label()
        self["addinfo"] = Label()
        self['ok_button'] = Cover3()
        self['rec_button'] = Cover3()
        self['exit_button'] = Cover3()

        self["icon"] = SimpleAnimatedCover()
        # prepare icon frames path
        frames = []
        for idx in range(1, self.NUM_OF_ICON_FRAMES + 1):
            frames.append(
                resolveFilename(
                    SCOPE_PLUGINS,
                    'Extensions/IPTVPlayer/icons/buffering/buffering_%d.png' %
                    idx))
        self["icon"].loadFrames(frames)

        self.inMoviePlayer = False
        self.canRunMoviePlayer = False  # used in function updateDisplay, so must be first initialized
        #main Timer
        self.mainTimer = eTimer()
        self.mainTimerEnabled = False
        self.mainTimer_conn = eConnectCallback(self.mainTimer.timeout,
                                               self.updateDisplay)
        self.mainTimerInterval = 1000  # by default 1s

        self.requestedBuffSize = requestedBuffSize
        self.playerAdditionalParams = playerAdditionalParams

        self.clipLength = None
        self.lastPosition = None
        self.lastSize = 0

        # Some MP4 files are not prepared for streaming
        # MOOV atom is needed to start playback
        # if it is located at the end of file, then
        # will try to download it separately to start playback
        # without downloading the whole file
        self.clouldBeMP4 = False
        self.isMOOVAtomAtTheBeginning = None
        self.checkMOOVAtom = True
        self.maxMOOVAtomSize = 10 * 1024 * 1024  # 10 MB max moov atom size
        self.moovAtomOffset = 0
        self.moovAtomSize = 0

        self.MOOV_STS = enum(UNKNOWN=0,
                             WAITING=1,
                             DOWNLOADING=2,
                             DOWNLOADED=3,
                             ERROR=4)
        self.moovAtomStatus = self.MOOV_STS.UNKNOWN
        self.moovAtomDownloader = None
        self.moovAtomPath = pathForBuffering + '/.iptv_buffering_moov.flv'
        self.closeRequestedByUser = None

        printDBG(">> activMoviePlayer[%s]" % self.activMoviePlayer)

    #end def __init__(self, session):

    def onStart(self):
        '''
            this method is called once like __init__ but in __init__ we cannot display MessageBox
        '''
        self['rec_button'].hide()
        self['ok_button'].hide()

        # create downloader
        self.downloader = DownloaderCreator(self.url)
        self._cleanedUp()

        if self.downloader:
            self.downloader.isWorkingCorrectly(self._startDownloader)
        else:
            self.session.openWithCallback(
                self.iptvDoClose,
                MessageBox,
                _("Downloading can not be started.\n The address ('%r') is incorrect."
                  ) % self.url,
                type=MessageBox.TYPE_ERROR,
                timeout=10)

    def _startDownloader(self, sts, reason):
        if sts:
            url, downloaderParams = DMHelper.getDownloaderParamFromUrl(
                self.url)
            if url.split('?', 1)[0].lower().endswith('.mp4'):
                self.clouldBeMP4 = True
            self.downloader.start(url, self.filePath, downloaderParams)
            self.setMainTimerSts(True)
            self.canRunMoviePlayer = True
        else:
            self.session.openWithCallback(
                self.iptvDoClose,
                MessageBox,
                _("Downloading can not be started.\n Downloader %s does not work properly.\nStatus[%s]"
                  ) % (self.downloader.getName(), reason.strip()),
                type=MessageBox.TYPE_ERROR,
                timeout=10)

    def _isInLiveMode(self):
        if isinstance(self.url, strwithmeta):
            if 'iptv_livestream' in self.url.meta:
                return self.url.meta['iptv_livestream']
        # if we do not have information if it is live try to figure out from other sources
        if self.downloader:
            tmp = self.downloader.isLiveStream()
            if None != tmp:
                return tmp
        if self.url.startswith('rtmp'):
            return True

    def onEnd(self):
        self.setMainTimerSts(False)
        if self.downloader:
            self.downloader.terminate()
            self.downloader = None

        if self.moovAtomDownloader:
            self.moovAtomDownloader.terminate()
            self.moovAtomDownloader = None
        self._cleanedUp()

    def leaveMoviePlayer(self,
                         ret=None,
                         lastPosition=None,
                         clipLength=None,
                         *args,
                         **kwargs):
        printDBG("leaveMoviePlayer ret[%r], lastPosition[%r]" %
                 (ret, lastPosition))
        # There is need to set None for current service
        # otherwise there is a problem with resuming play
        self.session.nav.playService(None)
        self.lastPosition = lastPosition
        self.clipLength = clipLength
        self.canRunMoviePlayer = False
        self.inMoviePlayer = False

        self.closeRequestedByUser = ret

        if 'save_buffer' == ret:
            self.moveToDownloadManager()
        elif ret in ['key_exit', None]:
            if DMHelper.STS.DOWNLOADING == self.downloader.getStatus():
                self.lastSize = self.downloader.getLocalFileSize(True)
                printDBG(
                    "E2iPlayerBufferingWidget.leaveMoviePlayer: movie player consume all data from buffer - still downloading"
                )
                self.confirmExitCallBack()  # continue
            else:
                printDBG(
                    "E2iPlayerBufferingWidget.leaveMoviePlayer: movie player consume all data from buffer - downloading finished"
                )
                if DMHelper.STS.DOWNLOADED != self.downloader.getStatus():
                    self.session.openWithCallback(
                        self.iptvDoClose,
                        MessageBox,
                        text=_("Error occurs during download."),
                        type=MessageBox.TYPE_ERROR,
                        timeout=5)
                else:
                    self.iptvDoClose()
        elif ret in ['key_stop']:
            # ask if we should close
            self.lastSize = self.downloader.getLocalFileSize(True)
            #list = [ (_("yes"), True), (_("no"), False) ]
            #if self.downloadManager and self.downloader and self.downloader.getPlayableFileSize() > 0:
            #    list.append((_("yes, move playback buffer to the download manager"), 'move'))
            self.session.openWithCallback(self.confirmExitCallBack,
                                          MessageBox,
                                          text=_("Stop playing?"),
                                          type=MessageBox.TYPE_YESNO)

    def confirmExitCallBack(self, ret=None):
        if ret == True:
            self.iptvDoClose()
        elif ret == 'move':
            self.moveToDownloadManager()
        else:
            if not self._isInLiveMode():
                self.canRunMoviePlayer = True
                self.setMainTimerSts(True)
            else:
                # for live streams we will remove old buffer and start downloader once again
                self.lastSize = 0
                self.onEnd()
                self.onStart()

    def moveToDownloadManager(self, fromPlayer=True):
        fullFilesPaths = [
            self.downloadingPath + '/' + self.movieTitle + self.fileExtension,
            self.bufferingPath + '/' + self.movieTitle + self.fileExtension
        ]
        bRet, msg = self.downloadManager.addBufferItem(self.downloader,
                                                       fullFilesPaths)
        if bRet:
            self.downloader = None
            message = _(
                'The playback buffer has been moved to the download manager.\nIt will be saved in the file:\n\"%s\"'
            ) % msg
            self.session.openWithCallback(self.iptvDoClose,
                                          MessageBox,
                                          text=message,
                                          type=MessageBox.TYPE_INFO,
                                          timeout=5)
        else:
            # show error message and ask user what to do
            message = _(
                "Moving playback buffer to the download manager failed with the following error \"%s\""
                % msg)
            #message += '\n\n' + _("What do you want to do?")
            #list = [ (_("Continue playback"), True), (_("Stop playback"), False) ]
            if fromPlayer:
                message += '\n\n' + _("Stop playing?")
                self.session.openWithCallback(self.confirmExitCallBack,
                                              MessageBox,
                                              text=message,
                                              type=MessageBox.TYPE_YESNO)
            else:
                self.session.openWithCallback(self.iptvContinue,
                                              MessageBox,
                                              text=message,
                                              type=MessageBox.TYPE_INFO)

    def iptvContinue(self, *args, **kwargs):
        self.setMainTimerSts(True)
        self.canRunMoviePlayer = True

    def back_pressed(self):
        self.closeRequestedByUser = '******'
        self.iptvDoClose()

    def record_pressed(self):
        if self.canRunMoviePlayer:  # and self.downloader.getPlayableFileSize() > 0:
            self.canRunMoviePlayer = False
            self.setMainTimerSts(False)
            self.closeRequestedByUser = '******'
            self.moveToDownloadManager(False)

    def iptvDoClose(self, *args, **kwargs):
        self.onEnd()
        self.close(self.closeRequestedByUser, self.lastPosition,
                   self.clipLength)

    def ok_pressed(self):
        if self.canRunMoviePlayer and self.downloader.getPlayableFileSize(
        ) > 0:
            self.runMovePlayer()

    def runMovePlayer(self):
        # this shoudl not happen but to make sure
        if not self.canRunMoviePlayer:
            printDBG(
                'called runMovePlayer with canRunMoviePlayer set to False')
            return

        self.inMoviePlayer = True
        buffSize = self.downloader.getLocalFileSize() - self.lastSize
        printDBG("Run MoviePlayer with buffer size [%s]" %
                 formatBytes(float(buffSize)))
        self.setMainTimerSts(False)

        player = self.activMoviePlayer
        printDBG('E2iPlayerBufferingWidget.runMovePlayer [%r]' % player)
        playerAdditionalParams = dict(self.playerAdditionalParams)
        playerAdditionalParams['downloader'] = self.downloader
        if self.isMOOVAtomAtTheBeginning:
            playerAdditionalParams['moov_atom_info'] = {
                'offset': 0,
                'size': self.moovAtomOffset + self.moovAtomSize,
                'file': ''
            }
        elif self.moovAtomStatus == self.MOOV_STS.DOWNLOADED and \
             DMHelper.STS.DOWNLOADED != self.downloader.getStatus():
            playerAdditionalParams['moov_atom_info'] = {
                'offset': self.moovAtomOffset,
                'size': self.moovAtomSize,
                'file': self.moovAtomPath
            }

        if strwithmeta(self.url).meta.get('iptv_proto',
                                          '') in ['f4m', 'uds', 'm3u8']:
            playerAdditionalParams['file-download-timeout'] = 90000  # 90s
        else:
            playerAdditionalParams['file-download-timeout'] = 10000  # 10s
        playerAdditionalParams['file-download-live'] = self._isInLiveMode()
        playerAdditionalParams[
            'download_manager_available'] = self.downloadManager != None
        if "mini" == player:
            self.session.openWithCallback(self.leaveMoviePlayer,
                                          IPTVMiniMoviePlayer, self.filePath,
                                          self.movieTitle, self.lastPosition,
                                          4)
        elif "exteplayer" == player:
            self.session.openWithCallback(self.leaveMoviePlayer,
                                          IPTVExtMoviePlayer, self.filePath,
                                          self.movieTitle, self.lastPosition,
                                          'eplayer', playerAdditionalParams)
        elif "extgstplayer" == player:
            self.session.openWithCallback(self.leaveMoviePlayer,
                                          IPTVExtMoviePlayer, self.filePath,
                                          self.movieTitle, self.lastPosition,
                                          'gstplayer', playerAdditionalParams)
        else:
            self.session.openWithCallback(self.leaveMoviePlayer,
                                          IPTVStandardMoviePlayer,
                                          self.filePath, self.movieTitle)
        playerAdditionalParams = None

    def setMainTimerSts(self, start):
        try:
            if start:
                if not self.mainTimerEnabled:
                    self.mainTimer.start(self.mainTimerInterval)
                    self.mainTimerEnabled = True
                    self.updateDisplay()
            else:
                if self.mainTimerEnabled:
                    self.mainTimer.stop()
                    self.mainTimerEnabled = False
        except Exception:
            printDBG("setMainTimerSts status[%r] EXCEPTION" % start)

    def updateRecButton(self):
        if self.canRunMoviePlayer:  #and self.downloader.getPlayableFileSize() > 0:
            self['rec_button'].show()
        else:
            self['rec_button'].hide()

    def updateOKButton(self):
        if self.canRunMoviePlayer and False == self.checkMOOVAtom and (
                self.isMOOVAtomAtTheBeginning == None
                or self.moovAtomStatus == self.MOOV_STS.DOWNLOADED):
            self['ok_button'].show()
        else:
            self['rec_button'].hide()

    def updateDisplay(self):
        printDBG("updateDisplay")
        if self.inMoviePlayer:
            printDBG("updateDisplay aborted - we are in moviePlayer")
            return

        self.updateRecButton()

        if not self.mainTimerEnabled:
            printDBG("updateDisplay aborted - timer stoped")
            return

        self.downloader.updateStatistic()
        localSize = self.downloader.getLocalFileSize()
        remoteSize = self.downloader.getRemoteFileSize()

        if self.checkMOOVAtom and \
           localSize > 10240:
            self.checkMOOVAtom = False

            if remoteSize > self.maxMOOVAtomSize and \
               self.downloader.getName() == "wget" and \
               (self.clouldBeMP4 or (None != self.downloader.getMimeType() and \
               'mp4' in self.downloader.getMimeType())):
                # check moov atom position
                # if it is located at the begining of MP4 file
                # it should be just after ftyp atom
                try:
                    f = open(self.filePath, "rb")
                    currOffset = 0
                    while currOffset < localSize:
                        rawSize = ReadUint32(f.read(4), False)
                        rawType = f.read(4)
                        printDBG(">> rawType [%s]" % rawType)
                        printDBG(">> rawSize [%d]" % rawSize)
                        if currOffset == 0 and rawType != "ftyp":
                            # this does not looks like MP4 file
                            break
                        else:
                            if rawType == "moov":
                                self.moovAtomOffset = currOffset
                                self.moovAtomSize = rawSize
                                self.isMOOVAtomAtTheBeginning = True
                                break
                            elif rawType == "mdat":
                                # we are not sure if after mdat will be moov atom but
                                # if this will be max last 10MB of file then
                                # we will download it
                                self.moovAtomOffset = currOffset + rawSize
                                self.moovAtomSize = remoteSize - self.moovAtomOffset
                                self.isMOOVAtomAtTheBeginning = False
                                break
                            currOffset += rawSize
                        f.seek(currOffset, 0)
                    printDBG(">> moovAtomOffset[%d]" % self.moovAtomOffset)
                    printDBG(">> moovAtomSize[%d]" % self.moovAtomSize)
                except Exception:
                    printExc()

        if None != self.downloader and self.downloader.hasDurationInfo() \
           and self.downloader.getTotalFileDuration() > 0:
            totalDuration = self.downloader.getTotalFileDuration()
            downloadDuration = self.downloader.getDownloadedFileDuration()
            rFileSize = str(timedelta(seconds=totalDuration))
            lFileSize = str(timedelta(seconds=downloadDuration))
            if rFileSize.startswith('0:'):
                rFileSize = rFileSize[2:]
            if lFileSize.startswith('0:'):
                lFileSize = lFileSize[2:]
        else:
            # remote size
            if -1 == remoteSize: rFileSize = '??'
            else: rFileSize = formatBytes(float(remoteSize))
            # local size
            if -1 == localSize: lFileSize = '??'
            else: lFileSize = formatBytes(float(localSize))

        # download speed
        dSpeed = self.downloader.getDownloadSpeed()
        if dSpeed > -1 and localSize > 0:
            dSpeed = formatBytes(float(dSpeed))
        else:
            dSpeed = ''

        speed = self.downloader.getDownloadSpeed()
        tmpStr = ''
        if '??' != lFileSize:
            if '??' != rFileSize:
                tmpStr = "\n%s/%s" % (lFileSize, rFileSize)
            else:
                tmpStr = "\n%s" % (lFileSize)
            if '' != dSpeed:
                tmpStr += "\n%s/s" % (dSpeed)
        else:
            tmpStr += '\n\n'

        self["console"].setText(self.movieTitle + tmpStr)

        handled = False
        percentage = 0
        requestedBuffSize = -1
        tmpBuffSize = 0
        if self.isMOOVAtomAtTheBeginning == True:
            moovAtomDataSize = self.moovAtomOffset + self.moovAtomSize
            if moovAtomDataSize > localSize:
                if self.moovAtomStatus != self.MOOV_STS.DOWNLOADING:
                    self["addinfo"].setText(
                        _("Please wait for initialization data."))
                    self.moovAtomStatus = self.MOOV_STS.DOWNLOADING
                remoteSize = self.moovAtomOffset + self.moovAtomSize
                if localSize > remoteSize: percentage = 100
                else: percentage = (100 * localSize) / remoteSize
            else:
                requestedBuffSize = self.requestedBuffSize
                if self.lastSize > moovAtomDataSize:
                    tmpBuffSize = localSize - self.lastSize
                else:
                    tmpBuffSize = localSize - moovAtomDataSize
                if tmpBuffSize > requestedBuffSize: percentage = 100
                else: percentage = (100 * tmpBuffSize) / requestedBuffSize
                if self.moovAtomStatus != self.MOOV_STS.DOWNLOADED:
                    self["addinfo"].setText("")
                    self.moovAtomStatus = self.MOOV_STS.DOWNLOADED
            handled = True
        elif self.isMOOVAtomAtTheBeginning == False and self.moovAtomStatus not in [
                self.MOOV_STS.WAITING, self.MOOV_STS.ERROR,
                self.MOOV_STS.DOWNLOADED
        ]:
            # At now only exteplayer3 is able to use moov atom in separate file
            if self.activMoviePlayer == 'exteplayer' and self.moovAtomStatus == self.MOOV_STS.UNKNOWN:
                url, downloaderParams = DMHelper.getDownloaderParamFromUrl(
                    self.url)
                downloaderParams['start_pos'] = self.moovAtomOffset
                self.moovAtomDownloader = DownloaderCreator(self.url)
                self.moovAtomDownloader.start(url, self.moovAtomPath,
                                              downloaderParams)
                self.moovAtomStatus = self.MOOV_STS.DOWNLOADING
                self["addinfo"].setText(
                    _("Please wait - downloading initialization data."))
            elif self.moovAtomStatus == self.MOOV_STS.DOWNLOADING:
                self.moovAtomDownloader.updateStatistic()
                status = self.moovAtomDownloader.getStatus()
                moovLocalSize = self.moovAtomDownloader.getLocalFileSize()
                moovRemoteSize = self.moovAtomDownloader.getRemoteFileSize()
                if status == DMHelper.STS.DOWNLOADING:
                    if moovLocalSize > 0 and self.moovAtomSize > 0:
                        if moovLocalSize > self.moovAtomSize: percentage = 100
                        else:
                            percentage = (100 *
                                          moovLocalSize) / self.moovAtomSize
                elif status == DMHelper.STS.DOWNLOADED or (
                        status == DMHelper.STS.INTERRUPTED
                        and moovLocalSize == self.moovAtomSize):
                    self.moovAtomStatus = self.MOOV_STS.DOWNLOADED
                    self["addinfo"].setText("")
                else:
                    self.moovAtomStatus = self.MOOV_STS.ERROR

            handled = True
            if self.moovAtomStatus in [
                    self.MOOV_STS.UNKNOWN, self.MOOV_STS.ERROR
            ]:
                printDBG(">> [%s] [%s]" %
                         (self.activMoviePlayer, self.moovAtomStatus))
                msg = [_("Whole file must be downloaded to start playback!")]
                if self.moovAtomStatus == self.MOOV_STS.UNKNOWN and self.activMoviePlayer != 'exteplayer':
                    msg.append(
                        _("You can use external eplayer to start playback faster."
                          ))
                self["addinfo"].setText('\n'.join(msg))
                self.moovAtomStatus = self.MOOV_STS.WAITING
                handled = False

        if not handled and self.moovAtomStatus != self.MOOV_STS.WAITING:
            tmpBuffSize = localSize - self.lastSize + 1  # simple when getLocalFileSize() returns -1
            if self.downloader.getPlayableFileSize() > 0:
                requestedBuffSize = self.requestedBuffSize
                if tmpBuffSize > requestedBuffSize: percentage = 100
                else: percentage = (100 * tmpBuffSize) / requestedBuffSize
                handled = True

        if not handled and localSize > 0 and remoteSize > 0:
            if localSize > remoteSize: percentage = 100
            else: percentage = (100 * localSize) / remoteSize

        self["percentage"].setText(str(percentage))
        self["icon"].nextFrame()

        # check if we start movie player
        if self.canRunMoviePlayer:
            if (requestedBuffSize > -1 and tmpBuffSize >= requestedBuffSize) or \
               (self.downloader.getStatus() == DMHelper.STS.DOWNLOADED and 0 < localSize):
                self.runMovePlayer()
                return

        # check if it is downloading
        if self.downloader.getStatus() not in [
                DMHelper.STS.POSTPROCESSING, DMHelper.STS.DOWNLOADING,
                DMHelper.STS.WAITING
        ]:
            #messageTab = [_("Error occurs during download. \nStatus[%s], tmpBuffSize[%r], canRunMoviePlayer[%r]") % (self.downloader.getStatus(), tmpBuffSize, self.canRunMoviePlayer)]
            messageTab = [_("Error occurs during download.")]
            errorCode, errorDesc = self.downloader.getLastError()
            if errorCode != None:
                messageTab.append(
                    _('%s returned %s: %s') %
                    (self.downloader.getName(), errorCode, _(errorDesc)))
            self.session.openWithCallback(self.iptvDoClose,
                                          MessageBox,
                                          '\n'.join(messageTab),
                                          type=MessageBox.TYPE_ERROR,
                                          timeout=10)
            self.canRunMoviePlayer = False
            # stop timer before message
            self.setMainTimerSts(False)

        self.updateOKButton()
        self.updateRecButton()
        return

    def __del__(self):
        printDBG(
            'E2iPlayerBufferingWidget.__del__ --------------------------------------'
        )

    def __onClose(self):
        printDBG(
            'E2iPlayerBufferingWidget.__onClose ------------------------------------'
        )
        self.onEnd()
        self.session.nav.playService(self.currentService)
        try:
            self.mainTimer_conn = None
            self.mainTimer = None
        except Exception:
            printExc()

        self.onClose.remove(self.__onClose)
        #self.onLayoutFinish.remove(self.doStart)
        self.onShow.remove(self.onWindowShow)
        #self.onHide.remove(self.onWindowHide)
        self.downloadManager = None

    def _cleanedUp(self):
        if fileExists(self.filePath):
            try:
                os_remove(self.filePath)
            except Exception:
                printDBG('Problem with removing old buffering file (%s)' %
                         self.filePath)

        if fileExists(self.moovAtomPath):
            try:
                os_remove(self.moovAtomPath)
            except Exception:
                printDBG('Problem with removing old buffering file (%s)' %
                         self.moovAtomPath)

    '''
    def doStart(self):
        if not self.onStartCalled:
            self.onStartCalled = True
            self.onStart()
    
    
    def onWindowHide(self): 
        self.visible = False
    '''

    def onWindowShow(self):
        if not self.onStartCalled:
            self.onStartCalled = True
            self.onStart()
    def __init__(self,
                 session,
                 filesrcLocation,
                 FileName,
                 lastPosition=None,
                 player='eplayer',
                 additionalParams={}):
        # 'gstplayer'
        Screen.__init__(self, session)
        self.skinName = "IPTVExtMoviePlayer"
        self.player = player
        if 'gstplayer' == self.player:
            self.playerName = _("external gstplayer")
            self.gstAdditionalParams = {}
            self.gstAdditionalParams[
                'download-buffer-path'] = additionalParams.get(
                    'download-buffer-path', ''
                )  # File template to store temporary files in, should contain directory and XXXXXX
            self.gstAdditionalParams[
                'ring-buffer-max-size'] = additionalParams.get(
                    'ring-buffer-max-size', 0)  # in MB
            self.gstAdditionalParams['buffer-duration'] = additionalParams.get(
                'buffer-duration', -1)  # in s
            self.gstAdditionalParams['buffer-size'] = additionalParams.get(
                'buffer-size', 0)  # in KB
        else:
            self.playerName = _("external eplayer3")

        self.session.nav.playService(
            None
        )  # current service must be None to give free access to DVB Audio and Video Sinks
        self.fileSRC = filesrcLocation
        self.title = FileName
        if lastPosition:
            self.lastPosition = lastPosition
        else:
            self.lastPosition = 0
        self.downloader = additionalParams.get('downloader', None)

        printDBG('IPTVExtMoviePlayer.__init__ lastPosition[%r]' %
                 self.lastPosition)

        self.extPlayerCmddDispatcher = ExtPlayerCommandsDispatcher(self)

        self["actions"] = ActionMap(
            [
                'IPTVAlternateVideoPlayer', 'MoviePlayerActions',
                'MediaPlayerActions', 'MediaPlayerSeekActions', 'WizardActions'
            ], {
                "leavePlayer": self.key_stop,
                'play': self.key_play,
                'pause': self.key_pause,
                'exit': self.key_exit,
                'back': self.key_exit,
                'info': self.key_info,
                'seekdef:1': self.key_seek1,
                'seekdef:3': self.key_seek3,
                'seekdef:4': self.key_seek4,
                'seekdef:6': self.key_seek6,
                'seekdef:7': self.key_seek7,
                'seekdef:9': self.key_seek9,
                'seekFwd': self.key_seekFwd,
                'seekBack': self.key_seekBack,
                'left_press': self.key_left_press,
                'left_repeat': self.key_left_repeat,
                'rigth_press': self.key_rigth_press,
                'rigth_repeat': self.key_rigth_repeat,
                'ok': self.key_ok,
            }, -1)

        self.onClose.append(self.__onClose)
        #self.onShow.append(self.__onShow)
        self.onLayoutFinish.append(self.onStart)

        self.console = None

        self.isClosing = False
        self.responseData = ""

        # playback info
        # GUI
        self.updateInfoTimer = eTimer()
        self.updateInfoTimer_conn = eConnectCallback(
            self.updateInfoTimer.timeout, self.updateInfo)

        # playback info bar gui elements
        self['playbackInfoBaner'] = Cover3()
        self['statusIcon'] = Cover3()
        self['progressBar'] = ProgressBar()
        self['bufferingBar'] = ProgressBar()
        self['goToSeekPointer'] = Cover3()
        self['infoBarTitle'] = Label(self.title)
        self['goToSeekLabel'] = Label("0:00:00")
        self['currTimeLabel'] = Label("0:00:00")
        self['remainedLabel'] = Label("-0:00:00")
        self['lengthTimeLabel'] = Label("0:00:00")

        # goto seek  timer
        self.playback = {}
        self.playback['GoToSeekTimer'] = eTimer()
        self.playback['GoToSeekTimer_conn'] = eConnectCallback(
            self.playback['GoToSeekTimer'].timeout, self.doGoToSeek)

        self.playback.update({
            'CurrentTime': 0,
            'Length': 0,
            'LengthFromPlayerReceived': False,
            'GoToSeekTime': 0,
            'StartGoToSeekTime': 0,
            'GoToSeeking': False,
            'IsLive': False,
            'Status': None
        })
        # load pixmaps for statusIcon
        self.playback['statusIcons'] = {
            'Play': None,
            'Pause': None,
            'FastForward': None,
            'SlowMotion': None
        }
        try:
            self.playback['statusIcons']['Play'] = LoadPixmap(
                GetIPTVDMImgDir("playback_a_play.png"))
            self.playback['statusIcons']['Pause'] = LoadPixmap(
                GetIPTVDMImgDir("playback_a_pause.png"))
            self.playback['statusIcons']['FastForward'] = LoadPixmap(
                GetIPTVDMImgDir("playback_a_ff.png"))
            self.playback['statusIcons']['SlowMotion'] = self.playback[
                'statusIcons']['FastForward']
        except:
            printExc()

        # show hide info bar functionality
        self.goToSeekRepeatCount = 0
        self.goToSeekStep = 0
        self.playbackInfoBar = {
            'visible':
            False,
            'blocked':
            False,
            'guiElemNames': [
                'playbackInfoBaner', 'progressBar', 'bufferingBar',
                'goToSeekPointer', 'goToSeekLabel', 'infoBarTitle',
                'currTimeLabel', 'remainedLabel', 'lengthTimeLabel',
                'statusIcon'
            ]
        }
        self.playbackInfoBar['timer'] = eTimer()
        self.playbackInfoBar['timer_conn'] = eConnectCallback(
            self.playbackInfoBar['timer'].timeout, self.hidePlaybackInfoBar)

        self.isStarted = False
        self.hidePlaybackInfoBar()

        self.waitEOSAbortedFix = {
            'EOSaborted_received': False,
            'poll_received': False,
            'timer': None
        }
        self.waitEOSAbortedFix['timer'] = eTimer()
        self.waitEOSAbortedFix['timer_conn'] = eConnectCallback(
            self.waitEOSAbortedFix['timer'].timeout,
            self.waitEOSAbortedFixTimeoutCallback)

        self.waitCloseFix = {'waiting': False}
        self.waitCloseFix['timer'] = eTimer()
        self.waitCloseFix['timer_conn'] = eConnectCallback(
            self.waitCloseFix['timer'].timeout, self.waitCloseTimeoutCallback)

        self.isCloseRequestedByUser = False
        self.playerBinaryInfo = {'version': None, 'data': ''}
        self.messageQueue = []
        self.underMessage = False

        try:
            self.autoHideTime = 1000 * int(
                config.plugins.iptvplayer.extplayer_infobar_timeout.value)
        except:
            self.autoHideTime = 1000
class IPTVExtMoviePlayer(Screen):
    #
    skin = """
    <screen name="IPTVExtMoviePlayer"    position="center,center" size="%d,%d" flags="wfNoBorder" backgroundColor="#FFFFFFFF" >
            <widget name="playbackInfoBaner"  position="0,30"          size="650,77"  zPosition="2" pixmap="%s" transparent="1" alphatest="blend" />
            <widget name="progressBar"        position="94,54"         size="544,7"   zPosition="4" pixmap="%s" transparent="1" borderWidth="1" borderColor="#888888" />
            <widget name="bufferingBar"       position="94,54"         size="544,7"   zPosition="3" pixmap="%s" borderWidth="1" borderColor="#888888" />
            <widget name="statusIcon"         position="20,45"         size="40,40"   zPosition="4"             transparent="1" alphatest="blend" />
            
            <widget name="goToSeekPointer"    position="94,0"          size="150,60"  zPosition="8" pixmap="%s" transparent="1" alphatest="blend" />
            <widget name="goToSeekLabel"      position="94,0"          size="150,40"  zPosition="9" transparent="1" foregroundColor="white"     backgroundColor="#251f1f1f" font="Regular;24" halign="center" valign="center"/>
            <widget name="infoBarTitle"       position="82,30"         size="568,23"  zPosition="3" transparent="1" foregroundColor="white"     backgroundColor="#251f1f1f" font="Regular;18" halign="center" valign="center"/>
            <widget name="currTimeLabel"      position="94,62"         size="100,30"  zPosition="3" transparent="1" foregroundColor="#66ccff"   backgroundColor="#251f1f1f" font="Regular;24" halign="left"   valign="top"/>
            <widget name="lengthTimeLabel"    position="317,62"        size="100,30"  zPosition="3" transparent="1" foregroundColor="#999999"   backgroundColor="#251f1f1f" font="Regular;24" halign="center" valign="top"/>
            <widget name="remainedLabel"      position="538,62"        size="100,30"  zPosition="3" transparent="1" foregroundColor="#66ccff"   backgroundColor="#251f1f1f" font="Regular;24" halign="right"  valign="top"/>    
    </screen>""" % (getDesktop(0).size().width(),
                    getDesktop(0).size().height(),
                    GetIPTVDMImgDir("playback_banner.png"),
                    GetIPTVDMImgDir("playback_progress.png"),
                    GetIPTVDMImgDir("playback_buff_progress.png"),
                    GetIPTVDMImgDir('playback_pointer.png'))

    def __init__(self,
                 session,
                 filesrcLocation,
                 FileName,
                 lastPosition=None,
                 player='eplayer',
                 additionalParams={}):
        # 'gstplayer'
        Screen.__init__(self, session)
        self.skinName = "IPTVExtMoviePlayer"
        self.player = player
        if 'gstplayer' == self.player:
            self.playerName = _("external gstplayer")
            self.gstAdditionalParams = {}
            self.gstAdditionalParams[
                'download-buffer-path'] = additionalParams.get(
                    'download-buffer-path', ''
                )  # File template to store temporary files in, should contain directory and XXXXXX
            self.gstAdditionalParams[
                'ring-buffer-max-size'] = additionalParams.get(
                    'ring-buffer-max-size', 0)  # in MB
            self.gstAdditionalParams['buffer-duration'] = additionalParams.get(
                'buffer-duration', -1)  # in s
            self.gstAdditionalParams['buffer-size'] = additionalParams.get(
                'buffer-size', 0)  # in KB
        else:
            self.playerName = _("external eplayer3")

        self.session.nav.playService(
            None
        )  # current service must be None to give free access to DVB Audio and Video Sinks
        self.fileSRC = filesrcLocation
        self.title = FileName
        if lastPosition:
            self.lastPosition = lastPosition
        else:
            self.lastPosition = 0
        self.downloader = additionalParams.get('downloader', None)

        printDBG('IPTVExtMoviePlayer.__init__ lastPosition[%r]' %
                 self.lastPosition)

        self.extPlayerCmddDispatcher = ExtPlayerCommandsDispatcher(self)

        self["actions"] = ActionMap(
            [
                'IPTVAlternateVideoPlayer', 'MoviePlayerActions',
                'MediaPlayerActions', 'MediaPlayerSeekActions', 'WizardActions'
            ], {
                "leavePlayer": self.key_stop,
                'play': self.key_play,
                'pause': self.key_pause,
                'exit': self.key_exit,
                'back': self.key_exit,
                'info': self.key_info,
                'seekdef:1': self.key_seek1,
                'seekdef:3': self.key_seek3,
                'seekdef:4': self.key_seek4,
                'seekdef:6': self.key_seek6,
                'seekdef:7': self.key_seek7,
                'seekdef:9': self.key_seek9,
                'seekFwd': self.key_seekFwd,
                'seekBack': self.key_seekBack,
                'left_press': self.key_left_press,
                'left_repeat': self.key_left_repeat,
                'rigth_press': self.key_rigth_press,
                'rigth_repeat': self.key_rigth_repeat,
                'ok': self.key_ok,
            }, -1)

        self.onClose.append(self.__onClose)
        #self.onShow.append(self.__onShow)
        self.onLayoutFinish.append(self.onStart)

        self.console = None

        self.isClosing = False
        self.responseData = ""

        # playback info
        # GUI
        self.updateInfoTimer = eTimer()
        self.updateInfoTimer_conn = eConnectCallback(
            self.updateInfoTimer.timeout, self.updateInfo)

        # playback info bar gui elements
        self['playbackInfoBaner'] = Cover3()
        self['statusIcon'] = Cover3()
        self['progressBar'] = ProgressBar()
        self['bufferingBar'] = ProgressBar()
        self['goToSeekPointer'] = Cover3()
        self['infoBarTitle'] = Label(self.title)
        self['goToSeekLabel'] = Label("0:00:00")
        self['currTimeLabel'] = Label("0:00:00")
        self['remainedLabel'] = Label("-0:00:00")
        self['lengthTimeLabel'] = Label("0:00:00")

        # goto seek  timer
        self.playback = {}
        self.playback['GoToSeekTimer'] = eTimer()
        self.playback['GoToSeekTimer_conn'] = eConnectCallback(
            self.playback['GoToSeekTimer'].timeout, self.doGoToSeek)

        self.playback.update({
            'CurrentTime': 0,
            'Length': 0,
            'LengthFromPlayerReceived': False,
            'GoToSeekTime': 0,
            'StartGoToSeekTime': 0,
            'GoToSeeking': False,
            'IsLive': False,
            'Status': None
        })
        # load pixmaps for statusIcon
        self.playback['statusIcons'] = {
            'Play': None,
            'Pause': None,
            'FastForward': None,
            'SlowMotion': None
        }
        try:
            self.playback['statusIcons']['Play'] = LoadPixmap(
                GetIPTVDMImgDir("playback_a_play.png"))
            self.playback['statusIcons']['Pause'] = LoadPixmap(
                GetIPTVDMImgDir("playback_a_pause.png"))
            self.playback['statusIcons']['FastForward'] = LoadPixmap(
                GetIPTVDMImgDir("playback_a_ff.png"))
            self.playback['statusIcons']['SlowMotion'] = self.playback[
                'statusIcons']['FastForward']
        except:
            printExc()

        # show hide info bar functionality
        self.goToSeekRepeatCount = 0
        self.goToSeekStep = 0
        self.playbackInfoBar = {
            'visible':
            False,
            'blocked':
            False,
            'guiElemNames': [
                'playbackInfoBaner', 'progressBar', 'bufferingBar',
                'goToSeekPointer', 'goToSeekLabel', 'infoBarTitle',
                'currTimeLabel', 'remainedLabel', 'lengthTimeLabel',
                'statusIcon'
            ]
        }
        self.playbackInfoBar['timer'] = eTimer()
        self.playbackInfoBar['timer_conn'] = eConnectCallback(
            self.playbackInfoBar['timer'].timeout, self.hidePlaybackInfoBar)

        self.isStarted = False
        self.hidePlaybackInfoBar()

        self.waitEOSAbortedFix = {
            'EOSaborted_received': False,
            'poll_received': False,
            'timer': None
        }
        self.waitEOSAbortedFix['timer'] = eTimer()
        self.waitEOSAbortedFix['timer_conn'] = eConnectCallback(
            self.waitEOSAbortedFix['timer'].timeout,
            self.waitEOSAbortedFixTimeoutCallback)

        self.waitCloseFix = {'waiting': False}
        self.waitCloseFix['timer'] = eTimer()
        self.waitCloseFix['timer_conn'] = eConnectCallback(
            self.waitCloseFix['timer'].timeout, self.waitCloseTimeoutCallback)

        self.isCloseRequestedByUser = False
        self.playerBinaryInfo = {'version': None, 'data': ''}
        self.messageQueue = []
        self.underMessage = False

        try:
            self.autoHideTime = 1000 * int(
                config.plugins.iptvplayer.extplayer_infobar_timeout.value)
        except:
            self.autoHideTime = 1000

    def updateInfo(self):
        self.extPlayerCmddDispatcher.doUpdateInfo()
        if None != self.downloader:
            remoteFileSize = self.downloader.getRemoteFileSize()
            if 0 < remoteFileSize:
                localFileSize = self.downloader.getLocalFileSize(True)
                if 0 < localFileSize:
                    self['bufferingBar'].value = (localFileSize *
                                                  100000) / remoteFileSize

    def showMessage(self, message, type, callback=None):
        printDBG("IPTVExtMoviePlayer.showMessage")
        if self.isClosing and type != None: return
        messageItem = {'msg': message, 'type': type, 'callback': callback}
        self.messageQueue.append(messageItem)
        self.processMessageQueue()

    def processMessageQueue(self):
        if self.underMessage or 0 == len(self.messageQueue): return
        self.underMessage = True
        while len(self.messageQueue):
            messageItem = self.messageQueue.pop(0)
            message, type, callback = messageItem['msg'], messageItem[
                'type'], messageItem['callback']
            if None == type and None != callback:
                callback()
            else:
                if self.isClosing and None != callback:
                    continue  # skip message with callback
                else:
                    self.session.openWithCallback(boundFunction(
                        self.messageClosedCallback, callback),
                                                  MessageBox,
                                                  text=message,
                                                  type=type)
            return

    def messageClosedCallback(self, callback, arg=None):
        self.underMessage = False
        if None != callback: callback()
        else: self.processMessageQueue()

    def waitEOSAbortedFixTimeoutCallback(self):
        if self.waitEOSAbortedFix['EOSaborted_received']:
            self.extPlayerCmddDispatcher.stop()

    def playbackUpdateInfo(self, stsObj):
        for key, val in stsObj.iteritems():
            if 'Length' == key:
                if 0 > val:
                    printDBG(
                        'IPTVExtMoviePlayer.playbackUpdateInfo Length[%d] - live stream?'
                        % val)
                    val = 0
                    self.playback['IsLive'] = True
                else:
                    self.playback['IsLive'] = False
                if 0 < val:
                    # restore last position
                    if 10 < self.lastPosition and self.lastPosition < self.playback[
                            'Length']:
                        self.showPlaybackInfoBar()
                        self.extPlayerCmddDispatcher.doGoToSeek(
                            str(self.lastPosition - 5))
                        self.lastPosition = 0
                    tmpLength = self.playback['CurrentTime']
                    if val > self.playback['CurrentTime']: tmpLength = val
                    if 0 < tmpLength:
                        self.playback['Length'] = tmpLength
                        self['progressBar'].range = (0, tmpLength)
                        self['lengthTimeLabel'].setText(
                            str(timedelta(seconds=tmpLength)))
                    self.playback['LengthFromPlayerReceived'] = True
            elif 'CurrentTime' == key:
                if self.playback['Length'] < val:
                    self.playback['Length'] = val
                    self['progressBar'].range = (0, val)
                    self['lengthTimeLabel'].setText(str(
                        timedelta(seconds=val)))
                self['progressBar'].value = val
                self.playback['CurrentTime'] = stsObj['CurrentTime']
                if 0 < self.playback['CurrentTime']:
                    self.playback['StartGoToSeekTime'] = self.playback[
                        'CurrentTime']
                self['currTimeLabel'].setText(
                    str(timedelta(seconds=self.playback['CurrentTime'])))
                self['remainedLabel'].setText('-' + str(
                    timedelta(seconds=self.playback['Length'] -
                              self.playback['CurrentTime'])))
            elif 'Status' == key:
                curSts = self.playback['Status']
                if self.playback['Status'] != val[0]:
                    if 'Play' == val[0]:
                        self.showPlaybackInfoBar()
                    elif val[0] in ['Pause', 'FastForward', 'SlowMotion']:
                        self.showPlaybackInfoBar(blocked=True)
                    self.playback['Status'] = val[0]
                    self['statusIcon'].setPixmap(
                        self.playback['statusIcons'].get(val[0], None))
            else:
                self.playback[key] = val

    def doGoToSeek(self):
        self.playback['GoToSeekTimer'].stop()
        if self.playback['GoToSeeking']:
            self.showPlaybackInfoBar()
            self.playback['StartGoToSeekTime'] = self.playback['GoToSeekTime']
            self.extPlayerCmddDispatcher.doGoToSeek(
                str(self.playback['GoToSeekTime']))
            self.playback['GoToSeeking'] = False
            self['goToSeekPointer'].hide()
            self["goToSeekLabel"].hide()

    def doGoToSeekPointerMove(self, seek):
        printDBG(
            'IPTVExtMoviePlayer.doGoToSeekPointerMove seek[%r], LengthFromPlayerReceived[%r], GoToSeeking[%r]'
            % (seek, self.playback['LengthFromPlayerReceived'],
               self.playback['GoToSeeking']))
        self.playback['GoToSeekTimer'].stop()
        if not self.playback['LengthFromPlayerReceived']: return
        if not self.playback['GoToSeeking']:
            self.playback['GoToSeeking'] = True
            self.playback['GoToSeekTime'] = self.playback['StartGoToSeekTime']
            self.showPlaybackInfoBar([], True)
            self['goToSeekPointer'].show()
            self["goToSeekLabel"].show()

        # update data
        self.playback['GoToSeekTime'] += seek
        if self.playback['GoToSeekTime'] < 0: self.playback['GoToSeekTime'] = 0
        if self.playback['GoToSeekTime'] > self.playback['Length']:
            self.playback['GoToSeekTime'] = self.playback['Length']
        self["goToSeekLabel"].setText(
            str(timedelta(seconds=self.playback['GoToSeekTime'])))

        # update position
        # convert time to width
        relativeX = self["progressBar"].instance.size().width(
        ) * self.playback['GoToSeekTime'] / self.playback['Length']
        x = self['progressBar'].position[0] - self["goToSeekPointer"].getWidth(
        ) / 2 + relativeX

        self['goToSeekPointer'].setPosition(
            x, self['goToSeekPointer'].position[1])
        self["goToSeekLabel"].setPosition(x, self['goToSeekLabel'].position[1])

        # trigger delayed seek
        self.playback['GoToSeekTimer'].start(1000)

    # handling of RCU keys
    def key_stop(self):
        self.isCloseRequestedByUser = True
        self.extPlayerCmddDispatcher.stop()

    def key_play(self):
        self.extPlayerCmddDispatcher.play()

    def key_pause(self):
        self.extPlayerCmddDispatcher.pause()

    def key_exit(self):
        self.doExit()

    def key_info(self):
        self.doInfo()

    def key_seek1(self):
        self.extPlayerCmddDispatcher.doSeek(config.seek.selfdefined_13.value *
                                            -1)

    def key_seek3(self):
        self.extPlayerCmddDispatcher.doSeek(config.seek.selfdefined_13.value)

    def key_seek4(self):
        self.extPlayerCmddDispatcher.doSeek(config.seek.selfdefined_46.value *
                                            -1)

    def key_seek6(self):
        self.extPlayerCmddDispatcher.doSeek(config.seek.selfdefined_46.value)

    def key_seek7(self):
        self.extPlayerCmddDispatcher.doSeek(config.seek.selfdefined_79.value *
                                            -1)

    def key_seek9(self):
        self.extPlayerCmddDispatcher.doSeek(config.seek.selfdefined_79.value)

    def key_seekFwd(self):
        self.extPlayerCmddDispatcher.seekFwd()

    def key_seekBack(self):
        self.extPlayerCmddDispatcher.seekBack()

    def key_left_press(self):
        self.goToSeekKey(-1, 'press')

    def key_left_repeat(self):
        self.goToSeekKey(-1, 'repeat')

    def key_rigth_press(self):
        self.goToSeekKey(1, 'press')

    def key_rigth_repeat(self):
        self.goToSeekKey(1, 'repeat')

    def key_ok(self):
        if 'Pause' == self.playback['Status']:
            self.extPlayerCmddDispatcher.play()
        else:
            self.extPlayerCmddDispatcher.pause()

    def goToSeekKey(self, direction, state='press'):
        if 'press' == state:
            self.goToSeekStep = 5
            self.goToSeekRepeatCount = 1
        elif 3 <= self.goToSeekRepeatCount:
            self.goToSeekRepeatCount = 1
            self.goToSeekStep *= 2
        else:
            self.goToSeekRepeatCount += 1

        # not allow faster than (0.1 * playback length)
        if self.goToSeekStep > (self.playback['Length'] / 10):
            self.goToSeekStep = self.playback['Length'] / 10
        if 0 >= self.goToSeekStep:
            self.goToSeekStep = 1

        self.doGoToSeekPointerMove(self.goToSeekStep * direction)

    def doExit(self):
        if self.playbackInfoBar['visible']:
            self.playbackInfoBar['blocked'] = False
            self.hidePlaybackInfoBar()
        elif not self.isClosing:
            self.extPlayerCmddDispatcher.stop()

    def doInfo(self):
        if not self.playbackInfoBar['visible']:
            if self.isStarted and not self.isClosing:
                self.playbackInfoBar['blocked'] = True
                self.showPlaybackInfoBar()
        else:
            self.doExit()

    def eplayer3Finished(self, code):
        printDBG("IPTVExtMoviePlayer.eplayer3Finished code[%r]" % code)
        if self.isClosing: return

        msg = _(
            "It seems that the video player \"%s\" does not work properly.\n\nSTS: %s\nERROR CODE: %r"
        )
        if None == self.playerBinaryInfo['version']:
            msg = msg % (self.playerName, self.playerBinaryInfo['data'], code)
            self.showMessage(msg, MessageBox.TYPE_ERROR, self.onLeavePlayer)
        elif 'gstplayer' == self.player and 246 == code:
            msg = msg % (
                self.playerName,
                _("ERROR: pipeline could not be constructed: no element \"playbin2\" \nPlease check if gstreamer plugins are available in your system."
                  ), code)
            self.showMessage(msg, MessageBox.TYPE_ERROR, self.onLeavePlayer)
        else:
            self.onLeavePlayer()

    def waitCloseTimeoutCallback(self):
        printDBG("IPTVExtMoviePlayer.waitCloseTimeoutCallback")
        if None != self.console:
            printDBG("Force close movie player by sending CtrlC")
            self.console.sendCtrlC()
        self.onLeavePlayer()

    def eplayer3DataAvailable2(self, data):
        if None == data or self.isClosing:
            return

        if 'got buffer empty from driver!' in data:
            self.extPlayerCmddDispatcher.stop()

        # work around to catch EOF event after seeking, pause .etc
        if 'wait EOS aborted!!' in data:
            self.waitEOSAbortedFix['EOSaborted_received'] = True
            self.waitEOSAbortedFix['timer'].start(2000, True)  # singleshot

        if self.waitEOSAbortedFix['EOSaborted_received'] and 'poll' in data:
            self.waitEOSAbortedFix['timer'].stop()
            self.waitEOSAbortedFix['timer'].start(2000, True)

    def eplayer3DataAvailable(self, data):
        if None == data or self.isClosing:
            return
        if None == self.playerBinaryInfo['version']:
            self.playerBinaryInfo['data'] += data
        data = self.responseData + data
        if '\n' != data[-1]: truncated = True
        else: truncated = False
        data = data.split('\n')
        if truncated:
            self.responseData = data[-1]
            del data[-1]
        for item in data:
            printDBG(item)
            if item.startswith('{'):
                try:
                    obj = json.loads(item.strip())
                    printDBG("Status object [%r]" % obj)
                    key = obj.keys()[0]
                    obj = obj[key]
                except:
                    printExc()
                    continue

                if "PLAYBACK_PLAY" == key:
                    self.onStartPlayer()
                    if 'gstplayer' != self.player:
                        self.updateInfoTimer.start(1000)
                elif "PLAYBACK_STOP" == key:
                    self.onLeavePlayer()
                elif "PLAYBACK_LENGTH" == key and 0 == obj['sts']:
                    self.playbackUpdateInfo({'Length': int(obj['length'])})
                elif "PLAYBACK_CURRENT_TIME" == key and 0 == obj['sts']:
                    self.playbackUpdateInfo({'CurrentTime': int(obj['sec'])})
                elif "PLAYBACK_INFO" == key:
                    if obj['isPaused']:
                        self.playbackUpdateInfo({'Status': ['Pause', '0']})
                        if 'gstplayer' == self.player:
                            self.updateInfoTimer.stop()
                    else:
                        if 'gstplayer' == self.player:
                            self.updateInfoTimer.start(1000)
                        if obj['isForwarding']:
                            self.playbackUpdateInfo(
                                {'Status': ['FastForward',
                                            str(obj['Speed'])]})
                        elif 0 < obj['SlowMotion']:
                            self.playbackUpdateInfo({
                                'Status':
                                ['SlowMotion',
                                 '1/%d' % obj['SlowMotion']]
                            })
                        elif obj['isPlaying']:  # and 1 == obj['Speed']:
                            self.playbackUpdateInfo({'Status': ['Play', '1']})
                        else:
                            printDBG(
                                'eplayer3DataAvailable PLAYBACK_INFO not handled'
                            )
                elif "GSTPLAYER_EXTENDED" == key:
                    self.playerBinaryInfo['version'] = obj['version']
                elif "EPLAYER3_EXTENDED" == key:
                    self.playerBinaryInfo['version'] = obj['version']
                elif "GST_ERROR" == key:
                    self.showMessage(
                        '%s\ncode:%s' %
                        (obj['msg'].encode('utf-8'), obj['code']),
                        MessageBox.TYPE_ERROR, None)
                elif "GST_MISSING_PLUGIN" == key:
                    self.showMessage(obj['msg'].encode('utf-8'),
                                     MessageBox.TYPE_INFO, None)

                # {u'PLAYBACK_INFO':
                # {u'isSeeking': False,
                # u'BackWard': 0.0,
                # u'isForwarding': False,
                # u'mayWriteToFramebuffer': True,
                # u'AVSync': 1,
                # u'isTeletext': False,
                # u'isAudio': True,
                # u'isCreationPhase': False,
                # u'abortRequested': False,
                # u'isVideo': True,
                # u'isPaused': False,
                # u'SlowMotion': 0,
                # u'isPlaying': True,
                # u'Speed': 1,
                # u'isSubtitle': False,
                # u'isDvbSubtitle': False}}

    def __onClose(self):
        self.isClosing = True
        if None != self.console:
            self.console_appClosed_conn = None
            self.console_stderrAvail_conn = None
            self.console_stdoutAvail_conn = None
            self.console.sendCtrlC()
            self.console = None
        self.downloader = None
        self.playbackInfoBar['timer'].stop()
        self.playbackInfoBar['timer_conn'] = None
        self.waitEOSAbortedFix['timer_conn'] = None
        self.waitCloseFix['timer_conn'] = None

        self.updateInfoTimer_conn = None
        self.playback['GoToSeekTimer_conn'] = None
        self.onClose.remove(self.__onClose)
        self.messageQueue = []

    def onStartPlayer(self):
        self.isStarted = True
        self.showPlaybackInfoBar()

    def onLeavePlayer(self):
        printDBG("IPTVExtMoviePlayer.onLeavePlayer")
        if self.waitCloseFix['waiting'] and None != self.waitCloseFix['timer']:
            self.waitCloseFix['timer'].stop()
        self.updateInfoTimer.stop()
        self.playbackInfoBar['blocked'] = False
        self.hidePlaybackInfoBar()

        # onLeavePlayer can be called by two reason:
        #   - no data in buffer - should return sts = 1
        #   - triggered by user - should return sts = 0
        if self.isCloseRequestedByUser:
            sts = 0
        else:
            sts = 1

        self.isClosing = True
        self.showMessage(
            None, None,
            boundFunction(self.close, sts, self.playback.get('CurrentTime',
                                                             0)))

    def onStart(self):
        self.onLayoutFinish.remove(self.onStart)
        self['progressBar'].value = 0
        self['bufferingBar'].range = (0, 100000)
        self['bufferingBar'].value = 0
        self.initGuiComponentsPos()
        if 'gstplayer' == self.player:
            gstplayerPath = config.plugins.iptvplayer.gstplayerpath.value
            #'export GST_DEBUG="*:6" &&' +
            cmd = gstplayerPath + ' "%s"' % self.fileSRC
            if "://" in self.fileSRC:
                cmd += ' "%s" "%s"  "%s"  "%s" ' % (
                    self.gstAdditionalParams['download-buffer-path'],
                    self.gstAdditionalParams['ring-buffer-max-size'],
                    self.gstAdditionalParams['buffer-duration'],
                    self.gstAdditionalParams['buffer-size'])
                tmp = strwithmeta(self.fileSRC)
                url, httpParams = DMHelper.getDownloaderParamFromUrl(tmp)
                for key in httpParams:
                    cmd += (' "%s=%s" ' % (key, httpParams[key]))
                if 'http_proxy' in tmp.meta:
                    tmp = tmp.meta['http_proxy']
                    if '://' in tmp:
                        if '@' in tmp:
                            tmp = re.search(
                                '([^:]+?://)([^:]+?):([^@]+?)@(.+?)$', tmp)
                            if tmp:
                                cmd += (
                                    ' "proxy=%s" "proxy-id=%s" "proxy-pw=%s" '
                                    % (tmp.group(1) + tmp.group(4),
                                       tmp.group(2), tmp.group(3)))
                        else:
                            cmd += (' "proxy=%s" ' % tmp)
        else:
            cmd = 'exteplayer3 "%s"' % self.fileSRC + " > /dev/null"

        self.console = eConsoleAppContainer()
        self.console_appClosed_conn = eConnectCallback(self.console.appClosed,
                                                       self.eplayer3Finished)
        self.console_stderrAvail_conn = eConnectCallback(
            self.console.stderrAvail, self.eplayer3DataAvailable)
        #if 'gstplayer' == self.player:
        #    self.console_stdoutAvail_conn = eConnectCallback(self.console.stdoutAvail, self.eplayer3DataAvailable2 ) # work around to catch EOF event after seeking, pause .etc
        printDBG("onStart cmd[%s]" % cmd)
        self.console.execute(cmd)
        self['statusIcon'].setPixmap(
            self.playback['statusIcons']['Play'])  # sulge for test

    def initGuiComponentsPos(self):

        # calculate offset
        offset_x = (getDesktop(0).size().width() -
                    self['playbackInfoBaner'].instance.size().width()) / 2
        offset_y = (getDesktop(0).size().height() -
                    self['playbackInfoBaner'].instance.size().height()
                    ) - 50  # 10px - cropping guard
        if offset_x < 0: offset_x = 0
        if offset_y < 0: offset_y = 0

        for elem in self.playbackInfoBar['guiElemNames']:
            self[elem].setPosition(self[elem].position[0] + offset_x,
                                   self[elem].position[1] + offset_y)

    def showPlaybackInfoBar(self,
                            excludeElems=['goToSeekPointer', 'goToSeekLabel'],
                            blocked=None):
        self.playbackInfoBar['timer'].stop()

        for elem in self.playbackInfoBar['guiElemNames']:
            if elem not in excludeElems:
                self[elem].show()

        if None == blocked or self.playbackInfoBar['blocked']:
            blocked = self.playbackInfoBar['blocked']

        self.playbackInfoBar['visible'] = True

        if not blocked:
            self.playbackInfoBar['timer'].start(self.autoHideTime,
                                                True)  # singleshot

    def hidePlaybackInfoBar(self, excludeElems=[], force=False):
        self.playbackInfoBar['timer'].stop()

        if self.playbackInfoBar['blocked'] and not force:
            return

        for elem in self.playbackInfoBar['guiElemNames']:
            if elem not in excludeElems:
                self[elem].hide()

        self.playbackInfoBar['visible'] = False

    def __onShow(self):
        pass
        #Screen.hide(self) # we do not need window at now maybe in future

    def extPlayerSendCommand(self, command, arg1=''):
        printDBG(
            "IPTVExtMoviePlayer.extPlayerSendCommand command[%s] arg1[%s]" %
            (command, arg1))
        if None == self.console:
            printExc(
                "IPTVExtMoviePlayer.extPlayerSendCommand console not available"
            )
            return

        if 'PLAYBACK_LENGTH' == command:
            self.console.write("l\n")
        elif 'PLAYBACK_CURRENT_TIME' == command:
            self.console.write("j\n")
        elif 'PLAYBACK_INFO' == command:
            self.console.write("i\n")
        else:
            # All below commands require that 'PLAY ' status,
            # so we first send command to resume playback
            self.console.write("c\n")

            if 'PLAYBACK_CONTINUE' == command:
                # this is done to flush data
                # without thos workaround for some materials
                # there is a lack of liquidity playback after resume
                if 'eplayer' == self.player:
                    #self.console.write( "k-2\n" ) # this causing problem for non-seekable streams
                    self.console.write("c\n")
            elif 'PLAYBACK_PAUSE' == command:
                self.console.write("p\n")
            elif 'PLAYBACK_SEEK_RELATIVE' == command:
                self.console.write("kc%s\n" % (arg1))
            elif 'PLAYBACK_SEEK_ABS' == command:
                self.console.write("gf%s\n" % (arg1))
            elif 'PLAYBACK_FASTFORWARD' == command:
                self.console.write("f%s\n" % arg1)
            elif 'PLAYBACK_FASTBACKWARD' == command:
                self.console.write("b%s\n" % arg1)
            elif 'PLAYBACK_SLOWMOTION' == command:
                self.console.write("m%s\n" % arg1)
            elif 'PLAYBACK_STOP' == command:
                if not self.waitCloseFix['waiting']:
                    self.waitCloseFix['waiting'] = True
                    self.waitCloseFix['timer'].start(10000, True)  # singleshot
                self.console.write("q\n")
            else:
                printDBG(
                    "IPTVExtMoviePlayer.extPlayerSendCommand unknown command[%s]"
                    % command)