def __init__(self, session, url, pathForRecordings, pictureTitle): self.session = session Screen.__init__(self, session) self.onStartCalled = False self.recordingPath = pathForRecordings try: self.filePath = os.path.join(pathForRecordings, '.iptv_buffering.jpg') except: self.filePath = '' printExc() self.url = url self.pictureTitle = pictureTitle self.audioUrl = strwithmeta(url).meta.get("iptv_audio_url", '') self["actions"] = ActionMap(['IPTVAlternateVideoPlayer', 'MoviePlayerActions', 'MediaPlayerActions', 'WizardActions', 'DirectionActions'], { 'leavePlayer' : self.key_exit, 'play' : self.key_play, 'pause' : self.key_pause, 'exit' : self.key_exit, 'back' : self.key_exit, 'ok' : self.key_ok, }, -1) self["status"] = Label() self["console"] = Label() self["icon"] = SimpleAnimatedCover() self["picture"] = Cover() # prepare icon frames path frames = [] for idx in range(1,self.NUM_OF_ICON_FRAMES+1): frames.append( GetIconDir('/buffering/buffering_%d.png' % idx) ) self["icon"].loadFrames(frames) #main Timer self.mainTimer = eTimer() self.mainTimerEnabled = False self.mainTimer_conn = eConnectCallback(self.mainTimer.timeout, self.updateDisplay) self.mainTimerInterval = 100 # by default 0,1s # download self.downloader = DownloaderCreator(self.url) self.onClose.append(self.__onClose) self.onShow.append(self.doStart) #self.onLayoutFinish.append(self.doStart) self.autoRefresh = False self.refreshPostfixes = ['_0', '_1'] self.refreshCount = 0 self.refreshing = False if len(self.audioUrl) and len(config.plugins.iptvplayer.gstplayerpath.value): self.audioPlayer = IPTVSimpleAudioPlayer() else: self.audioPlayer = None
def _doStart(self, force=False): if self.autoRefresh or force: self.refreshing = True self.downloader = DownloaderCreator(self.url) url,downloaderParams = DMHelper.getDownloaderParamFromUrl(self.url) self.downloader.subscribeFor_Finish(self.downloaderEnd) self.downloader.start(url, self._getDownloadFilePath(), downloaderParams) self.setMainTimerSts(True) else: self.refreshing = False
def startDownload(self, item): self.setListMode(False) self.cleanDownloader() self.currItem = item self["console"].setText(_("Downloading subtitles.\n ('%r').") % self.currItem.get('url', '')) # create downloader self.downloader = DownloaderCreator(self.currItem.get('url', '')) if self.downloader: self.downloader.isWorkingCorrectly(self._startDownloader) else: self["console"].setText(_("Download can not be started.\n Incorrect address ('%r')."))
def onStart(self): ''' this method is called once like __init__ but in __init__ we cannot display MessageBox ''' self.lastPosition = None self.lastSize = 0 # create downloader self.downloader = DownloaderCreator(self.url) self._cleanedUp() if self.downloader: self.downloader.isWorkingCorrectly(self._startDownloader) else: self.session.openWithCallback(self.close, MessageBox, _("Pobieranie nie może zostać rozpoczęte.\n Podany adres ('%r') jest niepoprawny.") % self.url, type = MessageBox.TYPE_ERROR, timeout = 10)
def onStart(self): ''' this method is called once like __init__ but in __init__ we cannot display MessageBox ''' self.lastPosition = None self.lastSize = 0 # create downloader self.downloader = DownloaderCreator(self.url) self._cleanedUp() if self.downloader: self.downloader.isWorkingCorrectly(self._startDownloader) else: self.session.openWithCallback(self.close, MessageBox, _("Downloading can not be started.\n The address ('%r') is incorrect.") % self.url, type = MessageBox.TYPE_ERROR, timeout = 10)
def loadCover(self): self["cover"].hide() if 0 == len(self.artItem.images): return self.cover['src'] = self.artItem.images[0].get('url', '') if not self.cover['src'].startswith('http'): return self.cover['downloader'] = DownloaderCreator(self.cover['src']) if self.cover['downloader']: self.cover['downloader'].isWorkingCorrectly(self.startDownloader) else: self.session.openWithCallback( self.close, MessageBox, _("Downloading cannot be started.\n Invalid URI[%s].") % self.cover['src'], type=MessageBox.TYPE_ERROR, timeout=10)
def runCMD(self, item): printDBG("runCMD for downloadIdx[%d]" % item.downloadIdx) if DMHelper.DOWNLOAD_TYPE.INITIAL == item.tries: item.fileName = DMHelper.makeUnikalFileName( item.fileName, False, False) printDBG("Downloading started downloadIdx[%s] File[%s] URL[%s]" % (item.downloadIdx, item.fileName, item.url)) listUDIdx = self.findIdxInQueueUD(item.downloadIdx) self.queueUD[listUDIdx].status = DMHelper.STS.DOWNLOADING self.queueUD[listUDIdx].fileName = item.fileName url, downloaderParams = DMHelper.getDownloaderParamFromUrl(item.url) self.queueUD[listUDIdx].downloader = DownloaderCreator(url) self.queueUD[listUDIdx].callback = boundFunction( self.cmdFinished, item.downloadIdx) self.queueUD[listUDIdx].downloader.subscribeFor_Finish( self.queueUD[listUDIdx].callback) self.queueUD[listUDIdx].downloader.start(url, item.fileName, downloaderParams)
class IPTVPlayerBufferingWidget(Screen): GST_FLV_DEMUX_IS_DEMUXING_INFINITE_FILE = "/tmp/gst_flv_demux_is_demuxing_infinite_file" 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 ####################### # 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 printDBG("[IPTVPlayerBufferingWidget] desktop size %dx%d" % (sz_w, sz_h)) skin = """ <screen name="IPTVPlayerBufferingWidget" position="center,center" size="%d,%d" title="IPTV Player 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" /> </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 ) def __init__(self, session, url, pathForRecordings, movieTitle, activMoviePlayer, requestedBuffSize, playerAdditionalParams={}): self.session = session Screen.__init__(self, session) self.onStartCalled = False self.recordingPath = pathForRecordings self.filePath = pathForRecordings + '/.iptv_buffering.flv' self.url = url self.movieTitle = movieTitle 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( ["WizardActions", "MoviePlayerActions"], { "ok": self.ok_pressed, "back": self.back_pressed, "leavePlayer": self.back_pressed, }, -1) self["console"] = Label() self["percentage"] = Label() 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 #end def __init__(self, session): def onStart(self): ''' this method is called once like __init__ but in __init__ we cannot display MessageBox ''' self.lastPosition = None self.lastSize = 0 # create downloader self.downloader = DownloaderCreator(self.url) self._cleanedUp() if self.downloader: self.downloader.isWorkingCorrectly(self._startDownloader) else: self.session.openWithCallback( self.close, MessageBox, _("Pobieranie nie może zostać rozpoczęte.\n Podany adres ('%r') jest niepoprawny." ) % self.url, type=MessageBox.TYPE_ERROR, timeout=10) def _isFlvInfiniteFile(self, url): try: url = strwithmeta(url) if (url.startswith('rtmp') or url.split('?')[0].endswith('.f4m')) and url.meta.get( 'iptv_livestream', True): return True except: printExc() return False def _startDownloader(self, sts, reason): if sts: url, downloaderParams = DMHelper.getDownloaderParamFromUrl( self.url) if self._isFlvInfiniteFile(self.url): ret = touch( self.GST_FLV_DEMUX_IS_DEMUXING_INFINITE_FILE ) # TODO: check returns value, and display message in case of False self.downloader.start(url, self.filePath, downloaderParams) self.setMainTimerSts(True) self.canRunMoviePlayer = True else: self.session.openWithCallback( self.close, MessageBox, _("Pobieranie nie może zostać rozpoczęte.\n Downloader %s nie działa prawidłowo.\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 self._cleanedUp() def leaveMoviePlayer(self, ret=None, lastPosition=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.canRunMoviePlayer = False self.inMoviePlayer = False # ret == 1 - no data in buffer # ret == 0 - triggered by user if 1 == ret: if DMHelper.STS.DOWNLOADING == self.downloader.getStatus(): self.lastSize = self.downloader.getLocalFileSize(True) printDBG( "IPTVPlayerBufferingWidget.leaveMoviePlayer: movie player consume all data from buffer - still downloading" ) self.confirmExitCallBack() # continue else: printDBG( "IPTVPlayerBufferingWidget.leaveMoviePlayer: movie player consume all data from buffer - downloading finished" ) if DMHelper.STS.DOWNLOADED != self.downloader.getStatus(): self.session.openWithCallback( self.close, MessageBox, text=_("Nastąpił błąd pobierania."), type=MessageBox.TYPE_ERROR, timeout=5) else: self.close() elif 0 == ret or None == ret: # ask if we should close self.lastSize = self.downloader.getLocalFileSize(True) self.session.openWithCallback(self.confirmExitCallBack, MessageBox, text=_("Zakończyć odtwarzanie?"), type=MessageBox.TYPE_YESNO) def confirmExitCallBack(self, ret=None): if ret and ret == True: self.close() 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.onEnd() self.onStart() def back_pressed(self): self.close() return def ok_pressed(self): if self.canRunMoviePlayer and self.downloader.getLocalFileSize() > 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) exteplayerBlocked = strwithmeta(self.url).meta.get( 'iptv_block_exteplayer', False) printDBG( "runMovePlayer >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> exteplayerBlocked[%s]" % exteplayerBlocked) player = self.activMoviePlayer printDBG('IPTVPlayerBufferingWidget.runMovePlayer [%r]' % player) playerAdditionalParams = dict(self.playerAdditionalParams) playerAdditionalParams['downloader'] = self.downloader 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() if "mini" == player: self.session.openWithCallback(self.leaveMoviePlayer, IPTVMiniMoviePlayer, self.filePath, self.movieTitle, self.lastPosition, 4) elif "exteplayer" == player: if not exteplayerBlocked: self.session.openWithCallback(self.leaveMoviePlayer, IPTVExtMoviePlayer, self.filePath, self.movieTitle, self.lastPosition, 'eplayer', playerAdditionalParams) else: self.session.openWithCallback(self.leaveMoviePlayer, IPTVExtMoviePlayer, self.filePath, self.movieTitle, self.lastPosition, 'gstplayer', 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: printDBG("setMainTimerSts status[%r] EXCEPTION" % start) def updateDisplay(self): printDBG("updateDisplay") if self.inMoviePlayer: printDBG("updateDisplay aborted - we are in moviePlayer") return if not self.mainTimerEnabled: printDBG("updateDisplay aborted - timer stoped") return self.downloader.updateStatistic() tmpBuffSize = self.downloader.getLocalFileSize( ) - self.lastSize + 1 # simple when getLocalFileSize() returns -1 # remote size rFileSize = self.downloader.getRemoteFileSize() if -1 == rFileSize: rFileSize = '??' else: rFileSize = formatBytes(float(rFileSize)) # local size lFileSize = self.downloader.getLocalFileSize() if -1 == lFileSize: lFileSize = '??' else: lFileSize = formatBytes(float(lFileSize)) # download speed dSpeed = self.downloader.getDownloadSpeed() if -1 == dSpeed: dSpeed = '' else: dSpeed = formatBytes(float(dSpeed)) speed = self.downloader.getDownloadSpeed() tmpStr = '' if 0 < self.downloader.getLocalFileSize(): if 0 <= self.downloader.getRemoteFileSize(): tmpStr = "\n%s/%s" % (lFileSize, rFileSize) else: tmpStr = "\n%s" % (lFileSize) if 0 <= dSpeed: tmpStr += "\n%s/s" % (dSpeed) else: tmpStr += '\n\n' self["console"].setText(self.movieTitle + tmpStr) if tmpBuffSize > self.requestedBuffSize: percentage = 100 else: percentage = (100 * tmpBuffSize) / self.requestedBuffSize self["percentage"].setText(str(percentage)) self["icon"].nextFrame() # check if we start move player if self.canRunMoviePlayer: if tmpBuffSize >= self.requestedBuffSize or ( self.downloader.getStatus() == DMHelper.STS.DOWNLOADED and 0 < self.downloader.getLocalFileSize()): self.runMovePlayer() return # check if it is downloading if self.downloader.getStatus() not in [ DMHelper.STS.DOWNLOADING, DMHelper.STS.WAITING ]: self.session.openWithCallback( self.close, MessageBox, "Nastąpił błąd pobierania. \nStatus[%s], tmpBuffSize[%r], canRunMoviePlayer[%r]" % (self.downloader.getStatus(), tmpBuffSize, self.canRunMoviePlayer), type=MessageBox.TYPE_ERROR, timeout=10) self.canRunMoviePlayer = False # stop timer before message self.setMainTimerSts(False) return def __del__(self): printDBG( 'IPTVPlayerBufferingWidget.__del__ --------------------------------------' ) def __onClose(self): printDBG( 'IPTVPlayerBufferingWidget.__onClose ------------------------------------' ) self.onEnd() self.session.nav.playService(self.currentService) try: self.mainTimer_conn = None self.mainTimer = None except: printExc() self.onClose.remove(self.__onClose) #self.onLayoutFinish.remove(self.doStart) self.onShow.remove(self.onWindowShow) #self.onHide.remove(self.onWindowHide) def _cleanedUp(self): if fileExists(self.filePath): try: os_remove(self.filePath) except: printDBG('Problem with removing old buffering file') if fileExists(self.GST_FLV_DEMUX_IS_DEMUXING_INFINITE_FILE): try: os_remove(self.GST_FLV_DEMUX_IS_DEMUXING_INFINITE_FILE) except: printDBG('Problem with removing gstreamer flag file [%s]' % self.GST_FLV_DEMUX_IS_DEMUXING_INFINITE_FILE) ''' 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() #class IPTVPlayerWidget
class IPTVPlayerBufferingWidget(Screen): GST_FLV_DEMUX_IS_DEMUXING_INFINITE_FILE = "/tmp/gst_flv_demux_is_demuxing_infinite_file" 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 ####################### # 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 printDBG("[IPTVPlayerBufferingWidget] desktop size %dx%d" % (sz_w, sz_h) ) skin = """ <screen name="IPTVPlayerBufferingWidget" position="center,center" size="%d,%d" title="IPTV Player 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" /> </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 ) def __init__(self, session, url, pathForRecordings, movieTitle, activMoviePlayer, requestedBuffSize, playerAdditionalParams={}): self.session = session Screen.__init__(self, session) self.onStartCalled = False self.recordingPath = pathForRecordings self.filePath = pathForRecordings + '/.iptv_buffering.flv' self.url = url self.movieTitle = movieTitle 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(["WizardActions", "MoviePlayerActions"], { "ok": self.ok_pressed, "back": self.back_pressed, "leavePlayer": self.back_pressed, }, -1) self["console"] = Label() self["percentage"] = Label() 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 #end def __init__(self, session): def onStart(self): ''' this method is called once like __init__ but in __init__ we cannot display MessageBox ''' self.lastPosition = None self.lastSize = 0 # create downloader self.downloader = DownloaderCreator(self.url) self._cleanedUp() if self.downloader: self.downloader.isWorkingCorrectly(self._startDownloader) else: self.session.openWithCallback(self.close, MessageBox, _("Pobieranie nie może zostać rozpoczęte.\n Podany adres ('%r') jest niepoprawny.") % self.url, type = MessageBox.TYPE_ERROR, timeout = 10) def _isFlvInfiniteFile(self, url): try: url = strwithmeta(url) if (url.startswith('rtmp') or url.split('?')[0].endswith('.f4m')) and url.meta.get('iptv_livestream', True): return True except: printExc() return False def _startDownloader(self, sts, reason): if sts: url,downloaderParams = DMHelper.getDownloaderParamFromUrl(self.url) if self._isFlvInfiniteFile(self.url): ret = touch(self.GST_FLV_DEMUX_IS_DEMUXING_INFINITE_FILE) # TODO: check returns value, and display message in case of False self.downloader.start(url, self.filePath, downloaderParams) self.setMainTimerSts(True) self.canRunMoviePlayer = True else: self.session.openWithCallback(self.close, MessageBox, _("Pobieranie nie może zostać rozpoczęte.\n Downloader %s nie działa prawidłowo.\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 self._cleanedUp() def leaveMoviePlayer(self, ret=None, lastPosition=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.canRunMoviePlayer = False self.inMoviePlayer = False # ret == 1 - no data in buffer # ret == 0 - triggered by user if 1 == ret: if DMHelper.STS.DOWNLOADING == self.downloader.getStatus(): self.lastSize = self.downloader.getLocalFileSize(True) printDBG("IPTVPlayerBufferingWidget.leaveMoviePlayer: movie player consume all data from buffer - still downloading") self.confirmExitCallBack() # continue else: printDBG("IPTVPlayerBufferingWidget.leaveMoviePlayer: movie player consume all data from buffer - downloading finished") if DMHelper.STS.DOWNLOADED != self.downloader.getStatus(): self.session.openWithCallback(self.close, MessageBox, text=_("Nastąpił błąd pobierania."), type = MessageBox.TYPE_ERROR, timeout=5) else: self.close() elif 0 == ret or None == ret: # ask if we should close self.lastSize = self.downloader.getLocalFileSize(True) self.session.openWithCallback(self.confirmExitCallBack, MessageBox, text=_("Zakończyć odtwarzanie?"), type=MessageBox.TYPE_YESNO) def confirmExitCallBack(self, ret=None): if ret and ret == True: self.close() 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.onEnd() self.onStart() def back_pressed(self): self.close() return def ok_pressed(self): if self.canRunMoviePlayer and self.downloader.getLocalFileSize() > 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) exteplayerBlocked = strwithmeta(self.url).meta.get('iptv_block_exteplayer', False) printDBG("runMovePlayer >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> exteplayerBlocked[%s]" % exteplayerBlocked) player = self.activMoviePlayer printDBG('IPTVPlayerBufferingWidget.runMovePlayer [%r]' % player) playerAdditionalParams = dict(self.playerAdditionalParams) playerAdditionalParams['downloader'] = self.downloader 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() if "mini" == player: self.session.openWithCallback(self.leaveMoviePlayer, IPTVMiniMoviePlayer, self.filePath, self.movieTitle, self.lastPosition, 4) elif "exteplayer" == player: if not exteplayerBlocked: self.session.openWithCallback(self.leaveMoviePlayer, IPTVExtMoviePlayer, self.filePath, self.movieTitle, self.lastPosition, 'eplayer', playerAdditionalParams) else: self.session.openWithCallback(self.leaveMoviePlayer, IPTVExtMoviePlayer, self.filePath, self.movieTitle, self.lastPosition, 'gstplayer', 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: printDBG("setMainTimerSts status[%r] EXCEPTION" % start) def updateDisplay(self): printDBG("updateDisplay") if self.inMoviePlayer: printDBG("updateDisplay aborted - we are in moviePlayer") return if not self.mainTimerEnabled: printDBG("updateDisplay aborted - timer stoped") return self.downloader.updateStatistic() tmpBuffSize = self.downloader.getLocalFileSize() - self.lastSize + 1 # simple when getLocalFileSize() returns -1 # remote size rFileSize = self.downloader.getRemoteFileSize() if -1 == rFileSize: rFileSize = '??' else: rFileSize = formatBytes(float(rFileSize)) # local size lFileSize = self.downloader.getLocalFileSize() if -1 == lFileSize: lFileSize = '??' else: lFileSize = formatBytes(float(lFileSize)) # download speed dSpeed = self.downloader.getDownloadSpeed() if -1 == dSpeed: dSpeed = '' else: dSpeed = formatBytes(float(dSpeed)) speed = self.downloader.getDownloadSpeed() tmpStr = '' if 0 < self.downloader.getLocalFileSize(): if 0 <= self.downloader.getRemoteFileSize(): tmpStr = "\n%s/%s" % (lFileSize, rFileSize) else: tmpStr = "\n%s" % (lFileSize) if 0 <= dSpeed: tmpStr += "\n%s/s" % (dSpeed) else: tmpStr += '\n\n' self["console"].setText(self.movieTitle + tmpStr) if tmpBuffSize > self.requestedBuffSize: percentage = 100 else: percentage = (100 * tmpBuffSize) / self.requestedBuffSize self["percentage"].setText(str(percentage)) self["icon"].nextFrame() # check if we start move player if self.canRunMoviePlayer: if tmpBuffSize >= self.requestedBuffSize or (self.downloader.getStatus() == DMHelper.STS.DOWNLOADED and 0 < self.downloader.getLocalFileSize()): self.runMovePlayer() return # check if it is downloading if self.downloader.getStatus() not in [DMHelper.STS.DOWNLOADING, DMHelper.STS.WAITING]: self.session.openWithCallback(self.close, MessageBox, "Nastąpił błąd pobierania. \nStatus[%s], tmpBuffSize[%r], canRunMoviePlayer[%r]" % (self.downloader.getStatus(), tmpBuffSize, self.canRunMoviePlayer), type = MessageBox.TYPE_ERROR, timeout = 10 ) self.canRunMoviePlayer = False # stop timer before message self.setMainTimerSts(False) return def __del__(self): printDBG('IPTVPlayerBufferingWidget.__del__ --------------------------------------') def __onClose(self): printDBG('IPTVPlayerBufferingWidget.__onClose ------------------------------------') self.onEnd() self.session.nav.playService(self.currentService) try: self.mainTimer_conn = None self.mainTimer = None except: printExc() self.onClose.remove(self.__onClose) #self.onLayoutFinish.remove(self.doStart) self.onShow.remove(self.onWindowShow) #self.onHide.remove(self.onWindowHide) def _cleanedUp(self): if fileExists(self.filePath): try: os_remove(self.filePath) except: printDBG('Problem with removing old buffering file') if fileExists(self.GST_FLV_DEMUX_IS_DEMUXING_INFINITE_FILE): try: os_remove(self.GST_FLV_DEMUX_IS_DEMUXING_INFINITE_FILE) except: printDBG('Problem with removing gstreamer flag file [%s]' % self.GST_FLV_DEMUX_IS_DEMUXING_INFINITE_FILE) ''' 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() #class IPTVPlayerWidget
def __init__(self, session, url, pathForRecordings, pictureTitle, addParams={}): self.session = session Screen.__init__(self, session) self.onStartCalled = False self.recordingPath = pathForRecordings try: self.filePath = os.path.join(pathForRecordings, '.iptv_buffering.jpg') except Exception: self.filePath = '' printExc() self.addParams = {'seq_mode': False} self.addParams.update(addParams) self.url = url self.pictureTitle = pictureTitle self.audioUrl = strwithmeta(url).meta.get("iptv_audio_url", '') self["actions"] = ActionMap( [ 'IPTVAlternateVideoPlayer', 'MoviePlayerActions', 'MediaPlayerActions', 'WizardActions', 'DirectionActions' ], { 'leavePlayer': self.key_exit, 'play': self.key_play, 'pause': self.key_pause, 'exit': self.key_exit, 'back': self.key_exit, 'ok': self.key_ok, }, -1) self["status"] = Label() self["console"] = Label() self["icon"] = SimpleAnimatedCover() self["picture"] = Cover() # prepare icon frames path frames = [] for idx in range(1, self.NUM_OF_ICON_FRAMES + 1): frames.append(GetIconDir('/buffering/buffering_%d.png' % idx)) self["icon"].loadFrames(frames) #main Timer self.mainTimer = eTimer() self.mainTimerEnabled = False if self.addParams['seq_mode']: self.canAutoClose = True self.mainTimer_conn = eConnectCallback(self.mainTimer.timeout, self.closeAfterTimeout) self.mainTimerInterval = 1000 * 10 #10s else: self.mainTimer_conn = eConnectCallback(self.mainTimer.timeout, self.updateDisplay) self.mainTimerInterval = 100 # by default 0,1s # download self.downloader = DownloaderCreator(self.url) self.onClose.append(self.__onClose) self.onShow.append(self.doStart) #self.onLayoutFinish.append(self.doStart) self.autoRefresh = False self.refreshPostfixes = ['_0', '_1'] self.refreshCount = 0 self.refreshing = False if len(self.audioUrl) and len( config.plugins.iptvplayer.gstplayerpath.value): self.audioPlayer = IPTVSimpleAudioPlayer() else: self.audioPlayer = None
class IPTVPicturePlayerWidget(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() # percentage s_w = 120 s_h = 120 # icon i_w = 128 i_h = 128 # console c_w = sz_w c_h = 80 # picture p_w = sz_w - 20 p_h = sz_h - 20 ####################### # POSITIONS ####################### start_y = (sz_h - (i_h + c_h)) / 2 # percentage s_x = (sz_w - s_w) / 2 s_y = start_y + (i_h - s_h) / 2 # icon i_x = (sz_w - i_w) / 2 i_y = start_y # console c_x = 0 c_y = i_y + i_h # picture p_x = 10 p_y = 10 printDBG("[IPTVPicturePlayerWidget] desktop size %dx%d" % (sz_w, sz_h)) skin = """ <screen name="IPTVPicturePlayerWidget" position="center,center" size="%d,%d" title="IPTV Picture Player..."> <widget name="status" 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="on" /> <widget name="picture" size="%d,%d" position="%d,%d" zPosition="6" transparent="1" alphatest="on" /> </screen>""" % ( sz_w, sz_h, # screen s_w, s_h, s_x, s_y, # status c_w, c_h, c_x, c_y, # console i_w, i_h, i_x, i_y, # icon p_w, p_h, p_x, p_y # picture ) def __init__(self, session, url, pathForRecordings, pictureTitle, addParams={}): self.session = session Screen.__init__(self, session) self.onStartCalled = False self.recordingPath = pathForRecordings try: self.filePath = os.path.join(pathForRecordings, '.iptv_buffering.jpg') except Exception: self.filePath = '' printExc() self.addParams = {'seq_mode': False} self.addParams.update(addParams) self.url = url self.pictureTitle = pictureTitle self.audioUrl = strwithmeta(url).meta.get("iptv_audio_url", '') self["actions"] = ActionMap( [ 'IPTVAlternateVideoPlayer', 'MoviePlayerActions', 'MediaPlayerActions', 'WizardActions', 'DirectionActions' ], { 'leavePlayer': self.key_exit, 'play': self.key_play, 'pause': self.key_pause, 'exit': self.key_exit, 'back': self.key_exit, 'ok': self.key_ok, }, -1) self["status"] = Label() self["console"] = Label() self["icon"] = SimpleAnimatedCover() self["picture"] = Cover() # prepare icon frames path frames = [] for idx in range(1, self.NUM_OF_ICON_FRAMES + 1): frames.append(GetIconDir('/buffering/buffering_%d.png' % idx)) self["icon"].loadFrames(frames) #main Timer self.mainTimer = eTimer() self.mainTimerEnabled = False if self.addParams['seq_mode']: self.canAutoClose = True self.mainTimer_conn = eConnectCallback(self.mainTimer.timeout, self.closeAfterTimeout) self.mainTimerInterval = 1000 * 10 #10s else: self.mainTimer_conn = eConnectCallback(self.mainTimer.timeout, self.updateDisplay) self.mainTimerInterval = 100 # by default 0,1s # download self.downloader = DownloaderCreator(self.url) self.onClose.append(self.__onClose) self.onShow.append(self.doStart) #self.onLayoutFinish.append(self.doStart) self.autoRefresh = False self.refreshPostfixes = ['_0', '_1'] self.refreshCount = 0 self.refreshing = False if len(self.audioUrl) and len( config.plugins.iptvplayer.gstplayerpath.value): self.audioPlayer = IPTVSimpleAudioPlayer() else: self.audioPlayer = None #end def __init__(self, session): def __del__(self): printDBG( 'IPTVPicturePlayerWidget.__del__ --------------------------------------' ) def __onClose(self): printDBG( 'IPTVPicturePlayerWidget.__onClose ------------------------------------' ) if None != self.audioPlayer: self.audioPlayer.close() self.onEnd() if None != self.mainTimer: try: self.mainTimer.stop() except Exception: pass self.mainTimer_conn = None self.mainTimer = None self.onClose.remove(self.__onClose) #self.onLayoutFinish.remove(self.doStart) def _getDownloadFilePath(self): return self.filePath + self.refreshPostfixes[self.refreshCount % len( self.refreshPostfixes)] def closeAfterTimeout(self): if self.canAutoClose: self.close() def onStart(self): ''' this method is called once like __init__ but in __init__ we cannot display MessageBox ''' self["picture"].hide() self["console"].setText(self.pictureTitle) self["status"].setText(_("--")) self._cleanedUp() if self.url.startswith('file://'): self.filePath = self.url[7:] self["status"].setText(_("++")) if -1 == self["picture"].decodeCover(self.filePath, self.decodePictureEnd, ' '): self.decodePictureEnd() else: if self.downloader: self.downloader.isWorkingCorrectly(self._startDownloader) else: self.session.openWithCallback( self.close, MessageBox, _("Downloading cannot be started.\n Invalid URI[%s].") % self.url, type=MessageBox.TYPE_ERROR, timeout=10) def _doStart(self, force=False): if self.addParams['seq_mode']: self.mainTimer.start(self.mainTimerInterval, True) #single shot return if self.autoRefresh or force: self.refreshing = True self.downloader = DownloaderCreator(self.url) url, downloaderParams = DMHelper.getDownloaderParamFromUrl( self.url) self.downloader.subscribeFor_Finish(self.downloaderEnd) self.downloader.start(url, self._getDownloadFilePath(), downloaderParams) self.setMainTimerSts(True) else: self.refreshing = False def _startDownloader(self, sts, reason): if sts: self._doStart(True) else: self.session.openWithCallback( self.close, MessageBox, _("Downloading cannot be started.\n Downloader [%s] not working properly.\n Status[%s]" ) % (self.downloader.getName(), reason.strip()), type=MessageBox.TYPE_ERROR, timeout=10) def onEnd(self, withCleanUp=True): self.setMainTimerSts(False) if self.downloader: self.downloader.unsubscribeFor_Finish(self.downloaderEnd) downloader = self.downloader self.downloader = None downloader.terminate() downloader = None if withCleanUp: self._cleanedUp() def key_exit(self): self.close('key_exit') def key_play(self): if self.addParams['seq_mode']: self.canAutoClose = False return if not self.autoRefresh and not self.url.startswith('file://'): if None != self.audioPlayer: self.audioPlayer.start(self.audioUrl) self.autoRefresh = True if not self.refreshing: self._doStart() def key_pause(self): if self.addParams['seq_mode']: self.canAutoClose = False return if self.autoRefresh: if None != self.audioPlayer: self.audioPlayer.stop() self.autoRefresh = False def key_ok(self): if self.addParams['seq_mode']: self.canAutoClose = False return if self.autoRefresh: self.key_pause() else: self.key_play() def downloaderEnd(self, status): if None != self.downloader: self.onEnd(False) if DMHelper.STS.DOWNLOADED == status: self["status"].setText(_("++")) if -1 == self["picture"].decodeCover( self._getDownloadFilePath(), self.decodePictureEnd, ' '): self.decodePictureEnd() else: if 0 == self.refreshCount: self.session.openWithCallback( self.close, MessageBox, (_("Downloading file [%s] problem.") % self.url) + (" sts[%r]" % status), type=MessageBox.TYPE_ERROR, timeout=10) self._doStart() def decodePictureEnd(self, ret={}): printDBG('IPTVPicturePlayerWidget.decodePictureEnd') if None == ret.get('Pixmap', None): if 0 == self.refreshCount: self.session.openWithCallback(self.close, MessageBox, _("Decode file [%s] problem.") % self.filePath, type=MessageBox.TYPE_ERROR, timeout=10) else: self.refreshCount += 1 self["status"].hide() self["console"].hide() self["icon"].hide() self["picture"].updatePixmap(ret.get('Pixmap', None), ret.get('FileName', self.filePath)) self["picture"].show() self.setMainTimerSts(False) self._doStart() 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: printExc( "IPTVPicturePlayerWidget.setMainTimerSts status[%r] EXCEPTION" % start) def updateDisplay(self): printDBG("updateDisplay") if not self.mainTimerEnabled: printDBG("updateDisplay aborted - timer stopped") return self["icon"].nextFrame() return def _cleanedUp(self): for item in self.refreshPostfixes: filePath = self.filePath + item if fileExists(filePath): try: os.remove(filePath) except Exception: printDBG('Problem with removing old buffering file') def doStart(self): self.onShow.remove(self.doStart) if not self.onStartCalled: self.onStartCalled = True self.onStart()
class IPTVPlayerBufferingWidget(Screen): NUM_OF_ICON_FRAMES = 8 ####################### # SIZES ####################### # screen size # we do not want borders, so make the screen lager than a desktop sz_w = 1980 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 printDBG("[IPTVPlayerBufferingWidget] desktop size %dx%d" % (sz_w, sz_h) ) skin = """ <screen name="IPTVPlayerBufferingWidget" position="center,center" size="%d,%d" title="IPTV Player 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" /> </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 ) def __init__(self, session, url, pathForRecordings, movieTitle, activMoviePlayer, requestedBuffSize, playerAdditionalParams={}): self.session = session Screen.__init__(self, session) self.onStartCalled = False self.recordingPath = pathForRecordings self.filePath = pathForRecordings + '/.iptv_buffering.flv' self.url = url self.movieTitle = movieTitle 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(["WizardActions", "MoviePlayerActions"], { "ok": self.ok_pressed, "back": self.back_pressed, "leavePlayer": self.back_pressed, }, -1) self["console"] = Label() self["percentage"] = Label() self["addinfo"] = Label() 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 = pathForRecordings + '/.iptv_buffering_moov.flv' 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 ''' # 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.downloader: self.moovAtomDownloader.terminate() self.downloader = 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 # ret == 1 - no data in buffer # ret == 0 - triggered by user if 1 == ret: if DMHelper.STS.DOWNLOADING == self.downloader.getStatus(): self.lastSize = self.downloader.getLocalFileSize(True) printDBG("IPTVPlayerBufferingWidget.leaveMoviePlayer: movie player consume all data from buffer - still downloading") self.confirmExitCallBack() # continue else: printDBG("IPTVPlayerBufferingWidget.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 0 == ret or None == ret: # ask if we should close self.lastSize = self.downloader.getLocalFileSize(True) self.session.openWithCallback(self.confirmExitCallBack, MessageBox, text=_("Stop playing?"), type=MessageBox.TYPE_YESNO) def confirmExitCallBack(self, ret=None): if ret and ret == True: self.iptvDoClose() 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 back_pressed(self): self.iptvDoClose() return def iptvDoClose(self, *args, **kwargs): self.onEnd() self.close(None, 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('IPTVPlayerBufferingWidget.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() 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 updateDisplay(self): printDBG("updateDisplay") if self.inMoviePlayer: printDBG("updateDisplay aborted - we are in moviePlayer") return 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]: self.session.openWithCallback(self.iptvDoClose, MessageBox, _("Error occurs during download. \nStatus[%s], tmpBuffSize[%r], canRunMoviePlayer[%r]") % (self.downloader.getStatus(), tmpBuffSize, self.canRunMoviePlayer), type = MessageBox.TYPE_ERROR, timeout = 10 ) self.canRunMoviePlayer = False # stop timer before message self.setMainTimerSts(False) return def __del__(self): printDBG('IPTVPlayerBufferingWidget.__del__ --------------------------------------') def __onClose(self): printDBG('IPTVPlayerBufferingWidget.__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) 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() #class IPTVPlayerWidget
class IPTVSubSimpleDownloaderWidget(Screen): _TMP_FILE_NAME = '.externaltmpsub' sz_w = getDesktop(0).size().width() - 190 sz_h = getDesktop(0).size().height() - 195 if sz_h < 500: sz_h += 4 skin = """ <screen name="IPTVSubSimpleDownloaderWidget" position="center,center" title="%s" size="%d,%d"> <widget name="icon_red" position="5,9" zPosition="4" size="30,30" transparent="1" alphatest="on" /> <widget name="icon_green" position="355,9" zPosition="4" size="30,30" transparent="1" alphatest="on" /> <widget name="label_red" position="45,9" size="175,27" zPosition="5" valign="center" halign="left" backgroundColor="black" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget name="label_green" position="395,9" size="175,27" zPosition="5" valign="center" halign="left" backgroundColor="black" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget name="list" position="5,80" zPosition="2" size="%d,%d" scrollbarMode="showOnDemand" transparent="1" backgroundColor="#00000000" enableWrapAround="1" /> <widget name="title" position="5,47" zPosition="1" size="%d,23" font="Regular;20" transparent="1" backgroundColor="#00000000"/> <widget name="console" position="10,%d" zPosition="2" size="%d,160" valign="center" halign="center" font="Regular;24" transparent="0" foregroundColor="white" backgroundColor="black"/> </screen>""" % ( _("Simple subtitles downloader"), sz_w, sz_h, # size sz_w - 10, sz_h - 105, # size list sz_w - 135, # size title (sz_h - 160) / 2, sz_w - 20, # console ) def __init__(self, session, params={}): # params: movie_title, sub_list: [{'title':'', 'lang':'', 'url':''}] self.session = session Screen.__init__(self, session) self.params = params self.onShown.append(self.onStart) self.onClose.append(self.__onClose) self["title"] = Label(" ") self["console"] = Label(" ") self["label_red"] = Label(_("Cancel")) self["label_yellow"] = Label(_("Move group")) self["label_green"] = Label(_("Apply")) self["icon_red"] = Cover3() self["icon_green"] = Cover3() self["list"] = IPTVMainNavigatorList() self["list"].connectSelChanged(self.onSelectionChanged) self["actions"] = ActionMap( [ "ColorActions", "SetupActions", "WizardActions", "ListboxActions" ], { "cancel": self.keyExit, "ok": self.keyOK, "red": self.keyRed, "green": self.keyGreen, }, -2) self.iconPixmap = {} for icon in ['red', 'green']: self.iconPixmap[icon] = LoadPixmap(GetIconDir(icon + '.png')) self.movieTitle = '' self.stackList = [] self.stackItems = [] self.defaultLanguage = GetDefaultLang() self.listMode = False self.downloadedSubFilePath = "" self.currItem = {} self.downloader = None self.cleanDownloader() self.workconsole = None def __onClose(self): self["list"].disconnectSelChanged(self.onSelectionChanged) if None != self.workconsole: self.workconsole.kill() self.workconsole = None self.cleanDownloader() def cleanDownloader(self): self.downloadedSubFilePath = "" self.currItem = {} if self.downloader != None: self.downloader.unsubscribeFor_Finish(self.downloadFinished) self.downloader.terminate() self.downloader = None def startDownload(self, item): self.setListMode(False) self.cleanDownloader() self.currItem = item self["console"].setText( _("Downloading subtitles.\n ('%r').") % self.currItem.get('url', '')) # create downloader self.downloader = DownloaderCreator(self.currItem.get('url', '')) if self.downloader: self.downloader.isWorkingCorrectly(self._startDownloader) else: self["console"].setText( _("Download can not be started.\n Incorrect address ('%r').")) def _startDownloader(self, sts, reason): if sts: self.downloader.subscribeFor_Finish(self.downloadFinished) url, downloaderParams = DMHelper.getDownloaderParamFromUrl( self.currItem.get('url', '')) self.downloader.start(url, GetTmpDir(self._TMP_FILE_NAME), downloaderParams) else: self["console"].setText( _("Download can not be started.\nDownloader %s not working correctly.\nStatus[%s]" )) def downloadFinished(self, status): if status != DMHelper.STS.DOWNLOADED: self["console"].setText(_("Download failed.\nStatus[%s]") % status) else: self["console"].setText( _('Subtitles downloaded successfully. [%s], conversion to UTF-8.' ) % self.downloader.getFullFileName()) cmd = '%s "%s"' % (config.plugins.iptvplayer.uchardetpath.value, self.downloader.getFullFileName()) printDBG("cmd[%s]" % cmd) self.workconsole = iptv_system(cmd, self.convertSubtitles) def convertSubtitles(self, code=127, encoding=""): encoding = MapUcharEncoding(encoding) if 0 != code or 'unknown' in encoding: encoding = 'utf-8' else: encoding = encoding.strip() try: with codecs.open(self.downloader.getFullFileName(), 'r', encoding, 'replace') as fp: subText = fp.read().encode('utf-8').strip() ext = self.currItem.get('format', '') if ext == '': ext = self.currItem.get('url', '').split('?')[-1].split('.')[-1] filePath = '{0}_{1}_{2}'.format(self.params['movie_title'], self.currItem.get('title', ''), self.currItem.get('lang', '')) filePath = RemoveDisallowedFilenameChars(filePath) filePath += '.' + ext with open(GetSubtitlesDir(filePath), 'w') as fp: fp.write(subText) self.downloadedSubFilePath = GetSubtitlesDir(filePath) self.showButtons(['green']) tmpList = self.params.get('sub_list', []) if len(tmpList) == 1: self.acceptSub() except Exception: printExc() self["console"].setText(_('Subtitles conversion to UTF-8 failed.')) def loadIcons(self): try: for icon in self.iconPixmap: self['icon_' + icon].setPixmap(self.iconPixmap[icon]) except Exception: printExc() def hideButtons(self, buttons=['red', 'green']): try: for button in buttons: self['icon_' + button].hide() self['label_' + button].hide() except Exception: printExc() def showButtons(self, buttons=['red', 'green']): try: for button in buttons: self['icon_' + button].show() self['label_' + button].show() except Exception: printExc() def onStart(self): self.onShown.remove(self.onStart) self.setTitle( _("Subtitles for: %s") % self.params.get('movie_title', '')) self.loadIcons() tmpList = self.params.get('sub_list', []) if len(tmpList) > 1: self.displayList() else: self.startDownload(tmpList[0]) def setListMode(self, sts=False): if False == sts: self['list'].hide() self["title"].hide() self.hideButtons() self.showButtons(['red']) self["console"].show() self["console"].setText(" ") else: self.hideButtons(['green']) self["console"].hide() self["console"].setText(" ") self.listMode = sts def displayList(self): list = [] self["title"].setText(_("Select subtitles to download")) self["title"].show() tmpList = self.params.get('sub_list', []) try: for item in tmpList: printDBG(item) dItem = CDisplayListItem(name=item['title'], type=CDisplayListItem.TYPE_ARTICLE) dItem.privateData = item list.append((dItem, )) except Exception: printExc() self["list"].setList(list) self["list"].show() self.setListMode(True) def onSelectionChanged(self): pass def keyExit(self): if False == self.listMode: if self.downloader != None and self.downloader.isDownloading(): self.downloader.terminate() else: tmpList = self.params.get('sub_list', []) if len(tmpList) > 1: self.displayList() else: self.close(None) else: self.close(None) def keyOK(self): if False == self.listMode: return idx, item = self.getSelectedItem() if None != item: self.startDownload(item.privateData) def keyRed(self): self.close(None) def keyGreen(self): self.acceptSub() def acceptSub(self): try: if self["icon_green"].visible: track = { 'title': self.currItem.get('lang', _('default')), 'lang': self.currItem.get('lang', _('default')), 'path': self.downloadedSubFilePath } track['id'] = self.currItem.get('url', '') self.close(track) except Exception: printExc() def getSelectedItem(self): try: idx = self["list"].getCurrentIndex() except Exception: idx = 0 sel = None try: if self["list"].visible: sel = self["list"].l.getCurrentSelection()[0] if None != sel: return idx, sel except Exception: printExc() sel = None return -1, None
class IPTVPicturePlayerWidget(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() # percentage s_w = 120 s_h = 120 # icon i_w = 128 i_h = 128 # console c_w = sz_w c_h = 80 # picture p_w = sz_w-20 p_h = sz_h-20 ####################### # POSITIONS ####################### start_y = (sz_h - (i_h + c_h)) / 2 # percentage s_x = (sz_w - s_w) / 2 s_y = start_y + (i_h - s_h) / 2 # icon i_x = (sz_w - i_w) / 2 i_y = start_y # console c_x = 0 c_y = i_y + i_h # picture p_x = 10 p_y = 10 printDBG("[IPTVPicturePlayerWidget] desktop size %dx%d" % (sz_w, sz_h) ) skin = """ <screen name="IPTVPicturePlayerWidget" position="center,center" size="%d,%d" title="IPTV Picture Player..."> <widget name="status" 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="on" /> <widget name="picture" size="%d,%d" position="%d,%d" zPosition="6" transparent="1" alphatest="on" /> </screen>""" %( sz_w, sz_h, # screen s_w, s_h, s_x, s_y, # status c_w, c_h, c_x, c_y, # console i_w, i_h, i_x, i_y, # icon p_w, p_h, p_x, p_y # picture ) def __init__(self, session, url, pathForRecordings, pictureTitle): self.session = session Screen.__init__(self, session) self.onStartCalled = False self.recordingPath = pathForRecordings try: self.filePath = os.path.join(pathForRecordings, '.iptv_buffering.jpg') except: self.filePath = '' printExc() self.url = url self.pictureTitle = pictureTitle self.audioUrl = strwithmeta(url).meta.get("iptv_audio_url", '') self["actions"] = ActionMap(['IPTVAlternateVideoPlayer', 'MoviePlayerActions', 'MediaPlayerActions', 'WizardActions', 'DirectionActions'], { 'leavePlayer' : self.key_exit, 'play' : self.key_play, 'pause' : self.key_pause, 'exit' : self.key_exit, 'back' : self.key_exit, 'ok' : self.key_ok, }, -1) self["status"] = Label() self["console"] = Label() self["icon"] = SimpleAnimatedCover() self["picture"] = Cover() # prepare icon frames path frames = [] for idx in range(1,self.NUM_OF_ICON_FRAMES+1): frames.append( GetIconDir('/buffering/buffering_%d.png' % idx) ) self["icon"].loadFrames(frames) #main Timer self.mainTimer = eTimer() self.mainTimerEnabled = False self.mainTimer_conn = eConnectCallback(self.mainTimer.timeout, self.updateDisplay) self.mainTimerInterval = 100 # by default 0,1s # download self.downloader = DownloaderCreator(self.url) self.onClose.append(self.__onClose) self.onLayoutFinish.append(self.doStart) self.autoRefresh = False self.refreshPostfixes = ['_0', '_1'] self.refreshCount = 0 self.refreshing = False if len(self.audioUrl) and len(config.plugins.iptvplayer.gstplayerpath.value): self.audioPlayer = IPTVSimpleAudioPlayer() else: self.audioPlayer = None #end def __init__(self, session): def __del__(self): printDBG('IPTVPicturePlayerWidget.__del__ --------------------------------------') def __onClose(self): printDBG('IPTVPicturePlayerWidget.__onClose ------------------------------------') if None != self.audioPlayer: self.audioPlayer.close() self.onEnd() self.mainTimer_conn = None self.mainTimer = None self.onClose.remove(self.__onClose) self.onLayoutFinish.remove(self.doStart) def _getDownloadFilePath(self): return self.filePath + self.refreshPostfixes[self.refreshCount % len(self.refreshPostfixes) ] def onStart(self): ''' this method is called once like __init__ but in __init__ we cannot display MessageBox ''' self["picture"].hide() self["console"].setText(self.pictureTitle) self["status"].setText(_("--")) self._cleanedUp() if self.downloader: self.downloader.isWorkingCorrectly(self._startDownloader) else: self.session.openWithCallback(self.close, MessageBox, _("Downloading cannot be started.\n Invalid URI[%s].") % self.url, type = MessageBox.TYPE_ERROR, timeout = 10) def _doStart(self, force=False): if self.autoRefresh or force: self.refreshing = True self.downloader = DownloaderCreator(self.url) url,downloaderParams = DMHelper.getDownloaderParamFromUrl(self.url) self.downloader.subscribeFor_Finish(self.downloaderEnd) self.downloader.start(url, self._getDownloadFilePath(), downloaderParams) self.setMainTimerSts(True) else: self.refreshing = False def _startDownloader(self, sts, reason): if sts: self._doStart(True) else: self.session.openWithCallback(self.close, MessageBox, _("Downloading cannot be started.\n Downloader [%s] not working properly.\n Status[%s]") % (self.downloader.getName(), reason.strip()), type = MessageBox.TYPE_ERROR, timeout = 10 ) def onEnd(self, withCleanUp=True): self.setMainTimerSts(False) if self.downloader: self.downloader.unsubscribeFor_Finish(self.downloaderEnd) downloader = self.downloader self.downloader = None downloader.terminate() downloader = None if withCleanUp: self._cleanedUp() def key_exit(self): self.close() def key_play(self): if not self.autoRefresh: if None != self.audioPlayer: self.audioPlayer.start(self.audioUrl) self.autoRefresh = True if not self.refreshing: self._doStart() def key_pause(self): if self.autoRefresh: if None != self.audioPlayer: self.audioPlayer.stop() self.autoRefresh = False def key_ok(self): if self.autoRefresh: self.key_pause() else: self.key_play() def downloaderEnd(self, status): if None != self.downloader: self.onEnd(False) if DMHelper.STS.DOWNLOADED == status: self["status"].setText(_("++")) self["picture"].decodeCover(self._getDownloadFilePath(), self.decodePictureEnd, ' ') else: if 0 == self.refreshCount: self.session.openWithCallback(self.close, MessageBox, (_("Downloading file [%s] problem.") % self.url) + (" sts[%r]" % status), type=MessageBox.TYPE_ERROR, timeout=10) self._doStart() def decodePictureEnd(self, ret={}): if None == ret.get('Pixmap', None): if 0 == self.refreshCount: self.session.openWithCallback(self.close, MessageBox, _("Downloading file [%s] problem.") % self.filePath, type=MessageBox.TYPE_ERROR, timeout=10) else: self.refreshCount += 1 self["status"].hide() self["console"].hide() self["icon"].hide() self["picture"].updatePixmap(ret.get('Pixmap', None), ret.get('FileName', self.filePath)) self["picture"].show() self.setMainTimerSts(False) self._doStart() 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: printExc("IPTVPicturePlayerWidget.setMainTimerSts status[%r] EXCEPTION" % start) def updateDisplay(self): printDBG("updateDisplay") if not self.mainTimerEnabled: printDBG("updateDisplay aborted - timer stopped") return self["icon"].nextFrame() return def _cleanedUp(self): for item in self.refreshPostfixes: filePath = self.filePath + item if fileExists(filePath): try: os.remove(filePath) except: printDBG('Problem with removing old buffering file') def doStart(self): if not self.onStartCalled: self.onStartCalled = True self.onStart()
class IPTVSubSimpleDownloaderWidget(Screen): _TMP_FILE_NAME='.externaltmpsub' sz_w = getDesktop(0).size().width() - 190 sz_h = getDesktop(0).size().height() - 195 if sz_h < 500: sz_h += 4 skin = """ <screen name="IPTVSubSimpleDownloaderWidget" position="center,center" title="%s" size="%d,%d"> <widget name="icon_red" position="5,9" zPosition="4" size="30,30" transparent="1" alphatest="on" /> <widget name="icon_green" position="355,9" zPosition="4" size="30,30" transparent="1" alphatest="on" /> <widget name="label_red" position="45,9" size="175,27" zPosition="5" valign="center" halign="left" backgroundColor="black" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget name="label_green" position="395,9" size="175,27" zPosition="5" valign="center" halign="left" backgroundColor="black" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget name="list" position="5,80" zPosition="2" size="%d,%d" scrollbarMode="showOnDemand" transparent="1" backgroundColor="#00000000" enableWrapAround="1" /> <widget name="title" position="5,47" zPosition="1" size="%d,23" font="Regular;20" transparent="1" backgroundColor="#00000000"/> <widget name="console" position="10,%d" zPosition="2" size="%d,160" valign="center" halign="center" font="Regular;24" transparent="0" foregroundColor="white" backgroundColor="black"/> </screen>""" %( _("Simple subtitles downloader"), sz_w, sz_h, # size sz_w - 10, sz_h - 105, # size list sz_w - 135, # size title (sz_h - 160)/2, sz_w - 20, # console ) def __init__(self, session, params={}): # params: movie_title, sub_list: [{'title':'', 'lang':'', 'url':''}] self.session = session Screen.__init__(self, session) self.params = params self.onShown.append(self.onStart) self.onClose.append(self.__onClose) self["title"] = Label(" ") self["console"] = Label(" ") self["label_red"] = Label(_("Cancel")) self["label_yellow"] = Label(_("Move group")) self["label_green"] = Label(_("Apply")) self["icon_red"] = Cover3() self["icon_green"] = Cover3() self["list"] = IPTVMainNavigatorList() self["list"].connectSelChanged(self.onSelectionChanged) self["actions"] = ActionMap(["ColorActions", "SetupActions", "WizardActions", "ListboxActions"], { "cancel": self.keyExit, "ok" : self.keyOK, "red" : self.keyRed, "green" : self.keyGreen, }, -2) self.iconPixmap = {} for icon in ['red', 'green']: self.iconPixmap[icon] = LoadPixmap(GetIconDir(icon+'.png')) self.movieTitle = '' self.stackList = [] self.stackItems = [] self.defaultLanguage = GetDefaultLang() self.listMode = False self.downloadedSubFilePath = "" self.currItem = {} self.downloader = None self.cleanDownloader() self.workconsole = None def __onClose(self): self["list"].disconnectSelChanged(self.onSelectionChanged) if None != self.workconsole: self.workconsole.kill() self.workconsole = None self.cleanDownloader() def cleanDownloader(self): self.downloadedSubFilePath = "" self.currItem = {} if self.downloader != None: self.downloader.unsubscribeFor_Finish(self.downloadFinished) self.downloader.terminate() self.downloader = None def startDownload(self, item): self.setListMode(False) self.cleanDownloader() self.currItem = item self["console"].setText(_("Downloading subtitles.\n ('%r').") % self.currItem.get('url', '')) # create downloader self.downloader = DownloaderCreator(self.currItem.get('url', '')) if self.downloader: self.downloader.isWorkingCorrectly(self._startDownloader) else: self["console"].setText(_("Download can not be started.\n Incorrect address ('%r').")) def _startDownloader(self, sts, reason): if sts: self.downloader.subscribeFor_Finish(self.downloadFinished) url,downloaderParams = DMHelper.getDownloaderParamFromUrl(self.currItem.get('url', '')) self.downloader.start(url, GetTmpDir(self._TMP_FILE_NAME), downloaderParams) else: self["console"].setText(_("Download can not be started.\nDownloader %s not working correctly.\nStatus[%s]")) def downloadFinished(self, status): if status != DMHelper.STS.DOWNLOADED: self["console"].setText(_("Download failed.\nStatus[%s]") % status) else: self["console"].setText(_('Subtitles downloaded successfully. [%s], conversion to UTF-8.') % self.downloader.getFullFileName()) cmd = '%s "%s"' % (config.plugins.iptvplayer.uchardetpath.value, self.downloader.getFullFileName()) printDBG("cmd[%s]" % cmd) self.workconsole = iptv_system(cmd, self.convertSubtitles) def convertSubtitles(self, code=127, encoding=""): if 0 != code or 'unknown' in encoding: encoding = 'utf-8' else: encoding = encoding.strip() try: with codecs.open(self.downloader.getFullFileName(), 'r', encoding, 'replace') as fp: subText = fp.read().encode('utf-8') ext = self.currItem.get('format', '') if ext == '': ext = self.currItem.get('url', '').split('?')[-1].split('.')[-1] filePath = '{0}_{1}_{2}'.format(self.params['movie_title'], self.currItem.get('title', ''), self.currItem.get('lang', '')) filePath = RemoveDisallowedFilenameChars(filePath) filePath += '.' + ext with open(GetSubtitlesDir(filePath), 'w') as fp: fp.write(subText) self.downloadedSubFilePath = GetSubtitlesDir(filePath) self.showButtons(['green']) tmpList = self.params.get('sub_list', []) if len(tmpList) == 1: self.acceptSub() except: printExc() self["console"].setText(_('Subtitles conversion to UTF-8 failed.')) def loadIcons(self): try: for icon in self.iconPixmap: self['icon_'+icon].setPixmap(self.iconPixmap[icon]) except: printExc() def hideButtons(self, buttons=['red', 'green']): try: for button in buttons: self['icon_'+button].hide() self['label_'+button].hide() except: printExc() def showButtons(self, buttons=['red', 'green']): try: for button in buttons: self['icon_'+button].show() self['label_'+button].show() except: printExc() def onStart(self): self.onShown.remove(self.onStart) self.setTitle( _("Subtitles for: %s") % self.params.get('movie_title', '') ) self.loadIcons() tmpList = self.params.get('sub_list', []) if len(tmpList) > 1: self.displayList() else: self.startDownload(tmpList[0]) def setListMode(self, sts=False): if False == sts: self['list'].hide() self["title"].hide() self.hideButtons() self.showButtons(['red']) self["console"].show() self["console"].setText(" ") else: self.hideButtons(['green']) self["console"].hide() self["console"].setText(" ") self.listMode = sts def displayList(self): list = [] self["title"].setText(_("Select subtitles to download")) self["title"].show() tmpList = self.params.get('sub_list', []) try: for item in tmpList: printDBG(item) dItem = CDisplayListItem(name = item['title'], type=CDisplayListItem.TYPE_ARTICLE) dItem.privateData = item list.append( (dItem,) ) except: printExc() self["list"].setList(list) self["list"].show() self.setListMode(True) def onSelectionChanged(self): pass def keyExit(self): if False == self.listMode: if self.downloader != None and self.downloader.isDownloading(): self.downloader.terminate() else: tmpList = self.params.get('sub_list', []) if len(tmpList) > 1: self.displayList() else: self.close(None) else: self.close(None) def keyOK(self): if False == self.listMode: return idx, item = self.getSelectedItem() if None != item: self.startDownload(item.privateData) def keyRed(self): self.close(None) def keyGreen(self): self.acceptSub() def acceptSub(self): try: if self["icon_green"].visible: track = {'title':self.currItem.get('lang', _('default')), 'lang':self.currItem.get('lang', _('default')), 'path':self.downloadedSubFilePath} track['id'] = self.currItem.get('url', '') self.close(track) except: printExc() def getSelectedItem(self): try: idx = self["list"].getCurrentIndex() except: idx = 0 sel = None try: if self["list"].visible: sel = self["list"].l.getCurrentSelection()[0] if None != sel: return idx, sel except: printExc() sel = None return -1, None
def run(self): ret=None _temp = __import__('hosts.' + self.hostName, globals(), locals(), ['IPTVHost'], -1) self.title = _temp.gettytul() logState("Host title: %s\n" % self.title) self.host = _temp.IPTVHost() self.SelectedLink = '' try: if not isinstance(self.host, IHost): logState("Host [%r] inherits from IHost :)\n" % (self.hostName)) except: logState( 'Cannot import class IPTVHost for host [%r]\n' % self.hostName) self.stop() return hostconfig = __import__('hosts.' + self.hostName, globals(), locals(), ['GetConfigList'], -1) ConfList = hostconfig.GetConfigList() configureHOST(self.hostName) monitor = xbmc.Monitor() while not monitor.abortRequested() or xbmcgui.Window(10000).getProperty('plugin.video.IPTVplayer.HOST') == self.hostName: #logState("plugin.video.IPTVplayer.HOST=%s self.hostName=%s\n" %(xbmcgui.Window(10000).getProperty('plugin.video.IPTVplayer.HOST'),self.hostName)) timestamp = long(myTime()) xbmcgui.Window(10000).setProperty("kodiIPTVserviceHeartBeat", str(timestamp)) # Sleep/wait for abort for 10 seconds if monitor.waitForAbort(1): break # Abort was requested while waiting. We should exit self.myCommand = getCMD() if self.myCommand == '': continue elif self.myCommand == 'STOPservice': self.stop() return elif self.myCommand == 'Title': myAnswer(self.title) continue elif self.myCommand == 'LogoPath': myAnswer(self.host.getLogoPath().value) continue elif self.myCommand == 'SupportedTypes': myAnswer(self.host.getSupportedFavoritesTypes().value) continue elif self.myCommand == 'InitList': ret = self.host.getInitList() if len(ConfList) > 0: #### TBC myAnswer(ToItemsListTable(ret.value, self.clientType) + ToConfigTable(ConfList, clientType)) #if host hasconfig, return it too myAnswer(ToItemsListTable(ret.value, self.clientType)) #if host hasconfig, return it too else: myAnswer(ToItemsListTable(ret.value, self.clientType)) continue elif self.myCommand == 'RefreshList': ret = self.host.getCurrentList() myAnswer(ToItemsListTable(ret.value, self.clientType)) continue elif self.myCommand == 'PreviousList': ret= self.host.getPrevList() myAnswer(ToItemsListTable(ret.value, self.clientType)) continue elif self.myCommand.startswith('ListForItem='): #Param: item ID myID = self.myCommand.split('=')[1] if myID.isdigit(): myID = int(myID) ret= self.host.getListForItem(myID,0,ret.value[myID]) myAnswer(ToItemsListTable(ret.value, self.clientType)) else: myAnswer('ERROR: wrong index') continue elif self.myCommand.startswith('getVideoLinks='): #Param: link ID myID = self.myCommand.split('=')[1] daemonLog("daemon:getVideoLinks=%s" % myID) if myID.isdigit(): myID = int(myID) self.movieTitle = ret.value[myID].name.replace('"', "'") try: links = ret.value[myID].urlItems except: links='NOVALIDURLS' try: retUrl= self.host.getLinksForVideo(myID,ret.value[myID]) #returns "NOT_IMPLEMENTED" when host is using curlitem myAnswer(ToUrlsTable(retUrl.value, self.clientType)) daemonLog("retUrl found") except: daemonLog("Exception running getLinksForVideo (means not implemented), using CUrlItem") retUrl = RetHost(RetHost.NOT_IMPLEMENTED, value = []) if retUrl.status == "NOT_IMPLEMENTED" and links != 'NOVALIDURLS': daemonLog("getLinksForVideo not implemented, using CUrlItem") tempUrls=[] daemonLog("Iterating links...") iindex=1 for link in links: if link.name == '': tempUrls.append(CUrlItem('link %d' % iindex, link.url, link.urlNeedsResolve)) else: tempUrls.append(CUrlItem(link.name, link.url, link.urlNeedsResolve)) iindex += 1 retUrl = RetHost(RetHost.OK, value = tempUrls) myAnswer(ToUrlsTable(tempUrls, self.clientType)) else: myAnswer('ERROR: wrong index') continue #### ResolveURL #### elif self.myCommand.startswith('ResolveURL='): #Param: selected quality link ID myParm = self.myCommand.split('=')[1] url = "NOVALIDURLS" linksList = [] if myParm.isdigit(): myID = int(myParm) #czasami jest zwracana lista linkow wiec trzeba ja sparsowac linksList = self.host.getResolvedURL(retUrl.value[myID].url).value daemonLog("myParm.isdigit and points to:%s" % retUrl.value[myID].url) else: linksList = self.host.getResolvedURL(myParm).value if len(linksList) == 0: #There is no free links for current video daemonLog("linksList has no items :(") elif len(linksList) >1: daemonLog('WARNING: more than one link returned, selecting first') if isinstance(linksList[0], CUrlItem): if int(linksList[0].urlNeedsResolve) == 1: daemonLog('ERROR: url should be already resolved. :(') else: url = linksList[0].url daemonLog("CUrlItem url:%s" %url) elif isinstance(linksList[0], basestring): url = linksList[0] daemonLog("basestring url:%s" %url) elif isinstance(linksList, (list, tuple)): url = linksList[0] daemonLog("list/tuple url:%s" %url) myAnswer( url ) #### Download movie #### elif self.myCommand.startswith('DownloadURL='): #Param: full download url url = self.myCommand[len('DownloadURL='):] #using split results in wrong links from Plugins.Extensions.IPTVPlayer.iptvdm.iptvdownloadercreator import IsUrlDownloadable, DownloaderCreator if IsUrlDownloadable(url): from Plugins.Extensions.IPTVPlayer.iptvdm.iptvdh import DMHelper url, downloaderParams = DMHelper.getDownloaderParamFromUrl(url) currentDownloader = DownloaderCreator(url) #correct downloader is assigned e.g. wget MovieRecordFileName = os.path.join(config.plugins.iptvplayer.NaszaSciezka.value , getValidFileName(self.movieTitle)) MovieRecordFileNameExt = MovieRecordFileName[-4:] if not MovieRecordFileNameExt in ('.mpg', '.flv', '.mp4'): MovieRecordFileName += ".mp4" currentDownloader.start(url, MovieRecordFileName, downloaderParams) myAnswer(MovieRecordFileName) else: myAnswer( 'ERROR:wrong url' ) #### buffer movie #### elif self.myCommand.startswith('BufferURL='): #Param: full download url url = self.myCommand[len('BufferURL='):] #using split results in wrong links from Plugins.Extensions.IPTVPlayer.iptvdm.iptvdownloadercreator import IsUrlDownloadable, DownloaderCreator if IsUrlDownloadable(url): from Plugins.Extensions.IPTVPlayer.iptvdm.iptvdh import DMHelper url, downloaderParams = DMHelper.getDownloaderParamFromUrl(url) currentDownloader = DownloaderCreator(url) #correct downloader is assigned e.g. wget MovieRecordFileName = config.plugins.iptvplayer.NaszaSciezka.value + "iptv_buffering.mp4" currentDownloader.start(url, MovieRecordFileName, downloaderParams) myAnswer(MovieRecordFileName) else: myAnswer( 'ERROR:wrong url' ) #### Search items #### elif self.myCommand.startswith('Search='): #Param: search pattern self.searchPattern = self.myCommand[len('Search='):] #param can contain '='. Using split function would brake everything ;) ret = self.host.getSearchResults(self.searchPattern) myAnswer(ToItemsListTable(ret.value, self.clientType)) #### doCommand - not finished#### elif self.myCommand.startswith('doCommand='): #Param: selected quality link ID execCMD = self.myCommand.replace('doCommand=','') try: exec(execCMD) myAnswer( 'OK' ) except Exception: myAnswer( 'ERROR executing command.') elif self.myCommand.startswith('doUnsafeCommand='): #Param: selected quality link ID execCMD = self.myCommand.replace('doUnsafeCommand=','') exec(execCMD) myAnswer( 'OK' ) else: daemonLog("Unknown command:'%s'\n" % self.myCommand) myAnswer("ERROR: Unknown command:'%s'\n" % self.myCommand) self.stop() return
class SingleFileDownloaderWidget(Screen): sz_w = getDesktop(0).size().width() - 190 sz_h = getDesktop(0).size().height() - 195 if sz_h < 500: sz_h += 4 skin = """ <screen position="center,center" title="%s" size="%d,%d"> <widget name="icon_red" position="5,9" zPosition="4" size="30,30" transparent="1" alphatest="on" /> <widget name="icon_green" position="355,9" zPosition="4" size="30,30" transparent="1" alphatest="on" /> <widget name="label_red" position="45,9" size="175,27" zPosition="5" valign="center" halign="left" backgroundColor="black" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget name="label_green" position="395,9" size="175,27" zPosition="5" valign="center" halign="left" backgroundColor="black" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" /> <widget name="title" position="5,47" zPosition="1" size="%d,23" font="Regular;20" transparent="1" backgroundColor="#00000000"/> <widget name="console" position="10,%d" zPosition="2" size="%d,160" valign="center" halign="center" font="Regular;24" transparent="0" foregroundColor="white" backgroundColor="black"/> </screen>""" % ( _("Single file downloader"), sz_w, sz_h, # size sz_w - 135, # size title (sz_h - 160) / 2, sz_w - 20, # console ) def __init__(self, session, uri, outFile, title=''): self.session = session Screen.__init__(self, session) self.uri = uri self.outFile = outFile self.title = title self.onShown.append(self.onStart) self.onClose.append(self.__onClose) self["title"] = Label(" ") self["console"] = Label(" ") self["label_red"] = Label(_("Cancel")) self["label_green"] = Label(_("Apply")) self["icon_red"] = Cover3() self["icon_green"] = Cover3() self["actions"] = ActionMap([ "ColorActions", "SetupActions", "WizardActions", "ListboxActions" ], { "cancel": self.keyExit, "red": self.keyRed, "green": self.keyGreen, }, -2) self.iconPixmap = {} for icon in ['red', 'green']: self.iconPixmap[icon] = LoadPixmap(GetIconDir(icon + '.png')) self.downloader = None self.cleanDownloader() def __onClose(self): self.cleanDownloader() def cleanDownloader(self): if self.downloader != None: self.downloader.unsubscribeFor_Finish(self.downloadFinished) self.downloader.terminate() self.downloader = None def startDownload(self): self.cleanDownloader() self["console"].setText(_("Downloading file:\n%r.") % self.uri) self.downloader = DownloaderCreator(self.uri) if self.downloader: self.downloader.isWorkingCorrectly(self._startDownloader) else: self["console"].setText( _("Download can not be started.\nIncorrect address \"%r\".") % self.uri) def _startDownloader(self, sts, reason): if sts: self.downloader.subscribeFor_Finish(self.downloadFinished) url, downloaderParams = DMHelper.getDownloaderParamFromUrl( self.uri) self.downloader.start(url, self.outFile, downloaderParams) else: error, desc = self.downloader.getLastError() self["console"].setText( _("Download can not be started.\nDownloader %s not working correctly.\nLast error \"%s (%s)\"." ) % (self.downloader.getName(), desc, error)) def downloadFinished(self, status): if status != DMHelper.STS.DOWNLOADED: error, desc = self.downloader.getLastError() self["console"].setText( _("Download failed.\nLast error \"%s (%s)\".") % (desc, error)) rm(self.outFile) else: self.close(True) def loadIcons(self): try: for icon in self.iconPixmap: self['icon_' + icon].setPixmap(self.iconPixmap[icon]) except Exception: printExc() def hideButtons(self, buttons=['green']): try: for button in buttons: self['icon_' + button].hide() self['label_' + button].hide() except Exception: printExc() def showButtons(self, buttons=['red', 'green']): try: for button in buttons: self['icon_' + button].show() self['label_' + button].show() except Exception: printExc() def onStart(self): self.onShown.remove(self.onStart) self.setTitle(self.title) self.loadIcons() self.hideButtons() self.startDownload() def keyExit(self): if self.downloader != None and self.downloader.isDownloading(): self.downloader.terminate() else: self.close(None) def keyRed(self): self.keyExit() def keyGreen(self): pass
def updateDisplay(self): printDBG("updateDisplay") if self.inMoviePlayer: printDBG("updateDisplay aborted - we are in moviePlayer") return 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]: self.session.openWithCallback(self.iptvDoClose, MessageBox, _("Error occurs during download. \nStatus[%s], tmpBuffSize[%r], canRunMoviePlayer[%r]") % (self.downloader.getStatus(), tmpBuffSize, self.canRunMoviePlayer), type = MessageBox.TYPE_ERROR, timeout = 10 ) self.canRunMoviePlayer = False # stop timer before message self.setMainTimerSts(False) return