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