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