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)
85 def embeddedCoverArt(self):
86 print "[embeddedCoverArt] found"
87 self.coverArtFileName = "/tmp/.id3coverart"
88 self.picload.startDecode(self.coverArtFileName)
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,
228 iPlayableService.evUser+13: self["coverArt"].embeddedCoverArt
234 def createSummary(self):
235 return MediaPlayerLCDScreen
238 self.playlistIOInternal.clear()
239 for x in self.playlist.list:
240 self.playlistIOInternal.addService(ServiceReference(x[0]))
241 if self.savePlaylistOnExit:
242 self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
243 if config.mediaplayer.saveDirOnExit.getValue():
244 config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory())
245 config.mediaplayer.defaultDir.save()
246 hotplugNotifier.remove(self.hotplugCB)
247 del self["coverArt"].picload
250 def checkSkipShowHideLock(self):
251 self.updatedSeekState()
253 def doEofInternal(self, playing):
260 self.session.nav.playService(self.oldService)
262 def __evUpdatedInfo(self):
263 currPlay = self.session.nav.getCurrentService()
264 currenttitle = currPlay.info().getInfo(iServiceInformation.sCurrentTitle)
265 totaltitles = currPlay.info().getInfo(iServiceInformation.sTotalTitles)
266 sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
267 print "[__evUpdatedInfo] title %d of %d (%s)" % (currenttitle, totaltitles, sTitle)
268 self.readTitleInformation()
270 def __evDecodeError(self):
271 currPlay = self.session.nav.getCurrentService()
272 sVideoType = currPlay.info().getInfoString(iServiceInformation.sVideoType)
273 print "[__evDecodeError] video-codec %s can't be decoded by hardware" % (sVideoType)
274 self.session.open(MessageBox, _("This Dreambox can't decode %s video streams!") % sVideoType, type = MessageBox.TYPE_INFO,timeout = 20 )
276 def __evPluginError(self):
277 currPlay = self.session.nav.getCurrentService()
278 message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
279 print "[__evPluginError]" , message
280 self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 )
282 def delMPTimer(self):
283 del self.rightKeyTimer
284 del self.leftKeyTimer
286 def readTitleInformation(self):
287 currPlay = self.session.nav.getCurrentService()
288 if currPlay is not None:
289 sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle)
290 sAlbum = currPlay.info().getInfoString(iServiceInformation.sAlbum)
291 sGenre = currPlay.info().getInfoString(iServiceInformation.sGenre)
292 sArtist = currPlay.info().getInfoString(iServiceInformation.sArtist)
293 sYear = currPlay.info().getInfoString(iServiceInformation.sTimeCreate)
296 if not self.isAudioCD:
297 sTitle = currPlay.info().getName().split('/')[-1]
299 sTitle = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getName()
301 if self.AudioCD_albuminfo:
302 if sAlbum == "" and "title" in self.AudioCD_albuminfo:
303 sAlbum = self.AudioCD_albuminfo["title"]
304 if sGenre == "" and "genre" in self.AudioCD_albuminfo:
305 sGenre = self.AudioCD_albuminfo["genre"]
306 if sArtist == "" and "artist" in self.AudioCD_albuminfo:
307 sArtist = self.AudioCD_albuminfo["artist"]
308 if "year" in self.AudioCD_albuminfo:
309 sYear = self.AudioCD_albuminfo["year"]
311 self.updateMusicInformation( sArtist, sTitle, sAlbum, sYear, sGenre, clear = True )
313 self.updateMusicInformation()
315 def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False):
316 self.updateSingleMusicInformation("artist", artist, clear)
317 self.updateSingleMusicInformation("title", title, clear)
318 self.updateSingleMusicInformation("album", album, clear)
319 self.updateSingleMusicInformation("year", year, clear)
320 self.updateSingleMusicInformation("genre", genre, clear)
322 def updateSingleMusicInformation(self, name, info, clear):
323 if info != "" or clear:
324 if self[name].getText() != info:
325 self[name].setText(info)
328 self.lefttimer = True
329 self.leftKeyTimer.start(1000)
332 self.righttimer = True
333 self.rightKeyTimer.start(1000)
337 self.leftKeyTimer.stop()
338 self.lefttimer = False
339 self[self.currList].pageUp()
340 self.updateCurrentInfo()
344 self.rightKeyTimer.stop()
345 self.righttimer = False
346 self[self.currList].pageDown()
347 self.updateCurrentInfo()
349 def leftTimerFire(self):
350 self.leftKeyTimer.stop()
351 self.lefttimer = False
352 self.switchToFileList()
354 def rightTimerFire(self):
355 self.rightKeyTimer.stop()
356 self.righttimer = False
357 self.switchToPlayList()
359 def switchToFileList(self):
360 self.currList = "filelist"
361 self.filelist.selectionEnabled(1)
362 self.playlist.selectionEnabled(0)
363 self.updateCurrentInfo()
365 def switchToPlayList(self):
366 if len(self.playlist) != 0:
367 self.currList = "playlist"
368 self.filelist.selectionEnabled(0)
369 self.playlist.selectionEnabled(1)
370 self.updateCurrentInfo()
373 self[self.currList].up()
374 self.updateCurrentInfo()
377 self[self.currList].down()
378 self.updateCurrentInfo()
380 def showAfterSeek(self):
383 def showAfterCuesheetOperation(self):
386 def hideAfterResume(self):
389 def getIdentifier(self, ref):
394 return text.split('/')[-1]
396 # FIXME: maybe this code can be optimized
397 def updateCurrentInfo(self):
399 if self.currList == "filelist":
400 idx = self.filelist.getSelectionIndex()
401 r = self.filelist.list[idx]
408 self.summaries.setText(text,1)
411 if idx < len(self.filelist.list):
412 r = self.filelist.list[idx]
416 self.summaries.setText(text,3)
418 self.summaries.setText(" ",3)
421 if idx < len(self.filelist.list):
422 r = self.filelist.list[idx]
426 self.summaries.setText(text,4)
428 self.summaries.setText(" ",4)
431 if not self.filelist.canDescent():
432 r = self.filelist.getServiceRef()
436 self["currenttext"].setText(os_path.basename(text))
438 if self.currList == "playlist":
439 t = self.playlist.getSelection()
442 #display current selected entry on LCD
443 text = self.getIdentifier(t)
444 self.summaries.setText(text,1)
445 self["currenttext"].setText(text)
446 idx = self.playlist.getSelectionIndex()
448 if idx < len(self.playlist):
449 currref = self.playlist.getServiceRefList()[idx]
450 text = self.getIdentifier(currref)
451 self.summaries.setText(text,3)
453 self.summaries.setText(" ",3)
456 if idx < len(self.playlist):
457 currref = self.playlist.getServiceRefList()[idx]
458 text = self.getIdentifier(currref)
459 self.summaries.setText(text,4)
461 self.summaries.setText(" ",4)
464 if self.currList == "filelist":
465 if self.filelist.canDescent():
466 self.filelist.descent()
467 self.updateCurrentInfo()
471 if self.currList == "playlist":
472 selection = self["playlist"].getSelection()
473 self.changeEntry(self.playlist.getSelectionIndex())
477 if len(self.cdAudioTrackFiles):
478 menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
479 if self.currList == "filelist":
480 if self.filelist.canDescent():
481 menu.append((_("add directory to playlist"), "copydir"))
483 menu.append((_("add files to playlist"), "copyfiles"))
484 menu.append((_("switch to playlist"), "playlist"))
485 menu.append((_("delete file"), "deletefile"))
487 menu.append((_("switch to filelist"), "filelist"))
488 menu.append((_("shuffle playlist"), "shuffle"))
489 menu.append((_("Delete entry"), "deleteentry"))
490 menu.append((_("clear playlist"), "clear"))
491 menu.append((_("hide player"), "hide"));
492 menu.append((_("save playlist"), "saveplaylist"));
493 menu.append((_("load playlist"), "loadplaylist"));
494 menu.append((_("delete saved playlist"), "deleteplaylist"));
495 menu.append((_("Edit settings"), "settings"))
496 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
498 def menuCallback(self, choice):
502 if choice[1] == "copydir":
503 self.copyDirectory(self.filelist.getSelection()[0])
504 elif choice[1] == "copyfiles":
506 self.playlist.clear()
507 self.isAudioCD = False
508 self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
509 self.playServiceRefEntry(self.filelist.getServiceRef())
510 elif choice[1] == "playlist":
511 self.switchToPlayList()
512 elif choice[1] == "filelist":
513 self.switchToFileList()
514 elif choice[1] == "deleteentry":
515 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
518 elif choice[1] == "clear":
519 self.clear_playlist()
520 elif choice[1] == "hide":
522 elif choice[1] == "saveplaylist":
524 elif choice[1] == "loadplaylist":
526 elif choice[1] == "deleteplaylist":
527 self.delete_saved_playlist()
528 elif choice[1] == "shuffle":
529 self.playlist.PlayListShuffle()
530 elif choice[1] == "deletefile":
532 elif choice[1] == "settings":
533 self.session.openWithCallback(self.applySettings, MediaPlayerSettings, self)
534 elif choice[1] == "audiocd":
537 def playAudioCD(self):
538 from enigma import eServiceReference
539 from Plugins.Extensions.CDInfo.plugin import Query
541 if len(self.cdAudioTrackFiles):
542 self.playlist.clear()
543 self.savePlaylistOnExit = False
544 self.isAudioCD = True
545 for file in self.cdAudioTrackFiles:
546 ref = eServiceReference(4097, 0, file)
547 self.playlist.addFile(ref)
551 self.switchToPlayList()
553 def applySettings(self):
554 self.savePlaylistOnExit = config.mediaplayer.savePlaylistOnExit.getValue()
555 if config.mediaplayer.repeat.getValue() == True:
556 self["repeat"].setPixmapNum(1)
558 self["repeat"].setPixmapNum(0)
560 def showEventInformation(self):
561 from Screens.EventView import EventViewSimple
562 from ServiceReference import ServiceReference
563 evt = self[self.currList].getCurrentEvent()
565 self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
567 # also works on filelist (?)
568 def getCurrent(self):
569 return self["playlist"].getCurrent()
571 def deletePlaylistEntry(self):
572 if self.currList == "playlist":
573 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
577 def skip_listbegin(self):
578 if self.currList == "filelist":
579 self.filelist.moveToIndex(0)
581 self.playlist.moveToIndex(0)
582 self.updateCurrentInfo()
584 def skip_listend(self):
585 if self.currList == "filelist":
586 idx = len(self.filelist.list)
587 self.filelist.moveToIndex(idx - 1)
589 self.playlist.moveToIndex(len(self.playlist)-1)
590 self.updateCurrentInfo()
592 def save_playlist(self):
593 self.session.openWithCallback(self.save_playlist2,InputBox, title=_("Please enter filename (empty = use current date)"),windowTitle = _("Save Playlist"))
595 def save_playlist2(self, name):
599 name = strftime("%y%m%d_%H%M%S")
601 self.playlistIOInternal.clear()
602 for x in self.playlist.list:
603 self.playlistIOInternal.addService(ServiceReference(x[0]))
604 self.playlistIOInternal.save(resolveFilename(SCOPE_PLAYLIST) + name)
606 def load_playlist(self):
608 playlistdir = resolveFilename(SCOPE_PLAYLIST)
610 for i in os_listdir(playlistdir):
611 listpath.append((i,playlistdir + i))
613 print "Error while scanning subdirs ",e
614 self.session.openWithCallback(self.PlaylistSelected, ChoiceBox, title=_("Please select a playlist..."), list = listpath)
616 def PlaylistSelected(self,path):
618 self.clear_playlist()
619 extension = path[0].rsplit('.',1)[-1]
620 if self.playlistparsers.has_key(extension):
621 playlist = self.playlistparsers[extension]()
622 list = playlist.open(path[1])
624 self.playlist.addFile(x.ref)
625 self.playlist.updateList()
627 def delete_saved_playlist(self):
629 playlistdir = resolveFilename(SCOPE_PLAYLIST)
631 for i in os_listdir(playlistdir):
632 listpath.append((i,playlistdir + i))
634 print "Error while scanning subdirs ",e
635 self.session.openWithCallback(self.DeletePlaylistSelected, ChoiceBox, title=_("Please select a playlist to delete..."), list = listpath)
637 def DeletePlaylistSelected(self,path):
639 self.delname = path[1]
640 self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (path[1]))
642 def deleteConfirmed(self, confirmed):
645 os_remove(self.delname)
647 print "delete failed:", e
648 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
650 def clear_playlist(self):
651 self.isAudioCD = False
653 self.playlist.clear()
654 self.switchToFileList()
656 def copyDirectory(self, directory, recursive = True):
657 print "copyDirectory", directory
658 filelist = FileList(directory, useServiceRef = True, isTop = True)
660 for x in filelist.getFileList():
661 if x[0][1] == True: #isDir
663 self.copyDirectory(x[0][0])
664 elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097:
665 self.playlist.addFile(x[0][0])
666 self.playlist.updateList()
668 def deleteFile(self):
669 if self.currList == "filelist":
670 self.service = self.filelist.getServiceRef()
672 self.service = self.playlist.getSelection()
673 if self.service is None:
675 if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None:
676 if self.service == self.session.nav.getCurrentlyPlayingServiceReference():
679 serviceHandler = eServiceCenter.getInstance()
680 offline = serviceHandler.offlineOperations(self.service)
681 info = serviceHandler.info(self.service)
682 name = info and info.getName(self.service)
684 if offline is not None:
686 if not offline.deleteFromDisk(1):
689 self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name))
691 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
693 def deleteConfirmed_offline(self, confirmed):
695 serviceHandler = eServiceCenter.getInstance()
696 offline = serviceHandler.offlineOperations(self.service)
698 if offline is not None:
700 if not offline.deleteFromDisk(0):
703 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
705 self.removeListEntry()
707 def removeListEntry(self):
708 currdir = self.filelist.getCurrentDirectory()
709 self.filelist.changeDir(currdir)
714 if len(self.playlist) > 0:
715 for x in self.playlist.list:
716 if self.service == x[0]:
717 self.playlist.deleteFile(index)
721 self.playlist.updateList()
722 if self.currList == "playlist":
723 if len(self.playlist) == 0:
724 self.switchToFileList()
727 if self.filelist.getServiceRef().type == 4098: # playlist
728 ServiceRef = self.filelist.getServiceRef()
729 extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
730 if self.playlistparsers.has_key(extension):
731 playlist = self.playlistparsers[extension]()
732 list = playlist.open(ServiceRef.getPath())
734 self.playlist.addFile(x.ref)
735 self.playlist.updateList()
737 self.playlist.addFile(self.filelist.getServiceRef())
738 self.playlist.updateList()
739 if len(self.playlist) == 1:
742 def addPlaylistParser(self, parser, extension):
743 self.playlistparsers[extension] = parser
746 next = self.playlist.getCurrentIndex() + 1
747 if next < len(self.playlist):
748 self.changeEntry(next)
749 elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ):
753 def nextMarkOrEntry(self):
754 if not self.jumpPreviousNextMark(lambda x: x):
755 next = self.playlist.getCurrentIndex() + 1
756 if next < len(self.playlist):
757 self.changeEntry(next)
761 def previousMarkOrEntry(self):
762 if not self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True):
763 next = self.playlist.getCurrentIndex() - 1
765 self.changeEntry(next)
767 def deleteEntry(self):
768 self.playlist.deleteFile(self.playlist.getSelectionIndex())
769 self.playlist.updateList()
770 if len(self.playlist) == 0:
771 self.switchToFileList()
773 def changeEntry(self, index):
774 self.playlist.setCurrentPlaying(index)
777 def playServiceRefEntry(self, serviceref):
778 serviceRefList = self.playlist.getServiceRefList()
779 for count in range(len(serviceRefList)):
780 if serviceRefList[count] == serviceref:
781 self.changeEntry(count)
784 def xplayEntry(self):
785 if self.currList == "playlist":
789 self.playlist.clear()
790 self.isAudioCD = False
791 sel = self.filelist.getSelection()
793 if sel[1]: # can descent
794 # add directory to playlist
795 self.copyDirectory(sel[0])
797 # add files to playlist
798 self.copyDirectory(os_path.dirname(sel[0].getPath()) + "/", recursive = False)
799 if len(self.playlist) > 0:
803 if len(self.playlist.getServiceRefList()):
804 needsInfoUpdate = False
805 currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
806 if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
807 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
808 info = eServiceCenter.getInstance().info(currref)
809 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
810 self["title"].setText(description)
811 # display just playing musik on LCD
812 idx = self.playlist.getCurrentIndex()
813 currref = self.playlist.getServiceRefList()[idx]
814 text = self.getIdentifier(currref)
816 ext = text[-4:].lower()
818 # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead
819 if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
822 needsInfoUpdate = True
823 self.summaries.setText(text,1)
825 # get the next two entries
827 if idx < len(self.playlist):
828 currref = self.playlist.getServiceRefList()[idx]
829 text = self.getIdentifier(currref)
830 self.summaries.setText(text,3)
832 self.summaries.setText(" ",3)
835 if idx < len(self.playlist):
836 currref = self.playlist.getServiceRefList()[idx]
837 text = self.getIdentifier(currref)
838 self.summaries.setText(text,4)
840 self.summaries.setText(" ",4)
842 idx = self.playlist.getCurrentIndex()
843 currref = self.playlist.getServiceRefList()[idx]
844 text = currref.getPath()
845 ext = text[-4:].lower()
846 if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD:
849 needsInfoUpdate = True
851 self.unPauseService()
852 if needsInfoUpdate == True:
853 path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath()
854 self["coverArt"].updateCoverArt(path)
856 self["coverArt"].showDefaultCover()
857 self.readTitleInformation()
859 def updatedSeekState(self):
860 if self.seekstate == self.SEEK_STATE_PAUSE:
861 self.playlist.pauseFile()
862 elif self.seekstate == self.SEEK_STATE_PLAY:
863 self.playlist.playFile()
864 elif self.isStateForward(self.seekstate):
865 self.playlist.forwardFile()
866 elif self.isStateBackward(self.seekstate):
867 self.playlist.rewindFile()
869 def pauseEntry(self):
871 if self.seekstate == self.SEEK_STATE_PAUSE:
877 self.playlist.stopFile()
878 self.session.nav.playService(None)
879 self.updateMusicInformation(clear=True)
882 def unPauseService(self):
883 self.setSeekState(self.SEEK_STATE_PLAY)
885 def subtitleSelection(self):
886 from Screens.Subtitles import Subtitles
887 self.session.open(Subtitles)
889 def hotplugCB(self, dev, media_state):
890 if dev == harddiskmanager.getCD():
891 if media_state == "1":
892 from Components.Scanner import scanDevice
893 devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
894 self.cdAudioTrackFiles = []
895 res = scanDevice(devpath)
896 list = [ (r.description, r, res[r], self.session) for r in res ]
898 (desc, scanner, files, session) = list[0]
900 if file.mimetype == "audio/x-cda":
901 self.cdAudioTrackFiles.append(file.path)
903 self.cdAudioTrackFiles = []
905 self.clear_playlist()
907 class MediaPlayerLCDScreen(Screen):
909 <screen position="0,0" size="132,64" title="LCD Text">
910 <widget name="text1" position="4,0" size="132,35" font="Regular;16"/>
911 <widget name="text3" position="4,36" size="132,14" font="Regular;10"/>
912 <widget name="text4" position="4,49" size="132,14" font="Regular;10"/>
915 def __init__(self, session, parent):
916 Screen.__init__(self, session)
917 self["text1"] = Label("Mediaplayer")
918 self["text3"] = Label("")
919 self["text4"] = Label("")
921 def setText(self, text, line):
923 if text[-4:] == ".mp3":
926 text = text + textleer*10
928 self["text1"].setText(text)
930 self["text3"].setText(text)
932 self["text4"].setText(text)
934 def main(session, **kwargs):
935 session.open(MediaPlayer)
937 def menu(menuid, **kwargs):
938 if menuid == "mainmenu":
939 return [(_("Media player"), main, "media_player", 45)]
942 def filescan_open(list, session, **kwargs):
943 from enigma import eServiceReference
945 mp = session.open(MediaPlayer)
947 mp.savePlaylistOnExit = False
950 if file.mimetype == "video/MP2T":
954 ref = eServiceReference(stype, 0, file.path)
955 mp.playlist.addFile(ref)
958 mp.switchToPlayList()
960 def audioCD_open(list, session, **kwargs):
961 from enigma import eServiceReference
963 mp = session.open(MediaPlayer)
964 mp.cdAudioTrackFiles = []
966 mp.cdAudioTrackFiles.append(file.path)
969 def filescan(**kwargs):
970 from Components.Scanner import Scanner, ScanPath
972 Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"],
975 ScanPath(path = "", with_subdirs = False),
978 description = "View Movies...",
979 openfnc = filescan_open,
981 Scanner(mimetypes = ["video/x-vcd"],
984 ScanPath(path = "mpegav", with_subdirs = False),
985 ScanPath(path = "MPEGAV", with_subdirs = False),
988 description = "View Video CD...",
989 openfnc = filescan_open,
991 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
994 ScanPath(path = "", with_subdirs = False),
997 description = "Play Music...",
998 openfnc = filescan_open,
1001 from Plugins.Extensions.CDInfo.plugin import Query
1003 Scanner(mimetypes = ["audio/x-cda"],
1006 ScanPath(path = "", with_subdirs = False),
1009 description = "Play Audio-CD...",
1010 openfnc = audioCD_open,
1016 from Plugins.Plugin import PluginDescriptor
1017 def Plugins(**kwargs):
1019 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, fnc = menu),
1020 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)