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):
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.picload = ePicLoad()
175 self.picload.PictureData.get().append(self.paintCoverArtPixmapCB)
177 self.isAudioCD = False
178 self.AudioCD_albuminfo = {}
179 self.cdAudioTrackFiles = []
182 self.playlistIOInternal = PlaylistIOInternal()
183 list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
186 self.playlist.addFile(x.ref)
187 self.playlist.updateList()
189 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
191 iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
192 iPlayableService.evUser+11: self.__evDecodeError,
193 iPlayableService.evUser+12: self.__evPluginError
199 def createSummary(self):
200 return MediaPlayerLCDScreen
203 self.playlistIOInternal.clear()
204 for x in self.playlist.list:
205 self.playlistIOInternal.addService(ServiceReference(x[0]))
206 if self.savePlaylistOnExit:
207 self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
208 if config.mediaplayer.saveDirOnExit.getValue():
209 config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory())
210 config.mediaplayer.defaultDir.save()
211 hotplugNotifier.remove(self.hotplugCB)
215 def checkSkipShowHideLock(self):
216 self.updatedSeekState()
218 def doEofInternal(self, playing):
225 self.session.nav.playService(self.oldService)
227 def __evUpdatedInfo(self):
228 currPlay = self.session.nav.getCurrentService()
229 currenttitle = currPlay.info().getInfo(iServiceInformation.sCurrentTitle)
230 totaltitles = currPlay.info().getInfo(iServiceInformation.sTotalTitles)
231 sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
232 print "[__evUpdatedInfo] title %d of %d (%s)" % (currenttitle, totaltitles, sTitle)
233 self.readTitleInformation()
235 def __evDecodeError(self):
236 currPlay = self.session.nav.getCurrentService()
237 sVideoType = currPlay.info().getInfoString(iServiceInformation.sVideoType)
238 print "[__evDecodeError] video-codec %s can't be decoded by hardware" % (sVideoType)
239 self.session.open(MessageBox, _("This Dreambox can't decode %s video streams!") % sVideoType, type = MessageBox.TYPE_INFO,timeout = 20 )
241 def __evPluginError(self):
242 currPlay = self.session.nav.getCurrentService()
243 message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
244 print "[__evPluginError]" , message
245 self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 )
247 def delMPTimer(self):
248 del self.rightKeyTimer
249 del self.leftKeyTimer
251 def readTitleInformation(self):
252 currPlay = self.session.nav.getCurrentService()
253 if currPlay is not None:
254 sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
255 sAlbum = currPlay.info().getInfoString(iServiceInformation.sAlbum)
256 sGenre = currPlay.info().getInfoString(iServiceInformation.sGenre)
257 sArtist = currPlay.info().getInfoString(iServiceInformation.sArtist)
258 sYear = currPlay.info().getInfoString(iServiceInformation.sTimeCreate)
261 if not self.isAudioCD:
262 sTitle = currPlay.info().getName().split('/')[-1]
264 sTitle = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getName()
266 if self.AudioCD_albuminfo:
267 if sAlbum == "" and "title" in self.AudioCD_albuminfo:
268 sAlbum = self.AudioCD_albuminfo["title"]
269 if sGenre == "" and "genre" in self.AudioCD_albuminfo:
270 sGenre = self.AudioCD_albuminfo["genre"]
271 if sArtist == "" and "artist" in self.AudioCD_albuminfo:
272 sArtist = self.AudioCD_albuminfo["artist"]
273 if "year" in self.AudioCD_albuminfo:
274 sYear = self.AudioCD_albuminfo["year"]
276 self.updateMusicInformation( sArtist, sTitle, sAlbum, sYear, sGenre, clear = True )
278 self.updateMusicInformation()
280 def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False):
281 self.updateSingleMusicInformation("artist", artist, clear)
282 self.updateSingleMusicInformation("title", title, clear)
283 self.updateSingleMusicInformation("album", album, clear)
284 self.updateSingleMusicInformation("year", year, clear)
285 self.updateSingleMusicInformation("genre", genre, clear)
287 def updateSingleMusicInformation(self, name, info, clear):
288 if info != "" or clear:
289 if self[name].getText() != info:
290 self[name].setText(info)
292 def updateCoverArtPixmap(self, path):
293 while not path.endswith("/"):
295 new_coverArtFileName = self["coverArt"].default_pixmap
296 for filename in self["coverArt"].coverFileNames:
297 if fileExists(path + filename):
298 new_coverArtFileName = path + filename
299 if self.coverArtFileName != new_coverArtFileName:
300 self.coverArtFileName = new_coverArtFileName
301 sc = AVSwitch().getFramebufferScale()
302 #0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB)
303 self.picload.setPara((self["coverArt"].instance.size().width(), self["coverArt"].instance.size().height(), sc[0], sc[1], False, 1, "#ff000000"))
304 self.picload.startDecode(self.coverArtFileName)
306 def paintCoverArtPixmapCB(self, picInfo=None):
307 ptr = self.picload.getData()
309 self["coverArt"].instance.setPixmap(ptr.__deref__())
312 self.lefttimer = True
313 self.leftKeyTimer.start(1000)
316 self.righttimer = True
317 self.rightKeyTimer.start(1000)
321 self.leftKeyTimer.stop()
322 self.lefttimer = False
323 self[self.currList].pageUp()
324 self.updateCurrentInfo()
328 self.rightKeyTimer.stop()
329 self.righttimer = False
330 self[self.currList].pageDown()
331 self.updateCurrentInfo()
333 def leftTimerFire(self):
334 self.leftKeyTimer.stop()
335 self.lefttimer = False
336 self.switchToFileList()
338 def rightTimerFire(self):
339 self.rightKeyTimer.stop()
340 self.righttimer = False
341 self.switchToPlayList()
343 def switchToFileList(self):
344 self.currList = "filelist"
345 self.filelist.selectionEnabled(1)
346 self.playlist.selectionEnabled(0)
347 self.updateCurrentInfo()
349 def switchToPlayList(self):
350 if len(self.playlist) != 0:
351 self.currList = "playlist"
352 self.filelist.selectionEnabled(0)
353 self.playlist.selectionEnabled(1)
354 self.updateCurrentInfo()
357 self[self.currList].up()
358 self.updateCurrentInfo()
361 self[self.currList].down()
362 self.updateCurrentInfo()
364 def showAfterSeek(self):
367 def showAfterCuesheetOperation(self):
370 def hideAfterResume(self):
373 def getIdentifier(self, ref):
378 return text.split('/')[-1]
380 # FIXME: maybe this code can be optimized
381 def updateCurrentInfo(self):
383 if self.currList == "filelist":
384 idx = self.filelist.getSelectionIndex()
385 r = self.filelist.list[idx]
392 self.summaries.setText(text,1)
395 if idx < len(self.filelist.list):
396 r = self.filelist.list[idx]
400 self.summaries.setText(text,3)
402 self.summaries.setText(" ",3)
405 if idx < len(self.filelist.list):
406 r = self.filelist.list[idx]
410 self.summaries.setText(text,4)
412 self.summaries.setText(" ",4)
415 if not self.filelist.canDescent():
416 r = self.filelist.getServiceRef()
420 self["currenttext"].setText(os_path.basename(text))
422 if self.currList == "playlist":
423 t = self.playlist.getSelection()
426 #display current selected entry on LCD
427 text = self.getIdentifier(t)
428 self.summaries.setText(text,1)
429 self["currenttext"].setText(text)
430 idx = self.playlist.getSelectionIndex()
432 if idx < len(self.playlist):
433 currref = self.playlist.getServiceRefList()[idx]
434 text = self.getIdentifier(currref)
435 self.summaries.setText(text,3)
437 self.summaries.setText(" ",3)
440 if idx < len(self.playlist):
441 currref = self.playlist.getServiceRefList()[idx]
442 text = self.getIdentifier(currref)
443 self.summaries.setText(text,4)
445 self.summaries.setText(" ",4)
448 if self.currList == "filelist":
449 if self.filelist.canDescent():
450 self.filelist.descent()
451 self.updateCurrentInfo()
455 if self.currList == "playlist":
456 selection = self["playlist"].getSelection()
457 self.changeEntry(self.playlist.getSelectionIndex())
461 if len(self.cdAudioTrackFiles):
462 menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
463 if self.currList == "filelist":
464 if self.filelist.canDescent():
465 menu.append((_("add directory to playlist"), "copydir"))
467 menu.append((_("add files to playlist"), "copyfiles"))
468 menu.append((_("switch to playlist"), "playlist"))
469 menu.append((_("delete file"), "deletefile"))
471 menu.append((_("switch to filelist"), "filelist"))
472 menu.append((_("shuffle playlist"), "shuffle"))
473 menu.append((_("Delete entry"), "deleteentry"))
474 menu.append((_("clear playlist"), "clear"))
475 menu.append((_("hide player"), "hide"));
476 menu.append((_("save playlist"), "saveplaylist"));
477 menu.append((_("load playlist"), "loadplaylist"));
478 menu.append((_("delete saved playlist"), "deleteplaylist"));
479 menu.append((_("Edit settings"), "settings"))
480 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
482 def menuCallback(self, choice):
486 if choice[1] == "copydir":
487 self.copyDirectory(self.filelist.getSelection()[0])
488 elif choice[1] == "copyfiles":
490 self.playlist.clear()
491 self.isAudioCD = False
492 self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
493 self.playServiceRefEntry(self.filelist.getServiceRef())
494 elif choice[1] == "playlist":
495 self.switchToPlayList()
496 elif choice[1] == "filelist":
497 self.switchToFileList()
498 elif choice[1] == "deleteentry":
499 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
502 elif choice[1] == "clear":
503 self.clear_playlist()
504 elif choice[1] == "hide":
506 elif choice[1] == "saveplaylist":
508 elif choice[1] == "loadplaylist":
510 elif choice[1] == "deleteplaylist":
511 self.delete_saved_playlist()
512 elif choice[1] == "shuffle":
513 self.playlist.PlayListShuffle()
514 elif choice[1] == "deletefile":
516 elif choice[1] == "settings":
517 self.session.openWithCallback(self.applySettings, MediaPlayerSettings, self)
518 elif choice[1] == "audiocd":
521 def playAudioCD(self):
522 from enigma import eServiceReference
523 from Plugins.Extensions.CDInfo.plugin import Query
525 if len(self.cdAudioTrackFiles):
526 self.playlist.clear()
527 self.savePlaylistOnExit = False
528 self.isAudioCD = True
529 for file in self.cdAudioTrackFiles:
530 ref = eServiceReference(4097, 0, file)
531 self.playlist.addFile(ref)
535 self.switchToPlayList()
537 def applySettings(self):
538 self.savePlaylistOnExit = config.mediaplayer.savePlaylistOnExit.getValue()
539 if config.mediaplayer.repeat.getValue() == True:
540 self["repeat"].setPixmapNum(1)
542 self["repeat"].setPixmapNum(0)
544 def showEventInformation(self):
545 from Screens.EventView import EventViewSimple
546 from ServiceReference import ServiceReference
547 evt = self[self.currList].getCurrentEvent()
549 self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
551 # also works on filelist (?)
552 def getCurrent(self):
553 return self["playlist"].getCurrent()
555 def deletePlaylistEntry(self):
556 if self.currList == "playlist":
557 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
561 def skip_listbegin(self):
562 if self.currList == "filelist":
563 self.filelist.moveToIndex(0)
565 self.playlist.moveToIndex(0)
566 self.updateCurrentInfo()
568 def skip_listend(self):
569 if self.currList == "filelist":
570 idx = len(self.filelist.list)
571 self.filelist.moveToIndex(idx - 1)
573 self.playlist.moveToIndex(len(self.playlist)-1)
574 self.updateCurrentInfo()
576 def save_playlist(self):
577 self.session.openWithCallback(self.save_playlist2,InputBox, title=_("Please enter filename (empty = use current date)"),windowTitle = _("Save Playlist"))
579 def save_playlist2(self, name):
583 name = strftime("%y%m%d_%H%M%S")
585 self.playlistIOInternal.clear()
586 for x in self.playlist.list:
587 self.playlistIOInternal.addService(ServiceReference(x[0]))
588 self.playlistIOInternal.save(resolveFilename(SCOPE_PLAYLIST) + name)
590 def load_playlist(self):
592 playlistdir = resolveFilename(SCOPE_PLAYLIST)
594 for i in os_listdir(playlistdir):
595 listpath.append((i,playlistdir + i))
597 print "Error while scanning subdirs ",e
598 self.session.openWithCallback(self.PlaylistSelected, ChoiceBox, title=_("Please select a playlist..."), list = listpath)
600 def PlaylistSelected(self,path):
602 self.clear_playlist()
603 extension = path[0].rsplit('.',1)[-1]
604 if self.playlistparsers.has_key(extension):
605 playlist = self.playlistparsers[extension]()
606 list = playlist.open(path[1])
608 self.playlist.addFile(x.ref)
609 self.playlist.updateList()
611 def delete_saved_playlist(self):
613 playlistdir = resolveFilename(SCOPE_PLAYLIST)
615 for i in os_listdir(playlistdir):
616 listpath.append((i,playlistdir + i))
618 print "Error while scanning subdirs ",e
619 self.session.openWithCallback(self.DeletePlaylistSelected, ChoiceBox, title=_("Please select a playlist to delete..."), list = listpath)
621 def DeletePlaylistSelected(self,path):
623 self.delname = path[1]
624 self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (path[1]))
626 def deleteConfirmed(self, confirmed):
629 os_remove(self.delname)
631 print "delete failed:", e
632 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
634 def clear_playlist(self):
635 self.isAudioCD = False
637 self.playlist.clear()
638 self.switchToFileList()
640 def copyDirectory(self, directory, recursive = True):
641 print "copyDirectory", directory
642 filelist = FileList(directory, useServiceRef = True, isTop = True)
644 for x in filelist.getFileList():
645 if x[0][1] == True: #isDir
647 self.copyDirectory(x[0][0])
648 elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097:
649 self.playlist.addFile(x[0][0])
650 self.playlist.updateList()
652 def deleteFile(self):
653 if self.currList == "filelist":
654 self.service = self.filelist.getServiceRef()
656 self.service = self.playlist.getSelection()
657 if self.service is None:
659 if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None:
660 if self.service == self.session.nav.getCurrentlyPlayingServiceReference():
663 serviceHandler = eServiceCenter.getInstance()
664 offline = serviceHandler.offlineOperations(self.service)
665 info = serviceHandler.info(self.service)
666 name = info and info.getName(self.service)
668 if offline is not None:
670 if not offline.deleteFromDisk(1):
673 self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name))
675 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
677 def deleteConfirmed_offline(self, confirmed):
679 serviceHandler = eServiceCenter.getInstance()
680 offline = serviceHandler.offlineOperations(self.service)
682 if offline is not None:
684 if not offline.deleteFromDisk(0):
687 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
689 self.removeListEntry()
691 def removeListEntry(self):
692 currdir = self.filelist.getCurrentDirectory()
693 self.filelist.changeDir(currdir)
698 if len(self.playlist) > 0:
699 for x in self.playlist.list:
700 if self.service == x[0]:
701 self.playlist.deleteFile(index)
705 self.playlist.updateList()
706 if self.currList == "playlist":
707 if len(self.playlist) == 0:
708 self.switchToFileList()
711 if self.filelist.getServiceRef().type == 4098: # playlist
712 ServiceRef = self.filelist.getServiceRef()
713 extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
714 if self.playlistparsers.has_key(extension):
715 playlist = self.playlistparsers[extension]()
716 list = playlist.open(ServiceRef.getPath())
718 self.playlist.addFile(x.ref)
719 self.playlist.updateList()
721 self.playlist.addFile(self.filelist.getServiceRef())
722 self.playlist.updateList()
723 if len(self.playlist) == 1:
726 def addPlaylistParser(self, parser, extension):
727 self.playlistparsers[extension] = parser
730 next = self.playlist.getCurrentIndex() + 1
731 if next < len(self.playlist):
732 self.changeEntry(next)
733 elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ):
737 def nextMarkOrEntry(self):
738 if not self.jumpPreviousNextMark(lambda x: x):
739 next = self.playlist.getCurrentIndex() + 1
740 if next < len(self.playlist):
741 self.changeEntry(next)
745 def previousMarkOrEntry(self):
746 if not self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True):
747 next = self.playlist.getCurrentIndex() - 1
749 self.changeEntry(next)
751 def deleteEntry(self):
752 self.playlist.deleteFile(self.playlist.getSelectionIndex())
753 self.playlist.updateList()
754 if len(self.playlist) == 0:
755 self.switchToFileList()
757 def changeEntry(self, index):
758 self.playlist.setCurrentPlaying(index)
761 def playServiceRefEntry(self, serviceref):
762 serviceRefList = self.playlist.getServiceRefList()
763 for count in range(len(serviceRefList)):
764 if serviceRefList[count] == serviceref:
765 self.changeEntry(count)
768 def xplayEntry(self):
769 if self.currList == "playlist":
773 self.playlist.clear()
774 self.isAudioCD = False
775 sel = self.filelist.getSelection()
777 if sel[1]: # can descent
778 # add directory to playlist
779 self.copyDirectory(sel[0])
781 # add files to playlist
782 self.copyDirectory(os_path.dirname(sel[0].getPath()) + "/", recursive = False)
783 if len(self.playlist) > 0:
787 if len(self.playlist.getServiceRefList()):
788 needsInfoUpdate = False
789 currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
790 if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
791 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
792 info = eServiceCenter.getInstance().info(currref)
793 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
794 self["title"].setText(description)
795 # display just playing musik on LCD
796 idx = self.playlist.getCurrentIndex()
797 currref = self.playlist.getServiceRefList()[idx]
798 text = self.getIdentifier(currref)
800 ext = text[-4:].lower()
802 # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead
803 if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
806 needsInfoUpdate = True
807 self.summaries.setText(text,1)
809 # get the next two entries
811 if idx < len(self.playlist):
812 currref = self.playlist.getServiceRefList()[idx]
813 text = self.getIdentifier(currref)
814 self.summaries.setText(text,3)
816 self.summaries.setText(" ",3)
819 if idx < len(self.playlist):
820 currref = self.playlist.getServiceRefList()[idx]
821 text = self.getIdentifier(currref)
822 self.summaries.setText(text,4)
824 self.summaries.setText(" ",4)
826 idx = self.playlist.getCurrentIndex()
827 currref = self.playlist.getServiceRefList()[idx]
828 text = currref.getPath()
829 ext = text[-4:].lower()
830 if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
833 needsInfoUpdate = True
835 self.unPauseService()
836 if needsInfoUpdate == True:
837 path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath()
838 self.updateCoverArtPixmap(path)
840 pngname = self["coverArt"].default_pixmap
841 self.coverArtFileName = pngname
842 self["coverArt"].instance.setPixmapFromFile(self.coverArtFileName)
843 self.readTitleInformation()
845 def updatedSeekState(self):
846 if self.seekstate == self.SEEK_STATE_PAUSE:
847 self.playlist.pauseFile()
848 elif self.seekstate == self.SEEK_STATE_PLAY:
849 self.playlist.playFile()
850 elif self.isStateForward(self.seekstate):
851 self.playlist.forwardFile()
852 elif self.isStateBackward(self.seekstate):
853 self.playlist.rewindFile()
855 def pauseEntry(self):
857 if self.seekstate == self.SEEK_STATE_PAUSE:
863 self.playlist.stopFile()
864 self.session.nav.playService(None)
865 self.updateMusicInformation(clear=True)
868 def unPauseService(self):
869 self.setSeekState(self.SEEK_STATE_PLAY)
871 def subtitleSelection(self):
872 from Screens.Subtitles import Subtitles
873 self.session.open(Subtitles)
875 def hotplugCB(self, dev, media_state):
876 if dev == harddiskmanager.getCD():
877 if media_state == "1":
878 from Components.Scanner import scanDevice
879 devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
880 self.cdAudioTrackFiles = []
881 res = scanDevice(devpath)
882 list = [ (r.description, r, res[r], self.session) for r in res ]
884 (desc, scanner, files, session) = list[0]
886 if file.mimetype == "audio/x-cda":
887 self.cdAudioTrackFiles.append(file.path)
889 self.cdAudioTrackFiles = []
891 self.clear_playlist()
893 class MediaPlayerLCDScreen(Screen):
895 <screen position="0,0" size="132,64" title="LCD Text">
896 <widget name="text1" position="4,0" size="132,35" font="Regular;16"/>
897 <widget name="text3" position="4,36" size="132,14" font="Regular;10"/>
898 <widget name="text4" position="4,49" size="132,14" font="Regular;10"/>
901 def __init__(self, session, parent):
902 Screen.__init__(self, session)
903 self["text1"] = Label("Mediaplayer")
904 self["text3"] = Label("")
905 self["text4"] = Label("")
907 def setText(self, text, line):
909 if text[-4:] == ".mp3":
912 text = text + textleer*10
914 self["text1"].setText(text)
916 self["text3"].setText(text)
918 self["text4"].setText(text)
920 def main(session, **kwargs):
921 session.open(MediaPlayer)
923 def menu(menuid, **kwargs):
924 if menuid == "mainmenu":
925 return [(_("Media player"), main, "media_player", 45)]
928 def filescan_open(list, session, **kwargs):
929 from enigma import eServiceReference
931 mp = session.open(MediaPlayer)
933 mp.savePlaylistOnExit = False
936 if file.mimetype == "video/MP2T":
940 ref = eServiceReference(stype, 0, file.path)
941 mp.playlist.addFile(ref)
944 mp.switchToPlayList()
946 def audioCD_open(list, session, **kwargs):
947 from enigma import eServiceReference
949 mp = session.open(MediaPlayer)
950 mp.cdAudioTrackFiles = []
952 mp.cdAudioTrackFiles.append(file.path)
955 def filescan(**kwargs):
956 from Components.Scanner import Scanner, ScanPath
958 Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"],
961 ScanPath(path = "", with_subdirs = False),
964 description = "View Movies...",
965 openfnc = filescan_open,
967 Scanner(mimetypes = ["video/x-vcd"],
970 ScanPath(path = "mpegav", with_subdirs = False),
971 ScanPath(path = "MPEGAV", with_subdirs = False),
974 description = "View Video CD...",
975 openfnc = filescan_open,
977 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
980 ScanPath(path = "", with_subdirs = False),
983 description = "Play Music...",
984 openfnc = filescan_open,
987 from Plugins.Extensions.CDInfo.plugin import Query
989 Scanner(mimetypes = ["audio/x-cda"],
992 ScanPath(path = "", with_subdirs = False),
995 description = "Play Audio-CD...",
996 openfnc = audioCD_open,
1002 from Plugins.Plugin import PluginDescriptor
1003 def Plugins(**kwargs):
1005 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, fnc = menu),
1006 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)