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, ePicLoad
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):
40 self.coverArtFileName = ""
41 self.picload = ePicLoad()
42 self.picload.PictureData.get().append(self.paintCoverArtPixmapCB)
43 self.coverFileNames = ["folder.png", "folder.jpg"]
45 def applySkin(self, desktop, screen):
46 from Tools.LoadPixmap import LoadPixmap
47 if self.skinAttributes is not None:
48 for (attrib, value) in self.skinAttributes:
49 if attrib == "pixmap":
52 if noCoverFile is None:
53 noCoverFile = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png")
54 self.noCoverPixmap = LoadPixmap(noCoverFile)
55 return Pixmap.applySkin(self, desktop, screen)
59 sc = AVSwitch().getFramebufferScale()
60 #0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB)
61 self.picload.setPara((self.instance.size().width(), self.instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
63 def paintCoverArtPixmapCB(self, picInfo=None):
64 ptr = self.picload.getData()
66 self.instance.setPixmap(ptr.__deref__())
68 def updateCoverArt(self, path):
69 while not path.endswith("/"):
71 new_coverArtFileName = None
72 for filename in self.coverFileNames:
73 if fileExists(path + filename):
74 new_coverArtFileName = path + filename
75 if self.coverArtFileName != new_coverArtFileName:
76 self.coverArtFileName = new_coverArtFileName
77 if new_coverArtFileName:
78 self.picload.startDecode(self.coverArtFileName)
80 self.showDefaultCover()
82 def showDefaultCover(self):
83 self.instance.setPixmap(self.noCoverPixmap)
87 #print "mediapixmap ***********+ destroy"
90 class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport, HelpableScreen):
92 ENABLE_RESUME_SUPPORT = True
94 def __init__(self, session, args = None):
95 Screen.__init__(self, session)
96 InfoBarAudioSelection.__init__(self)
97 InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
98 InfoBarNotifications.__init__(self)
99 InfoBarBase.__init__(self)
100 InfoBarSubtitleSupport.__init__(self)
101 HelpableScreen.__init__(self)
103 self.oldService = self.session.nav.getCurrentlyPlayingServiceReference()
104 self.session.nav.stopService()
106 self.playlistparsers = {}
107 self.addPlaylistParser(PlaylistIOM3U, "m3u")
108 self.addPlaylistParser(PlaylistIOPLS, "pls")
109 self.addPlaylistParser(PlaylistIOInternal, "e2pls")
111 # 'None' is magic to start at the list of mountpoints
112 defaultDir = config.mediaplayer.defaultDir.getValue()
113 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")
114 self["filelist"] = self.filelist
116 self.playlist = MyPlayList()
117 self.is_closing = False
119 self["playlist"] = self.playlist
121 self["PositionGauge"] = ServicePositionGauge(self.session.nav)
123 self["currenttext"] = Label("")
125 self["artisttext"] = Label(_("Artist:"))
126 self["artist"] = Label("")
127 self["titletext"] = Label(_("Title:"))
128 self["title"] = Label("")
129 self["albumtext"] = Label(_("Album:"))
130 self["album"] = Label("")
131 self["yeartext"] = Label(_("Year:"))
132 self["year"] = Label("")
133 self["genretext"] = Label(_("Genre:"))
134 self["genre"] = Label("")
135 self["coverArt"] = MediaPixmap()
136 self["repeat"] = MultiPixmap()
138 self.seek_target = None
139 hotplugNotifier.append(self.hotplugCB)
141 class MoviePlayerActionMap(NumberActionMap):
142 def __init__(self, player, contexts = [ ], actions = { }, prio=0):
143 NumberActionMap.__init__(self, contexts, actions, prio)
146 def action(self, contexts, action):
148 return NumberActionMap.action(self, contexts, action)
151 self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions",
153 "ok": (self.ok, _("add file to playlist")),
154 "cancel": (self.exit, _("exit mediaplayer")),
157 self["MediaPlayerActions"] = HelpableActionMap(self, "MediaPlayerActions",
159 "play": (self.xplayEntry, _("play entry")),
160 "pause": (self.pauseEntry, _("pause")),
161 "stop": (self.stopEntry, _("stop entry")),
162 "previous": (self.previousMarkOrEntry, _("play from previous mark or playlist entry")),
163 "next": (self.nextMarkOrEntry, _("play from next mark or playlist entry")),
164 "menu": (self.showMenu, _("menu")),
165 "skipListbegin": (self.skip_listbegin, _("jump to listbegin")),
166 "skipListend": (self.skip_listend, _("jump to listend")),
167 "prevBouquet": (self.switchToPlayList, _("switch to playlist")),
168 "nextBouquet": (self.switchToFileList, _("switch to filelist")),
169 "delete": (self.deletePlaylistEntry, _("delete playlist entry")),
170 "shift_stop": (self.clear_playlist, _("clear playlist")),
171 "shift_record": (self.playlist.PlayListShuffle, _("shuffle playlist")),
172 "subtitles": (self.subtitleSelection, _("Subtitle selection")),
175 self["InfobarEPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
177 "showEventInfo": (self.showEventInformation, _("show event details")),
180 self["actions"] = MoviePlayerActionMap(self, ["DirectionActions"],
182 "right": self.rightDown,
183 "rightRepeated": self.doNothing,
184 "rightUp": self.rightUp,
185 "left": self.leftDown,
186 "leftRepeated": self.doNothing,
187 "leftUp": self.leftUp,
190 "upRepeated": self.up,
191 "upUp": self.doNothing,
193 "downRepeated": self.down,
194 "downUp": self.doNothing,
197 InfoBarSeek.__init__(self, actionmap = "MediaPlayerSeekActions")
199 self.onClose.append(self.delMPTimer)
200 self.onClose.append(self.__onClose)
202 self.righttimer = False
203 self.rightKeyTimer = eTimer()
204 self.rightKeyTimer.callback.append(self.rightTimerFire)
206 self.lefttimer = False
207 self.leftKeyTimer = eTimer()
208 self.leftKeyTimer.callback.append(self.leftTimerFire)
210 self.currList = "filelist"
211 self.isAudioCD = False
212 self.AudioCD_albuminfo = {}
213 self.cdAudioTrackFiles = []
216 self.playlistIOInternal = PlaylistIOInternal()
217 list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
220 self.playlist.addFile(x.ref)
221 self.playlist.updateList()
223 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
225 iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
226 iPlayableService.evUser+11: self.__evDecodeError,
227 iPlayableService.evUser+12: self.__evPluginError
233 def createSummary(self):
234 return MediaPlayerLCDScreen
237 self.playlistIOInternal.clear()
238 for x in self.playlist.list:
239 self.playlistIOInternal.addService(ServiceReference(x[0]))
240 if self.savePlaylistOnExit:
241 self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
242 if config.mediaplayer.saveDirOnExit.getValue():
243 config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory())
244 config.mediaplayer.defaultDir.save()
245 hotplugNotifier.remove(self.hotplugCB)
246 del self["coverArt"].picload
249 def checkSkipShowHideLock(self):
250 self.updatedSeekState()
252 def doEofInternal(self, playing):
259 self.session.nav.playService(self.oldService)
261 def __evUpdatedInfo(self):
262 currPlay = self.session.nav.getCurrentService()
263 currenttitle = currPlay.info().getInfo(iServiceInformation.sCurrentTitle)
264 totaltitles = currPlay.info().getInfo(iServiceInformation.sTotalTitles)
265 sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
266 print "[__evUpdatedInfo] title %d of %d (%s)" % (currenttitle, totaltitles, sTitle)
267 self.readTitleInformation()
269 def __evDecodeError(self):
270 currPlay = self.session.nav.getCurrentService()
271 sVideoType = currPlay.info().getInfoString(iServiceInformation.sVideoType)
272 print "[__evDecodeError] video-codec %s can't be decoded by hardware" % (sVideoType)
273 self.session.open(MessageBox, _("This Dreambox can't decode %s video streams!") % sVideoType, type = MessageBox.TYPE_INFO,timeout = 20 )
275 def __evPluginError(self):
276 currPlay = self.session.nav.getCurrentService()
277 message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
278 print "[__evPluginError]" , message
279 self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 )
281 def delMPTimer(self):
282 del self.rightKeyTimer
283 del self.leftKeyTimer
285 def readTitleInformation(self):
286 currPlay = self.session.nav.getCurrentService()
287 if currPlay is not None:
288 sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
289 sAlbum = currPlay.info().getInfoString(iServiceInformation.sAlbum)
290 sGenre = currPlay.info().getInfoString(iServiceInformation.sGenre)
291 sArtist = currPlay.info().getInfoString(iServiceInformation.sArtist)
292 sYear = currPlay.info().getInfoString(iServiceInformation.sTimeCreate)
295 if not self.isAudioCD:
296 sTitle = currPlay.info().getName().split('/')[-1]
298 sTitle = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getName()
300 if self.AudioCD_albuminfo:
301 if sAlbum == "" and "title" in self.AudioCD_albuminfo:
302 sAlbum = self.AudioCD_albuminfo["title"]
303 if sGenre == "" and "genre" in self.AudioCD_albuminfo:
304 sGenre = self.AudioCD_albuminfo["genre"]
305 if sArtist == "" and "artist" in self.AudioCD_albuminfo:
306 sArtist = self.AudioCD_albuminfo["artist"]
307 if "year" in self.AudioCD_albuminfo:
308 sYear = self.AudioCD_albuminfo["year"]
310 self.updateMusicInformation( sArtist, sTitle, sAlbum, sYear, sGenre, clear = True )
312 self.updateMusicInformation()
314 def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False):
315 self.updateSingleMusicInformation("artist", artist, clear)
316 self.updateSingleMusicInformation("title", title, clear)
317 self.updateSingleMusicInformation("album", album, clear)
318 self.updateSingleMusicInformation("year", year, clear)
319 self.updateSingleMusicInformation("genre", genre, clear)
321 def updateSingleMusicInformation(self, name, info, clear):
322 if info != "" or clear:
323 if self[name].getText() != info:
324 self[name].setText(info)
327 self.lefttimer = True
328 self.leftKeyTimer.start(1000)
331 self.righttimer = True
332 self.rightKeyTimer.start(1000)
336 self.leftKeyTimer.stop()
337 self.lefttimer = False
338 self[self.currList].pageUp()
339 self.updateCurrentInfo()
343 self.rightKeyTimer.stop()
344 self.righttimer = False
345 self[self.currList].pageDown()
346 self.updateCurrentInfo()
348 def leftTimerFire(self):
349 self.leftKeyTimer.stop()
350 self.lefttimer = False
351 self.switchToFileList()
353 def rightTimerFire(self):
354 self.rightKeyTimer.stop()
355 self.righttimer = False
356 self.switchToPlayList()
358 def switchToFileList(self):
359 self.currList = "filelist"
360 self.filelist.selectionEnabled(1)
361 self.playlist.selectionEnabled(0)
362 self.updateCurrentInfo()
364 def switchToPlayList(self):
365 if len(self.playlist) != 0:
366 self.currList = "playlist"
367 self.filelist.selectionEnabled(0)
368 self.playlist.selectionEnabled(1)
369 self.updateCurrentInfo()
372 self[self.currList].up()
373 self.updateCurrentInfo()
376 self[self.currList].down()
377 self.updateCurrentInfo()
379 def showAfterSeek(self):
382 def showAfterCuesheetOperation(self):
385 def hideAfterResume(self):
388 def getIdentifier(self, ref):
393 return text.split('/')[-1]
395 # FIXME: maybe this code can be optimized
396 def updateCurrentInfo(self):
398 if self.currList == "filelist":
399 idx = self.filelist.getSelectionIndex()
400 r = self.filelist.list[idx]
407 self.summaries.setText(text,1)
410 if idx < len(self.filelist.list):
411 r = self.filelist.list[idx]
415 self.summaries.setText(text,3)
417 self.summaries.setText(" ",3)
420 if idx < len(self.filelist.list):
421 r = self.filelist.list[idx]
425 self.summaries.setText(text,4)
427 self.summaries.setText(" ",4)
430 if not self.filelist.canDescent():
431 r = self.filelist.getServiceRef()
435 self["currenttext"].setText(os_path.basename(text))
437 if self.currList == "playlist":
438 t = self.playlist.getSelection()
441 #display current selected entry on LCD
442 text = self.getIdentifier(t)
443 self.summaries.setText(text,1)
444 self["currenttext"].setText(text)
445 idx = self.playlist.getSelectionIndex()
447 if idx < len(self.playlist):
448 currref = self.playlist.getServiceRefList()[idx]
449 text = self.getIdentifier(currref)
450 self.summaries.setText(text,3)
452 self.summaries.setText(" ",3)
455 if idx < len(self.playlist):
456 currref = self.playlist.getServiceRefList()[idx]
457 text = self.getIdentifier(currref)
458 self.summaries.setText(text,4)
460 self.summaries.setText(" ",4)
463 if self.currList == "filelist":
464 if self.filelist.canDescent():
465 self.filelist.descent()
466 self.updateCurrentInfo()
470 if self.currList == "playlist":
471 selection = self["playlist"].getSelection()
472 self.changeEntry(self.playlist.getSelectionIndex())
476 if len(self.cdAudioTrackFiles):
477 menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
478 if self.currList == "filelist":
479 if self.filelist.canDescent():
480 menu.append((_("add directory to playlist"), "copydir"))
482 menu.append((_("add files to playlist"), "copyfiles"))
483 menu.append((_("switch to playlist"), "playlist"))
484 menu.append((_("delete file"), "deletefile"))
486 menu.append((_("switch to filelist"), "filelist"))
487 menu.append((_("shuffle playlist"), "shuffle"))
488 menu.append((_("Delete entry"), "deleteentry"))
489 menu.append((_("clear playlist"), "clear"))
490 menu.append((_("hide player"), "hide"));
491 menu.append((_("save playlist"), "saveplaylist"));
492 menu.append((_("load playlist"), "loadplaylist"));
493 menu.append((_("delete saved playlist"), "deleteplaylist"));
494 menu.append((_("Edit settings"), "settings"))
495 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
497 def menuCallback(self, choice):
501 if choice[1] == "copydir":
502 self.copyDirectory(self.filelist.getSelection()[0])
503 elif choice[1] == "copyfiles":
505 self.playlist.clear()
506 self.isAudioCD = False
507 self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
508 self.playServiceRefEntry(self.filelist.getServiceRef())
509 elif choice[1] == "playlist":
510 self.switchToPlayList()
511 elif choice[1] == "filelist":
512 self.switchToFileList()
513 elif choice[1] == "deleteentry":
514 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
517 elif choice[1] == "clear":
518 self.clear_playlist()
519 elif choice[1] == "hide":
521 elif choice[1] == "saveplaylist":
523 elif choice[1] == "loadplaylist":
525 elif choice[1] == "deleteplaylist":
526 self.delete_saved_playlist()
527 elif choice[1] == "shuffle":
528 self.playlist.PlayListShuffle()
529 elif choice[1] == "deletefile":
531 elif choice[1] == "settings":
532 self.session.openWithCallback(self.applySettings, MediaPlayerSettings, self)
533 elif choice[1] == "audiocd":
536 def playAudioCD(self):
537 from enigma import eServiceReference
538 from Plugins.Extensions.CDInfo.plugin import Query
540 if len(self.cdAudioTrackFiles):
541 self.playlist.clear()
542 self.savePlaylistOnExit = False
543 self.isAudioCD = True
544 for file in self.cdAudioTrackFiles:
545 ref = eServiceReference(4097, 0, file)
546 self.playlist.addFile(ref)
550 self.switchToPlayList()
552 def applySettings(self):
553 self.savePlaylistOnExit = config.mediaplayer.savePlaylistOnExit.getValue()
554 if config.mediaplayer.repeat.getValue() == True:
555 self["repeat"].setPixmapNum(1)
557 self["repeat"].setPixmapNum(0)
559 def showEventInformation(self):
560 from Screens.EventView import EventViewSimple
561 from ServiceReference import ServiceReference
562 evt = self[self.currList].getCurrentEvent()
564 self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
566 # also works on filelist (?)
567 def getCurrent(self):
568 return self["playlist"].getCurrent()
570 def deletePlaylistEntry(self):
571 if self.currList == "playlist":
572 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
576 def skip_listbegin(self):
577 if self.currList == "filelist":
578 self.filelist.moveToIndex(0)
580 self.playlist.moveToIndex(0)
581 self.updateCurrentInfo()
583 def skip_listend(self):
584 if self.currList == "filelist":
585 idx = len(self.filelist.list)
586 self.filelist.moveToIndex(idx - 1)
588 self.playlist.moveToIndex(len(self.playlist)-1)
589 self.updateCurrentInfo()
591 def save_playlist(self):
592 self.session.openWithCallback(self.save_playlist2,InputBox, title=_("Please enter filename (empty = use current date)"),windowTitle = _("Save Playlist"))
594 def save_playlist2(self, name):
598 name = strftime("%y%m%d_%H%M%S")
600 self.playlistIOInternal.clear()
601 for x in self.playlist.list:
602 self.playlistIOInternal.addService(ServiceReference(x[0]))
603 self.playlistIOInternal.save(resolveFilename(SCOPE_PLAYLIST) + name)
605 def load_playlist(self):
607 playlistdir = resolveFilename(SCOPE_PLAYLIST)
609 for i in os_listdir(playlistdir):
610 listpath.append((i,playlistdir + i))
612 print "Error while scanning subdirs ",e
613 self.session.openWithCallback(self.PlaylistSelected, ChoiceBox, title=_("Please select a playlist..."), list = listpath)
615 def PlaylistSelected(self,path):
617 self.clear_playlist()
618 extension = path[0].rsplit('.',1)[-1]
619 if self.playlistparsers.has_key(extension):
620 playlist = self.playlistparsers[extension]()
621 list = playlist.open(path[1])
623 self.playlist.addFile(x.ref)
624 self.playlist.updateList()
626 def delete_saved_playlist(self):
628 playlistdir = resolveFilename(SCOPE_PLAYLIST)
630 for i in os_listdir(playlistdir):
631 listpath.append((i,playlistdir + i))
633 print "Error while scanning subdirs ",e
634 self.session.openWithCallback(self.DeletePlaylistSelected, ChoiceBox, title=_("Please select a playlist to delete..."), list = listpath)
636 def DeletePlaylistSelected(self,path):
638 self.delname = path[1]
639 self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (path[1]))
641 def deleteConfirmed(self, confirmed):
644 os_remove(self.delname)
646 print "delete failed:", e
647 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
649 def clear_playlist(self):
650 self.isAudioCD = False
652 self.playlist.clear()
653 self.switchToFileList()
655 def copyDirectory(self, directory, recursive = True):
656 print "copyDirectory", directory
657 filelist = FileList(directory, useServiceRef = True, isTop = True)
659 for x in filelist.getFileList():
660 if x[0][1] == True: #isDir
662 self.copyDirectory(x[0][0])
663 elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097:
664 self.playlist.addFile(x[0][0])
665 self.playlist.updateList()
667 def deleteFile(self):
668 if self.currList == "filelist":
669 self.service = self.filelist.getServiceRef()
671 self.service = self.playlist.getSelection()
672 if self.service is None:
674 if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None:
675 if self.service == self.session.nav.getCurrentlyPlayingServiceReference():
678 serviceHandler = eServiceCenter.getInstance()
679 offline = serviceHandler.offlineOperations(self.service)
680 info = serviceHandler.info(self.service)
681 name = info and info.getName(self.service)
683 if offline is not None:
685 if not offline.deleteFromDisk(1):
688 self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name))
690 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
692 def deleteConfirmed_offline(self, confirmed):
694 serviceHandler = eServiceCenter.getInstance()
695 offline = serviceHandler.offlineOperations(self.service)
697 if offline is not None:
699 if not offline.deleteFromDisk(0):
702 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
704 self.removeListEntry()
706 def removeListEntry(self):
707 currdir = self.filelist.getCurrentDirectory()
708 self.filelist.changeDir(currdir)
713 if len(self.playlist) > 0:
714 for x in self.playlist.list:
715 if self.service == x[0]:
716 self.playlist.deleteFile(index)
720 self.playlist.updateList()
721 if self.currList == "playlist":
722 if len(self.playlist) == 0:
723 self.switchToFileList()
726 if self.filelist.getServiceRef().type == 4098: # playlist
727 ServiceRef = self.filelist.getServiceRef()
728 extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
729 if self.playlistparsers.has_key(extension):
730 playlist = self.playlistparsers[extension]()
731 list = playlist.open(ServiceRef.getPath())
733 self.playlist.addFile(x.ref)
734 self.playlist.updateList()
736 self.playlist.addFile(self.filelist.getServiceRef())
737 self.playlist.updateList()
738 if len(self.playlist) == 1:
741 def addPlaylistParser(self, parser, extension):
742 self.playlistparsers[extension] = parser
745 next = self.playlist.getCurrentIndex() + 1
746 if next < len(self.playlist):
747 self.changeEntry(next)
748 elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ):
752 def nextMarkOrEntry(self):
753 if not self.jumpPreviousNextMark(lambda x: x):
754 next = self.playlist.getCurrentIndex() + 1
755 if next < len(self.playlist):
756 self.changeEntry(next)
760 def previousMarkOrEntry(self):
761 if not self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True):
762 next = self.playlist.getCurrentIndex() - 1
764 self.changeEntry(next)
766 def deleteEntry(self):
767 self.playlist.deleteFile(self.playlist.getSelectionIndex())
768 self.playlist.updateList()
769 if len(self.playlist) == 0:
770 self.switchToFileList()
772 def changeEntry(self, index):
773 self.playlist.setCurrentPlaying(index)
776 def playServiceRefEntry(self, serviceref):
777 serviceRefList = self.playlist.getServiceRefList()
778 for count in range(len(serviceRefList)):
779 if serviceRefList[count] == serviceref:
780 self.changeEntry(count)
783 def xplayEntry(self):
784 if self.currList == "playlist":
788 self.playlist.clear()
789 self.isAudioCD = False
790 sel = self.filelist.getSelection()
792 if sel[1]: # can descent
793 # add directory to playlist
794 self.copyDirectory(sel[0])
796 # add files to playlist
797 self.copyDirectory(os_path.dirname(sel[0].getPath()) + "/", recursive = False)
798 if len(self.playlist) > 0:
802 if len(self.playlist.getServiceRefList()):
803 needsInfoUpdate = False
804 currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
805 if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
806 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
807 info = eServiceCenter.getInstance().info(currref)
808 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
809 self["title"].setText(description)
810 # display just playing musik on LCD
811 idx = self.playlist.getCurrentIndex()
812 currref = self.playlist.getServiceRefList()[idx]
813 text = self.getIdentifier(currref)
815 ext = text[-4:].lower()
817 # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead
818 if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
821 needsInfoUpdate = True
822 self.summaries.setText(text,1)
824 # get the next two entries
826 if idx < len(self.playlist):
827 currref = self.playlist.getServiceRefList()[idx]
828 text = self.getIdentifier(currref)
829 self.summaries.setText(text,3)
831 self.summaries.setText(" ",3)
834 if idx < len(self.playlist):
835 currref = self.playlist.getServiceRefList()[idx]
836 text = self.getIdentifier(currref)
837 self.summaries.setText(text,4)
839 self.summaries.setText(" ",4)
841 idx = self.playlist.getCurrentIndex()
842 currref = self.playlist.getServiceRefList()[idx]
843 text = currref.getPath()
844 ext = text[-4:].lower()
845 if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
848 needsInfoUpdate = True
850 self.unPauseService()
851 if needsInfoUpdate == True:
852 path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath()
853 self["coverArt"].updateCoverArt(path)
855 self["coverArt"].showDefaultCover()
856 self.readTitleInformation()
858 def updatedSeekState(self):
859 if self.seekstate == self.SEEK_STATE_PAUSE:
860 self.playlist.pauseFile()
861 elif self.seekstate == self.SEEK_STATE_PLAY:
862 self.playlist.playFile()
863 elif self.isStateForward(self.seekstate):
864 self.playlist.forwardFile()
865 elif self.isStateBackward(self.seekstate):
866 self.playlist.rewindFile()
868 def pauseEntry(self):
870 if self.seekstate == self.SEEK_STATE_PAUSE:
876 self.playlist.stopFile()
877 self.session.nav.playService(None)
878 self.updateMusicInformation(clear=True)
881 def unPauseService(self):
882 self.setSeekState(self.SEEK_STATE_PLAY)
884 def subtitleSelection(self):
885 from Screens.Subtitles import Subtitles
886 self.session.open(Subtitles)
888 def hotplugCB(self, dev, media_state):
889 if dev == harddiskmanager.getCD():
890 if media_state == "1":
891 from Components.Scanner import scanDevice
892 devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
893 self.cdAudioTrackFiles = []
894 res = scanDevice(devpath)
895 list = [ (r.description, r, res[r], self.session) for r in res ]
897 (desc, scanner, files, session) = list[0]
899 if file.mimetype == "audio/x-cda":
900 self.cdAudioTrackFiles.append(file.path)
902 self.cdAudioTrackFiles = []
904 self.clear_playlist()
906 class MediaPlayerLCDScreen(Screen):
908 <screen position="0,0" size="132,64" title="LCD Text">
909 <widget name="text1" position="4,0" size="132,35" font="Regular;16"/>
910 <widget name="text3" position="4,36" size="132,14" font="Regular;10"/>
911 <widget name="text4" position="4,49" size="132,14" font="Regular;10"/>
914 def __init__(self, session, parent):
915 Screen.__init__(self, session)
916 self["text1"] = Label("Mediaplayer")
917 self["text3"] = Label("")
918 self["text4"] = Label("")
920 def setText(self, text, line):
922 if text[-4:] == ".mp3":
925 text = text + textleer*10
927 self["text1"].setText(text)
929 self["text3"].setText(text)
931 self["text4"].setText(text)
933 def main(session, **kwargs):
934 session.open(MediaPlayer)
936 def menu(menuid, **kwargs):
937 if menuid == "mainmenu":
938 return [(_("Media player"), main, "media_player", 45)]
941 def filescan_open(list, session, **kwargs):
942 from enigma import eServiceReference
944 mp = session.open(MediaPlayer)
946 mp.savePlaylistOnExit = False
949 if file.mimetype == "video/MP2T":
953 ref = eServiceReference(stype, 0, file.path)
954 mp.playlist.addFile(ref)
957 mp.switchToPlayList()
959 def audioCD_open(list, session, **kwargs):
960 from enigma import eServiceReference
962 mp = session.open(MediaPlayer)
963 mp.cdAudioTrackFiles = []
965 mp.cdAudioTrackFiles.append(file.path)
968 def filescan(**kwargs):
969 from Components.Scanner import Scanner, ScanPath
971 Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"],
974 ScanPath(path = "", with_subdirs = False),
977 description = "View Movies...",
978 openfnc = filescan_open,
980 Scanner(mimetypes = ["video/x-vcd"],
983 ScanPath(path = "mpegav", with_subdirs = False),
984 ScanPath(path = "MPEGAV", with_subdirs = False),
987 description = "View Video CD...",
988 openfnc = filescan_open,
990 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
993 ScanPath(path = "", with_subdirs = False),
996 description = "Play Music...",
997 openfnc = filescan_open,
1000 from Plugins.Extensions.CDInfo.plugin import Query
1002 Scanner(mimetypes = ["audio/x-cda"],
1005 ScanPath(path = "", with_subdirs = False),
1008 description = "Play Audio-CD...",
1009 openfnc = audioCD_open,
1015 from Plugins.Plugin import PluginDescriptor
1016 def Plugins(**kwargs):
1018 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, fnc = menu),
1019 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)