from os import path as os_path, remove as os_remove, listdir as os_listdir, system from time import strftime from enigma import eTimer, iPlayableService, eServiceCenter, iServiceInformation, eServiceReference, iServiceKeys from Screens.Screen import Screen from Screens.MessageBox import MessageBox from Screens.ChoiceBox import ChoiceBox from Screens.InputBox import InputBox from Screens.HelpMenu import HelpableScreen from Screens.InfoBarGenerics import InfoBarSeek, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarShowHide, InfoBarNotifications from Components.ActionMap import ActionMap, NumberActionMap, HelpableActionMap from Components.Label import Label from Components.FileList import FileList from Components.ServiceEventTracker import ServiceEventTracker from Components.config import config from Components.ProgressBar import ProgressBar from ServiceReference import ServiceReference from Tools.Directories import pathExists, fileExists import random import servicedvd # load c++ part of dvd player plugin class FileBrowser(Screen): skin = """ """ def __init__(self, session): Screen.__init__(self, session) currDir = "/media/dvd/" if not pathExists(currDir): currDir = "/" #else: #print system("mount "+currDir) self.filelist = FileList(currDir, matchingPattern = "(?i)^.*\.(iso)", useServiceRef = True) self["filelist"] = self.filelist self["FilelistActions"] = ActionMap(["OkCancelActions"], { "ok": self.ok, "cancel": self.exit }) def ok(self): if self["filelist"].getFilename().upper().endswith("VIDEO_TS/"): print "dvd structure found, trying to open..." self.close(self["filelist"].getFilename()[0:-9]) elif self["filelist"].canDescent(): # isDir self["filelist"].descent() else: self.close(self["filelist"].getFilename()) def exit(self): self.close(None) class DVDSummary(Screen): skin = """ Name Position Position """ def __init__(self, session, parent): Screen.__init__(self, session, parent) self["DVDPlayer"] = Label("DVD Player") self["Title"] = Label("") self["Time"] = Label("") self["Chapter"] = Label("") def updateChapter(self, chapter): self["Chapter"].setText(chapter) def setTitle(self, title): self["Title"].setText(title) class DVDOverlay(Screen): skin = """""" def __init__(self, session, args = None): Screen.__init__(self, session) class ChapterZap(Screen): skin = """ """ def quit(self): self.Timer.stop() self.close(0) def keyOK(self): self.Timer.stop() self.close(int(self["number"].getText())) def keyNumberGlobal(self, number): self.Timer.start(3000, True) #reset timer self.field = self.field + str(number) self["number"].setText(self.field) if len(self.field) >= 4: self.keyOK() def __init__(self, session, number): Screen.__init__(self, session) self.field = str(number) self["chapter"] = Label(_("Chapter:")) self["number"] = Label(self.field) self["actions"] = NumberActionMap( [ "SetupActions" ], { "cancel": self.quit, "ok": self.keyOK, "1": self.keyNumberGlobal, "2": self.keyNumberGlobal, "3": self.keyNumberGlobal, "4": self.keyNumberGlobal, "5": self.keyNumberGlobal, "6": self.keyNumberGlobal, "7": self.keyNumberGlobal, "8": self.keyNumberGlobal, "9": self.keyNumberGlobal, "0": self.keyNumberGlobal }) self.Timer = eTimer() self.Timer.callback.append(self.keyOK) self.Timer.start(3000, True) class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSupport, InfoBarPVRState, InfoBarShowHide, HelpableScreen): ALLOW_SUSPEND = True ENABLE_RESUME_SUPPORT = True skin = """ Name HasTelext Position,ShowHours Gauge Remaining,Negate,ShowHours """ def save_infobar_seek_config(self): self.saved_config_speeds_forward = config.seek.speeds_forward.value self.saved_config_speeds_backward = config.seek.speeds_backward.value self.saved_config_enter_forward = config.seek.enter_forward.value self.saved_config_enter_backward = config.seek.enter_backward.value self.saved_config_seek_stepwise_minspeed = config.seek.stepwise_minspeed.value self.saved_config_seek_stepwise_repeat = config.seek.stepwise_repeat.value self.saved_config_seek_on_pause = config.seek.on_pause.value self.saved_config_seek_speeds_slowmotion = config.seek.speeds_slowmotion.value def change_infobar_seek_config(self): config.seek.speeds_forward.value = [2, 4, 8, 16, 32, 64] config.seek.speeds_backward.value = [8, 16, 32, 64] config.seek.speeds_slowmotion.value = [ ] config.seek.enter_forward.value = "2" config.seek.enter_backward.value = "2" config.seek.stepwise_minspeed.value = "Never" config.seek.stepwise_repeat.value = "3" config.seek.on_pause.value = "play" def restore_infobar_seek_config(self): config.seek.speeds_forward.value = self.saved_config_speeds_forward config.seek.speeds_backward.value = self.saved_config_speeds_backward config.seek.speeds_slowmotion.value = self.saved_config_seek_speeds_slowmotion config.seek.enter_forward.value = self.saved_config_enter_forward config.seek.enter_backward.value = self.saved_config_enter_backward config.seek.stepwise_minspeed.value = self.saved_config_seek_stepwise_minspeed config.seek.stepwise_repeat.value = self.saved_config_seek_stepwise_repeat config.seek.on_pause.value = self.saved_config_seek_on_pause def __init__(self, session, args = None): Screen.__init__(self, session) InfoBarNotifications.__init__(self) InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions") InfoBarShowHide.__init__(self) HelpableScreen.__init__(self) self.save_infobar_seek_config() self.change_infobar_seek_config() InfoBarSeek.__init__(self) InfoBarPVRState.__init__(self) self.dvdScreen = self.session.instantiateDialog(DVDOverlay) self.oldService = self.session.nav.getCurrentlyPlayingServiceReference() self.session.nav.stopService() self["audioLabel"] = Label("1") self["subtitleLabel"] = Label("") self["chapterLabel"] = Label("") self.totalChapters = 0 self.currentChapter = 0 self.totalTitles = 0 self.currentTitle = 0 self.__event_tracker = ServiceEventTracker(screen=self, eventmap= { iPlayableService.evUser: self.__timeUpdated, iPlayableService.evUser+1: self.__statePlay, iPlayableService.evUser+2: self.__statePause, iPlayableService.evUser+3: self.__osdFFwdInfoAvail, iPlayableService.evUser+4: self.__osdFBwdInfoAvail, iPlayableService.evUser+5: self.__osdStringAvail, iPlayableService.evUser+6: self.__osdAudioInfoAvail, iPlayableService.evUser+7: self.__osdSubtitleInfoAvail, iPlayableService.evUser+8: self.__chapterUpdated, iPlayableService.evUser+9: self.__titleUpdated, #iPlayableService.evUser+10: self.__initializeDVDinfo, iPlayableService.evUser+11: self.__menuOpened, iPlayableService.evUser+12: self.__menuClosed }) self["DVDPlayerDirectionActions"] = HelpableActionMap(self, "DirectionActions", { #MENU KEY DOWN ACTIONS "left": (self.keyLeft, _("DVD left key")), "right": (self.keyRight, _("DVD right key")), "up": (self.keyUp, _("DVD up key")), "down": (self.keyDown, _("DVD down key")), #MENU KEY REPEATED ACTIONS "leftRepeated": self.doNothing, "rightRepeated": self.doNothing, "upRepeated": self.doNothing, "downRepeated": self.doNothing, #MENU KEY UP ACTIONS "leftUp": self.doNothing, "rightUp": self.doNothing, "upUp": self.doNothing, "downUp": self.doNothing, }, -2) self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", { "ok": (self.keyOk, _("DVD ENTER key")), "cancel": self.keyCancel, }, -2) self["DVDPlayerPlaybackActions"] = HelpableActionMap(self, "DVDPlayerActions", { #PLAYER ACTIONS "dvdMenu": (self.enterDVDMenu, _("show DVD main menu")), "toggleInfo": (self.toggleInfo, _("toggle time, chapter, audio, subtitle info")), "nextChapter": (self.nextChapter, _("forward to the next chapter")), "prevChapter": (self.prevChapter, _("rewind to the previous chapter")), "nextTitle": (self.nextTitle, _("jump forward to the next title")), "prevTitle": (self.prevTitle, _("jump back to the previous title")), "tv": (self.askLeavePlayer, _("exit DVD player or return to file browser")), "dvdAudioMenu": (self.enterDVDAudioMenu, _("(show optional DVD audio menu)")), "nextAudioTrack": (self.nextAudioTrack, _("switch to the next audio track")), "nextSubtitleTrack": (self.nextSubtitleTrack, _("switch to the next subtitle language")), "seekBeginning": (self.seekBeginning, _("Jump to video title 1 (play movie from start)")), }, -2) self["NumberActions"] = NumberActionMap( [ "NumberActions"], { "1": self.keyNumberGlobal, "2": self.keyNumberGlobal, "3": self.keyNumberGlobal, "4": self.keyNumberGlobal, "5": self.keyNumberGlobal, "6": self.keyNumberGlobal, "7": self.keyNumberGlobal, "8": self.keyNumberGlobal, "9": self.keyNumberGlobal, "0": self.keyNumberGlobal, }) self.onClose.append(self.__onClose) self.onFirstExecBegin.append(self.showFileBrowser) self.service = None self.in_menu = False def keyNumberGlobal(self, number): print "You pressed number " + str(number) self.session.openWithCallback(self.numberEntered, ChapterZap, number) def numberEntered(self, retval): # print self.servicelist if retval > 0: self.zapToNumber(retval) def serviceStarted(self): #override InfoBarShowHide function pass def doEofInternal(self, playing): if self.in_menu: self.hide() def __menuOpened(self): self.hide() self.in_menu = True def __menuClosed(self): self.show() self.in_menu = False def setChapterLabel(self): chapterLCD = "Menu" chapterOSD = "DVD Menu" if self.currentTitle > 0: chapterLCD = "%s %d" % (_("Chap."), self.currentChapter) chapterOSD = "DVD %s %d/%d" % (_("Chapter"), self.currentChapter, self.totalChapters) chapterOSD += " (%s %d/%d)" % (_("Title"), self.currentTitle, self.totalTitles) self["chapterLabel"].setText(chapterOSD) try: self.session.summary.updateChapter(chapterLCD) except: pass def doNothing(self): pass def toggleInfo(self): if not self.in_menu: self.toggleShow() print "toggleInfo" def __timeUpdated(self): print "timeUpdated" def __statePlay(self): print "statePlay" def __statePause(self): print "statePause" def __osdFFwdInfoAvail(self): self.setChapterLabel() print "FFwdInfoAvail" def __osdFBwdInfoAvail(self): self.setChapterLabel() print "FBwdInfoAvail" def __osdStringAvail(self): print "StringAvail" def __osdAudioInfoAvail(self): audioString = self.service.info().getInfoString(iPlayableService.evUser+6) print "AudioInfoAvail "+audioString self["audioLabel"].setText(audioString) self.doShow() def __osdSubtitleInfoAvail(self): subtitleString = self.service.info().getInfoString(iPlayableService.evUser+7) print "SubtitleInfoAvail "+subtitleString self["subtitleLabel"].setText(subtitleString) self.doShow() def __chapterUpdated(self): self.currentChapter = self.service.info().getInfo(iPlayableService.evUser+8) self.totalChapters = self.service.info().getInfo(iPlayableService.evUser+80) self.setChapterLabel() print "__chapterUpdated: %d/%d" % (self.currentChapter, self.totalChapters) def __titleUpdated(self): self.currentTitle = self.service.info().getInfo(iPlayableService.evUser+9) self.totalTitles = self.service.info().getInfo(iPlayableService.evUser+90) self.setChapterLabel() print "__titleUpdated: %d/%d" % (self.currentTitle, self.totalTitles) self.doShow() #def __initializeDVDinfo(self): #self.__osdAudioInfoAvail() #self.__osdSubtitleInfoAvail() def askLeavePlayer(self): self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list=[(_("Exit"), "exit"), (_("Return to file browser"), "browser"), (_("Continue playing"), "play")]) def nextAudioTrack(self): if self.service: self.service.keys().keyPressed(iServiceKeys.keyUser) def nextSubtitleTrack(self): if self.service: self.service.keys().keyPressed(iServiceKeys.keyUser+1) def enterDVDAudioMenu(self): if self.service: self.service.keys().keyPressed(iServiceKeys.keyUser+2) def nextChapter(self): if self.service: self.service.keys().keyPressed(iServiceKeys.keyUser+3) def prevChapter(self): if self.service: self.service.keys().keyPressed(iServiceKeys.keyUser+4) def nextTitle(self): if self.service: self.service.keys().keyPressed(iServiceKeys.keyUser+5) def prevTitle(self): if self.service: self.service.keys().keyPressed(iServiceKeys.keyUser+6) def enterDVDMenu(self): if self.service: self.service.keys().keyPressed(iServiceKeys.keyUser+7) def seekBeginning(self): if self.service: seekable = self.getSeek() if seekable is not None: seekable.seekTo(0) def zapToNumber(self, number): if self.service: seekable = self.getSeek() if seekable is not None: print "seek to chapter %d" % number seekable.seekChapter(number) # MENU ACTIONS def keyRight(self): if self.service: self.service.keys().keyPressed(iServiceKeys.keyRight) def keyLeft(self): if self.service: self.service.keys().keyPressed(iServiceKeys.keyLeft) def keyUp(self): if self.service: self.service.keys().keyPressed(iServiceKeys.keyUp) def keyDown(self): if self.service: self.service.keys().keyPressed(iServiceKeys.keyDown) def keyOk(self): if self.service: self.service.keys().keyPressed(iServiceKeys.keyOk) def keyCancel(self): self.askLeavePlayer() def showFileBrowser(self): self.session.openWithCallback(self.FileBrowserClosed, FileBrowser) def FileBrowserClosed(self, val): curref = self.session.nav.getCurrentlyPlayingServiceReference() print "FileBrowserClosed", val if val is None: self.askLeavePlayer() else: newref = eServiceReference(4369, 0, val) print "play", newref.toString() if curref is None or curref != newref: self.session.nav.playService(newref) self.service = self.session.nav.getCurrentService() print "self.service", self.service print "cur_dlg", self.session.current_dialog self.dvdScreen.show() self.service.subtitle().enableSubtitles(self.dvdScreen.instance, None) def exitCB(self, answer): if answer is not None: if answer[1] == "exit": if self.service: self.dvdScreen.hide() self.service.subtitle().disableSubtitles(self.session.current_dialog.instance) self.service = None self.close() if answer[1] == "browser": #TODO check here if a paused dvd playback is already running... then re-start it... #else self.showFileBrowser() else: pass def __onClose(self): self.restore_infobar_seek_config() self.session.nav.playService(self.oldService) def showAfterCuesheetOperation(self): self.show() def createSummary(self): print "DVDCreateSummary" return DVDSummary def main(session, **kwargs): session.open(DVDPlayer) def menu(menuid, **kwargs): if menuid == "mainmenu": return [(_("DVD Player"), main, "dvd_player", 46)] return [] from Plugins.Plugin import PluginDescriptor def Plugins(**kwargs): return [PluginDescriptor(name = "DVDPlayer", description = "Play DVDs", where = PluginDescriptor.WHERE_MENU, fnc = menu)]