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