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
663 print "refusing to operate on /"
665 filelist = FileList(directory, useServiceRef = True, showMountpoints = False, isTop = True)
667 for x in filelist.getFileList():
668 if x[0][1] == True: #isDir
670 if x[0][0] != directory:
671 self.copyDirectory(x[0][0])
672 elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097:
673 self.playlist.addFile(x[0][0])
674 self.playlist.updateList()
676 def deleteFile(self):
677 if self.currList == "filelist":
678 self.service = self.filelist.getServiceRef()
680 self.service = self.playlist.getSelection()
681 if self.service is None:
683 if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None:
684 if self.service == self.session.nav.getCurrentlyPlayingServiceReference():
687 serviceHandler = eServiceCenter.getInstance()
688 offline = serviceHandler.offlineOperations(self.service)
689 info = serviceHandler.info(self.service)
690 name = info and info.getName(self.service)
692 if offline is not None:
694 if not offline.deleteFromDisk(1):
697 self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name))
699 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
701 def deleteConfirmed_offline(self, confirmed):
703 serviceHandler = eServiceCenter.getInstance()
704 offline = serviceHandler.offlineOperations(self.service)
706 if offline is not None:
708 if not offline.deleteFromDisk(0):
711 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
713 self.removeListEntry()
715 def removeListEntry(self):
716 currdir = self.filelist.getCurrentDirectory()
717 self.filelist.changeDir(currdir)
722 if len(self.playlist) > 0:
723 for x in self.playlist.list:
724 if self.service == x[0]:
725 self.playlist.deleteFile(index)
729 self.playlist.updateList()
730 if self.currList == "playlist":
731 if len(self.playlist) == 0:
732 self.switchToFileList()
735 if self.filelist.getServiceRef().type == 4098: # playlist
736 ServiceRef = self.filelist.getServiceRef()
737 extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
738 if self.playlistparsers.has_key(extension):
739 playlist = self.playlistparsers[extension]()
740 list = playlist.open(ServiceRef.getPath())
742 self.playlist.addFile(x.ref)
743 self.playlist.updateList()
745 self.playlist.addFile(self.filelist.getServiceRef())
746 self.playlist.updateList()
747 if len(self.playlist) == 1:
750 def addPlaylistParser(self, parser, extension):
751 self.playlistparsers[extension] = parser
754 next = self.playlist.getCurrentIndex() + 1
755 if next < len(self.playlist):
756 self.changeEntry(next)
757 elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ):
761 def nextMarkOrEntry(self):
762 if not self.jumpPreviousNextMark(lambda x: x):
763 next = self.playlist.getCurrentIndex() + 1
764 if next < len(self.playlist):
765 self.changeEntry(next)
769 def previousMarkOrEntry(self):
770 if not self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True):
771 next = self.playlist.getCurrentIndex() - 1
773 self.changeEntry(next)
775 def deleteEntry(self):
776 self.playlist.deleteFile(self.playlist.getSelectionIndex())
777 self.playlist.updateList()
778 if len(self.playlist) == 0:
779 self.switchToFileList()
781 def changeEntry(self, index):
782 self.playlist.setCurrentPlaying(index)
785 def playServiceRefEntry(self, serviceref):
786 serviceRefList = self.playlist.getServiceRefList()
787 for count in range(len(serviceRefList)):
788 if serviceRefList[count] == serviceref:
789 self.changeEntry(count)
792 def xplayEntry(self):
793 if self.currList == "playlist":
797 self.playlist.clear()
798 self.isAudioCD = False
799 sel = self.filelist.getSelection()
801 if sel[1]: # can descent
802 # add directory to playlist
803 self.copyDirectory(sel[0])
805 # add files to playlist
806 self.copyDirectory(os_path.dirname(sel[0].getPath()) + "/", recursive = False)
807 if len(self.playlist) > 0:
811 if len(self.playlist.getServiceRefList()):
812 audio_extensions = (".mp2", ".mp3", ".wav", ".ogg", "flac", "m4a")
813 needsInfoUpdate = False
814 currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
815 if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
816 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
817 info = eServiceCenter.getInstance().info(currref)
818 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
819 self["title"].setText(description)
820 # display just playing musik on LCD
821 idx = self.playlist.getCurrentIndex()
822 currref = self.playlist.getServiceRefList()[idx]
823 text = self.getIdentifier(currref)
825 ext = text[-4:].lower()
827 # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead
828 if ext not in audio_extensions and not self.isAudioCD:
831 needsInfoUpdate = True
832 self.summaries.setText(text,1)
834 # get the next two entries
836 if idx < len(self.playlist):
837 currref = self.playlist.getServiceRefList()[idx]
838 text = self.getIdentifier(currref)
839 self.summaries.setText(text,3)
841 self.summaries.setText(" ",3)
844 if idx < len(self.playlist):
845 currref = self.playlist.getServiceRefList()[idx]
846 text = self.getIdentifier(currref)
847 self.summaries.setText(text,4)
849 self.summaries.setText(" ",4)
851 idx = self.playlist.getCurrentIndex()
852 currref = self.playlist.getServiceRefList()[idx]
853 text = currref.getPath()
854 ext = text[-4:].lower()
855 if ext not in audio_extensions and not self.isAudioCD:
858 needsInfoUpdate = True
860 self.unPauseService()
861 if needsInfoUpdate == True:
862 path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath()
863 self["coverArt"].updateCoverArt(path)
865 self["coverArt"].showDefaultCover()
866 self.readTitleInformation()
868 def updatedSeekState(self):
869 if self.seekstate == self.SEEK_STATE_PAUSE:
870 self.playlist.pauseFile()
871 elif self.seekstate == self.SEEK_STATE_PLAY:
872 self.playlist.playFile()
873 elif self.isStateForward(self.seekstate):
874 self.playlist.forwardFile()
875 elif self.isStateBackward(self.seekstate):
876 self.playlist.rewindFile()
878 def pauseEntry(self):
880 if self.seekstate == self.SEEK_STATE_PAUSE:
886 self.playlist.stopFile()
887 self.session.nav.playService(None)
888 self.updateMusicInformation(clear=True)
891 def unPauseService(self):
892 self.setSeekState(self.SEEK_STATE_PLAY)
894 def subtitleSelection(self):
895 from Screens.Subtitles import Subtitles
896 self.session.open(Subtitles)
898 def hotplugCB(self, dev, media_state):
899 if dev == harddiskmanager.getCD():
900 if media_state == "1":
901 from Components.Scanner import scanDevice
902 devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
903 self.cdAudioTrackFiles = []
904 res = scanDevice(devpath)
905 list = [ (r.description, r, res[r], self.session) for r in res ]
907 (desc, scanner, files, session) = list[0]
909 if file.mimetype == "audio/x-cda":
910 self.cdAudioTrackFiles.append(file.path)
912 self.cdAudioTrackFiles = []
914 self.clear_playlist()
916 class MediaPlayerLCDScreen(Screen):
918 <screen position="0,0" size="132,64" title="LCD Text">
919 <widget name="text1" position="4,0" size="132,35" font="Regular;16"/>
920 <widget name="text3" position="4,36" size="132,14" font="Regular;10"/>
921 <widget name="text4" position="4,49" size="132,14" font="Regular;10"/>
924 def __init__(self, session, parent):
925 Screen.__init__(self, session)
926 self["text1"] = Label("Mediaplayer")
927 self["text3"] = Label("")
928 self["text4"] = Label("")
930 def setText(self, text, line):
932 if text[-4:] == ".mp3":
935 text = text + textleer*10
937 self["text1"].setText(text)
939 self["text3"].setText(text)
941 self["text4"].setText(text)
943 def main(session, **kwargs):
944 session.open(MediaPlayer)
946 def menu(menuid, **kwargs):
947 if menuid == "mainmenu":
948 return [(_("Media player"), main, "media_player", 45)]
951 def filescan_open(list, session, **kwargs):
952 from enigma import eServiceReference
954 mp = session.open(MediaPlayer)
956 mp.savePlaylistOnExit = False
959 if file.mimetype == "video/MP2T":
963 ref = eServiceReference(stype, 0, file.path)
964 mp.playlist.addFile(ref)
967 mp.switchToPlayList()
969 def audioCD_open(list, session, **kwargs):
970 from enigma import eServiceReference
972 mp = session.open(MediaPlayer)
973 mp.cdAudioTrackFiles = []
975 mp.cdAudioTrackFiles.append(file.path)
978 def filescan(**kwargs):
979 from Components.Scanner import Scanner, ScanPath
981 Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"],
984 ScanPath(path = "", with_subdirs = False),
987 description = "View Movies...",
988 openfnc = filescan_open,
990 Scanner(mimetypes = ["video/x-vcd"],
993 ScanPath(path = "mpegav", with_subdirs = False),
994 ScanPath(path = "MPEGAV", with_subdirs = False),
997 description = "View Video CD...",
998 openfnc = filescan_open,
1000 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
1003 ScanPath(path = "", with_subdirs = False),
1006 description = "Play Music...",
1007 openfnc = filescan_open,
1010 from Plugins.Extensions.CDInfo.plugin import Query
1012 Scanner(mimetypes = ["audio/x-cda"],
1015 ScanPath(path = "", with_subdirs = False),
1018 description = "Play Audio-CD...",
1019 openfnc = audioCD_open,
1025 from Plugins.Plugin import PluginDescriptor
1026 def Plugins(**kwargs):
1028 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, fnc = menu),
1029 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)