Allow playing DVD structure from arbitrary directories
[enigma2.git] / lib / python / Plugins / Extensions / DVDPlayer / plugin.py
index bab64ce12faa404dfffb08baa456cce5b5349d5b..101166bb74ba0a17588f8fd0aa050e3c6fbdc54b 100644 (file)
@@ -10,7 +10,7 @@ from Screens.InfoBarGenerics import InfoBarSeek, InfoBarPVRState, InfoBarCueShee
 from Components.ActionMap import ActionMap, NumberActionMap, HelpableActionMap
 from Components.Label import Label
 from Components.FileList import FileList
 from Components.ActionMap import ActionMap, NumberActionMap, HelpableActionMap
 from Components.Label import Label
 from Components.FileList import FileList
-from Components.ServiceEventTracker import ServiceEventTracker
+from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
 from Components.config import config
 from Components.ProgressBar import ProgressBar
 from ServiceReference import ServiceReference
 from Components.config import config
 from Components.ProgressBar import ProgressBar
 from ServiceReference import ServiceReference
@@ -19,6 +19,8 @@ from Tools.Directories import pathExists, fileExists
 import random
 import servicedvd # load c++ part of dvd player plugin
 
 import random
 import servicedvd # load c++ part of dvd player plugin
 
+lastpath = ""
+
 class FileBrowser(Screen):
        skin = """
        <screen name="FileBrowser" position="100,100" size="520,376" title="DVD File Browser" >
 class FileBrowser(Screen):
        skin = """
        <screen name="FileBrowser" position="100,100" size="520,376" title="DVD File Browser" >
@@ -26,7 +28,11 @@ class FileBrowser(Screen):
        </screen>"""
        def __init__(self, session):
                Screen.__init__(self, session)
        </screen>"""
        def __init__(self, session):
                Screen.__init__(self, session)
-               currDir = "/media/dvd/"
+               global lastpath
+               if lastpath is not None:
+                       currDir = lastpath + "/"
+               else:
+                       currDir = "/media/dvd/"
                if not pathExists(currDir):
                        currDir = "/"
                #else:
                if not pathExists(currDir):
                        currDir = "/"
                #else:
@@ -41,15 +47,23 @@ class FileBrowser(Screen):
                        })
 
        def ok(self):
                        })
 
        def ok(self):
+               global lastpath
                filename = self["filelist"].getFilename()
                filename = self["filelist"].getFilename()
-               if filename is not None and filename.upper().endswith("VIDEO_TS/"):
-                       print "dvd structure found, trying to open..."
-                       self.close(filename[0:-9])
-               elif self["filelist"].canDescent(): # isDir
+               if filename is not None:
+                       lastpath = filename[0:filename.rfind("/")]
+                       if filename.upper().endswith("VIDEO_TS/"):
+                               print "dvd structure found, trying to open..."
+                               self.close(filename[0:-9])
+               if self["filelist"].canDescent(): # isDir
                        self["filelist"].descent()
                        self["filelist"].descent()
+                       pathname = self["filelist"].getCurrentDirectory()
+                       print self["filelist"].getFilename()
+                       if fileExists(pathname+"VIDEO_TS.IFO"):
+                               print "dvd structure found, trying to open..."
+                               self.close(pathname)
                else:
                        self.close(filename)
                else:
                        self.close(filename)
-                       
+
        def exit(self):
                self.close(None)
                
        def exit(self):
                self.close(None)
                
@@ -138,9 +152,10 @@ class ChapterZap(Screen):
                self.Timer.callback.append(self.keyOK)
                self.Timer.start(3000, True)
 
                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
+class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarPVRState, InfoBarShowHide, HelpableScreen):
+#InfoBarCueSheetSupport, 
+#      ALLOW_SUSPEND = True
+#      ENABLE_RESUME_SUPPORT = True
        
        skin = """
        <screen name="DVDPlayer" flags="wfNoBorder" position="0,380" size="720,160" title="InfoBar" backgroundColor="transparent" >
        
        skin = """
        <screen name="DVDPlayer" flags="wfNoBorder" position="0,380" size="720,160" title="InfoBar" backgroundColor="transparent" >
@@ -211,13 +226,14 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
 
        def __init__(self, session, args = None):
                Screen.__init__(self, session)
 
        def __init__(self, session, args = None):
                Screen.__init__(self, session)
+               InfoBarBase.__init__(self)
                InfoBarNotifications.__init__(self)
                InfoBarNotifications.__init__(self)
-               InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
+#              InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
                InfoBarShowHide.__init__(self)
                HelpableScreen.__init__(self)
                self.save_infobar_seek_config()
                self.change_infobar_seek_config()
                InfoBarShowHide.__init__(self)
                HelpableScreen.__init__(self)
                self.save_infobar_seek_config()
                self.change_infobar_seek_config()
-               InfoBarSeek.__init__(self)
+               InfoBarSeek.__init__(self, useSeekBackHack=False)
                InfoBarPVRState.__init__(self)
                self.dvdScreen = self.session.instantiateDialog(DVDOverlay)
 
                InfoBarPVRState.__init__(self)
                self.dvdScreen = self.session.instantiateDialog(DVDOverlay)
 
@@ -233,6 +249,7 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
 
                self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
                        {
 
                self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
                        {
+                               iPlayableService.evStopped: self.__serviceStopped,
                                iPlayableService.evUser: self.__timeUpdated,
                                iPlayableService.evUser+1: self.__statePlay,
                                iPlayableService.evUser+2: self.__statePause,
                                iPlayableService.evUser: self.__timeUpdated,
                                iPlayableService.evUser+1: self.__statePlay,
                                iPlayableService.evUser+2: self.__statePause,
@@ -306,10 +323,20 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
                        })
 
                self.onClose.append(self.__onClose)
                        })
 
                self.onClose.append(self.__onClose)
+
+               if fileExists("/dev/cdroms/cdrom0"):
+                       print "physical dvd found (/dev/cdroms/cdrom0)"
+                       self.physicalDVD = True
+               else:
+                       self.physicalDVD = False
+
                self.onFirstExecBegin.append(self.showFileBrowser)
                self.service = None
                self.in_menu = False
                self.onFirstExecBegin.append(self.showFileBrowser)
                self.service = None
                self.in_menu = False
-               
+               self.old_aspect = open("/proc/stb/video/aspect", "r").read()
+               self.old_policy = open("/proc/stb/video/policy", "r").read()
+               self.old_wss = open("/proc/stb/denc/0/wss", "r").read()
+
        def keyNumberGlobal(self, number):
                print "You pressed number " + str(number)
                self.session.openWithCallback(self.numberEntered, ChapterZap, number)
        def keyNumberGlobal(self, number):
                print "You pressed number " + str(number)
                self.session.openWithCallback(self.numberEntered, ChapterZap, number)
@@ -319,8 +346,13 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
                if retval > 0:
                        self.zapToNumber(retval)
 
                if retval > 0:
                        self.zapToNumber(retval)
 
+       def __serviceStopped(self):
+               self.dvdScreen.hide()
+               self.service.subtitle().disableSubtitles(self.session.current_dialog.instance)
+
        def serviceStarted(self): #override InfoBarShowHide function
        def serviceStarted(self): #override InfoBarShowHide function
-               pass
+               self.dvdScreen.show()
+               self.service.subtitle().enableSubtitles(self.dvdScreen.instance, None)
 
        def doEofInternal(self, playing):
                if self.in_menu:
 
        def doEofInternal(self, playing):
                if self.in_menu:
@@ -329,10 +361,12 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
        def __menuOpened(self):
                self.hide()
                self.in_menu = True
        def __menuOpened(self):
                self.hide()
                self.in_menu = True
+               self["NumberActions"].setEnabled(False)
 
        def __menuClosed(self):
                self.show()
                self.in_menu = False
 
        def __menuClosed(self):
                self.show()
                self.in_menu = False
+               self["NumberActions"].setEnabled(True)
 
        def setChapterLabel(self):
                chapterLCD = "Menu"
 
        def setChapterLabel(self):
                chapterLCD = "Menu"
@@ -376,28 +410,28 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
                print "StringAvail"
 
        def __osdAudioInfoAvail(self):
                print "StringAvail"
 
        def __osdAudioInfoAvail(self):
-               audioString = self.service.info().getInfoString(iPlayableService.evUser+6)
+               audioString = self.service.info().getInfoString(iServiceInformation.sUser+6)
                print "AudioInfoAvail "+audioString
                self["audioLabel"].setText(audioString)
                if not self.in_menu:
                        self.doShow()
 
        def __osdSubtitleInfoAvail(self):
                print "AudioInfoAvail "+audioString
                self["audioLabel"].setText(audioString)
                if not self.in_menu:
                        self.doShow()
 
        def __osdSubtitleInfoAvail(self):
-               subtitleString = self.service.info().getInfoString(iPlayableService.evUser+7)
+               subtitleString = self.service.info().getInfoString(iServiceInformation.sUser+7)
                print "SubtitleInfoAvail "+subtitleString
                self["subtitleLabel"].setText(subtitleString)
                if not self.in_menu:
                        self.doShow()
 
        def __chapterUpdated(self):
                print "SubtitleInfoAvail "+subtitleString
                self["subtitleLabel"].setText(subtitleString)
                if not self.in_menu:
                        self.doShow()
 
        def __chapterUpdated(self):
-               self.currentChapter = self.service.info().getInfo(iPlayableService.evUser+8)
-               self.totalChapters = self.service.info().getInfo(iPlayableService.evUser+80)
+               self.currentChapter = self.service.info().getInfo(iServiceInformation.sUser+8)
+               self.totalChapters = self.service.info().getInfo(iServiceInformation.sUser+80)
                self.setChapterLabel()
                print "__chapterUpdated: %d/%d" % (self.currentChapter, self.totalChapters)
 
        def __titleUpdated(self):
                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.currentTitle = self.service.info().getInfo(iServiceInformation.sUser+9)
+               self.totalTitles = self.service.info().getInfo(iServiceInformation.sUser+90)
                self.setChapterLabel()
                print "__titleUpdated: %d/%d" % (self.currentTitle, self.totalTitles)
                if not self.in_menu:
                self.setChapterLabel()
                print "__titleUpdated: %d/%d" % (self.currentTitle, self.totalTitles)
                if not self.in_menu:
@@ -441,13 +475,13 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
        def enterDVDMenu(self):
                if self.service:
                        self.service.keys().keyPressed(iServiceKeys.keyUser+7)
        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 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()
        def zapToNumber(self, number):
                if self.service:
                        seekable = self.getSeek()
@@ -474,13 +508,24 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
 
        def keyOk(self):
                if self.service:
 
        def keyOk(self):
                if self.service:
+                       if not self.in_menu:
+                               self.toggleInfo()
                        self.service.keys().keyPressed(iServiceKeys.keyOk)
 
        def keyCancel(self):
                self.askLeavePlayer()
 
        def showFileBrowser(self):
                        self.service.keys().keyPressed(iServiceKeys.keyOk)
 
        def keyCancel(self):
                self.askLeavePlayer()
 
        def showFileBrowser(self):
-               self.session.openWithCallback(self.FileBrowserClosed, FileBrowser)
+               if self.physicalDVD:
+                       self.session.openWithCallback(self.DVDdriveCB, MessageBox, text=_("Do you want to play DVD in drive?"), timeout=5 )
+               else:
+                       self.session.openWithCallback(self.FileBrowserClosed, FileBrowser)
+       
+       def DVDdriveCB(self, answer):
+               if answer == True:
+                       self.FileBrowserClosed("/dev/cdroms/cdrom0")
+               else:
+                       self.session.openWithCallback(self.FileBrowserClosed, FileBrowser)
 
        def FileBrowserClosed(self, val):
                curref = self.session.nav.getCurrentlyPlayingServiceReference()
 
        def FileBrowserClosed(self, val):
                curref = self.session.nav.getCurrentlyPlayingServiceReference()
@@ -495,15 +540,11 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
                                self.service = self.session.nav.getCurrentService()
                                print "self.service", self.service
                                print "cur_dlg", self.session.current_dialog
                                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:
 
        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":
                                        self.service = None
                                self.close()
                        if answer[1] == "browser":
@@ -514,9 +555,34 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
                                pass
 
        def __onClose(self):
                                pass
 
        def __onClose(self):
+               for i in (("/proc/stb/video/aspect", self.old_aspect), ("/proc/stb/video/policy", self.old_policy), ("/proc/stb/denc/0/wss", self.old_wss)):
+                       try:
+                               open(i[0], "w").write(i[1])
+                       except IOError:
+                               print "restore", i[0], "failed"
                self.restore_infobar_seek_config()
                self.session.nav.playService(self.oldService)
 
                self.restore_infobar_seek_config()
                self.session.nav.playService(self.oldService)
 
+#      def playLastCB(self, answer): # overwrite infobar cuesheet function
+#              print "playLastCB", answer, self.resume_point
+#              pos = self.resume_point
+#              title = self.resume_point % 90000
+#              pos -= title
+#              chapter = title % 256
+#              title /= 256
+#              print "pos", pos, "title", title, "chapter", chapter
+#              if self.service:
+#                      seek = self.service.seek()
+#                      if title != 1:
+#                              seek.seekTitle(title)
+#                              self.resume_state = 1
+#                      elif chapter != 1:
+#                              seek.seekChapter(chapter)
+#                              self.resume_state = 2
+#                      else:
+#                              seek.seekTo(pos)
+#              self.hideAfterResume()
+
        def showAfterCuesheetOperation(self):
                if not self.in_menu:
                        self.show()
        def showAfterCuesheetOperation(self):
                if not self.in_menu:
                        self.show()
@@ -525,6 +591,13 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
                print "DVDCreateSummary"
                return DVDSummary
 
                print "DVDCreateSummary"
                return DVDSummary
 
+#override some InfoBarSeek functions
+       def doEof(self):
+               self.setSeekState(self.SEEK_STATE_PLAY)
+
+       def calcRemainingTime(self):
+               return 0
+
 def main(session, **kwargs):
        session.open(DVDPlayer)
 
 def main(session, **kwargs):
        session.open(DVDPlayer)