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