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.Pixmap import Pixmap
11 from Components.FileList import FileList
12 from Components.MenuList import MenuList
13 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
14 from Components.config import config
15 from Tools.Directories import pathExists, fileExists
16 from Components.Harddisk import harddiskmanager
18 import servicedvd # load c++ part of dvd player plugin
22 class FileBrowser(Screen):
24 <screen name="FileBrowser" position="100,100" size="520,376" title="DVD File Browser" >
25 <widget name="filelist" position="0,0" size="520,376" scrollbarMode="showOnDemand" />
27 def __init__(self, session, dvd_filelist = [ ]):
28 Screen.__init__(self, session)
30 self.dvd_filelist = dvd_filelist
32 self["filelist"] = MenuList(self.dvd_filelist)
35 if lastpath is not None:
36 currDir = lastpath + "/"
38 currDir = "/media/dvd/"
39 if not pathExists(currDir):
42 self.filelist = FileList(currDir, matchingPattern = "(?i)^.*\.(iso)", useServiceRef = True)
43 self["filelist"] = self.filelist
45 self["FilelistActions"] = ActionMap(["OkCancelActions"],
52 if len(self.dvd_filelist):
53 print "OK " + self["filelist"].getCurrent()
54 self.close(self["filelist"].getCurrent())
57 filename = self["filelist"].getFilename()
58 if filename is not None:
59 if filename.upper().endswith("VIDEO_TS/"):
60 print "dvd structure found, trying to open..."
61 dvdpath = filename[0:-9]
62 lastpath = (dvdpath.rstrip("/").rsplit("/",1))[0]
63 print "lastpath video_ts/=", lastpath
66 if self["filelist"].canDescent(): # isDir
67 self["filelist"].descent()
68 pathname = self["filelist"].getCurrentDirectory() or ""
69 if fileExists(pathname+"VIDEO_TS.IFO"):
70 print "dvd structure found, trying to open..."
71 lastpath = (pathname.rstrip("/").rsplit("/",1))[0]
72 print "lastpath video_ts.ifo=", lastpath
75 lastpath = filename[0:filename.rfind("/")]
76 print "lastpath directory=", lastpath
82 class DVDSummary(Screen):
84 <screen position="0,0" size="132,64">
85 <widget source="session.CurrentService" render="Label" position="5,4" size="120,28" font="Regular;12" transparent="1" >
86 <convert type="ServiceName">Name</convert>
88 <widget name="DVDPlayer" position="5,30" size="66,16" font="Regular;12" transparent="1" />
89 <widget name="Chapter" position="72,30" size="54,16" font="Regular;12" transparent="1" halign="right" />
90 <widget source="session.CurrentService" render="Label" position="66,46" size="60,18" font="Regular;16" transparent="1" halign="right" >
91 <convert type="ServicePosition">Position</convert>
93 <widget source="session.CurrentService" render="Progress" position="6,46" size="60,18" borderWidth="1" >
94 <convert type="ServicePosition">Position</convert>
98 def __init__(self, session, parent):
99 Screen.__init__(self, session, parent)
101 self["DVDPlayer"] = Label("DVD Player")
102 self["Title"] = Label("")
103 self["Time"] = Label("")
104 self["Chapter"] = Label("")
106 def updateChapter(self, chapter):
107 self["Chapter"].setText(chapter)
109 def setTitle(self, title):
110 self["Title"].setText(title)
112 class DVDOverlay(Screen):
113 def __init__(self, session, args = None):
114 desktop_size = getDesktop(0).size()
115 DVDOverlay.skin = """<screen name="DVDOverlay" position="0,0" size="%d,%d" flags="wfNoBorder" zPosition="-1" backgroundColor="transparent" />""" %(desktop_size.width(), desktop_size.height())
116 Screen.__init__(self, session)
118 class ChapterZap(Screen):
120 <screen name="ChapterZap" position="235,255" size="250,60" title="Chapter" >
121 <widget name="chapter" position="35,15" size="110,25" font="Regular;23" />
122 <widget name="number" position="145,15" size="80,25" halign="right" font="Regular;23" />
131 self.close(int(self["number"].getText()))
133 def keyNumberGlobal(self, number):
134 self.Timer.start(3000, True) #reset timer
135 self.field = self.field + str(number)
136 self["number"].setText(self.field)
137 if len(self.field) >= 4:
140 def __init__(self, session, number):
141 Screen.__init__(self, session)
142 self.field = str(number)
144 self["chapter"] = Label(_("Chapter:"))
146 self["number"] = Label(self.field)
148 self["actions"] = NumberActionMap( [ "SetupActions" ],
152 "1": self.keyNumberGlobal,
153 "2": self.keyNumberGlobal,
154 "3": self.keyNumberGlobal,
155 "4": self.keyNumberGlobal,
156 "5": self.keyNumberGlobal,
157 "6": self.keyNumberGlobal,
158 "7": self.keyNumberGlobal,
159 "8": self.keyNumberGlobal,
160 "9": self.keyNumberGlobal,
161 "0": self.keyNumberGlobal
164 self.Timer = eTimer()
165 self.Timer.callback.append(self.keyOK)
166 self.Timer.start(3000, True)
168 class DVDPlayer(Screen, InfoBarBase, InfoBarNotifications, InfoBarSeek, InfoBarPVRState, InfoBarShowHide, HelpableScreen, InfoBarCueSheetSupport):
169 ALLOW_SUSPEND = Screen.SUSPEND_PAUSES
170 ENABLE_RESUME_SUPPORT = True
173 <screen name="DVDPlayer" flags="wfNoBorder" position="0,380" size="720,160" title="InfoBar" backgroundColor="transparent" >
175 <ePixmap position="0,0" zPosition="-2" size="720,160" pixmap="skin_default/info-bg_mp.png" alphatest="off" />
176 <ePixmap position="29,40" zPosition="0" size="665,104" pixmap="skin_default/screws_mp.png" alphatest="on" transparent="1" />
177 <!-- colorbuttons -->
178 <ePixmap position="48,70" zPosition="0" size="108,13" pixmap="skin_default/icons/mp_buttons.png" alphatest="on" />
180 <ePixmap pixmap="skin_default/icons/icon_event.png" position="207,78" zPosition="1" size="15,10" alphatest="on" />
181 <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">
182 <convert type="ServiceName">Name</convert>
184 <!-- Chapter info -->
185 <widget name="chapterLabel" position="230,96" size="360,22" font="Regular;20" foregroundColor="#c3c3c9" backgroundColor="#263c59" transparent="1" />
186 <!-- Audio track info -->
187 <ePixmap pixmap="skin_default/icons/icon_dolby.png" position="540,60" zPosition="1" size="26,16" alphatest="on"/>
188 <widget name="audioLabel" position="570,60" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
189 <!-- Subtitle track info -->
190 <widget source="session.CurrentService" render="Pixmap" pixmap="skin_default/icons/icon_txt.png" position="540,83" zPosition="1" size="26,16" alphatest="on" >
191 <convert type="ServiceInfo">HasTelext</convert>
192 <convert type="ConditionalShowHide" />
194 <widget name="subtitleLabel" position="570,83" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
196 <widget name="anglePix" pixmap="skin_default/icons/icon_view.png" position="540,106" size="26,16" alphatest="on" />
197 <widget name="angleLabel" position="570,106" size="130,22" font="Regular;18" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1" />
198 <!-- Elapsed time -->
199 <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" >
200 <convert type="ServicePosition">Position,ShowHours</convert>
202 <!-- Progressbar (movie position)-->
203 <widget source="session.CurrentService" render="PositionGauge" position="300,133" size="270,10" zPosition="2" pointer="skin_default/position_pointer.png:540,0" transparent="1" >
204 <convert type="ServicePosition">Gauge</convert>
206 <!-- Remaining time -->
207 <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" >
208 <convert type="ServicePosition">Remaining,Negate,ShowHours</convert>
212 def save_infobar_seek_config(self):
213 self.saved_config_speeds_forward = config.seek.speeds_forward.value
214 self.saved_config_speeds_backward = config.seek.speeds_backward.value
215 self.saved_config_enter_forward = config.seek.enter_forward.value
216 self.saved_config_enter_backward = config.seek.enter_backward.value
217 self.saved_config_seek_stepwise_minspeed = config.seek.stepwise_minspeed.value
218 self.saved_config_seek_stepwise_repeat = config.seek.stepwise_repeat.value
219 self.saved_config_seek_on_pause = config.seek.on_pause.value
220 self.saved_config_seek_speeds_slowmotion = config.seek.speeds_slowmotion.value
222 def change_infobar_seek_config(self):
223 config.seek.speeds_forward.value = [2, 4, 8, 16, 32, 64]
224 config.seek.speeds_backward.value = [8, 16, 32, 64]
225 config.seek.speeds_slowmotion.value = [ ]
226 config.seek.enter_forward.value = "2"
227 config.seek.enter_backward.value = "2"
228 config.seek.stepwise_minspeed.value = "Never"
229 config.seek.stepwise_repeat.value = "3"
230 config.seek.on_pause.value = "play"
232 def restore_infobar_seek_config(self):
233 config.seek.speeds_forward.value = self.saved_config_speeds_forward
234 config.seek.speeds_backward.value = self.saved_config_speeds_backward
235 config.seek.speeds_slowmotion.value = self.saved_config_seek_speeds_slowmotion
236 config.seek.enter_forward.value = self.saved_config_enter_forward
237 config.seek.enter_backward.value = self.saved_config_enter_backward
238 config.seek.stepwise_minspeed.value = self.saved_config_seek_stepwise_minspeed
239 config.seek.stepwise_repeat.value = self.saved_config_seek_stepwise_repeat
240 config.seek.on_pause.value = self.saved_config_seek_on_pause
242 def __init__(self, session, dvd_device = None, dvd_filelist = [ ], args = None):
243 Screen.__init__(self, session)
244 InfoBarBase.__init__(self)
245 InfoBarNotifications.__init__(self)
246 InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
247 InfoBarShowHide.__init__(self)
248 HelpableScreen.__init__(self)
249 self.save_infobar_seek_config()
250 self.change_infobar_seek_config()
251 InfoBarSeek.__init__(self, useSeekBackHack=False)
252 InfoBarPVRState.__init__(self)
253 self.dvdScreen = self.session.instantiateDialog(DVDOverlay)
255 self.oldService = self.session.nav.getCurrentlyPlayingServiceReference()
256 self.session.nav.stopService()
257 self["audioLabel"] = Label("n/a")
258 self["subtitleLabel"] = Label("")
259 self["angleLabel"] = Label("")
260 self["chapterLabel"] = Label("")
261 self["anglePix"] = Pixmap()
262 self["anglePix"].hide()
263 self.last_audioTuple = None
264 self.last_subtitleTuple = None
265 self.last_angleTuple = None
266 self.totalChapters = 0
267 self.currentChapter = 0
269 self.currentTitle = 0
271 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
273 iPlayableService.evStopped: self.__serviceStopped,
274 iPlayableService.evUser: self.__timeUpdated,
275 iPlayableService.evUser+1: self.__statePlay,
276 iPlayableService.evUser+2: self.__statePause,
277 iPlayableService.evUser+3: self.__osdFFwdInfoAvail,
278 iPlayableService.evUser+4: self.__osdFBwdInfoAvail,
279 iPlayableService.evUser+5: self.__osdStringAvail,
280 iPlayableService.evUser+6: self.__osdAudioInfoAvail,
281 iPlayableService.evUser+7: self.__osdSubtitleInfoAvail,
282 iPlayableService.evUser+8: self.__chapterUpdated,
283 iPlayableService.evUser+9: self.__titleUpdated,
284 iPlayableService.evUser+11: self.__menuOpened,
285 iPlayableService.evUser+12: self.__menuClosed,
286 iPlayableService.evUser+13: self.__osdAngleInfoAvail
289 self["DVDPlayerDirectionActions"] = ActionMap(["DirectionActions"],
291 #MENU KEY DOWN ACTIONS
292 "left": self.keyLeft,
293 "right": self.keyRight,
295 "down": self.keyDown,
297 #MENU KEY REPEATED ACTIONS
298 "leftRepeated": self.doNothing,
299 "rightRepeated": self.doNothing,
300 "upRepeated": self.doNothing,
301 "downRepeated": self.doNothing,
304 "leftUp": self.doNothing,
305 "rightUp": self.doNothing,
306 "upUp": self.doNothing,
307 "downUp": self.doNothing,
310 self["OkCancelActions"] = ActionMap(["OkCancelActions"],
313 "cancel": self.keyCancel,
316 self["DVDPlayerPlaybackActions"] = HelpableActionMap(self, "DVDPlayerActions",
319 "dvdMenu": (self.enterDVDMenu, _("show DVD main menu")),
320 "toggleInfo": (self.toggleInfo, _("toggle time, chapter, audio, subtitle info")),
321 "nextChapter": (self.nextChapter, _("forward to the next chapter")),
322 "prevChapter": (self.prevChapter, _("rewind to the previous chapter")),
323 "nextTitle": (self.nextTitle, _("jump forward to the next title")),
324 "prevTitle": (self.prevTitle, _("jump back to the previous title")),
325 "tv": (self.askLeavePlayer, _("exit DVD player or return to file browser")),
326 "dvdAudioMenu": (self.enterDVDAudioMenu, _("(show optional DVD audio menu)")),
327 "nextAudioTrack": (self.nextAudioTrack, _("switch to the next audio track")),
328 "nextSubtitleTrack": (self.nextSubtitleTrack, _("switch to the next subtitle language")),
329 "nextAngle": (self.nextAngle, _("switch to the next angle")),
330 "seekBeginning": self.seekBeginning,
333 self["NumberActions"] = NumberActionMap( [ "NumberActions"],
335 "1": self.keyNumberGlobal,
336 "2": self.keyNumberGlobal,
337 "3": self.keyNumberGlobal,
338 "4": self.keyNumberGlobal,
339 "5": self.keyNumberGlobal,
340 "6": self.keyNumberGlobal,
341 "7": self.keyNumberGlobal,
342 "8": self.keyNumberGlobal,
343 "9": self.keyNumberGlobal,
344 "0": self.keyNumberGlobal,
347 self.onClose.append(self.__onClose)
349 from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
350 hotplugNotifier.append(self.hotplugCB)
352 self.autoplay = dvd_device or dvd_filelist
355 self.physicalDVD = True
359 self.dvd_filelist = dvd_filelist
360 self.onFirstExecBegin.append(self.opened)
364 def keyNumberGlobal(self, number):
365 print "You pressed number " + str(number)
366 self.session.openWithCallback(self.numberEntered, ChapterZap, number)
368 def numberEntered(self, retval):
369 # print self.servicelist
371 self.zapToNumber(retval)
373 def getServiceInterface(self, iface):
374 service = self.service
376 attr = getattr(service, iface, None)
381 def __serviceStopped(self):
382 self.dvdScreen.hide()
383 subs = self.getServiceInterface("subtitle")
385 subs.disableSubtitles(self.session.current_dialog.instance)
387 def serviceStarted(self): #override InfoBarShowHide function
388 self.dvdScreen.show()
390 def doEofInternal(self, playing):
394 def __menuOpened(self):
397 self["NumberActions"].setEnabled(False)
399 def __menuClosed(self):
402 self["NumberActions"].setEnabled(True)
404 def setChapterLabel(self):
406 chapterOSD = "DVD Menu"
407 if self.currentTitle > 0:
408 chapterLCD = "%s %d" % (_("Chap."), self.currentChapter)
409 chapterOSD = "DVD %s %d/%d" % (_("Chapter"), self.currentChapter, self.totalChapters)
410 chapterOSD += " (%s %d/%d)" % (_("Title"), self.currentTitle, self.totalTitles)
411 self["chapterLabel"].setText(chapterOSD)
413 self.session.summary.updateChapter(chapterLCD)
420 def toggleInfo(self):
425 def __timeUpdated(self):
428 def __statePlay(self):
431 def __statePause(self):
434 def __osdFFwdInfoAvail(self):
435 self.setChapterLabel()
436 print "FFwdInfoAvail"
438 def __osdFBwdInfoAvail(self):
439 self.setChapterLabel()
440 print "FBwdInfoAvail"
442 def __osdStringAvail(self):
445 def __osdAudioInfoAvail(self):
446 info = self.getServiceInterface("info")
447 audioTuple = info and info.getInfoObject(iServiceInformation.sUser+6)
448 print "AudioInfoAvail ", repr(audioTuple)
450 audioString = "%d: %s (%s)" % (audioTuple[0],audioTuple[1],audioTuple[2])
451 self["audioLabel"].setText(audioString)
452 if audioTuple != self.last_audioTuple and not self.in_menu:
454 self.last_audioTuple = audioTuple
456 def __osdSubtitleInfoAvail(self):
457 info = self.getServiceInterface("info")
458 subtitleTuple = info and info.getInfoObject(iServiceInformation.sUser+7)
459 print "SubtitleInfoAvail ", repr(subtitleTuple)
462 if subtitleTuple[0] is not 0:
463 subtitleString = "%d: %s" % (subtitleTuple[0],subtitleTuple[1])
464 self["subtitleLabel"].setText(subtitleString)
465 if subtitleTuple != self.last_subtitleTuple and not self.in_menu:
467 self.last_subtitleTuple = subtitleTuple
469 def __osdAngleInfoAvail(self):
470 info = self.getServiceInterface("info")
471 angleTuple = info and info.getInfoObject(iServiceInformation.sUser+8)
472 print "AngleInfoAvail ", repr(angleTuple)
475 if angleTuple[1] > 1:
476 angleString = "%d / %d" % (angleTuple[0],angleTuple[1])
477 self["anglePix"].show()
479 self["anglePix"].hide()
480 self["angleLabel"].setText(angleString)
481 if angleTuple != self.last_angleTuple and not self.in_menu:
483 self.last_angleTuple = angleTuple
485 def __chapterUpdated(self):
486 info = self.getServiceInterface("info")
488 self.currentChapter = info.getInfo(iServiceInformation.sCurrentChapter)
489 self.totalChapters = info.getInfo(iServiceInformation.sTotalChapters)
490 self.setChapterLabel()
491 print "__chapterUpdated: %d/%d" % (self.currentChapter, self.totalChapters)
493 def __titleUpdated(self):
494 info = self.getServiceInterface("info")
496 self.currentTitle = info.getInfo(iServiceInformation.sCurrentTitle)
497 self.totalTitles = info.getInfo(iServiceInformation.sTotalTitles)
498 self.setChapterLabel()
499 print "__titleUpdated: %d/%d" % (self.currentTitle, self.totalTitles)
503 def askLeavePlayer(self):
504 choices = [(_("Exit"), "exit"), (_("Continue playing"), "play")]
505 if True or not self.physicalDVD:
506 choices.insert(1,(_("Return to file browser"), "browser"))
508 cur = self.session.nav.getCurrentlyPlayingServiceReference()
509 if cur and not cur.toString().endswith(harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())):
510 choices.insert(0,(_("Play DVD"), "playPhysical" ))
511 self.session.openWithCallback(self.exitCB, ChoiceBox, title=_("Leave DVD Player?"), list = choices)
513 def sendKey(self, key):
514 keys = self.getServiceInterface("keys")
519 def nextAudioTrack(self):
520 self.sendKey(iServiceKeys.keyUser)
522 def nextSubtitleTrack(self):
523 self.sendKey(iServiceKeys.keyUser+1)
525 def enterDVDAudioMenu(self):
526 self.sendKey(iServiceKeys.keyUser+2)
528 def nextChapter(self):
529 self.sendKey(iServiceKeys.keyUser+3)
531 def prevChapter(self):
532 self.sendKey(iServiceKeys.keyUser+4)
535 self.sendKey(iServiceKeys.keyUser+5)
538 self.sendKey(iServiceKeys.keyUser+6)
540 def enterDVDMenu(self):
541 self.sendKey(iServiceKeys.keyUser+7)
544 self.sendKey(iServiceKeys.keyUser+8)
546 def seekBeginning(self):
548 seekable = self.getSeek()
552 def zapToNumber(self, number):
554 seekable = self.getSeek()
556 print "seek to chapter %d" % number
557 seekable.seekChapter(number)
561 self.sendKey(iServiceKeys.keyRight)
564 self.sendKey(iServiceKeys.keyLeft)
567 self.sendKey(iServiceKeys.keyUp)
570 self.sendKey(iServiceKeys.keyDown)
573 if self.sendKey(iServiceKeys.keyOk) and not self.in_menu:
577 self.askLeavePlayer()
580 if self.autoplay and self.dvd_filelist:
581 # opened via autoplay
582 self.FileBrowserClosed(self.dvd_filelist[0])
583 elif self.autoplay and self.physicalDVD:
584 self.playPhysicalCB(True)
585 elif self.physicalDVD:
586 # opened from menu with dvd in drive
587 self.session.openWithCallback(self.playPhysicalCB, MessageBox, text=_("Do you want to play DVD in drive?"), timeout=5 )
589 # opened from menu without dvd in drive
590 self.session.openWithCallback(self.FileBrowserClosed, FileBrowser, self.dvd_filelist)
592 def playPhysicalCB(self, answer):
594 self.FileBrowserClosed(harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD()))
596 self.session.openWithCallback(self.FileBrowserClosed, FileBrowser)
598 def FileBrowserClosed(self, val):
599 curref = self.session.nav.getCurrentlyPlayingServiceReference()
600 print "FileBrowserClosed", val
602 self.askLeavePlayer()
604 newref = eServiceReference(4369, 0, val)
605 print "play", newref.toString()
606 if curref is None or curref != newref:
607 self.session.nav.playService(newref)
608 self.service = self.session.nav.getCurrentService()
609 print "self.service", self.service
610 print "cur_dlg", self.session.current_dialog
611 subs = self.getServiceInterface("subtitle")
613 subs.enableSubtitles(self.dvdScreen.instance, None)
615 def exitCB(self, answer):
616 if answer is not None:
617 if answer[1] == "exit":
621 if answer[1] == "browser":
622 #TODO check here if a paused dvd playback is already running... then re-start it...
626 self.session.openWithCallback(self.FileBrowserClosed, FileBrowser)
627 if answer[1] == "playPhysical":
630 self.playPhysicalCB(True)
635 self.restore_infobar_seek_config()
636 self.session.nav.playService(self.oldService)
637 from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
638 hotplugNotifier.remove(self.hotplugCB)
640 def playLastCB(self, answer): # overwrite infobar cuesheet function
641 print "playLastCB", answer, self.resume_point
644 seekable = self.getSeek()
646 seekable.seekTo(self.resume_point)
647 pause = self.service.pause()
649 self.hideAfterResume()
651 def showAfterCuesheetOperation(self):
655 def createSummary(self):
658 #override some InfoBarSeek functions
660 self.setSeekState(self.SEEK_STATE_PLAY)
662 def calcRemainingTime(self):
665 def hotplugCB(self, dev, media_state):
666 print "[hotplugCB]", dev, media_state
667 if dev == harddiskmanager.getCD():
668 if media_state == "1":
671 self.physicalDVD = False
673 def scanHotplug(self):
674 devicepath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
675 if pathExists(devicepath):
676 from Components.Scanner import scanDevice
677 res = scanDevice(devicepath)
678 list = [ (r.description, r, res[r], self.session) for r in res ]
680 (desc, scanner, files, session) = list[0]
683 if file.mimetype == "video/x-dvd":
684 print "physical dvd found:", devicepath
685 self.physicalDVD = True
687 self.physicalDVD = False
689 def main(session, **kwargs):
690 session.open(DVDPlayer)
692 def menu(menuid, **kwargs):
693 if menuid == "mainmenu":
694 return [(_("DVD Player"), main, "dvd_player", 46)]
697 from Plugins.Plugin import PluginDescriptor
699 def filescan_open(list, session, **kwargs):
700 if len(list) == 1 and list[0].mimetype == "video/x-dvd":
701 splitted = list[0].path.split('/')
702 print "splitted", splitted
703 if len(splitted) > 2:
704 if splitted[1] == 'autofs':
705 session.open(DVDPlayer, dvd_device="/dev/%s" %(splitted[2]))
708 print "splitted[0]", splitted[1]
712 if x.mimetype == "video/x-dvd-iso":
713 dvd_filelist.append(x.path)
714 if x.mimetype == "video/x-dvd":
715 dvd_filelist.append(x.path.rsplit('/',1)[0])
716 session.open(DVDPlayer, dvd_filelist=dvd_filelist)
718 def filescan(**kwargs):
719 from Components.Scanner import Scanner, ScanPath
721 # Overwrite checkFile to only detect local
722 class LocalScanner(Scanner):
723 def checkFile(self, file):
724 return fileExists(file.path)
727 LocalScanner(mimetypes = ["video/x-dvd","video/x-dvd-iso"],
730 ScanPath(path = "video_ts", with_subdirs = False),
731 ScanPath(path = "", with_subdirs = False),
734 description = _("Play DVD"),
735 openfnc = filescan_open,
738 def Plugins(**kwargs):
739 return [PluginDescriptor(name = "DVDPlayer", description = "Play DVDs", where = PluginDescriptor.WHERE_MENU, fnc = menu),
740 PluginDescriptor(where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)]