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