4298642c67b6e68fc7d85d48e06762e7d146d8ea
[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                 self.physicalDVD = False
338                 self.dvd_device = None
339                 if dvd_device:
340                                 self.dvd_device = dvd_device
341                                 self.physicalDVD = True
342                 else:
343                         devicepath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
344                         if pathExists(devicepath):
345                                 from Components.Scanner import scanDevice
346                                 res = scanDevice(devicepath)
347                                 list = [ (r.description, r, res[r], self.session) for r in res ]
348                                 if list:
349                                         (desc, scanner, files, session) = list[0]
350                                         for file in files:
351                                                 print file
352                                                 if file.mimetype == "video/x-dvd":
353                                                         self.dvd_device = devicepath
354                                                         print "physical dvd found:", self.dvd_device
355                                                         self.physicalDVD = True                 
356
357                 self.dvd_filelist = dvd_filelist
358                 self.onFirstExecBegin.append(self.showFileBrowser)
359                 self.service = None
360                 self.in_menu = False
361                 self.old_aspect = open("/proc/stb/video/aspect", "r").read()
362                 self.old_policy = open("/proc/stb/video/policy", "r").read()
363                 self.old_wss = open("/proc/stb/denc/0/wss", "r").read()
364
365         def keyNumberGlobal(self, number):
366                 print "You pressed number " + str(number)
367                 self.session.openWithCallback(self.numberEntered, ChapterZap, number)
368
369         def numberEntered(self, retval):
370 #               print self.servicelist
371                 if retval > 0:
372                         self.zapToNumber(retval)
373
374         def __serviceStopped(self):
375                 self.dvdScreen.hide()
376                 self.service.subtitle().disableSubtitles(self.session.current_dialog.instance)
377
378         def serviceStarted(self): #override InfoBarShowHide function
379                 self.dvdScreen.show()
380                 self.service.subtitle().enableSubtitles(self.dvdScreen.instance, None)
381
382         def doEofInternal(self, playing):
383                 if self.in_menu:
384                         self.hide()
385
386         def __menuOpened(self):
387                 self.hide()
388                 self.in_menu = True
389                 self["NumberActions"].setEnabled(False)
390
391         def __menuClosed(self):
392                 self.show()
393                 self.in_menu = False
394                 self["NumberActions"].setEnabled(True)
395
396         def setChapterLabel(self):
397                 chapterLCD = "Menu"
398                 chapterOSD = "DVD Menu"
399                 if self.currentTitle > 0:
400                         chapterLCD = "%s %d" % (_("Chap."), self.currentChapter)
401                         chapterOSD = "DVD %s %d/%d" % (_("Chapter"), self.currentChapter, self.totalChapters)
402                         chapterOSD += " (%s %d/%d)" % (_("Title"), self.currentTitle, self.totalTitles)
403                 self["chapterLabel"].setText(chapterOSD)
404                 try:
405                         self.session.summary.updateChapter(chapterLCD)
406                 except:
407                         pass
408
409         def doNothing(self):
410                 pass
411
412         def toggleInfo(self):
413                 if not self.in_menu:
414                         self.toggleShow()
415                         print "toggleInfo"
416
417         def __timeUpdated(self):
418                 print "timeUpdated"
419
420         def __statePlay(self):
421                 print "statePlay"
422
423         def __statePause(self):
424                 print "statePause"
425
426         def __osdFFwdInfoAvail(self):
427                 self.setChapterLabel()
428                 print "FFwdInfoAvail"
429
430         def __osdFBwdInfoAvail(self):
431                 self.setChapterLabel()
432                 print "FBwdInfoAvail"
433
434         def __osdStringAvail(self):
435                 print "StringAvail"
436
437         def __osdAudioInfoAvail(self):
438                 audioTuple = self.service.info().getInfoObject(iServiceInformation.sUser+6)
439                 print "AudioInfoAvail ", repr(audioTuple)
440                 if audioTuple:
441                         audioString = "%d: %s (%s)" % (audioTuple[0],audioTuple[1],audioTuple[2])
442                         self["audioLabel"].setText(audioString)
443                         if audioTuple != self.last_audioTuple and not self.in_menu:
444                                 self.doShow()
445                         self.last_audioTuple = audioTuple
446
447         def __osdSubtitleInfoAvail(self):
448                 subtitleTuple = self.service.info().getInfoObject(iServiceInformation.sUser+7)
449                 print "SubtitleInfoAvail ", repr(subtitleTuple)
450                 if subtitleTuple:
451                         subtitleString = ""
452                         if subtitleTuple[0] is not 0:
453                                 subtitleString = "%d: %s" % (subtitleTuple[0],subtitleTuple[1])
454                         self["subtitleLabel"].setText(subtitleString)
455                         if subtitleTuple != self.last_subtitleTuple and not self.in_menu:
456                                 self.doShow()
457                         self.last_subtitleTuple = subtitleTuple
458
459         def __chapterUpdated(self):
460                 self.currentChapter = self.service.info().getInfo(iServiceInformation.sCurrentChapter)
461                 self.totalChapters = self.service.info().getInfo(iServiceInformation.sTotalChapters)
462                 self.setChapterLabel()
463                 print "__chapterUpdated: %d/%d" % (self.currentChapter, self.totalChapters)
464
465         def __titleUpdated(self):
466                 self.currentTitle = self.service.info().getInfo(iServiceInformation.sCurrentTitle)
467                 self.totalTitles = self.service.info().getInfo(iServiceInformation.sTotalTitles)
468                 self.setChapterLabel()
469                 print "__titleUpdated: %d/%d" % (self.currentTitle, self.totalTitles)
470                 if not self.in_menu:
471                         self.doShow()
472                 
473         def askLeavePlayer(self):
474                 choices = [(_("Continue playing"), "play"), (_("Exit"), "exit")]
475                 if not self.physicalDVD:
476                         choices.insert(1,(_("Return to file browser"), "browser"))                      
477                 self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list = choices)
478
479         def nextAudioTrack(self):
480                 if self.service:
481                         self.service.keys().keyPressed(iServiceKeys.keyUser)
482
483         def nextSubtitleTrack(self):
484                 if self.service:
485                         self.service.keys().keyPressed(iServiceKeys.keyUser+1)
486
487         def enterDVDAudioMenu(self):
488                 if self.service:
489                         self.service.keys().keyPressed(iServiceKeys.keyUser+2)
490
491         def nextChapter(self):
492                 if self.service:
493                         self.service.keys().keyPressed(iServiceKeys.keyUser+3)
494
495         def prevChapter(self):
496                 if self.service:
497                         self.service.keys().keyPressed(iServiceKeys.keyUser+4)
498
499         def nextTitle(self):
500                 if self.service:
501                         self.service.keys().keyPressed(iServiceKeys.keyUser+5)
502
503         def prevTitle(self):
504                 if self.service:
505                         self.service.keys().keyPressed(iServiceKeys.keyUser+6)
506
507         def enterDVDMenu(self):
508                 if self.service:
509                         self.service.keys().keyPressed(iServiceKeys.keyUser+7)
510
511         def seekBeginning(self):
512                 if self.service:
513                         seekable = self.getSeek()
514                         if seekable is not None:
515                                 seekable.seekTo(0)
516
517         def zapToNumber(self, number):
518                 if self.service:
519                         seekable = self.getSeek()
520                         if seekable is not None:
521                                 print "seek to chapter %d" % number
522                                 seekable.seekChapter(number)
523
524 #       MENU ACTIONS
525         def keyRight(self):
526                 if self.service:
527                         self.service.keys().keyPressed(iServiceKeys.keyRight)
528
529         def keyLeft(self):
530                 if self.service:
531                         self.service.keys().keyPressed(iServiceKeys.keyLeft)
532
533         def keyUp(self):
534                 if self.service:
535                         self.service.keys().keyPressed(iServiceKeys.keyUp)
536
537         def keyDown(self):
538                 if self.service:
539                         self.service.keys().keyPressed(iServiceKeys.keyDown)
540
541         def keyOk(self):
542                 if self.service:
543                         if not self.in_menu:
544                                 self.toggleInfo()
545                         self.service.keys().keyPressed(iServiceKeys.keyOk)
546
547         def keyCancel(self):
548                 self.askLeavePlayer()
549
550         def showFileBrowser(self):
551                 if self.physicalDVD and len(self.dvd_filelist) == 0:
552                         if self.dvd_device == harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD()):
553                                 self.session.openWithCallback(self.DVDdriveCB, MessageBox, text=_("Do you want to play DVD in drive?"), timeout=5 )
554                         else:
555                                 self.DVDdriveCB(True)
556                 elif len(self.dvd_filelist) == 1:
557                         self.FileBrowserClosed(self.dvd_filelist[0])
558                 else:
559                         self.session.openWithCallback(self.FileBrowserClosed, FileBrowser, self.dvd_filelist)
560         
561         def DVDdriveCB(self, answer):
562                 if answer == True:
563                         self.FileBrowserClosed(self.dvd_device)
564                 else:
565                         self.session.openWithCallback(self.FileBrowserClosed, FileBrowser)
566                         self.physicalDVD = False
567
568         def FileBrowserClosed(self, val):
569                 curref = self.session.nav.getCurrentlyPlayingServiceReference()
570                 print "FileBrowserClosed", val
571                 if val is None:
572                         self.askLeavePlayer()
573                 else:
574                         newref = eServiceReference(4369, 0, val)
575                         print "play", newref.toString()
576                         if curref is None or curref != newref:
577                                 self.session.nav.playService(newref)
578                                 self.service = self.session.nav.getCurrentService()
579                                 print "self.service", self.service
580                                 print "cur_dlg", self.session.current_dialog
581
582         def exitCB(self, answer):
583                 if answer is not None:
584                         if answer[1] == "exit":
585                                 if self.service:
586                                         self.service = None
587                                 self.close()
588                         if answer[1] == "browser":
589                                 #TODO check here if a paused dvd playback is already running... then re-start it...
590                                 #else
591                                 if self.service:
592                                         self.service = None
593                                 self.showFileBrowser()
594                         else:
595                                 pass
596
597         def __onClose(self):
598                 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)):
599                         try:
600                                 open(i[0], "w").write(i[1])
601                         except IOError:
602                                 print "restore", i[0], "failed"
603                 self.restore_infobar_seek_config()
604                 self.session.nav.playService(self.oldService)
605
606         def playLastCB(self, answer): # overwrite infobar cuesheet function
607                 print "playLastCB", answer, self.resume_point
608                 if self.service:
609                         seek = self.service.seek()
610                         if answer == True:
611                                 seek.seekTo(self.resume_point)
612                         pause = self.service.pause()
613                         pause.unpause()
614                 self.hideAfterResume()
615
616         def showAfterCuesheetOperation(self):
617                 if not self.in_menu:
618                         self.show()
619
620         def createSummary(self):
621                 return DVDSummary
622
623 #override some InfoBarSeek functions
624         def doEof(self):
625                 self.setSeekState(self.SEEK_STATE_PLAY)
626
627         def calcRemainingTime(self):
628                 return 0
629
630 def main(session, **kwargs):
631         session.open(DVDPlayer)
632
633 def menu(menuid, **kwargs):
634         if menuid == "mainmenu":
635                 return [(_("DVD Player"), main, "dvd_player", 46)]
636         return []
637
638 from Plugins.Plugin import PluginDescriptor
639
640 def filescan_open(list, session, **kwargs):
641         if len(list) == 1 and list[0].mimetype == "video/x-dvd":
642                 splitted = list[0].path.split('/')
643                 print "splitted", splitted
644                 if len(splitted) > 2:
645                         if splitted[1] == 'autofs':
646                                 session.open(DVDPlayer, dvd_device="/dev/%s" %(splitted[2]))
647                                 return
648                         else:
649                                 print "splitted[0]", splitted[1]
650         else:
651                 dvd_filelist = []
652                 for x in list:
653                         if x.mimetype == "video/x-dvd-iso":
654                                 dvd_filelist.append(x.path)
655                         if x.mimetype == "video/x-dvd":
656                                 dvd_filelist.append(x.path.rsplit('/',1)[0])                    
657                 session.open(DVDPlayer, dvd_filelist=dvd_filelist)
658
659 def filescan(**kwargs):
660         from Components.Scanner import Scanner, ScanPath
661
662         # Overwrite checkFile to only detect local
663         class LocalScanner(Scanner):
664                 def checkFile(self, file):
665                         return fileExists(file.path)
666
667         return [
668                 LocalScanner(mimetypes = ["video/x-dvd","video/x-dvd-iso"],
669                         paths_to_scan =
670                                 [
671                                         ScanPath(path = "video_ts", with_subdirs = False),
672                                         ScanPath(path = "", with_subdirs = False),
673                                 ],
674                         name = "DVD",
675                         description = "Play DVD",
676                         openfnc = filescan_open,
677                 )]              
678
679 def Plugins(**kwargs):
680         return [PluginDescriptor(name = "DVDPlayer", description = "Play DVDs", where = PluginDescriptor.WHERE_MENU, fnc = menu),
681                         PluginDescriptor(where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)]