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