Enable cuesheet (resume) support plus some spu/audio display fixes ***requires Aug...
[enigma2.git] / lib / python / Plugins / Extensions / DVDPlayer / plugin.py
1 from os import path as os_path, remove as os_remove, listdir as os_listdir, system
2 from enigma import eTimer, iPlayableService, iServiceInformation, eServiceReference, iServiceKeys
3 from Screens.Screen import Screen
4 from Screens.MessageBox import MessageBox
5 from Screens.ChoiceBox import ChoiceBox
6 from Screens.HelpMenu import HelpableScreen
7 from Screens.InfoBarGenerics import InfoBarSeek, InfoBarPVRState, InfoBarCueSheetSupport, InfoBarShowHide, InfoBarNotifications
8 from Components.ActionMap import ActionMap, NumberActionMap, HelpableActionMap
9 from Components.Label import Label
10 from Components.FileList import FileList
11 from Components.MenuList import MenuList
12 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
13 from Components.config import config
14 from Tools.Directories import pathExists, fileExists
15
16 import servicedvd # load c++ part of dvd player plugin
17
18 lastpath = ""
19
20 class FileBrowser(Screen):
21         skin = """
22         <screen name="FileBrowser" position="100,100" size="520,376" title="DVD File Browser" >
23                 <widget name="filelist" position="0,0" size="520,376" scrollbarMode="showOnDemand" />
24         </screen>"""
25         def __init__(self, session, dvd_filelist = None):
26                 Screen.__init__(self, session)
27
28                 if dvd_filelist:
29                         self.dvd_filelist = dvd_filelist
30                         self["filelist"] = MenuList(self.dvd_filelist)
31
32                 else:
33                         self.dvd_filelist = None
34                         global lastpath
35                         if lastpath is not None:
36                                 currDir = lastpath + "/"
37                         else:
38                                 currDir = "/media/dvd/"
39                         if not pathExists(currDir):
40                                 currDir = "/"
41
42                         self.filelist = FileList(currDir, matchingPattern = "(?i)^.*\.(iso)", useServiceRef = True)
43                         self["filelist"] = self.filelist
44
45                 self["FilelistActions"] = ActionMap(["OkCancelActions"],
46                         {
47                                 "ok": self.ok,
48                                 "cancel": self.exit
49                         })
50
51         def ok(self):
52                 if self.dvd_filelist:
53                         print "OK " + self["filelist"].getCurrent()
54                         self.close(self["filelist"].getCurrent())
55                 else:
56                         global lastpath
57                         filename = self["filelist"].getFilename()
58                         if filename is not None:
59                                 lastpath = filename[0:filename.rfind("/")]
60                                 if filename.upper().endswith("VIDEO_TS/"):
61                                         print "dvd structure found, trying to open..."
62                                         self.close(filename[0:-9])
63                         if self["filelist"].canDescent(): # isDir
64                                 self["filelist"].descent()
65                                 pathname = self["filelist"].getCurrentDirectory() or ""
66                                 if fileExists(pathname+"VIDEO_TS.IFO"):
67                                         print "dvd structure found, trying to open..."
68                                         self.close(pathname)
69                         else:
70                                 self.close(filename)
71
72         def exit(self):
73                 self.close(None)
74
75 class DVDSummary(Screen):
76         skin = """
77         <screen position="0,0" size="132,64">
78                 <widget source="session.CurrentService" render="Label" position="5,4" size="120,28" font="Regular;12" transparent="1" >
79                         <convert type="ServiceName">Name</convert>
80                 </widget>
81                 <widget name="DVDPlayer" position="5,30" size="66,16" font="Regular;12" transparent="1" />
82                 <widget name="Chapter" position="72,30" size="54,16" font="Regular;12" transparent="1" halign="right" />
83                 <widget source="session.CurrentService" render="Label" position="66,46" size="60,18" font="Regular;16" transparent="1" halign="right" >
84                         <convert type="ServicePosition">Position</convert>
85                 </widget>
86                 <widget source="session.CurrentService" render="Progress" position="6,46" size="60,18" borderWidth="1" >
87                         <convert type="ServicePosition">Position</convert>
88                 </widget>
89         </screen>"""
90
91         def __init__(self, session, parent):
92                 Screen.__init__(self, session, parent)
93
94                 self["DVDPlayer"] = Label("DVD Player")
95                 self["Title"] = Label("")
96                 self["Time"] = Label("")
97                 self["Chapter"] = Label("")
98
99         def updateChapter(self, chapter):
100                 self["Chapter"].setText(chapter)
101
102         def setTitle(self, title):
103                 self["Title"].setText(title)
104
105 class DVDOverlay(Screen):
106         skin = """<screen name="DVDOverlay" position="0,0" size="720,576" flags="wfNoBorder" zPosition="-1" backgroundColor="transparent" />"""
107         def __init__(self, session, args = None):
108                 Screen.__init__(self, session)
109                 
110 class ChapterZap(Screen):
111         skin = """
112         <screen name="ChapterZap" position="235,255" size="250,60" title="Chapter" >
113                 <widget name="chapter" position="35,15" size="110,25" font="Regular;23" />
114                 <widget name="number" position="145,15" size="80,25" halign="right" font="Regular;23" />
115         </screen>"""
116         
117         def quit(self):
118                 self.Timer.stop()
119                 self.close(0)
120
121         def keyOK(self):
122                 self.Timer.stop()
123                 self.close(int(self["number"].getText()))
124
125         def keyNumberGlobal(self, number):
126                 self.Timer.start(3000, True)            #reset timer
127                 self.field = self.field + str(number)
128                 self["number"].setText(self.field)
129                 if len(self.field) >= 4:
130                         self.keyOK()
131
132         def __init__(self, session, number):
133                 Screen.__init__(self, session)
134                 self.field = str(number)
135
136                 self["chapter"] = Label(_("Chapter:"))
137
138                 self["number"] = Label(self.field)
139
140                 self["actions"] = NumberActionMap( [ "SetupActions" ],
141                         {
142                                 "cancel": self.quit,
143                                 "ok": self.keyOK,
144                                 "1": self.keyNumberGlobal,
145                                 "2": self.keyNumberGlobal,
146                                 "3": self.keyNumberGlobal,
147                                 "4": self.keyNumberGlobal,
148                                 "5": self.keyNumberGlobal,
149                                 "6": self.keyNumberGlobal,
150                                 "7": self.keyNumberGlobal,
151                                 "8": self.keyNumberGlobal,
152                                 "9": self.keyNumberGlobal,
153                                 "0": self.keyNumberGlobal
154                         })
155
156                 self.Timer = eTimer()
157                 self.Timer.callback.append(self.keyOK)
158                 self.Timer.start(3000, True)
159
160 class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarPVRState, InfoBarShowHide, HelpableScreen, InfoBarCueSheetSupport):
161 #       ALLOW_SUSPEND = True
162         ENABLE_RESUME_SUPPORT = True
163         
164         skin = """
165         <screen name="DVDPlayer" flags="wfNoBorder" position="0,380" size="720,160" title="InfoBar" backgroundColor="transparent" >
166                 <!-- Background -->
167                 <ePixmap position="0,0" zPosition="-2" size="720,160" pixmap="skin_default/info-bg_mp.png" alphatest="off" />
168                 <ePixmap position="29,40" zPosition="0" size="665,104" pixmap="skin_default/screws_mp.png" alphatest="on" transparent="1" />
169                 <!-- colorbuttons -->
170                 <ePixmap position="48,70" zPosition="0" size="108,13" pixmap="skin_default/icons/mp_buttons.png" alphatest="on" />
171                 <!-- Servicename -->
172                 <ePixmap pixmap="skin_default/icons/icon_event.png" position="207,78" zPosition="1" size="15,10" alphatest="on" />
173                 <widget source="session.CurrentService" render="Label" position="230,73" size="300,22" font="Regular;20" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" noWrap="1">
174                         <convert type="ServiceName">Name</convert>
175                 </widget>
176                 <!-- Chapter info -->
177                 <widget name="chapterLabel" position="230,96" size="360,22" font="Regular;20" foregroundColor="#c3c3c9" backgroundColor="#263c59" transparent="1" />
178                 <!-- Audio track info -->
179                 <ePixmap pixmap="skin_default/icons/icon_dolby.png" position="540,73" zPosition="1" size="26,16" alphatest="on"/>
180                 <widget name="audioLabel" position="570,73" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
181                 <!-- Subtitle track info -->
182                 <widget source="session.CurrentService" render="Pixmap" pixmap="skin_default/icons/icon_txt.png" position="540,96" zPosition="1" size="26,16" alphatest="on" >
183                         <convert type="ServiceInfo">HasTelext</convert>
184                         <convert type="ConditionalShowHide" />
185                 </widget>
186                 <widget name="subtitleLabel" position="570,96" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
187                 <!-- Elapsed time -->
188                 <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" >
189                         <convert type="ServicePosition">Position,ShowHours</convert>
190                 </widget>
191                 <!-- Progressbar (movie position)-->
192                 <widget source="session.CurrentService" render="PositionGauge" position="300,133" size="270,10" zPosition="2" pointer="skin_default/position_pointer.png:540,0" transparent="1" >
193                         <convert type="ServicePosition">Gauge</convert>
194                 </widget>
195                 <!-- Remaining time -->
196                 <widget source="session.CurrentService" render="Label" position="576,129" size="100,20" font="Regular;18" halign="center" valign="center" backgroundColor="#06224f" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" >
197                         <convert type="ServicePosition">Remaining,Negate,ShowHours</convert>
198                 </widget>
199         </screen>"""
200
201         def save_infobar_seek_config(self):
202                 self.saved_config_speeds_forward = config.seek.speeds_forward.value
203                 self.saved_config_speeds_backward = config.seek.speeds_backward.value
204                 self.saved_config_enter_forward = config.seek.enter_forward.value
205                 self.saved_config_enter_backward = config.seek.enter_backward.value
206                 self.saved_config_seek_stepwise_minspeed = config.seek.stepwise_minspeed.value
207                 self.saved_config_seek_stepwise_repeat = config.seek.stepwise_repeat.value
208                 self.saved_config_seek_on_pause = config.seek.on_pause.value
209                 self.saved_config_seek_speeds_slowmotion = config.seek.speeds_slowmotion.value
210
211         def change_infobar_seek_config(self):
212                 config.seek.speeds_forward.value = [2, 4, 8, 16, 32, 64]
213                 config.seek.speeds_backward.value = [8, 16, 32, 64]
214                 config.seek.speeds_slowmotion.value = [ ]
215                 config.seek.enter_forward.value = "2"
216                 config.seek.enter_backward.value = "2"
217                 config.seek.stepwise_minspeed.value = "Never"
218                 config.seek.stepwise_repeat.value = "3"
219                 config.seek.on_pause.value = "play"
220
221         def restore_infobar_seek_config(self):
222                 config.seek.speeds_forward.value = self.saved_config_speeds_forward
223                 config.seek.speeds_backward.value = self.saved_config_speeds_backward
224                 config.seek.speeds_slowmotion.value = self.saved_config_seek_speeds_slowmotion
225                 config.seek.enter_forward.value = self.saved_config_enter_forward
226                 config.seek.enter_backward.value = self.saved_config_enter_backward
227                 config.seek.stepwise_minspeed.value = self.saved_config_seek_stepwise_minspeed
228                 config.seek.stepwise_repeat.value = self.saved_config_seek_stepwise_repeat
229                 config.seek.on_pause.value = self.saved_config_seek_on_pause
230
231         def __init__(self, session, dvd_device = None, dvd_filelist = None, args = None):
232                 Screen.__init__(self, session)
233                 InfoBarBase.__init__(self)
234                 InfoBarNotifications.__init__(self)
235                 InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
236                 InfoBarShowHide.__init__(self)
237                 HelpableScreen.__init__(self)
238                 self.save_infobar_seek_config()
239                 self.change_infobar_seek_config()
240                 InfoBarSeek.__init__(self, useSeekBackHack=False)
241                 InfoBarPVRState.__init__(self)
242                 self.dvdScreen = self.session.instantiateDialog(DVDOverlay)
243
244                 self.oldService = self.session.nav.getCurrentlyPlayingServiceReference()
245                 self.session.nav.stopService()
246                 self["audioLabel"] = Label("n/a")
247                 self["subtitleLabel"] = Label("")
248                 self["chapterLabel"] = Label("")
249                 self.totalChapters = 0
250                 self.currentChapter = 0
251                 self.totalTitles = 0
252                 self.currentTitle = 0
253
254                 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
255                         {
256                                 iPlayableService.evStopped: self.__serviceStopped,
257                                 iPlayableService.evUser: self.__timeUpdated,
258                                 iPlayableService.evUser+1: self.__statePlay,
259                                 iPlayableService.evUser+2: self.__statePause,
260                                 iPlayableService.evUser+3: self.__osdFFwdInfoAvail,
261                                 iPlayableService.evUser+4: self.__osdFBwdInfoAvail,
262                                 iPlayableService.evUser+5: self.__osdStringAvail,
263                                 iPlayableService.evUser+6: self.__osdAudioInfoAvail,
264                                 iPlayableService.evUser+7: self.__osdSubtitleInfoAvail,
265                                 iPlayableService.evUser+8: self.__chapterUpdated,
266                                 iPlayableService.evUser+9: self.__titleUpdated,
267                                 iPlayableService.evUser+11: self.__menuOpened,
268                                 iPlayableService.evUser+12: self.__menuClosed
269                         })
270
271                 self["DVDPlayerDirectionActions"] = HelpableActionMap(self, "DirectionActions",
272                         {
273                                 #MENU KEY DOWN ACTIONS
274                                 "left": (self.keyLeft, _("DVD left key")),
275                                 "right": (self.keyRight, _("DVD right key")),
276                                 "up": (self.keyUp, _("DVD up key")),
277                                 "down": (self.keyDown, _("DVD down key")),
278
279                                 #MENU KEY REPEATED ACTIONS
280                                 "leftRepeated": self.doNothing,
281                                 "rightRepeated": self.doNothing,
282                                 "upRepeated": self.doNothing,
283                                 "downRepeated": self.doNothing,
284
285                                 #MENU KEY UP ACTIONS
286                                 "leftUp": self.doNothing,
287                                 "rightUp": self.doNothing,
288                                 "upUp": self.doNothing,
289                                 "downUp": self.doNothing,
290                         }, -2)
291
292                 self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions",
293                         {
294                                 "ok": (self.keyOk, _("DVD ENTER key")),
295                                 "cancel": self.keyCancel,
296                         }, -2)
297
298                 self["DVDPlayerPlaybackActions"] = HelpableActionMap(self, "DVDPlayerActions",
299                         {
300                                 #PLAYER ACTIONS
301                                 "dvdMenu": (self.enterDVDMenu, _("show DVD main menu")),
302                                 "toggleInfo": (self.toggleInfo, _("toggle time, chapter, audio, subtitle info")),
303                                 "nextChapter": (self.nextChapter, _("forward to the next chapter")),
304                                 "prevChapter": (self.prevChapter, _("rewind to the previous chapter")),
305                                 "nextTitle": (self.nextTitle, _("jump forward to the next title")),
306                                 "prevTitle": (self.prevTitle, _("jump back to the previous title")),
307                                 "tv": (self.askLeavePlayer, _("exit DVD player or return to file browser")),
308                                 "dvdAudioMenu": (self.enterDVDAudioMenu, _("(show optional DVD audio menu)")),
309                                 "nextAudioTrack": (self.nextAudioTrack, _("switch to the next audio track")),
310                                 "nextSubtitleTrack": (self.nextSubtitleTrack, _("switch to the next subtitle language")),
311                                 "seekBeginning": (self.seekBeginning, _("Jump to video title 1 (play movie from start)")),
312                         }, -2)
313                         
314                 self["NumberActions"] = NumberActionMap( [ "NumberActions"],
315                         {
316                                 "1": self.keyNumberGlobal,
317                                 "2": self.keyNumberGlobal,
318                                 "3": self.keyNumberGlobal,
319                                 "4": self.keyNumberGlobal,
320                                 "5": self.keyNumberGlobal,
321                                 "6": self.keyNumberGlobal,
322                                 "7": self.keyNumberGlobal,
323                                 "8": self.keyNumberGlobal,
324                                 "9": self.keyNumberGlobal,
325                                 "0": self.keyNumberGlobal,
326                         })
327
328                 self.onClose.append(self.__onClose)
329
330                 if dvd_device:
331                                 self.dvd_device = dvd_device
332                                 self.physicalDVD = True
333                 else:
334                         if fileExists("/dev/cdroms/cdrom0"):
335                                 print "physical dvd found (/dev/cdroms/cdrom0)"
336                                 self.dvd_device = "/dev/cdroms/cdrom0"
337                                 self.physicalDVD = True
338                         else:
339                                 self.dvd_device = None
340                                 self.physicalDVD = False
341
342                 self.dvd_filelist = dvd_filelist
343                 self.onFirstExecBegin.append(self.showFileBrowser)
344                 self.service = None
345                 self.in_menu = False
346                 self.old_aspect = open("/proc/stb/video/aspect", "r").read()
347                 self.old_policy = open("/proc/stb/video/policy", "r").read()
348                 self.old_wss = open("/proc/stb/denc/0/wss", "r").read()
349
350         def keyNumberGlobal(self, number):
351                 print "You pressed number " + str(number)
352                 self.session.openWithCallback(self.numberEntered, ChapterZap, number)
353
354         def numberEntered(self, retval):
355 #               print self.servicelist
356                 if retval > 0:
357                         self.zapToNumber(retval)
358
359         def __serviceStopped(self):
360                 self.dvdScreen.hide()
361                 self.service.subtitle().disableSubtitles(self.session.current_dialog.instance)
362
363         def serviceStarted(self): #override InfoBarShowHide function
364                 self.dvdScreen.show()
365                 self.service.subtitle().enableSubtitles(self.dvdScreen.instance, None)
366
367         def doEofInternal(self, playing):
368                 if self.in_menu:
369                         self.hide()
370
371         def __menuOpened(self):
372                 self.hide()
373                 self.in_menu = True
374                 self["NumberActions"].setEnabled(False)
375
376         def __menuClosed(self):
377                 self.show()
378                 self.in_menu = False
379                 self["NumberActions"].setEnabled(True)
380
381         def setChapterLabel(self):
382                 chapterLCD = "Menu"
383                 chapterOSD = "DVD Menu"
384                 if self.currentTitle > 0:
385                         chapterLCD = "%s %d" % (_("Chap."), self.currentChapter)
386                         chapterOSD = "DVD %s %d/%d" % (_("Chapter"), self.currentChapter, self.totalChapters)
387                         chapterOSD += " (%s %d/%d)" % (_("Title"), self.currentTitle, self.totalTitles)
388                 self["chapterLabel"].setText(chapterOSD)
389                 try:
390                         self.session.summary.updateChapter(chapterLCD)
391                 except:
392                         pass
393
394         def doNothing(self):
395                 pass
396
397         def toggleInfo(self):
398                 if not self.in_menu:
399                         self.toggleShow()
400                         print "toggleInfo"
401
402         def __timeUpdated(self):
403                 print "timeUpdated"
404
405         def __statePlay(self):
406                 print "statePlay"
407
408         def __statePause(self):
409                 print "statePause"
410
411         def __osdFFwdInfoAvail(self):
412                 self.setChapterLabel()
413                 print "FFwdInfoAvail"
414
415         def __osdFBwdInfoAvail(self):
416                 self.setChapterLabel()
417                 print "FBwdInfoAvail"
418
419         def __osdStringAvail(self):
420                 print "StringAvail"
421
422         def __osdAudioInfoAvail(self):
423                 audioTuple = self.service.info().getInfoObject(iServiceInformation.sUser+6)
424                 print "AudioInfoAvail ", repr(audioTuple)
425                 audioString = "%d: %s (%s)" % (audioTuple[0],audioTuple[1],audioTuple[2])
426                 self["audioLabel"].setText(audioString)
427                 if not self.in_menu:
428                         self.doShow()
429
430         def __osdSubtitleInfoAvail(self):
431                 subtitleTuple = self.service.info().getInfoObject(iServiceInformation.sUser+7)
432                 print "SubtitleInfoAvail ", repr(subtitleTuple)
433                 subtitleString = ""
434                 if subtitleTuple[0] is not 0:
435                         subtitleString = "%d: %s" % (subtitleTuple[0],subtitleTuple[1])
436                 self["subtitleLabel"].setText(subtitleString)
437                 if not self.in_menu:
438                         self.doShow()
439
440         def __chapterUpdated(self):
441                 self.currentChapter = self.service.info().getInfo(iServiceInformation.sCurrentChapter)
442                 self.totalChapters = self.service.info().getInfo(iServiceInformation.sTotalChapters)
443                 self.setChapterLabel()
444                 print "__chapterUpdated: %d/%d" % (self.currentChapter, self.totalChapters)
445
446         def __titleUpdated(self):
447                 self.currentTitle = self.service.info().getInfo(iServiceInformation.sCurrentTitle)
448                 self.totalTitles = self.service.info().getInfo(iServiceInformation.sTotalTitles)
449                 self.setChapterLabel()
450                 print "__titleUpdated: %d/%d" % (self.currentTitle, self.totalTitles)
451                 if not self.in_menu:
452                         self.doShow()
453                 
454         def askLeavePlayer(self):
455                 if self.physicalDVD:
456                         self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list=[(_("Continue playing"), "play"), (_("Exit"), "exit")])
457                 else:
458                         self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list=[(_("Continue playing"), "play"), (_("Return to file browser"), "browser"), (_("Exit"), "exit")])
459
460         def nextAudioTrack(self):
461                 if self.service:
462                         self.service.keys().keyPressed(iServiceKeys.keyUser)
463
464         def nextSubtitleTrack(self):
465                 if self.service:
466                         self.service.keys().keyPressed(iServiceKeys.keyUser+1)
467
468         def enterDVDAudioMenu(self):
469                 if self.service:
470                         self.service.keys().keyPressed(iServiceKeys.keyUser+2)
471
472         def nextChapter(self):
473                 if self.service:
474                         self.service.keys().keyPressed(iServiceKeys.keyUser+3)
475
476         def prevChapter(self):
477                 if self.service:
478                         self.service.keys().keyPressed(iServiceKeys.keyUser+4)
479
480         def nextTitle(self):
481                 if self.service:
482                         self.service.keys().keyPressed(iServiceKeys.keyUser+5)
483
484         def prevTitle(self):
485                 if self.service:
486                         self.service.keys().keyPressed(iServiceKeys.keyUser+6)
487
488         def enterDVDMenu(self):
489                 if self.service:
490                         self.service.keys().keyPressed(iServiceKeys.keyUser+7)
491
492         def seekBeginning(self):
493                 if self.service:
494                         seekable = self.getSeek()
495                         if seekable is not None:
496                                 seekable.seekTo(0)
497
498         def zapToNumber(self, number):
499                 if self.service:
500                         seekable = self.getSeek()
501                         if seekable is not None:
502                                 print "seek to chapter %d" % number
503                                 seekable.seekChapter(number)
504
505 #       MENU ACTIONS
506         def keyRight(self):
507                 if self.service:
508                         self.service.keys().keyPressed(iServiceKeys.keyRight)
509
510         def keyLeft(self):
511                 if self.service:
512                         self.service.keys().keyPressed(iServiceKeys.keyLeft)
513
514         def keyUp(self):
515                 if self.service:
516                         self.service.keys().keyPressed(iServiceKeys.keyUp)
517
518         def keyDown(self):
519                 if self.service:
520                         self.service.keys().keyPressed(iServiceKeys.keyDown)
521
522         def keyOk(self):
523                 if self.service:
524                         if not self.in_menu:
525                                 self.toggleInfo()
526                         self.service.keys().keyPressed(iServiceKeys.keyOk)
527
528         def keyCancel(self):
529                 self.askLeavePlayer()
530
531         def showFileBrowser(self):
532                 if self.physicalDVD:
533                         if self.dvd_device == "/dev/cdroms/cdrom0":
534                                 self.session.openWithCallback(self.DVDdriveCB, MessageBox, text=_("Do you want to play DVD in drive?"), timeout=5 )
535                         else:
536                                 self.DVDdriveCB(True)
537                 else:
538                         self.session.openWithCallback(self.FileBrowserClosed, FileBrowser, self.dvd_filelist)
539         
540         def DVDdriveCB(self, answer):
541                 if answer == True:
542                         self.FileBrowserClosed(self.dvd_device)
543                 else:
544                         self.session.openWithCallback(self.FileBrowserClosed, FileBrowser)
545
546         def FileBrowserClosed(self, val):
547                 curref = self.session.nav.getCurrentlyPlayingServiceReference()
548                 print "FileBrowserClosed", val
549                 if val is None:
550                         self.askLeavePlayer()
551                 else:
552                         newref = eServiceReference(4369, 0, val)
553                         print "play", newref.toString()
554                         if curref is None or curref != newref:
555                                 self.session.nav.playService(newref)
556                                 self.service = self.session.nav.getCurrentService()
557                                 print "self.service", self.service
558                                 print "cur_dlg", self.session.current_dialog
559
560         def exitCB(self, answer):
561                 if answer is not None:
562                         if answer[1] == "exit":
563                                 if self.service:
564                                         self.service = None
565                                 self.close()
566                         if answer[1] == "browser":
567                                 #TODO check here if a paused dvd playback is already running... then re-start it...
568                                 #else
569                                 if self.service:
570                                         self.service = None
571                                 self.showFileBrowser()
572                         else:
573                                 pass
574
575         def __onClose(self):
576                 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)):
577                         try:
578                                 open(i[0], "w").write(i[1])
579                         except IOError:
580                                 print "restore", i[0], "failed"
581                 self.restore_infobar_seek_config()
582                 self.session.nav.playService(self.oldService)
583
584         def playLastCB(self, answer): # overwrite infobar cuesheet function
585                 print "playLastCB", answer, self.resume_point
586                 if self.service:
587                         seek = self.service.seek()
588                         seek.seekTo(self.resume_point)
589                 self.hideAfterResume()
590
591         def showAfterCuesheetOperation(self):
592                 if not self.in_menu:
593                         self.show()
594
595         def createSummary(self):
596                 return DVDSummary
597
598 #override some InfoBarSeek functions
599         def doEof(self):
600                 self.setSeekState(self.SEEK_STATE_PLAY)
601
602         def calcRemainingTime(self):
603                 return 0
604
605 def main(session, **kwargs):
606         session.open(DVDPlayer)
607
608 def menu(menuid, **kwargs):
609         if menuid == "mainmenu":
610                 return [(_("DVD Player"), main, "dvd_player", 46)]
611         return []
612
613 from Plugins.Plugin import PluginDescriptor
614
615 def filescan_open(list, session, **kwargs):
616         if len(list) == 1 and list[0].mimetype == "video/x-dvd":
617                 splitted = list[0].path.split('/')
618                 print "splitted", splitted
619                 if len(splitted) > 2:
620                         if splitted[1] == 'autofs':
621                                 session.open(DVDPlayer, dvd_device="/dev/%s" %(splitted[2]))
622                                 return
623                         else:
624                                 print "splitted[0]", splitted[1]
625         else:
626                 dvd_filelist = []
627                 for x in list:
628                         if x.mimetype == "video/x-dvd-iso":
629                                 dvd_filelist.append(x.path)
630                         if x.mimetype == "video/x-dvd":
631                                 dvd_filelist.append(x.path.rsplit('/',1)[0])                    
632                 session.open(DVDPlayer, dvd_filelist=dvd_filelist)
633
634 def filescan(**kwargs):
635         from Components.Scanner import Scanner, ScanPath
636
637         # Overwrite checkFile to only detect local
638         class LocalScanner(Scanner):
639                 def checkFile(self, file):
640                         return fileExists(file.path)
641
642         return [
643                 LocalScanner(mimetypes = ["video/x-dvd","video/x-dvd-iso"],
644                         paths_to_scan =
645                                 [
646                                         ScanPath(path = "video_ts", with_subdirs = False),
647                                         ScanPath(path = "", with_subdirs = False),
648                                 ],
649                         name = "DVD",
650                         description = "Play DVD",
651                         openfnc = filescan_open,
652                 )]              
653
654 def Plugins(**kwargs):
655         return [PluginDescriptor(name = "DVDPlayer", description = "Play DVDs", where = PluginDescriptor.WHERE_MENU, fnc = menu),
656                         PluginDescriptor(where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)]