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