DVDPlayer/plugin.py: dont crash when no service is running end leave player
[enigma2.git] / lib / python / Plugins / Extensions / DVDPlayer / plugin.py
index bab64ce12faa404dfffb08baa456cce5b5349d5b..32e359332a48da00e6c68cbc66b0218e3c9258e5 100644 (file)
@@ -1,38 +1,46 @@
 from os import path as os_path, remove as os_remove, listdir as os_listdir, system
 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 enigma import eTimer, iPlayableService, iServiceInformation, eServiceReference, iServiceKeys, getDesktop
 from Screens.Screen import Screen
 from Screens.MessageBox import MessageBox
 from Screens.ChoiceBox import ChoiceBox
 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 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.Pixmap import Pixmap
 from Components.FileList import FileList
 from Components.FileList import FileList
-from Components.ServiceEventTracker import ServiceEventTracker
+from Components.MenuList import MenuList
+from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
 from Components.config import config
 from Components.config import config
-from Components.ProgressBar import ProgressBar
-from ServiceReference import ServiceReference
 from Tools.Directories import pathExists, fileExists
 from Tools.Directories import pathExists, fileExists
+from Components.Harddisk import harddiskmanager
 
 
-import random
 import servicedvd # load c++ part of dvd player plugin
 
 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" >
                <widget name="filelist" position="0,0" size="520,376" scrollbarMode="showOnDemand" />
        </screen>"""
 class FileBrowser(Screen):
        skin = """
        <screen name="FileBrowser" position="100,100" size="520,376" title="DVD File Browser" >
                <widget name="filelist" position="0,0" size="520,376" scrollbarMode="showOnDemand" />
        </screen>"""
-       def __init__(self, session):
+       def __init__(self, session, dvd_filelist = [ ]):
                Screen.__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.dvd_filelist = dvd_filelist
+               if len(dvd_filelist):   
+                       self["filelist"] = MenuList(self.dvd_filelist)
+               else:
+                       global lastpath
+                       if lastpath is not None:
+                               currDir = lastpath + "/"
+                       else:
+                               currDir = "/media/dvd/"
+                       if not pathExists(currDir):
+                               currDir = "/"
+
+                       self.filelist = FileList(currDir, matchingPattern = "(?i)^.*\.(iso)", useServiceRef = True)
+                       self["filelist"] = self.filelist
 
                self["FilelistActions"] = ActionMap(["OkCancelActions"],
                        {
 
                self["FilelistActions"] = ActionMap(["OkCancelActions"],
                        {
@@ -41,18 +49,36 @@ class FileBrowser(Screen):
                        })
 
        def ok(self):
                        })
 
        def ok(self):
-               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
-                       self["filelist"].descent()
+               if len(self.dvd_filelist):
+                       print "OK " + self["filelist"].getCurrent()
+                       self.close(self["filelist"].getCurrent())
                else:
                else:
-                       self.close(filename)
-                       
+                       global lastpath
+                       filename = self["filelist"].getFilename()
+                       if filename is not None:
+                               if filename.upper().endswith("VIDEO_TS/"):
+                                       print "dvd structure found, trying to open..."
+                                       dvdpath = filename[0:-9]
+                                       lastpath = (dvdpath.rstrip("/").rsplit("/",1))[0]
+                                       print "lastpath video_ts/=", lastpath
+                                       self.close(dvdpath)
+                                       return
+                       if self["filelist"].canDescent(): # isDir
+                               self["filelist"].descent()
+                               pathname = self["filelist"].getCurrentDirectory() or ""
+                               if fileExists(pathname+"VIDEO_TS.IFO"):
+                                       print "dvd structure found, trying to open..."
+                                       lastpath = (pathname.rstrip("/").rsplit("/",1))[0]
+                                       print "lastpath video_ts.ifo=", lastpath
+                                       self.close(pathname)
+                       else:
+                               lastpath = filename[0:filename.rfind("/")]
+                               print "lastpath directory=", lastpath
+                               self.close(filename)
+
        def exit(self):
                self.close(None)
        def exit(self):
                self.close(None)
-               
+
 class DVDSummary(Screen):
        skin = """
        <screen position="0,0" size="132,64">
 class DVDSummary(Screen):
        skin = """
        <screen position="0,0" size="132,64">
@@ -84,10 +110,11 @@ class DVDSummary(Screen):
                self["Title"].setText(title)
 
 class DVDOverlay(Screen):
                self["Title"].setText(title)
 
 class DVDOverlay(Screen):
-       skin = """<screen name="DVDOverlay" position="0,0" size="720,576" flags="wfNoBorder" zPosition="-1" backgroundColor="transparent" />"""
        def __init__(self, session, args = None):
        def __init__(self, session, args = None):
+               desktop_size = getDesktop(0).size()
+               DVDOverlay.skin = """<screen name="DVDOverlay" position="0,0" size="%d,%d" flags="wfNoBorder" zPosition="-1" backgroundColor="transparent" />""" %(desktop_size.width(), desktop_size.height())
                Screen.__init__(self, session)
                Screen.__init__(self, session)
-               
+
 class ChapterZap(Screen):
        skin = """
        <screen name="ChapterZap" position="235,255" size="250,60" title="Chapter" >
 class ChapterZap(Screen):
        skin = """
        <screen name="ChapterZap" position="235,255" size="250,60" title="Chapter" >
@@ -138,8 +165,8 @@ 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
+class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarPVRState, InfoBarShowHide, HelpableScreen, InfoBarCueSheetSupport):
+#      ALLOW_SUSPEND = True
        ENABLE_RESUME_SUPPORT = True
        
        skin = """
        ENABLE_RESUME_SUPPORT = True
        
        skin = """
@@ -157,14 +184,17 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
                <!-- Chapter info -->
                <widget name="chapterLabel" position="230,96" size="360,22" font="Regular;20" foregroundColor="#c3c3c9" backgroundColor="#263c59" transparent="1" />
                <!-- Audio track info -->
                <!-- Chapter info -->
                <widget name="chapterLabel" position="230,96" size="360,22" font="Regular;20" foregroundColor="#c3c3c9" backgroundColor="#263c59" transparent="1" />
                <!-- Audio track info -->
-               <ePixmap pixmap="skin_default/icons/icon_dolby.png" position="540,73" zPosition="1" size="26,16" alphatest="on"/>
-               <widget name="audioLabel" position="570,73" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
+               <ePixmap pixmap="skin_default/icons/icon_dolby.png" position="540,60" zPosition="1" size="26,16" alphatest="on"/>
+               <widget name="audioLabel" position="570,60" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
                <!-- Subtitle track info -->
                <!-- Subtitle track info -->
-               <widget source="session.CurrentService" render="Pixmap" pixmap="skin_default/icons/icon_txt.png" position="540,96" zPosition="1" size="26,16" alphatest="on" >
+               <widget source="session.CurrentService" render="Pixmap" pixmap="skin_default/icons/icon_txt.png" position="540,83" zPosition="1" size="26,16" alphatest="on" >
                        <convert type="ServiceInfo">HasTelext</convert>
                        <convert type="ConditionalShowHide" />
                </widget>
                        <convert type="ServiceInfo">HasTelext</convert>
                        <convert type="ConditionalShowHide" />
                </widget>
-               <widget name="subtitleLabel" position="570,96" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
+               <widget name="subtitleLabel" position="570,83" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
+               <!-- Angle info -->
+               <widget name="anglePix" pixmap="skin_default/icons/icon_view.png" position="540,106" size="26,16" alphatest="on" />
+               <widget name="angleLabel" position="570,106" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
                <!-- Elapsed time -->
                <widget source="session.CurrentService" render="Label" position="205,129" size="100,20" font="Regular;18" halign="center" valign="center" backgroundColor="#06224f" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" >
                        <convert type="ServicePosition">Position,ShowHours</convert>
                <!-- Elapsed time -->
                <widget source="session.CurrentService" render="Label" position="205,129" size="100,20" font="Regular;18" halign="center" valign="center" backgroundColor="#06224f" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" >
                        <convert type="ServicePosition">Position,ShowHours</convert>
@@ -209,23 +239,30 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
                config.seek.stepwise_repeat.value = self.saved_config_seek_stepwise_repeat
                config.seek.on_pause.value = self.saved_config_seek_on_pause
 
                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):
+       def __init__(self, session, dvd_device = None, dvd_filelist = [ ], args = None):
                Screen.__init__(self, session)
                Screen.__init__(self, session)
+               InfoBarBase.__init__(self)
                InfoBarNotifications.__init__(self)
                InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
                InfoBarShowHide.__init__(self)
                HelpableScreen.__init__(self)
                self.save_infobar_seek_config()
                self.change_infobar_seek_config()
                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)
+               InfoBarSeek.__init__(self, useSeekBackHack=False)
                InfoBarPVRState.__init__(self)
                self.dvdScreen = self.session.instantiateDialog(DVDOverlay)
 
                self.oldService = self.session.nav.getCurrentlyPlayingServiceReference()
                self.session.nav.stopService()
                InfoBarPVRState.__init__(self)
                self.dvdScreen = self.session.instantiateDialog(DVDOverlay)
 
                self.oldService = self.session.nav.getCurrentlyPlayingServiceReference()
                self.session.nav.stopService()
-               self["audioLabel"] = Label("1")
+               self["audioLabel"] = Label("n/a")
                self["subtitleLabel"] = Label("")
                self["subtitleLabel"] = Label("")
+               self["angleLabel"] = Label("")
                self["chapterLabel"] = Label("")
                self["chapterLabel"] = Label("")
+               self["anglePix"] = Pixmap()
+               self["anglePix"].hide()
+               self.last_audioTuple = None
+               self.last_subtitleTuple = None
+               self.last_angleTuple = None
                self.totalChapters = 0
                self.currentChapter = 0
                self.totalTitles = 0
                self.totalChapters = 0
                self.currentChapter = 0
                self.totalTitles = 0
@@ -233,6 +270,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,
@@ -243,18 +281,18 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
                                iPlayableService.evUser+7: self.__osdSubtitleInfoAvail,
                                iPlayableService.evUser+8: self.__chapterUpdated,
                                iPlayableService.evUser+9: self.__titleUpdated,
                                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+11: self.__menuOpened,
-                               iPlayableService.evUser+12: self.__menuClosed
+                               iPlayableService.evUser+12: self.__menuClosed,
+                               iPlayableService.evUser+13: self.__osdAngleInfoAvail
                        })
 
                        })
 
-               self["DVDPlayerDirectionActions"] = HelpableActionMap(self, "DirectionActions",
+               self["DVDPlayerDirectionActions"] = ActionMap(["DirectionActions"],
                        {
                                #MENU KEY DOWN ACTIONS
                        {
                                #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")),
+                               "left": self.keyLeft,
+                               "right": self.keyRight,
+                               "up": self.keyUp,
+                               "down": self.keyDown,
 
                                #MENU KEY REPEATED ACTIONS
                                "leftRepeated": self.doNothing,
 
                                #MENU KEY REPEATED ACTIONS
                                "leftRepeated": self.doNothing,
@@ -267,13 +305,13 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
                                "rightUp": self.doNothing,
                                "upUp": self.doNothing,
                                "downUp": self.doNothing,
                                "rightUp": self.doNothing,
                                "upUp": self.doNothing,
                                "downUp": self.doNothing,
-                       }, -2)
+                       })
 
 
-               self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions",
+               self["OkCancelActions"] = ActionMap(["OkCancelActions"],
                        {
                        {
-                               "ok": (self.keyOk, _("DVD ENTER key")),
+                               "ok": self.keyOk,
                                "cancel": self.keyCancel,
                                "cancel": self.keyCancel,
-                       }, -2)
+                       })
 
                self["DVDPlayerPlaybackActions"] = HelpableActionMap(self, "DVDPlayerActions",
                        {
 
                self["DVDPlayerPlaybackActions"] = HelpableActionMap(self, "DVDPlayerActions",
                        {
@@ -288,7 +326,8 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
                                "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")),
                                "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)")),
+                               "nextAngle": (self.nextAngle, _("switch to the next angle")),
+                               "seekBeginning": self.seekBeginning,
                        }, -2)
                        
                self["NumberActions"] = NumberActionMap( [ "NumberActions"],
                        }, -2)
                        
                self["NumberActions"] = NumberActionMap( [ "NumberActions"],
@@ -306,10 +345,20 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
                        })
 
                self.onClose.append(self.__onClose)
                        })
 
                self.onClose.append(self.__onClose)
-               self.onFirstExecBegin.append(self.showFileBrowser)
+
+               from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
+               hotplugNotifier.append(self.hotplugCB)
+               
+               if dvd_device:
+                       self.physicalDVD = True
+               else:
+                       self.scanHotplug()
+
+               self.dvd_filelist = dvd_filelist
+               self.onFirstExecBegin.append(self.opened)
                self.service = None
                self.in_menu = False
                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 keyNumberGlobal(self, number):
                print "You pressed number " + str(number)
                self.session.openWithCallback(self.numberEntered, ChapterZap, number)
@@ -319,8 +368,22 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
                if retval > 0:
                        self.zapToNumber(retval)
 
                if retval > 0:
                        self.zapToNumber(retval)
 
+       def getServiceInterface(self, iface):
+               service = self.service
+               if service:
+                       attr = getattr(service, iface, None)
+                       if callable(attr):
+                               return attr()
+               return None
+
+       def __serviceStopped(self):
+               self.dvdScreen.hide()
+               subs = self.getServiceInterface("subtitle")
+               if subs:
+                       subs.disableSubtitles(self.session.current_dialog.instance)
+
        def serviceStarted(self): #override InfoBarShowHide function
        def serviceStarted(self): #override InfoBarShowHide function
-               pass
+               self.dvdScreen.show()
 
        def doEofInternal(self, playing):
                if self.in_menu:
 
        def doEofInternal(self, playing):
                if self.in_menu:
@@ -329,10 +392,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,111 +441,155 @@ class DVDPlayer(Screen, InfoBarNotifications, InfoBarSeek, InfoBarCueSheetSuppor
                print "StringAvail"
 
        def __osdAudioInfoAvail(self):
                print "StringAvail"
 
        def __osdAudioInfoAvail(self):
-               audioString = self.service.info().getInfoString(iPlayableService.evUser+6)
-               print "AudioInfoAvail "+audioString
-               self["audioLabel"].setText(audioString)
-               if not self.in_menu:
-                       self.doShow()
+               info = self.getServiceInterface("info")
+               audioTuple = info and info.getInfoObject(iServiceInformation.sUser+6)
+               print "AudioInfoAvail ", repr(audioTuple)
+               if audioTuple:
+                       audioString = "%d: %s (%s)" % (audioTuple[0],audioTuple[1],audioTuple[2])
+                       self["audioLabel"].setText(audioString)
+                       if audioTuple != self.last_audioTuple and not self.in_menu:
+                               self.doShow()
+               self.last_audioTuple = audioTuple
 
        def __osdSubtitleInfoAvail(self):
 
        def __osdSubtitleInfoAvail(self):
-               subtitleString = self.service.info().getInfoString(iPlayableService.evUser+7)
-               print "SubtitleInfoAvail "+subtitleString
-               self["subtitleLabel"].setText(subtitleString)
-               if not self.in_menu:
-                       self.doShow()
+               info = self.getServiceInterface("info")
+               subtitleTuple = info and info.getInfoObject(iServiceInformation.sUser+7)
+               print "SubtitleInfoAvail ", repr(subtitleTuple)
+               if subtitleTuple:
+                       subtitleString = ""
+                       if subtitleTuple[0] is not 0:
+                               subtitleString = "%d: %s" % (subtitleTuple[0],subtitleTuple[1])
+                       self["subtitleLabel"].setText(subtitleString)
+                       if subtitleTuple != self.last_subtitleTuple and not self.in_menu:
+                               self.doShow()
+               self.last_subtitleTuple = subtitleTuple
+       
+       def __osdAngleInfoAvail(self):
+               info = self.getServiceInterface("info")
+               angleTuple = info and info.getInfoObject(iServiceInformation.sUser+8)
+               print "AngleInfoAvail ", repr(angleTuple)
+               if angleTuple:
+                       angleString = ""
+                       if angleTuple[1] > 1:
+                               angleString = "%d / %d" % (angleTuple[0],angleTuple[1])
+                               self["anglePix"].show()
+                       else:
+                               self["anglePix"].hide()
+                       self["angleLabel"].setText(angleString)
+                       if angleTuple != self.last_angleTuple and not self.in_menu:
+                               self.doShow()
+               self.last_angleTuple = angleTuple
 
        def __chapterUpdated(self):
 
        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)
+               info = self.getServiceInterface("info")
+               if info:
+                       self.currentChapter = info.getInfo(iServiceInformation.sCurrentChapter)
+                       self.totalChapters = info.getInfo(iServiceInformation.sTotalChapters)
+                       self.setChapterLabel()
+                       print "__chapterUpdated: %d/%d" % (self.currentChapter, self.totalChapters)
 
        def __titleUpdated(self):
 
        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)
-               if not self.in_menu:
-                       self.doShow()
+               info = self.getServiceInterface("info")
+               if info:
+                       self.currentTitle = info.getInfo(iServiceInformation.sCurrentTitle)
+                       self.totalTitles = info.getInfo(iServiceInformation.sTotalTitles)
+                       self.setChapterLabel()
+                       print "__titleUpdated: %d/%d" % (self.currentTitle, self.totalTitles)
+                       if not self.in_menu:
+                               self.doShow()
                
                
-       #def __initializeDVDinfo(self):
-               #self.__osdAudioInfoAvail()
-               #self.__osdSubtitleInfoAvail()
-
        def askLeavePlayer(self):
        def askLeavePlayer(self):
-               self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list=[(_("Exit"), "exit"), (_("Return to file browser"), "browser"), (_("Continue playing"), "play")])
+               choices = [(_("Exit"), "exit"), (_("Continue playing"), "play")]
+               if True or not self.physicalDVD:
+                       choices.insert(1,(_("Return to file browser"), "browser"))
+               if self.physicalDVD:
+                       cur = self.session.nav.getCurrentlyPlayingServiceReference()
+                       if cur and not cur.toString().endswith(harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())):
+                           choices.insert(0,(_("Play DVD"), "playPhysical" ))
+               self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list = choices)
+
+       def sendKey(self, key):
+               keys = self.getServiceInterface("keys")
+               if keys:
+                       keys.keyPressed(key)
+               return keys
 
        def nextAudioTrack(self):
 
        def nextAudioTrack(self):
-               if self.service:
-                       self.service.keys().keyPressed(iServiceKeys.keyUser)
+               self.sendKey(iServiceKeys.keyUser)
 
        def nextSubtitleTrack(self):
 
        def nextSubtitleTrack(self):
-               if self.service:
-                       self.service.keys().keyPressed(iServiceKeys.keyUser+1)
+               self.sendKey(iServiceKeys.keyUser+1)
 
        def enterDVDAudioMenu(self):
 
        def enterDVDAudioMenu(self):
-               if self.service:
-                       self.service.keys().keyPressed(iServiceKeys.keyUser+2)
+               self.sendKey(iServiceKeys.keyUser+2)
 
        def nextChapter(self):
 
        def nextChapter(self):
-               if self.service:
-                       self.service.keys().keyPressed(iServiceKeys.keyUser+3)
+               self.sendKey(iServiceKeys.keyUser+3)
 
        def prevChapter(self):
 
        def prevChapter(self):
-               if self.service:
-                       self.service.keys().keyPressed(iServiceKeys.keyUser+4)
+               self.sendKey(iServiceKeys.keyUser+4)
 
        def nextTitle(self):
 
        def nextTitle(self):
-               if self.service:
-                       self.service.keys().keyPressed(iServiceKeys.keyUser+5)
+               self.sendKey(iServiceKeys.keyUser+5)
 
        def prevTitle(self):
 
        def prevTitle(self):
-               if self.service:
-                       self.service.keys().keyPressed(iServiceKeys.keyUser+6)
+               self.sendKey(iServiceKeys.keyUser+6)
 
        def enterDVDMenu(self):
 
        def enterDVDMenu(self):
-               if self.service:
-                       self.service.keys().keyPressed(iServiceKeys.keyUser+7)
-                       
+               self.sendKey(iServiceKeys.keyUser+7)
+       
+       def nextAngle(self):
+               self.sendKey(iServiceKeys.keyUser+8)
+
        def seekBeginning(self):
                if self.service:
                        seekable = self.getSeek()
        def seekBeginning(self):
                if self.service:
                        seekable = self.getSeek()
-                       if seekable is not None:
+                       if seekable:
                                seekable.seekTo(0)
                                seekable.seekTo(0)
-                               
+
        def zapToNumber(self, number):
                if self.service:
                        seekable = self.getSeek()
        def zapToNumber(self, number):
                if self.service:
                        seekable = self.getSeek()
-                       if seekable is not None:
+                       if seekable:
                                print "seek to chapter %d" % number
                                seekable.seekChapter(number)
 
 #      MENU ACTIONS
        def keyRight(self):
                                print "seek to chapter %d" % number
                                seekable.seekChapter(number)
 
 #      MENU ACTIONS
        def keyRight(self):
-               if self.service:
-                       self.service.keys().keyPressed(iServiceKeys.keyRight)
+               self.sendKey(iServiceKeys.keyRight)
 
        def keyLeft(self):
 
        def keyLeft(self):
-               if self.service:
-                       self.service.keys().keyPressed(iServiceKeys.keyLeft)
+               self.sendKey(iServiceKeys.keyLeft)
 
        def keyUp(self):
 
        def keyUp(self):
-               if self.service:
-                       self.service.keys().keyPressed(iServiceKeys.keyUp)
+               self.sendKey(iServiceKeys.keyUp)
 
        def keyDown(self):
 
        def keyDown(self):
-               if self.service:
-                       self.service.keys().keyPressed(iServiceKeys.keyDown)
+               self.sendKey(iServiceKeys.keyDown)
 
        def keyOk(self):
 
        def keyOk(self):
-               if self.service:
-                       self.service.keys().keyPressed(iServiceKeys.keyOk)
+               if self.sendKey(iServiceKeys.keyOk) and not self.in_menu:
+                       self.toggleInfo()
 
        def keyCancel(self):
                self.askLeavePlayer()
 
 
        def keyCancel(self):
                self.askLeavePlayer()
 
-       def showFileBrowser(self):
-               self.session.openWithCallback(self.FileBrowserClosed, FileBrowser)
+       def opened(self):
+               if len(self.dvd_filelist) == 1:
+                       # opened via autoplay
+                       self.FileBrowserClosed(self.dvd_filelist[0])
+               elif self.physicalDVD:
+                       # opened from menu with dvd in drive
+                       self.session.openWithCallback(self.playPhysicalCB, MessageBox, text=_("Do you want to play DVD in drive?"), timeout=5 )
+               else:
+                       # opened from menu without dvd in drive
+                       self.session.openWithCallback(self.FileBrowserClosed, FileBrowser, self.dvd_filelist)
+
+       def playPhysicalCB(self, answer):
+               if answer == True:
+                       self.FileBrowserClosed(harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD()))
+               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,36 +604,84 @@ 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)
+                               subs = self.getServiceInterface("subtitle")
+                               if subs:
+                                       subs.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":
                                #TODO check here if a paused dvd playback is already running... then re-start it...
                                #else
                                        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()
+                               if self.service:
+                                       self.service = None
+                               self.session.openWithCallback(self.FileBrowserClosed, FileBrowser)
+                       if answer[1] == "playPhysical":
+                               if self.service:
+                                       self.service = None
+                               self.playPhysicalCB(True)
                        else:
                                pass
 
        def __onClose(self):
                self.restore_infobar_seek_config()
                self.session.nav.playService(self.oldService)
                        else:
                                pass
 
        def __onClose(self):
                self.restore_infobar_seek_config()
                self.session.nav.playService(self.oldService)
+               from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
+               hotplugNotifier.remove(self.hotplugCB)
+
+       def playLastCB(self, answer): # overwrite infobar cuesheet function
+               print "playLastCB", answer, self.resume_point
+               if self.service:
+                       if answer == True:
+                               seekable = self.getSeek()
+                               if seekable:
+                                       seekable.seekTo(self.resume_point)
+                       pause = self.service.pause()
+                       pause.unpause()
+               self.hideAfterResume()
 
        def showAfterCuesheetOperation(self):
                if not self.in_menu:
                        self.show()
 
        def createSummary(self):
 
        def showAfterCuesheetOperation(self):
                if not self.in_menu:
                        self.show()
 
        def createSummary(self):
-               print "DVDCreateSummary"
                return DVDSummary
 
                return DVDSummary
 
+#override some InfoBarSeek functions
+       def doEof(self):
+               self.setSeekState(self.SEEK_STATE_PLAY)
+
+       def calcRemainingTime(self):
+               return 0
+
+       def hotplugCB(self, dev, media_state):
+               print "[hotplugCB]", dev, media_state
+               if dev == harddiskmanager.getCD():
+                       if media_state == "1":
+                               self.scanHotplug()
+                       else:
+                               self.physicalDVD = False
+
+       def scanHotplug(self):
+               devicepath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
+               if pathExists(devicepath):
+                       from Components.Scanner import scanDevice
+                       res = scanDevice(devicepath)
+                       list = [ (r.description, r, res[r], self.session) for r in res ]
+                       if list:
+                               (desc, scanner, files, session) = list[0]
+                               for file in files:
+                                       print file
+                                       if file.mimetype == "video/x-dvd":
+                                               print "physical dvd found:", devicepath
+                                               self.physicalDVD = True
+                                               return
+               self.physicalDVD = False
+
 def main(session, **kwargs):
        session.open(DVDPlayer)
 
 def main(session, **kwargs):
        session.open(DVDPlayer)
 
@@ -534,5 +691,46 @@ def menu(menuid, **kwargs):
        return []
 
 from Plugins.Plugin import PluginDescriptor
        return []
 
 from Plugins.Plugin import PluginDescriptor
+
+def filescan_open(list, session, **kwargs):
+       if len(list) == 1 and list[0].mimetype == "video/x-dvd":
+               splitted = list[0].path.split('/')
+               print "splitted", splitted
+               if len(splitted) > 2:
+                       if splitted[1] == 'autofs':
+                               session.open(DVDPlayer, dvd_device="/dev/%s" %(splitted[2]))
+                               return
+                       else:
+                               print "splitted[0]", splitted[1]
+       else:
+               dvd_filelist = []
+               for x in list:
+                       if x.mimetype == "video/x-dvd-iso":
+                               dvd_filelist.append(x.path)
+                       if x.mimetype == "video/x-dvd":
+                               dvd_filelist.append(x.path.rsplit('/',1)[0])                    
+               session.open(DVDPlayer, dvd_filelist=dvd_filelist)
+
+def filescan(**kwargs):
+       from Components.Scanner import Scanner, ScanPath
+
+       # Overwrite checkFile to only detect local
+       class LocalScanner(Scanner):
+               def checkFile(self, file):
+                       return fileExists(file.path)
+
+       return [
+               LocalScanner(mimetypes = ["video/x-dvd","video/x-dvd-iso"],
+                       paths_to_scan =
+                               [
+                                       ScanPath(path = "video_ts", with_subdirs = False),
+                                       ScanPath(path = "", with_subdirs = False),
+                               ],
+                       name = "DVD",
+                       description = _("Play DVD"),
+                       openfnc = filescan_open,
+               )]              
+
 def Plugins(**kwargs):
 def Plugins(**kwargs):
-       return [PluginDescriptor(name = "DVDPlayer", description = "Play DVDs", where = PluginDescriptor.WHERE_MENU, fnc = menu)]
+       return [PluginDescriptor(name = "DVDPlayer", description = "Play DVDs", where = PluginDescriptor.WHERE_MENU, fnc = menu),
+                       PluginDescriptor(where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)]