1 from os import path as os_path, remove as os_remove, listdir as os_listdir
2 from time import strftime
3 from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation, loadPic
4 from ServiceReference import ServiceReference
5 from Screens.Screen import Screen
6 from Screens.HelpMenu import HelpableScreen
7 from Screens.MessageBox import MessageBox
8 from Screens.InputBox import InputBox
9 from Screens.ChoiceBox import ChoiceBox
10 from Screens.InfoBarGenerics import InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport
11 from Components.ActionMap import NumberActionMap, HelpableActionMap
12 from Components.Label import Label
13 from Components.Pixmap import Pixmap,MultiPixmap
14 from Components.FileList import FileList
15 from Components.MediaPlayer import PlayList
16 from Components.ServicePosition import ServicePositionGauge
17 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase
18 from Components.Playlist import PlaylistIOInternal, PlaylistIOM3U, PlaylistIOPLS
19 from Components.AVSwitch import AVSwitch
20 from Components.Harddisk import harddiskmanager
21 from Components.config import config
22 from Tools.Directories import fileExists, pathExists, resolveFilename, SCOPE_CONFIG, SCOPE_PLAYLIST, SCOPE_SKIN_IMAGE
23 from settings import MediaPlayerSettings
24 from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
27 class MyPlayList(PlayList):
29 PlayList.__init__(self)
31 def PlayListShuffle(self):
32 random.shuffle(self.list)
33 self.l.setList(self.list)
35 self.oldCurrPlaying = -1
37 class MediaPixmap(Pixmap):
38 def applySkin(self, desktop, screen):
39 self.default_pixmap = None
40 if self.skinAttributes is not None:
41 for (attrib, value) in self.skinAttributes:
42 if attrib == "pixmap":
43 self.default_pixmap = value
45 if self.default_pixmap is None:
46 self.default_pixmap = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png")
47 self.coverFileNames = ["folder.png", "folder.jpg"]
48 return Pixmap.applySkin(self, desktop, screen)
50 class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport, HelpableScreen):
52 ENABLE_RESUME_SUPPORT = True
54 def __init__(self, session, args = None):
55 Screen.__init__(self, session)
56 InfoBarAudioSelection.__init__(self)
57 InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
58 InfoBarNotifications.__init__(self)
59 InfoBarBase.__init__(self)
60 InfoBarSubtitleSupport.__init__(self)
61 HelpableScreen.__init__(self)
63 self.oldService = self.session.nav.getCurrentlyPlayingServiceReference()
64 self.session.nav.stopService()
66 self.playlistparsers = {}
67 self.addPlaylistParser(PlaylistIOM3U, "m3u")
68 self.addPlaylistParser(PlaylistIOPLS, "pls")
69 self.addPlaylistParser(PlaylistIOInternal, "e2pls")
71 # 'None' is magic to start at the list of mountpoints
72 defaultDir = config.mediaplayer.defaultDir.getValue()
73 self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|mkv|mp4|dat|flac)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
74 self["filelist"] = self.filelist
76 self.playlist = MyPlayList()
77 #self.playlist = PlayList()
78 self.is_closing = False
80 self["playlist"] = self.playlist
82 self["PositionGauge"] = ServicePositionGauge(self.session.nav)
84 self["currenttext"] = Label("")
86 self["artisttext"] = Label(_("Artist:"))
87 self["artist"] = Label("")
88 self["titletext"] = Label(_("Title:"))
89 self["title"] = Label("")
90 self["albumtext"] = Label(_("Album:"))
91 self["album"] = Label("")
92 self["yeartext"] = Label(_("Year:"))
93 self["year"] = Label("")
94 self["genretext"] = Label(_("Genre:"))
95 self["genre"] = Label("")
96 self["coverArt"] = MediaPixmap()
97 self["repeat"] = MultiPixmap()
99 self.seek_target = None
100 hotplugNotifier.append(self.hotplugCB)
102 class MoviePlayerActionMap(NumberActionMap):
103 def __init__(self, player, contexts = [ ], actions = { }, prio=0):
104 NumberActionMap.__init__(self, contexts, actions, prio)
107 def action(self, contexts, action):
109 return NumberActionMap.action(self, contexts, action)
112 self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions",
114 "ok": (self.ok, _("add file to playlist")),
115 "cancel": (self.exit, _("exit mediaplayer")),
118 self["MediaPlayerActions"] = HelpableActionMap(self, "MediaPlayerActions",
120 "play": (self.xplayEntry, _("play entry")),
121 "pause": (self.pauseEntry, _("pause")),
122 "stop": (self.stopEntry, _("stop entry")),
123 "previous": (self.previousMarkOrEntry, _("play from previous mark or playlist entry")),
124 "next": (self.nextMarkOrEntry, _("play from next mark or playlist entry")),
125 "menu": (self.showMenu, _("menu")),
126 "skipListbegin": (self.skip_listbegin, _("jump to listbegin")),
127 "skipListend": (self.skip_listend, _("jump to listend")),
128 "prevBouquet": (self.switchToPlayList, _("switch to playlist")),
129 "nextBouquet": (self.switchToFileList, _("switch to filelist")),
130 "delete": (self.deletePlaylistEntry, _("delete playlist entry")),
131 "shift_stop": (self.clear_playlist, _("clear playlist")),
132 "shift_record": (self.playlist.PlayListShuffle, _("shuffle playlist")),
133 "subtitles": (self.subtitleSelection, _("Subtitle selection")),
136 self["InfobarEPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
138 "showEventInfo": (self.showEventInformation, _("show event details")),
141 self["actions"] = MoviePlayerActionMap(self, ["DirectionActions"],
143 "right": self.rightDown,
144 "rightRepeated": self.doNothing,
145 "rightUp": self.rightUp,
146 "left": self.leftDown,
147 "leftRepeated": self.doNothing,
148 "leftUp": self.leftUp,
151 "upRepeated": self.up,
152 "upUp": self.doNothing,
154 "downRepeated": self.down,
155 "downUp": self.doNothing,
158 InfoBarSeek.__init__(self, actionmap = "MediaPlayerSeekActions")
160 self.onClose.append(self.delMPTimer)
161 self.onClose.append(self.__onClose)
163 self.righttimer = False
164 self.rightKeyTimer = eTimer()
165 self.rightKeyTimer.callback.append(self.rightTimerFire)
167 self.lefttimer = False
168 self.leftKeyTimer = eTimer()
169 self.leftKeyTimer.callback.append(self.leftTimerFire)
171 self.currList = "filelist"
173 self.coverArtFileName = ""
174 self.isAudioCD = False
175 self.AudioCD_albuminfo = {}
176 self.cdAudioTrackFiles = []
179 self.playlistIOInternal = PlaylistIOInternal()
180 list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
183 self.playlist.addFile(x.ref)
184 self.playlist.updateList()
186 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
188 iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
189 iPlayableService.evUser+11: self.__evDecodeError,
190 iPlayableService.evUser+12: self.__evPluginError
196 def createSummary(self):
197 return MediaPlayerLCDScreen
200 self.playlistIOInternal.clear()
201 for x in self.playlist.list:
202 self.playlistIOInternal.addService(ServiceReference(x[0]))
203 if self.savePlaylistOnExit:
204 self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
205 if config.mediaplayer.saveDirOnExit.getValue():
206 config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory())
207 config.mediaplayer.defaultDir.save()
208 hotplugNotifier.remove(self.hotplugCB)
211 def checkSkipShowHideLock(self):
212 self.updatedSeekState()
214 def doEofInternal(self, playing):
221 self.session.nav.playService(self.oldService)
223 def __evUpdatedInfo(self):
224 currPlay = self.session.nav.getCurrentService()
225 currenttitle = currPlay.info().getInfo(iServiceInformation.sCurrentTitle)
226 totaltitles = currPlay.info().getInfo(iServiceInformation.sTotalTitles)
227 sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
228 print "[__evUpdatedInfo] title %d of %d (%s)" % (currenttitle, totaltitles, sTitle)
229 self.readTitleInformation()
231 def __evDecodeError(self):
232 currPlay = self.session.nav.getCurrentService()
233 sVideoType = currPlay.info().getInfoString(iServiceInformation.sVideoType)
234 print "[__evDecodeError] video-codec %s can't be decoded by hardware" % (sVideoType)
235 self.session.open(MessageBox, _("This Dreambox can't decode %s video streams!") % sVideoType, type = MessageBox.TYPE_INFO,timeout = 20 )
237 def __evPluginError(self):
238 currPlay = self.session.nav.getCurrentService()
239 message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
240 print "[__evPluginError]" , message
241 self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 )
243 def delMPTimer(self):
244 del self.rightKeyTimer
245 del self.leftKeyTimer
247 def readTitleInformation(self):
248 currPlay = self.session.nav.getCurrentService()
249 if currPlay is not None:
250 sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
251 sAlbum = currPlay.info().getInfoString(iServiceInformation.sAlbum)
252 sGenre = currPlay.info().getInfoString(iServiceInformation.sGenre)
253 sArtist = currPlay.info().getInfoString(iServiceInformation.sArtist)
254 sYear = currPlay.info().getInfoString(iServiceInformation.sTimeCreate)
257 if not self.isAudioCD:
258 sTitle = currPlay.info().getName().split('/')[-1]
260 sTitle = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getName()
262 if self.AudioCD_albuminfo:
263 if sAlbum == "" and "title" in self.AudioCD_albuminfo:
264 sAlbum = self.AudioCD_albuminfo["title"]
265 if sGenre == "" and "genre" in self.AudioCD_albuminfo:
266 sGenre = self.AudioCD_albuminfo["genre"]
267 if sArtist == "" and "artist" in self.AudioCD_albuminfo:
268 sArtist = self.AudioCD_albuminfo["artist"]
269 if "year" in self.AudioCD_albuminfo:
270 sYear = self.AudioCD_albuminfo["year"]
272 self.updateMusicInformation( sArtist, sTitle, sAlbum, sYear, sGenre, clear = True )
274 self.updateMusicInformation()
276 def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False):
277 self.updateSingleMusicInformation("artist", artist, clear)
278 self.updateSingleMusicInformation("title", title, clear)
279 self.updateSingleMusicInformation("album", album, clear)
280 self.updateSingleMusicInformation("year", year, clear)
281 self.updateSingleMusicInformation("genre", genre, clear)
283 def updateSingleMusicInformation(self, name, info, clear):
284 if info != "" or clear:
285 if self[name].getText() != info:
286 self[name].setText(info)
288 def updateCoverArtPixmap(self, path):
289 while not path.endswith("/"):
291 new_coverArtFileName = self["coverArt"].default_pixmap
292 for filename in self["coverArt"].coverFileNames:
293 if fileExists(path + filename):
294 new_coverArtFileName = path + filename
295 if self.coverArtFileName != new_coverArtFileName:
296 self.coverArtFileName = new_coverArtFileName
297 pixmap = loadPic(self.coverArtFileName, 116, 116, AVSwitch().getAspectRatioSetting()/2,1,0,0)
298 if pixmap is not None:
299 self["coverArt"].instance.setPixmap(pixmap.__deref__())
302 self.lefttimer = True
303 self.leftKeyTimer.start(1000)
306 self.righttimer = True
307 self.rightKeyTimer.start(1000)
311 self.leftKeyTimer.stop()
312 self.lefttimer = False
313 self[self.currList].pageUp()
314 self.updateCurrentInfo()
318 self.rightKeyTimer.stop()
319 self.righttimer = False
320 self[self.currList].pageDown()
321 self.updateCurrentInfo()
323 def leftTimerFire(self):
324 self.leftKeyTimer.stop()
325 self.lefttimer = False
326 self.switchToFileList()
328 def rightTimerFire(self):
329 self.rightKeyTimer.stop()
330 self.righttimer = False
331 self.switchToPlayList()
333 def switchToFileList(self):
334 self.currList = "filelist"
335 self.filelist.selectionEnabled(1)
336 self.playlist.selectionEnabled(0)
337 self.updateCurrentInfo()
339 def switchToPlayList(self):
340 if len(self.playlist) != 0:
341 self.currList = "playlist"
342 self.filelist.selectionEnabled(0)
343 self.playlist.selectionEnabled(1)
344 self.updateCurrentInfo()
347 self[self.currList].up()
348 self.updateCurrentInfo()
351 self[self.currList].down()
352 self.updateCurrentInfo()
354 def showAfterSeek(self):
357 def showAfterCuesheetOperation(self):
360 def hideAfterResume(self):
363 def getIdentifier(self, ref):
368 return text.split('/')[-1]
370 # FIXME: maybe this code can be optimized
371 def updateCurrentInfo(self):
373 if self.currList == "filelist":
374 idx = self.filelist.getSelectionIndex()
375 r = self.filelist.list[idx]
382 self.summaries.setText(text,1)
385 if idx < len(self.filelist.list):
386 r = self.filelist.list[idx]
390 self.summaries.setText(text,3)
392 self.summaries.setText(" ",3)
395 if idx < len(self.filelist.list):
396 r = self.filelist.list[idx]
400 self.summaries.setText(text,4)
402 self.summaries.setText(" ",4)
405 if not self.filelist.canDescent():
406 r = self.filelist.getServiceRef()
410 self["currenttext"].setText(os_path.basename(text))
412 if self.currList == "playlist":
413 t = self.playlist.getSelection()
416 #display current selected entry on LCD
417 text = self.getIdentifier(t)
418 self.summaries.setText(text,1)
419 self["currenttext"].setText(text)
420 idx = self.playlist.getSelectionIndex()
422 if idx < len(self.playlist):
423 currref = self.playlist.getServiceRefList()[idx]
424 text = self.getIdentifier(currref)
425 self.summaries.setText(text,3)
427 self.summaries.setText(" ",3)
430 if idx < len(self.playlist):
431 currref = self.playlist.getServiceRefList()[idx]
432 text = self.getIdentifier(currref)
433 self.summaries.setText(text,4)
435 self.summaries.setText(" ",4)
438 if self.currList == "filelist":
439 if self.filelist.canDescent():
440 self.filelist.descent()
441 self.updateCurrentInfo()
445 if self.currList == "playlist":
446 selection = self["playlist"].getSelection()
447 self.changeEntry(self.playlist.getSelectionIndex())
451 if len(self.cdAudioTrackFiles):
452 menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
453 if self.currList == "filelist":
454 if self.filelist.canDescent():
455 menu.append((_("add directory to playlist"), "copydir"))
457 menu.append((_("add files to playlist"), "copyfiles"))
458 menu.append((_("switch to playlist"), "playlist"))
459 menu.append((_("delete file"), "deletefile"))
461 menu.append((_("switch to filelist"), "filelist"))
462 menu.append((_("shuffle playlist"), "shuffle"))
463 menu.append((_("Delete entry"), "deleteentry"))
464 menu.append((_("clear playlist"), "clear"))
465 menu.append((_("hide player"), "hide"));
466 menu.append((_("save playlist"), "saveplaylist"));
467 menu.append((_("load playlist"), "loadplaylist"));
468 menu.append((_("delete saved playlist"), "deleteplaylist"));
469 menu.append((_("Edit settings"), "settings"))
470 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
472 def menuCallback(self, choice):
476 if choice[1] == "copydir":
477 self.copyDirectory(self.filelist.getSelection()[0])
478 elif choice[1] == "copyfiles":
480 self.playlist.clear()
481 self.isAudioCD = False
482 self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
483 self.playServiceRefEntry(self.filelist.getServiceRef())
484 elif choice[1] == "playlist":
485 self.switchToPlayList()
486 elif choice[1] == "filelist":
487 self.switchToFileList()
488 elif choice[1] == "deleteentry":
489 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
492 elif choice[1] == "clear":
493 self.clear_playlist()
494 elif choice[1] == "hide":
496 elif choice[1] == "saveplaylist":
498 elif choice[1] == "loadplaylist":
500 elif choice[1] == "deleteplaylist":
501 self.delete_saved_playlist()
502 elif choice[1] == "shuffle":
503 self.playlist.PlayListShuffle()
504 elif choice[1] == "deletefile":
506 elif choice[1] == "settings":
507 self.session.openWithCallback(self.applySettings, MediaPlayerSettings, self)
508 elif choice[1] == "audiocd":
511 def playAudioCD(self):
512 from enigma import eServiceReference
513 from Plugins.Extensions.CDInfo.plugin import Query
515 if len(self.cdAudioTrackFiles):
516 self.playlist.clear()
517 self.savePlaylistOnExit = False
518 self.isAudioCD = True
519 for file in self.cdAudioTrackFiles:
520 ref = eServiceReference(4097, 0, file)
521 self.playlist.addFile(ref)
525 self.switchToPlayList()
527 def applySettings(self):
528 self.savePlaylistOnExit = config.mediaplayer.savePlaylistOnExit.getValue()
529 if config.mediaplayer.repeat.getValue() == True:
530 self["repeat"].setPixmapNum(1)
532 self["repeat"].setPixmapNum(0)
534 def showEventInformation(self):
535 from Screens.EventView import EventViewSimple
536 from ServiceReference import ServiceReference
537 evt = self[self.currList].getCurrentEvent()
539 self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
541 # also works on filelist (?)
542 def getCurrent(self):
543 return self["playlist"].getCurrent()
545 def deletePlaylistEntry(self):
546 if self.currList == "playlist":
547 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
551 def skip_listbegin(self):
552 if self.currList == "filelist":
553 self.filelist.moveToIndex(0)
555 self.playlist.moveToIndex(0)
556 self.updateCurrentInfo()
558 def skip_listend(self):
559 if self.currList == "filelist":
560 idx = len(self.filelist.list)
561 self.filelist.moveToIndex(idx - 1)
563 self.playlist.moveToIndex(len(self.playlist)-1)
564 self.updateCurrentInfo()
566 def save_playlist(self):
567 self.session.openWithCallback(self.save_playlist2,InputBox, title=_("Please enter filename (empty = use current date)"),windowTitle = _("Save Playlist"))
569 def save_playlist2(self, name):
573 name = strftime("%y%m%d_%H%M%S")
575 self.playlistIOInternal.clear()
576 for x in self.playlist.list:
577 self.playlistIOInternal.addService(ServiceReference(x[0]))
578 self.playlistIOInternal.save(resolveFilename(SCOPE_PLAYLIST) + name)
580 def load_playlist(self):
582 playlistdir = resolveFilename(SCOPE_PLAYLIST)
584 for i in os_listdir(playlistdir):
585 listpath.append((i,playlistdir + i))
587 print "Error while scanning subdirs ",e
588 self.session.openWithCallback(self.PlaylistSelected, ChoiceBox, title=_("Please select a playlist..."), list = listpath)
590 def PlaylistSelected(self,path):
592 self.clear_playlist()
593 extension = path[0].rsplit('.',1)[-1]
594 if self.playlistparsers.has_key(extension):
595 playlist = self.playlistparsers[extension]()
596 list = playlist.open(path[1])
598 self.playlist.addFile(x.ref)
599 self.playlist.updateList()
601 def delete_saved_playlist(self):
603 playlistdir = resolveFilename(SCOPE_PLAYLIST)
605 for i in os_listdir(playlistdir):
606 listpath.append((i,playlistdir + i))
608 print "Error while scanning subdirs ",e
609 self.session.openWithCallback(self.DeletePlaylistSelected, ChoiceBox, title=_("Please select a playlist to delete..."), list = listpath)
611 def DeletePlaylistSelected(self,path):
613 self.delname = path[1]
614 self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (path[1]))
616 def deleteConfirmed(self, confirmed):
619 os_remove(self.delname)
621 self.session.open(MessageBox, _("Delete failed!, %s") %e, MessageBox.TYPE_ERROR)
623 def clear_playlist(self):
624 self.isAudioCD = False
626 self.playlist.clear()
627 self.switchToFileList()
629 def copyDirectory(self, directory, recursive = True):
630 print "copyDirectory", directory
631 filelist = FileList(directory, useServiceRef = True, isTop = True)
633 for x in filelist.getFileList():
634 if x[0][1] == True: #isDir
636 self.copyDirectory(x[0][0])
637 elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097:
638 self.playlist.addFile(x[0][0])
639 self.playlist.updateList()
641 def deleteFile(self):
642 if self.currList == "filelist":
643 self.service = self.filelist.getServiceRef()
645 self.service = self.playlist.getSelection()
646 if self.service is None:
648 if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None:
649 if self.service == self.session.nav.getCurrentlyPlayingServiceReference():
652 serviceHandler = eServiceCenter.getInstance()
653 offline = serviceHandler.offlineOperations(self.service)
654 info = serviceHandler.info(self.service)
655 name = info and info.getName(self.service)
657 if offline is not None:
659 if not offline.deleteFromDisk(1):
662 self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name))
664 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
666 def deleteConfirmed_offline(self, confirmed):
668 serviceHandler = eServiceCenter.getInstance()
669 offline = serviceHandler.offlineOperations(self.service)
671 if offline is not None:
673 if not offline.deleteFromDisk(0):
676 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
678 self.removeListEntry()
680 def removeListEntry(self):
681 currdir = self.filelist.getCurrentDirectory()
682 self.filelist.changeDir(currdir)
687 if len(self.playlist) > 0:
688 for x in self.playlist.list:
689 if self.service == x[0]:
690 self.playlist.deleteFile(index)
694 self.playlist.updateList()
695 if self.currList == "playlist":
696 if len(self.playlist) == 0:
697 self.switchToFileList()
700 if self.filelist.getServiceRef().type == 4098: # playlist
701 ServiceRef = self.filelist.getServiceRef()
702 extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
703 if self.playlistparsers.has_key(extension):
704 playlist = self.playlistparsers[extension]()
705 list = playlist.open(ServiceRef.getPath())
707 self.playlist.addFile(x.ref)
708 self.playlist.updateList()
710 self.playlist.addFile(self.filelist.getServiceRef())
711 self.playlist.updateList()
712 if len(self.playlist) == 1:
715 def addPlaylistParser(self, parser, extension):
716 self.playlistparsers[extension] = parser
719 next = self.playlist.getCurrentIndex() + 1
720 if next < len(self.playlist):
721 self.changeEntry(next)
722 elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ):
726 def nextMarkOrEntry(self):
727 if not self.jumpPreviousNextMark(lambda x: x):
728 next = self.playlist.getCurrentIndex() + 1
729 if next < len(self.playlist):
730 self.changeEntry(next)
734 def previousMarkOrEntry(self):
735 if not self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True):
736 next = self.playlist.getCurrentIndex() - 1
738 self.changeEntry(next)
740 def deleteEntry(self):
741 self.playlist.deleteFile(self.playlist.getSelectionIndex())
742 self.playlist.updateList()
743 if len(self.playlist) == 0:
744 self.switchToFileList()
746 def changeEntry(self, index):
747 self.playlist.setCurrentPlaying(index)
750 def playServiceRefEntry(self, serviceref):
751 serviceRefList = self.playlist.getServiceRefList()
752 for count in range(len(serviceRefList)):
753 if serviceRefList[count] == serviceref:
754 self.changeEntry(count)
757 def xplayEntry(self):
758 if self.currList == "playlist":
762 self.playlist.clear()
763 self.isAudioCD = False
764 sel = self.filelist.getSelection()
766 if sel[1]: # can descent
767 # add directory to playlist
768 self.copyDirectory(sel[0])
770 # add files to playlist
771 self.copyDirectory(os_path.dirname(sel[0].getPath()) + "/", recursive = False)
772 if len(self.playlist) > 0:
776 if len(self.playlist.getServiceRefList()):
777 needsInfoUpdate = False
778 currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
779 if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
780 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
781 info = eServiceCenter.getInstance().info(currref)
782 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
783 self["title"].setText(description)
784 # display just playing musik on LCD
785 idx = self.playlist.getCurrentIndex()
786 currref = self.playlist.getServiceRefList()[idx]
787 text = self.getIdentifier(currref)
789 ext = text[-4:].lower()
791 # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead
792 if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
795 needsInfoUpdate = True
796 self.summaries.setText(text,1)
798 # get the next two entries
800 if idx < len(self.playlist):
801 currref = self.playlist.getServiceRefList()[idx]
802 text = self.getIdentifier(currref)
803 self.summaries.setText(text,3)
805 self.summaries.setText(" ",3)
808 if idx < len(self.playlist):
809 currref = self.playlist.getServiceRefList()[idx]
810 text = self.getIdentifier(currref)
811 self.summaries.setText(text,4)
813 self.summaries.setText(" ",4)
815 idx = self.playlist.getCurrentIndex()
816 currref = self.playlist.getServiceRefList()[idx]
817 text = currref.getPath()
818 ext = text[-4:].lower()
819 if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
822 needsInfoUpdate = True
824 self.unPauseService()
825 if needsInfoUpdate == True:
826 path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath()
827 self.updateCoverArtPixmap(path)
829 pngname = self["coverArt"].default_pixmap
830 self.coverArtFileName = pngname
831 self["coverArt"].instance.setPixmapFromFile(self.coverArtFileName)
832 self.readTitleInformation()
834 def updatedSeekState(self):
835 if self.seekstate == self.SEEK_STATE_PAUSE:
836 self.playlist.pauseFile()
837 elif self.seekstate == self.SEEK_STATE_PLAY:
838 self.playlist.playFile()
839 elif self.isStateForward(self.seekstate):
840 self.playlist.forwardFile()
841 elif self.isStateBackward(self.seekstate):
842 self.playlist.rewindFile()
844 def pauseEntry(self):
846 if self.seekstate == self.SEEK_STATE_PAUSE:
852 self.playlist.stopFile()
853 self.session.nav.playService(None)
854 self.updateMusicInformation(clear=True)
857 def unPauseService(self):
858 self.setSeekState(self.SEEK_STATE_PLAY)
860 def subtitleSelection(self):
861 from Screens.Subtitles import Subtitles
862 self.session.open(Subtitles)
864 def hotplugCB(self, dev, media_state):
865 if dev == harddiskmanager.getCD():
866 from Components.Scanner import scanDevice
867 devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
868 self.cdAudioTrackFiles = []
869 res = scanDevice(devpath)
870 list = [ (r.description, r, res[r], self.session) for r in res ]
872 (desc, scanner, files, session) = list[0]
874 if file.mimetype == "audio/x-cda":
875 self.cdAudioTrackFiles.append(file.path)
877 class MediaPlayerLCDScreen(Screen):
879 <screen position="0,0" size="132,64" title="LCD Text">
880 <widget name="text1" position="4,0" size="132,35" font="Regular;16"/>
881 <widget name="text3" position="4,36" size="132,14" font="Regular;10"/>
882 <widget name="text4" position="4,49" size="132,14" font="Regular;10"/>
885 def __init__(self, session, parent):
886 Screen.__init__(self, session)
887 self["text1"] = Label("Mediaplayer")
888 self["text3"] = Label("")
889 self["text4"] = Label("")
891 def setText(self, text, line):
893 if text[-4:] == ".mp3":
896 text = text + textleer*10
898 self["text1"].setText(text)
900 self["text3"].setText(text)
902 self["text4"].setText(text)
904 def main(session, **kwargs):
905 session.open(MediaPlayer)
907 def menu(menuid, **kwargs):
908 if menuid == "mainmenu":
909 return [(_("Media player"), main, "media_player", 45)]
912 def filescan_open(list, session, **kwargs):
913 from enigma import eServiceReference
915 mp = session.open(MediaPlayer)
917 mp.savePlaylistOnExit = False
920 if file.mimetype == "video/MP2T":
924 ref = eServiceReference(stype, 0, file.path)
925 mp.playlist.addFile(ref)
928 mp.switchToPlayList()
930 def audioCD_open(list, session, **kwargs):
931 from enigma import eServiceReference
933 mp = session.open(MediaPlayer)
934 mp.cdAudioTrackFiles = []
936 mp.cdAudioTrackFiles.append(file.path)
939 def filescan(**kwargs):
940 from Components.Scanner import Scanner, ScanPath
942 Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"],
945 ScanPath(path = "", with_subdirs = False),
948 description = "View Movies...",
949 openfnc = filescan_open,
951 Scanner(mimetypes = ["video/x-vcd"],
954 ScanPath(path = "mpegav", with_subdirs = False),
955 ScanPath(path = "MPEGAV", with_subdirs = False),
958 description = "View Video CD...",
959 openfnc = filescan_open,
961 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
964 ScanPath(path = "", with_subdirs = False),
967 description = "Play Music...",
968 openfnc = filescan_open,
971 from Plugins.Extensions.CDInfo.plugin import Query
973 Scanner(mimetypes = ["audio/x-cda"],
976 ScanPath(path = "", with_subdirs = False),
979 description = "Play Audio-CD...",
980 openfnc = audioCD_open,
986 from Plugins.Plugin import PluginDescriptor
987 def Plugins(**kwargs):
989 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, fnc = menu),
990 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)