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
48 if self.skinAttributes is not None:
49 for (attrib, value) in self.skinAttributes:
50 if attrib == "pixmap":
53 if noCoverFile is None:
54 noCoverFile = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png")
55 self.noCoverPixmap = LoadPixmap(noCoverFile)
56 return Pixmap.applySkin(self, desktop, screen)
60 sc = AVSwitch().getFramebufferScale()
61 #0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB)
62 self.picload.setPara((self.instance.size().width(), self.instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
64 def paintCoverArtPixmapCB(self, picInfo=None):
65 ptr = self.picload.getData()
67 self.instance.setPixmap(ptr.__deref__())
69 def updateCoverArt(self, path):
70 while not path.endswith("/"):
72 new_coverArtFileName = None
73 for filename in self.coverFileNames:
74 if fileExists(path + filename):
75 new_coverArtFileName = path + filename
76 if self.coverArtFileName != new_coverArtFileName:
77 self.coverArtFileName = new_coverArtFileName
78 if new_coverArtFileName:
79 self.picload.startDecode(self.coverArtFileName)
81 self.showDefaultCover()
83 def showDefaultCover(self):
84 self.instance.setPixmap(self.noCoverPixmap)
86 def embeddedCoverArt(self):
87 print "[embeddedCoverArt] found"
88 self.coverArtFileName = "/tmp/.id3coverart"
89 self.picload.startDecode(self.coverArtFileName)
91 class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport, HelpableScreen):
93 ENABLE_RESUME_SUPPORT = True
95 def __init__(self, session, args = None):
96 Screen.__init__(self, session)
97 InfoBarAudioSelection.__init__(self)
98 InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions")
99 InfoBarNotifications.__init__(self)
100 InfoBarBase.__init__(self)
101 InfoBarSubtitleSupport.__init__(self)
102 HelpableScreen.__init__(self)
104 self.oldService = self.session.nav.getCurrentlyPlayingServiceReference()
105 self.session.nav.stopService()
107 self.playlistparsers = {}
108 self.addPlaylistParser(PlaylistIOM3U, "m3u")
109 self.addPlaylistParser(PlaylistIOPLS, "pls")
110 self.addPlaylistParser(PlaylistIOInternal, "e2pls")
112 # 'None' is magic to start at the list of mountpoints
113 defaultDir = config.mediaplayer.defaultDir.getValue()
114 self.filelist = FileList(defaultDir, matchingPattern = "(?i)^.*\.(mp2|mp3|ogg|ts|wav|wave|m3u|pls|e2pls|mpg|vob|avi|divx|mkv|mp4|m4a|dat|flac)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls")
115 self["filelist"] = self.filelist
117 self.playlist = MyPlayList()
118 self.is_closing = False
120 self["playlist"] = self.playlist
122 self["PositionGauge"] = ServicePositionGauge(self.session.nav)
124 self["currenttext"] = Label("")
126 self["artisttext"] = Label(_("Artist:"))
127 self["artist"] = Label("")
128 self["titletext"] = Label(_("Title:"))
129 self["title"] = Label("")
130 self["albumtext"] = Label(_("Album:"))
131 self["album"] = Label("")
132 self["yeartext"] = Label(_("Year:"))
133 self["year"] = Label("")
134 self["genretext"] = Label(_("Genre:"))
135 self["genre"] = Label("")
136 self["coverArt"] = MediaPixmap()
137 self["repeat"] = MultiPixmap()
139 self.seek_target = None
140 hotplugNotifier.append(self.hotplugCB)
142 class MoviePlayerActionMap(NumberActionMap):
143 def __init__(self, player, contexts = [ ], actions = { }, prio=0):
144 NumberActionMap.__init__(self, contexts, actions, prio)
147 def action(self, contexts, action):
149 return NumberActionMap.action(self, contexts, action)
152 self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions",
154 "ok": (self.ok, _("add file to playlist")),
155 "cancel": (self.exit, _("exit mediaplayer")),
158 self["MediaPlayerActions"] = HelpableActionMap(self, "MediaPlayerActions",
160 "play": (self.xplayEntry, _("play entry")),
161 "pause": (self.pauseEntry, _("pause")),
162 "stop": (self.stopEntry, _("stop entry")),
163 "previous": (self.previousMarkOrEntry, _("play from previous mark or playlist entry")),
164 "next": (self.nextMarkOrEntry, _("play from next mark or playlist entry")),
165 "menu": (self.showMenu, _("menu")),
166 "skipListbegin": (self.skip_listbegin, _("jump to listbegin")),
167 "skipListend": (self.skip_listend, _("jump to listend")),
168 "prevBouquet": (self.switchToPlayList, _("switch to playlist")),
169 "nextBouquet": (self.switchToFileList, _("switch to filelist")),
170 "delete": (self.deletePlaylistEntry, _("delete playlist entry")),
171 "shift_stop": (self.clear_playlist, _("clear playlist")),
172 "shift_record": (self.playlist.PlayListShuffle, _("shuffle playlist")),
173 "subtitles": (self.subtitleSelection, _("Subtitle selection")),
176 self["InfobarEPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
178 "showEventInfo": (self.showEventInformation, _("show event details")),
181 self["actions"] = MoviePlayerActionMap(self, ["DirectionActions"],
183 "right": self.rightDown,
184 "rightRepeated": self.doNothing,
185 "rightUp": self.rightUp,
186 "left": self.leftDown,
187 "leftRepeated": self.doNothing,
188 "leftUp": self.leftUp,
191 "upRepeated": self.up,
192 "upUp": self.doNothing,
194 "downRepeated": self.down,
195 "downUp": self.doNothing,
198 InfoBarSeek.__init__(self, actionmap = "MediaPlayerSeekActions")
200 self.onClose.append(self.delMPTimer)
201 self.onClose.append(self.__onClose)
203 self.righttimer = False
204 self.rightKeyTimer = eTimer()
205 self.rightKeyTimer.callback.append(self.rightTimerFire)
207 self.lefttimer = False
208 self.leftKeyTimer = eTimer()
209 self.leftKeyTimer.callback.append(self.leftTimerFire)
211 self.currList = "filelist"
212 self.isAudioCD = False
213 self.AudioCD_albuminfo = {}
214 self.cdAudioTrackFiles = []
217 self.playlistIOInternal = PlaylistIOInternal()
218 list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
221 self.playlist.addFile(x.ref)
222 self.playlist.updateList()
224 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
226 iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
227 iPlayableService.evUser+11: self.__evDecodeError,
228 iPlayableService.evUser+12: self.__evPluginError,
229 iPlayableService.evUser+13: self["coverArt"].embeddedCoverArt
235 def createSummary(self):
236 return MediaPlayerLCDScreen
239 self.playlistIOInternal.clear()
240 for x in self.playlist.list:
241 self.playlistIOInternal.addService(ServiceReference(x[0]))
242 if self.savePlaylistOnExit:
243 self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
244 if config.mediaplayer.saveDirOnExit.getValue():
245 config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory())
246 config.mediaplayer.defaultDir.save()
247 hotplugNotifier.remove(self.hotplugCB)
248 del self["coverArt"].picload
251 def checkSkipShowHideLock(self):
252 self.updatedSeekState()
254 def doEofInternal(self, playing):
261 self.session.nav.playService(self.oldService)
263 def __evUpdatedInfo(self):
264 currPlay = self.session.nav.getCurrentService()
265 currenttitle = currPlay.info().getInfo(iServiceInformation.sCurrentTitle)
266 totaltitles = currPlay.info().getInfo(iServiceInformation.sTotalTitles)
267 sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
268 print "[__evUpdatedInfo] title %d of %d (%s)" % (currenttitle, totaltitles, sTitle)
269 self.readTitleInformation()
271 def __evDecodeError(self):
272 currPlay = self.session.nav.getCurrentService()
273 sVideoType = currPlay.info().getInfoString(iServiceInformation.sVideoType)
274 print "[__evDecodeError] video-codec %s can't be decoded by hardware" % (sVideoType)
275 self.session.open(MessageBox, _("This Dreambox can't decode %s video streams!") % sVideoType, type = MessageBox.TYPE_INFO,timeout = 20 )
277 def __evPluginError(self):
278 currPlay = self.session.nav.getCurrentService()
279 message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
280 print "[__evPluginError]" , message
281 self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 )
283 def delMPTimer(self):
284 del self.rightKeyTimer
285 del self.leftKeyTimer
287 def readTitleInformation(self):
288 currPlay = self.session.nav.getCurrentService()
289 if currPlay is not None:
290 sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
291 sAlbum = currPlay.info().getInfoString(iServiceInformation.sAlbum)
292 sGenre = currPlay.info().getInfoString(iServiceInformation.sGenre)
293 sArtist = currPlay.info().getInfoString(iServiceInformation.sArtist)
294 sYear = currPlay.info().getInfoString(iServiceInformation.sTimeCreate)
297 if not self.isAudioCD:
298 sTitle = currPlay.info().getName().split('/')[-1]
300 sTitle = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getName()
302 if self.AudioCD_albuminfo:
303 if sAlbum == "" and "title" in self.AudioCD_albuminfo:
304 sAlbum = self.AudioCD_albuminfo["title"]
305 if sGenre == "" and "genre" in self.AudioCD_albuminfo:
306 sGenre = self.AudioCD_albuminfo["genre"]
307 if sArtist == "" and "artist" in self.AudioCD_albuminfo:
308 sArtist = self.AudioCD_albuminfo["artist"]
309 if "year" in self.AudioCD_albuminfo:
310 sYear = self.AudioCD_albuminfo["year"]
312 self.updateMusicInformation( sArtist, sTitle, sAlbum, sYear, sGenre, clear = True )
314 self.updateMusicInformation()
316 def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False):
317 self.updateSingleMusicInformation("artist", artist, clear)
318 self.updateSingleMusicInformation("title", title, clear)
319 self.updateSingleMusicInformation("album", album, clear)
320 self.updateSingleMusicInformation("year", year, clear)
321 self.updateSingleMusicInformation("genre", genre, clear)
323 def updateSingleMusicInformation(self, name, info, clear):
324 if info != "" or clear:
325 if self[name].getText() != info:
326 self[name].setText(info)
329 self.lefttimer = True
330 self.leftKeyTimer.start(1000)
333 self.righttimer = True
334 self.rightKeyTimer.start(1000)
338 self.leftKeyTimer.stop()
339 self.lefttimer = False
340 self[self.currList].pageUp()
341 self.updateCurrentInfo()
345 self.rightKeyTimer.stop()
346 self.righttimer = False
347 self[self.currList].pageDown()
348 self.updateCurrentInfo()
350 def leftTimerFire(self):
351 self.leftKeyTimer.stop()
352 self.lefttimer = False
353 self.switchToFileList()
355 def rightTimerFire(self):
356 self.rightKeyTimer.stop()
357 self.righttimer = False
358 self.switchToPlayList()
360 def switchToFileList(self):
361 self.currList = "filelist"
362 self.filelist.selectionEnabled(1)
363 self.playlist.selectionEnabled(0)
364 self.updateCurrentInfo()
366 def switchToPlayList(self):
367 if len(self.playlist) != 0:
368 self.currList = "playlist"
369 self.filelist.selectionEnabled(0)
370 self.playlist.selectionEnabled(1)
371 self.updateCurrentInfo()
374 self[self.currList].up()
375 self.updateCurrentInfo()
378 self[self.currList].down()
379 self.updateCurrentInfo()
381 def showAfterSeek(self):
384 def showAfterCuesheetOperation(self):
387 def hideAfterResume(self):
390 def getIdentifier(self, ref):
395 return text.split('/')[-1]
397 # FIXME: maybe this code can be optimized
398 def updateCurrentInfo(self):
400 if self.currList == "filelist":
401 idx = self.filelist.getSelectionIndex()
402 r = self.filelist.list[idx]
409 self.summaries.setText(text,1)
412 if idx < len(self.filelist.list):
413 r = self.filelist.list[idx]
417 self.summaries.setText(text,3)
419 self.summaries.setText(" ",3)
422 if idx < len(self.filelist.list):
423 r = self.filelist.list[idx]
427 self.summaries.setText(text,4)
429 self.summaries.setText(" ",4)
432 if not self.filelist.canDescent():
433 r = self.filelist.getServiceRef()
437 self["currenttext"].setText(os_path.basename(text))
439 if self.currList == "playlist":
440 t = self.playlist.getSelection()
443 #display current selected entry on LCD
444 text = self.getIdentifier(t)
445 self.summaries.setText(text,1)
446 self["currenttext"].setText(text)
447 idx = self.playlist.getSelectionIndex()
449 if idx < len(self.playlist):
450 currref = self.playlist.getServiceRefList()[idx]
451 text = self.getIdentifier(currref)
452 self.summaries.setText(text,3)
454 self.summaries.setText(" ",3)
457 if idx < len(self.playlist):
458 currref = self.playlist.getServiceRefList()[idx]
459 text = self.getIdentifier(currref)
460 self.summaries.setText(text,4)
462 self.summaries.setText(" ",4)
465 if self.currList == "filelist":
466 if self.filelist.canDescent():
467 self.filelist.descent()
468 self.updateCurrentInfo()
472 if self.currList == "playlist":
473 selection = self["playlist"].getSelection()
474 self.changeEntry(self.playlist.getSelectionIndex())
478 if len(self.cdAudioTrackFiles):
479 menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
480 if self.currList == "filelist":
481 if self.filelist.canDescent():
482 menu.append((_("add directory to playlist"), "copydir"))
484 menu.append((_("add files to playlist"), "copyfiles"))
485 menu.append((_("switch to playlist"), "playlist"))
486 if config.usage.setup_level.index >= 1: # intermediate+
487 menu.append((_("delete file"), "deletefile"))
489 menu.append((_("switch to filelist"), "filelist"))
490 menu.append((_("clear playlist"), "clear"))
491 menu.append((_("Delete entry"), "deleteentry"))
492 if config.usage.setup_level.index >= 1: # intermediate+
493 menu.append((_("shuffle playlist"), "shuffle"))
494 menu.append((_("hide player"), "hide"));
495 menu.append((_("load playlist"), "loadplaylist"));
496 if config.usage.setup_level.index >= 1: # intermediate+
497 menu.append((_("save playlist"), "saveplaylist"));
498 menu.append((_("delete saved playlist"), "deleteplaylist"));
499 menu.append((_("Edit settings"), "settings"))
500 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
502 def menuCallback(self, choice):
506 if choice[1] == "copydir":
507 self.copyDirectory(self.filelist.getSelection()[0])
508 elif choice[1] == "copyfiles":
510 self.playlist.clear()
511 self.isAudioCD = False
512 self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
513 self.playServiceRefEntry(self.filelist.getServiceRef())
514 elif choice[1] == "playlist":
515 self.switchToPlayList()
516 elif choice[1] == "filelist":
517 self.switchToFileList()
518 elif choice[1] == "deleteentry":
519 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
522 elif choice[1] == "clear":
523 self.clear_playlist()
524 elif choice[1] == "hide":
526 elif choice[1] == "saveplaylist":
528 elif choice[1] == "loadplaylist":
530 elif choice[1] == "deleteplaylist":
531 self.delete_saved_playlist()
532 elif choice[1] == "shuffle":
533 self.playlist.PlayListShuffle()
534 elif choice[1] == "deletefile":
536 elif choice[1] == "settings":
537 self.session.openWithCallback(self.applySettings, MediaPlayerSettings, self)
538 elif choice[1] == "audiocd":
541 def playAudioCD(self):
542 from enigma import eServiceReference
543 from Plugins.Extensions.CDInfo.plugin import Query
545 if len(self.cdAudioTrackFiles):
546 self.playlist.clear()
547 self.savePlaylistOnExit = False
548 self.isAudioCD = True
549 for file in self.cdAudioTrackFiles:
550 ref = eServiceReference(4097, 0, file)
551 self.playlist.addFile(ref)
555 self.switchToPlayList()
557 def applySettings(self):
558 self.savePlaylistOnExit = config.mediaplayer.savePlaylistOnExit.getValue()
559 if config.mediaplayer.repeat.getValue() == True:
560 self["repeat"].setPixmapNum(1)
562 self["repeat"].setPixmapNum(0)
564 def showEventInformation(self):
565 from Screens.EventView import EventViewSimple
566 from ServiceReference import ServiceReference
567 evt = self[self.currList].getCurrentEvent()
569 self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
571 # also works on filelist (?)
572 def getCurrent(self):
573 return self["playlist"].getCurrent()
575 def deletePlaylistEntry(self):
576 if self.currList == "playlist":
577 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
581 def skip_listbegin(self):
582 if self.currList == "filelist":
583 self.filelist.moveToIndex(0)
585 self.playlist.moveToIndex(0)
586 self.updateCurrentInfo()
588 def skip_listend(self):
589 if self.currList == "filelist":
590 idx = len(self.filelist.list)
591 self.filelist.moveToIndex(idx - 1)
593 self.playlist.moveToIndex(len(self.playlist)-1)
594 self.updateCurrentInfo()
596 def save_playlist(self):
597 self.session.openWithCallback(self.save_playlist2,InputBox, title=_("Please enter filename (empty = use current date)"),windowTitle = _("Save Playlist"))
599 def save_playlist2(self, name):
603 name = strftime("%y%m%d_%H%M%S")
605 self.playlistIOInternal.clear()
606 for x in self.playlist.list:
607 self.playlistIOInternal.addService(ServiceReference(x[0]))
608 self.playlistIOInternal.save(resolveFilename(SCOPE_PLAYLIST) + name)
610 def load_playlist(self):
612 playlistdir = resolveFilename(SCOPE_PLAYLIST)
614 for i in os_listdir(playlistdir):
615 listpath.append((i,playlistdir + i))
617 print "Error while scanning subdirs ",e
618 self.session.openWithCallback(self.PlaylistSelected, ChoiceBox, title=_("Please select a playlist..."), list = listpath)
620 def PlaylistSelected(self,path):
622 self.clear_playlist()
623 extension = path[0].rsplit('.',1)[-1]
624 if self.playlistparsers.has_key(extension):
625 playlist = self.playlistparsers[extension]()
626 list = playlist.open(path[1])
628 self.playlist.addFile(x.ref)
629 self.playlist.updateList()
631 def delete_saved_playlist(self):
633 playlistdir = resolveFilename(SCOPE_PLAYLIST)
635 for i in os_listdir(playlistdir):
636 listpath.append((i,playlistdir + i))
638 print "Error while scanning subdirs ",e
639 self.session.openWithCallback(self.DeletePlaylistSelected, ChoiceBox, title=_("Please select a playlist to delete..."), list = listpath)
641 def DeletePlaylistSelected(self,path):
643 self.delname = path[1]
644 self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (path[1]))
646 def deleteConfirmed(self, confirmed):
649 os_remove(self.delname)
651 print "delete failed:", e
652 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
654 def clear_playlist(self):
655 self.isAudioCD = False
657 self.playlist.clear()
658 self.switchToFileList()
660 def copyDirectory(self, directory, recursive = True):
661 print "copyDirectory", directory
662 filelist = FileList(directory, useServiceRef = True, isTop = True)
664 for x in filelist.getFileList():
665 if x[0][1] == True: #isDir
667 self.copyDirectory(x[0][0])
668 elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097:
669 self.playlist.addFile(x[0][0])
670 self.playlist.updateList()
672 def deleteFile(self):
673 if self.currList == "filelist":
674 self.service = self.filelist.getServiceRef()
676 self.service = self.playlist.getSelection()
677 if self.service is None:
679 if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None:
680 if self.service == self.session.nav.getCurrentlyPlayingServiceReference():
683 serviceHandler = eServiceCenter.getInstance()
684 offline = serviceHandler.offlineOperations(self.service)
685 info = serviceHandler.info(self.service)
686 name = info and info.getName(self.service)
688 if offline is not None:
690 if not offline.deleteFromDisk(1):
693 self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name))
695 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
697 def deleteConfirmed_offline(self, confirmed):
699 serviceHandler = eServiceCenter.getInstance()
700 offline = serviceHandler.offlineOperations(self.service)
702 if offline is not None:
704 if not offline.deleteFromDisk(0):
707 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
709 self.removeListEntry()
711 def removeListEntry(self):
712 currdir = self.filelist.getCurrentDirectory()
713 self.filelist.changeDir(currdir)
718 if len(self.playlist) > 0:
719 for x in self.playlist.list:
720 if self.service == x[0]:
721 self.playlist.deleteFile(index)
725 self.playlist.updateList()
726 if self.currList == "playlist":
727 if len(self.playlist) == 0:
728 self.switchToFileList()
731 if self.filelist.getServiceRef().type == 4098: # playlist
732 ServiceRef = self.filelist.getServiceRef()
733 extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
734 if self.playlistparsers.has_key(extension):
735 playlist = self.playlistparsers[extension]()
736 list = playlist.open(ServiceRef.getPath())
738 self.playlist.addFile(x.ref)
739 self.playlist.updateList()
741 self.playlist.addFile(self.filelist.getServiceRef())
742 self.playlist.updateList()
743 if len(self.playlist) == 1:
746 def addPlaylistParser(self, parser, extension):
747 self.playlistparsers[extension] = parser
750 next = self.playlist.getCurrentIndex() + 1
751 if next < len(self.playlist):
752 self.changeEntry(next)
753 elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ):
757 def nextMarkOrEntry(self):
758 if not self.jumpPreviousNextMark(lambda x: x):
759 next = self.playlist.getCurrentIndex() + 1
760 if next < len(self.playlist):
761 self.changeEntry(next)
765 def previousMarkOrEntry(self):
766 if not self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True):
767 next = self.playlist.getCurrentIndex() - 1
769 self.changeEntry(next)
771 def deleteEntry(self):
772 self.playlist.deleteFile(self.playlist.getSelectionIndex())
773 self.playlist.updateList()
774 if len(self.playlist) == 0:
775 self.switchToFileList()
777 def changeEntry(self, index):
778 self.playlist.setCurrentPlaying(index)
781 def playServiceRefEntry(self, serviceref):
782 serviceRefList = self.playlist.getServiceRefList()
783 for count in range(len(serviceRefList)):
784 if serviceRefList[count] == serviceref:
785 self.changeEntry(count)
788 def xplayEntry(self):
789 if self.currList == "playlist":
793 self.playlist.clear()
794 self.isAudioCD = False
795 sel = self.filelist.getSelection()
797 if sel[1]: # can descent
798 # add directory to playlist
799 self.copyDirectory(sel[0])
801 # add files to playlist
802 self.copyDirectory(os_path.dirname(sel[0].getPath()) + "/", recursive = False)
803 if len(self.playlist) > 0:
807 if len(self.playlist.getServiceRefList()):
808 needsInfoUpdate = False
809 currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
810 if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
811 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
812 info = eServiceCenter.getInstance().info(currref)
813 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
814 self["title"].setText(description)
815 # display just playing musik on LCD
816 idx = self.playlist.getCurrentIndex()
817 currref = self.playlist.getServiceRefList()[idx]
818 text = self.getIdentifier(currref)
820 ext = text[-4:].lower()
822 # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead
823 if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
826 needsInfoUpdate = True
827 self.summaries.setText(text,1)
829 # get the next two entries
831 if idx < len(self.playlist):
832 currref = self.playlist.getServiceRefList()[idx]
833 text = self.getIdentifier(currref)
834 self.summaries.setText(text,3)
836 self.summaries.setText(" ",3)
839 if idx < len(self.playlist):
840 currref = self.playlist.getServiceRefList()[idx]
841 text = self.getIdentifier(currref)
842 self.summaries.setText(text,4)
844 self.summaries.setText(" ",4)
846 idx = self.playlist.getCurrentIndex()
847 currref = self.playlist.getServiceRefList()[idx]
848 text = currref.getPath()
849 ext = text[-4:].lower()
850 if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
853 needsInfoUpdate = True
855 self.unPauseService()
856 if needsInfoUpdate == True:
857 path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath()
858 self["coverArt"].updateCoverArt(path)
860 self["coverArt"].showDefaultCover()
861 self.readTitleInformation()
863 def updatedSeekState(self):
864 if self.seekstate == self.SEEK_STATE_PAUSE:
865 self.playlist.pauseFile()
866 elif self.seekstate == self.SEEK_STATE_PLAY:
867 self.playlist.playFile()
868 elif self.isStateForward(self.seekstate):
869 self.playlist.forwardFile()
870 elif self.isStateBackward(self.seekstate):
871 self.playlist.rewindFile()
873 def pauseEntry(self):
875 if self.seekstate == self.SEEK_STATE_PAUSE:
881 self.playlist.stopFile()
882 self.session.nav.playService(None)
883 self.updateMusicInformation(clear=True)
886 def unPauseService(self):
887 self.setSeekState(self.SEEK_STATE_PLAY)
889 def subtitleSelection(self):
890 from Screens.Subtitles import Subtitles
891 self.session.open(Subtitles)
893 def hotplugCB(self, dev, media_state):
894 if dev == harddiskmanager.getCD():
895 if media_state == "1":
896 from Components.Scanner import scanDevice
897 devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
898 self.cdAudioTrackFiles = []
899 res = scanDevice(devpath)
900 list = [ (r.description, r, res[r], self.session) for r in res ]
902 (desc, scanner, files, session) = list[0]
904 if file.mimetype == "audio/x-cda":
905 self.cdAudioTrackFiles.append(file.path)
907 self.cdAudioTrackFiles = []
909 self.clear_playlist()
911 class MediaPlayerLCDScreen(Screen):
913 <screen position="0,0" size="132,64" title="LCD Text">
914 <widget name="text1" position="4,0" size="132,35" font="Regular;16"/>
915 <widget name="text3" position="4,36" size="132,14" font="Regular;10"/>
916 <widget name="text4" position="4,49" size="132,14" font="Regular;10"/>
919 def __init__(self, session, parent):
920 Screen.__init__(self, session)
921 self["text1"] = Label("Mediaplayer")
922 self["text3"] = Label("")
923 self["text4"] = Label("")
925 def setText(self, text, line):
927 if text[-4:] == ".mp3":
930 text = text + textleer*10
932 self["text1"].setText(text)
934 self["text3"].setText(text)
936 self["text4"].setText(text)
938 def main(session, **kwargs):
939 session.open(MediaPlayer)
941 def menu(menuid, **kwargs):
942 if menuid == "mainmenu":
943 return [(_("Media player"), main, "media_player", 45)]
946 def filescan_open(list, session, **kwargs):
947 from enigma import eServiceReference
949 mp = session.open(MediaPlayer)
951 mp.savePlaylistOnExit = False
954 if file.mimetype == "video/MP2T":
958 ref = eServiceReference(stype, 0, file.path)
959 mp.playlist.addFile(ref)
962 mp.switchToPlayList()
964 def audioCD_open(list, session, **kwargs):
965 from enigma import eServiceReference
967 mp = session.open(MediaPlayer)
968 mp.cdAudioTrackFiles = []
970 mp.cdAudioTrackFiles.append(file.path)
973 def filescan(**kwargs):
974 from Components.Scanner import Scanner, ScanPath
976 Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"],
979 ScanPath(path = "", with_subdirs = False),
982 description = "View Movies...",
983 openfnc = filescan_open,
985 Scanner(mimetypes = ["video/x-vcd"],
988 ScanPath(path = "mpegav", with_subdirs = False),
989 ScanPath(path = "MPEGAV", with_subdirs = False),
992 description = "View Video CD...",
993 openfnc = filescan_open,
995 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
998 ScanPath(path = "", with_subdirs = False),
1001 description = "Play Music...",
1002 openfnc = filescan_open,
1005 from Plugins.Extensions.CDInfo.plugin import Query
1007 Scanner(mimetypes = ["audio/x-cda"],
1010 ScanPath(path = "", with_subdirs = False),
1013 description = "Play Audio-CD...",
1014 openfnc = audioCD_open,
1020 from Plugins.Plugin import PluginDescriptor
1021 def Plugins(**kwargs):
1023 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, fnc = menu),
1024 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)