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