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_CURRENT_SKIN
23 from settings import MediaPlayerSettings
26 class MyPlayList(PlayList):
28 PlayList.__init__(self)
30 def PlayListShuffle(self):
31 random.shuffle(self.list)
32 self.l.setList(self.list)
34 self.oldCurrPlaying = -1
36 class MediaPixmap(Pixmap):
39 self.coverArtFileName = ""
40 self.picload = ePicLoad()
41 self.picload.PictureData.get().append(self.paintCoverArtPixmapCB)
42 self.coverFileNames = ["folder.png", "folder.jpg"]
44 def applySkin(self, desktop, screen):
45 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_CURRENT_SKIN, "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|divx|m4v|mkv|mp4|m4a|dat|flac|mov|m2ts|flv|dts|3gp|3g2|mts|wmv|asf|wma)", 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
140 # from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
141 # hotplugNotifier.append(self.hotplugCB)
143 class MoviePlayerActionMap(NumberActionMap):
144 def __init__(self, player, contexts = [ ], actions = { }, prio=0):
145 NumberActionMap.__init__(self, contexts, actions, prio)
148 def action(self, contexts, action):
150 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 "shift_stop": self.clear_playlist,
174 "shift_record": self.playlist.PlayListShuffle,
175 "subtitles": (self.subtitleSelection, _("Subtitle selection")),
178 self["InfobarEPGActions"] = HelpableActionMap(self, "InfobarEPGActions",
180 "showEventInfo": (self.showEventInformation, _("show event details")),
183 self["actions"] = MoviePlayerActionMap(self, ["DirectionActions"],
185 "right": self.rightDown,
186 "rightRepeated": self.doNothing,
187 "rightUp": self.rightUp,
188 "left": self.leftDown,
189 "leftRepeated": self.doNothing,
190 "leftUp": self.leftUp,
193 "upRepeated": self.up,
194 "upUp": self.doNothing,
196 "downRepeated": self.down,
197 "downUp": self.doNothing,
200 InfoBarSeek.__init__(self, actionmap = "MediaPlayerSeekActions")
202 self.onClose.append(self.delMPTimer)
203 self.onClose.append(self.__onClose)
205 self.righttimer = False
206 self.rightKeyTimer = eTimer()
207 self.rightKeyTimer.callback.append(self.rightTimerFire)
209 self.lefttimer = False
210 self.leftKeyTimer = eTimer()
211 self.leftKeyTimer.callback.append(self.leftTimerFire)
213 self.currList = "filelist"
214 self.isAudioCD = False
215 self.AudioCD_albuminfo = {}
216 self.cdAudioTrackFiles = []
217 self.onShown.append(self.applySettings)
219 self.playlistIOInternal = PlaylistIOInternal()
220 list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
223 self.playlist.addFile(x.ref)
224 self.playlist.updateList()
226 self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
228 iPlayableService.evUpdatedInfo: self.__evUpdatedInfo,
229 iPlayableService.evUser+10: self.__evAudioDecodeError,
230 iPlayableService.evUser+11: self.__evVideoDecodeError,
231 iPlayableService.evUser+12: self.__evPluginError,
232 iPlayableService.evUser+13: self["coverArt"].embeddedCoverArt
238 def createSummary(self):
239 return MediaPlayerLCDScreen
242 self.playlistIOInternal.clear()
243 for x in self.playlist.list:
244 self.playlistIOInternal.addService(ServiceReference(x[0]))
245 if self.savePlaylistOnExit:
247 self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls"))
249 print "couldn't save playlist.e2pls"
250 if config.mediaplayer.saveDirOnExit.getValue():
251 config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory())
252 config.mediaplayer.defaultDir.save()
253 # from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier
254 # hotplugNotifier.remove(self.hotplugCB)
255 del self["coverArt"].picload
258 def checkSkipShowHideLock(self):
259 self.updatedSeekState()
261 def doEofInternal(self, playing):
268 self.session.nav.playService(self.oldService)
270 def __evUpdatedInfo(self):
271 currPlay = self.session.nav.getCurrentService()
272 sTagTrackNumber = currPlay.info().getInfo(iServiceInformation.sTagTrackNumber)
273 sTagTrackCount = currPlay.info().getInfo(iServiceInformation.sTagTrackCount)
274 sTagTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle)
275 print "[__evUpdatedInfo] title %d of %d (%s)" % (sTagTrackNumber, sTagTrackCount, sTagTitle)
276 self.readTitleInformation()
278 def __evAudioDecodeError(self):
279 currPlay = self.session.nav.getCurrentService()
280 sTagAudioCodec = currPlay.info().getInfoString(iServiceInformation.sTagAudioCodec)
281 print "[__evAudioDecodeError] audio-codec %s can't be decoded by hardware" % (sTagAudioCodec)
282 self.session.open(MessageBox, _("This STB can't decode %s streams!") % sTagAudioCodec, type = MessageBox.TYPE_INFO,timeout = 20 )
284 def __evVideoDecodeError(self):
285 currPlay = self.session.nav.getCurrentService()
286 sTagVideoCodec = currPlay.info().getInfoString(iServiceInformation.sTagVideoCodec)
287 print "[__evVideoDecodeError] video-codec %s can't be decoded by hardware" % (sTagVideoCodec)
288 self.session.open(MessageBox, _("This STB can't decode %s streams!") % sTagVideoCodec, type = MessageBox.TYPE_INFO,timeout = 20 )
290 def __evPluginError(self):
291 currPlay = self.session.nav.getCurrentService()
292 message = currPlay.info().getInfoString(iServiceInformation.sUser+12)
293 print "[__evPluginError]" , message
294 self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 )
296 def delMPTimer(self):
297 del self.rightKeyTimer
298 del self.leftKeyTimer
300 def readTitleInformation(self):
301 currPlay = self.session.nav.getCurrentService()
302 if currPlay is not None:
303 sTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle)
304 sAlbum = currPlay.info().getInfoString(iServiceInformation.sTagAlbum)
305 sGenre = currPlay.info().getInfoString(iServiceInformation.sTagGenre)
306 sArtist = currPlay.info().getInfoString(iServiceInformation.sTagArtist)
307 sYear = currPlay.info().getInfoString(iServiceInformation.sTagDate)
310 if not self.isAudioCD:
311 sTitle = currPlay.info().getName().split('/')[-1]
313 sTitle = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getName()
315 if self.AudioCD_albuminfo:
316 if sAlbum == "" and "title" in self.AudioCD_albuminfo:
317 sAlbum = self.AudioCD_albuminfo["title"]
318 if sGenre == "" and "genre" in self.AudioCD_albuminfo:
319 sGenre = self.AudioCD_albuminfo["genre"]
320 if sArtist == "" and "artist" in self.AudioCD_albuminfo:
321 sArtist = self.AudioCD_albuminfo["artist"]
322 if "year" in self.AudioCD_albuminfo:
323 sYear = self.AudioCD_albuminfo["year"]
325 self.updateMusicInformation( sArtist, sTitle, sAlbum, sYear, sGenre, clear = True )
327 self.updateMusicInformation()
329 def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False):
330 self.updateSingleMusicInformation("artist", artist, clear)
331 self.updateSingleMusicInformation("title", title, clear)
332 self.updateSingleMusicInformation("album", album, clear)
333 self.updateSingleMusicInformation("year", year, clear)
334 self.updateSingleMusicInformation("genre", genre, clear)
336 def updateSingleMusicInformation(self, name, info, clear):
337 if info != "" or clear:
338 if self[name].getText() != info:
339 self[name].setText(info)
342 self.lefttimer = True
343 self.leftKeyTimer.start(1000)
346 self.righttimer = True
347 self.rightKeyTimer.start(1000)
351 self.leftKeyTimer.stop()
352 self.lefttimer = False
353 self[self.currList].pageUp()
354 self.updateCurrentInfo()
358 self.rightKeyTimer.stop()
359 self.righttimer = False
360 self[self.currList].pageDown()
361 self.updateCurrentInfo()
363 def leftTimerFire(self):
364 self.leftKeyTimer.stop()
365 self.lefttimer = False
366 self.switchToFileList()
368 def rightTimerFire(self):
369 self.rightKeyTimer.stop()
370 self.righttimer = False
371 self.switchToPlayList()
373 def switchToFileList(self):
374 self.currList = "filelist"
375 self.filelist.selectionEnabled(1)
376 self.playlist.selectionEnabled(0)
377 self.updateCurrentInfo()
379 def switchToPlayList(self):
380 if len(self.playlist) != 0:
381 self.currList = "playlist"
382 self.filelist.selectionEnabled(0)
383 self.playlist.selectionEnabled(1)
384 self.updateCurrentInfo()
387 self[self.currList].up()
388 self.updateCurrentInfo()
391 self[self.currList].down()
392 self.updateCurrentInfo()
394 def showAfterSeek(self):
397 def showAfterCuesheetOperation(self):
400 def hideAfterResume(self):
403 def getIdentifier(self, ref):
408 return text.split('/')[-1]
410 # FIXME: maybe this code can be optimized
411 def updateCurrentInfo(self):
413 if self.currList == "filelist":
414 idx = self.filelist.getSelectionIndex()
415 r = self.filelist.list[idx]
422 self.summaries.setText(text,1)
425 if idx < len(self.filelist.list):
426 r = self.filelist.list[idx]
430 self.summaries.setText(text,3)
432 self.summaries.setText(" ",3)
435 if idx < len(self.filelist.list):
436 r = self.filelist.list[idx]
440 self.summaries.setText(text,4)
442 self.summaries.setText(" ",4)
445 if not self.filelist.canDescent():
446 r = self.filelist.getServiceRef()
450 self["currenttext"].setText(os_path.basename(text))
452 if self.currList == "playlist":
453 t = self.playlist.getSelection()
456 #display current selected entry on LCD
457 text = self.getIdentifier(t)
458 self.summaries.setText(text,1)
459 self["currenttext"].setText(text)
460 idx = self.playlist.getSelectionIndex()
462 if idx < len(self.playlist):
463 currref = self.playlist.getServiceRefList()[idx]
464 text = self.getIdentifier(currref)
465 self.summaries.setText(text,3)
467 self.summaries.setText(" ",3)
470 if idx < len(self.playlist):
471 currref = self.playlist.getServiceRefList()[idx]
472 text = self.getIdentifier(currref)
473 self.summaries.setText(text,4)
475 self.summaries.setText(" ",4)
478 if self.currList == "filelist":
479 if self.filelist.canDescent():
480 self.filelist.descent()
481 self.updateCurrentInfo()
485 if self.currList == "playlist":
486 selection = self["playlist"].getSelection()
487 self.changeEntry(self.playlist.getSelectionIndex())
491 if len(self.cdAudioTrackFiles):
492 menu.insert(0,(_("Play Audio-CD..."), "audiocd"))
493 if self.currList == "filelist":
494 if self.filelist.canDescent():
495 menu.append((_("add directory to playlist"), "copydir"))
497 menu.append((_("add files to playlist"), "copyfiles"))
498 menu.append((_("switch to playlist"), "playlist"))
499 if config.usage.setup_level.index >= 1: # intermediate+
500 menu.append((_("delete file"), "deletefile"))
502 menu.append((_("switch to filelist"), "filelist"))
503 menu.append((_("clear playlist"), "clear"))
504 menu.append((_("Delete entry"), "deleteentry"))
505 if config.usage.setup_level.index >= 1: # intermediate+
506 menu.append((_("shuffle playlist"), "shuffle"))
507 menu.append((_("hide player"), "hide"));
508 menu.append((_("load playlist"), "loadplaylist"));
509 if config.usage.setup_level.index >= 1: # intermediate+
510 menu.append((_("save playlist"), "saveplaylist"));
511 menu.append((_("delete saved playlist"), "deleteplaylist"));
512 menu.append((_("Edit settings"), "settings"))
513 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
515 def menuCallback(self, choice):
519 if choice[1] == "copydir":
520 self.copyDirectory(self.filelist.getSelection()[0])
521 elif choice[1] == "copyfiles":
523 self.playlist.clear()
524 self.isAudioCD = False
525 self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False)
526 self.playServiceRefEntry(self.filelist.getServiceRef())
527 elif choice[1] == "playlist":
528 self.switchToPlayList()
529 elif choice[1] == "filelist":
530 self.switchToFileList()
531 elif choice[1] == "deleteentry":
532 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
535 elif choice[1] == "clear":
536 self.clear_playlist()
537 elif choice[1] == "hide":
539 elif choice[1] == "saveplaylist":
541 elif choice[1] == "loadplaylist":
543 elif choice[1] == "deleteplaylist":
544 self.delete_saved_playlist()
545 elif choice[1] == "shuffle":
546 self.playlist.PlayListShuffle()
547 elif choice[1] == "deletefile":
549 elif choice[1] == "settings":
550 self.session.openWithCallback(self.applySettings, MediaPlayerSettings, self)
551 elif choice[1] == "audiocd":
554 def playAudioCD(self):
555 from enigma import eServiceReference
556 from Plugins.Extensions.CDInfo.plugin import Query
558 if len(self.cdAudioTrackFiles):
559 self.playlist.clear()
560 self.savePlaylistOnExit = False
561 self.isAudioCD = True
562 for file in self.cdAudioTrackFiles:
563 ref = eServiceReference(4097, 0, file)
564 self.playlist.addFile(ref)
568 self.switchToPlayList()
570 def applySettings(self):
571 self.savePlaylistOnExit = config.mediaplayer.savePlaylistOnExit.getValue()
572 if config.mediaplayer.repeat.getValue() == True:
573 self["repeat"].setPixmapNum(1)
575 self["repeat"].setPixmapNum(0)
577 def showEventInformation(self):
578 from Screens.EventView import EventViewSimple
579 from ServiceReference import ServiceReference
580 evt = self[self.currList].getCurrentEvent()
582 self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
584 # also works on filelist (?)
585 def getCurrent(self):
586 return self["playlist"].getCurrent()
588 def deletePlaylistEntry(self):
589 if self.currList == "playlist":
590 if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex():
594 def skip_listbegin(self):
595 if self.currList == "filelist":
596 self.filelist.moveToIndex(0)
598 self.playlist.moveToIndex(0)
599 self.updateCurrentInfo()
601 def skip_listend(self):
602 if self.currList == "filelist":
603 idx = len(self.filelist.list)
604 self.filelist.moveToIndex(idx - 1)
606 self.playlist.moveToIndex(len(self.playlist)-1)
607 self.updateCurrentInfo()
609 def save_playlist(self):
610 self.session.openWithCallback(self.save_playlist2,InputBox, title=_("Please enter filename (empty = use current date)"),windowTitle = _("Save Playlist"))
612 def save_playlist2(self, name):
616 name = strftime("%y%m%d_%H%M%S")
618 self.playlistIOInternal.clear()
619 for x in self.playlist.list:
620 self.playlistIOInternal.addService(ServiceReference(x[0]))
621 self.playlistIOInternal.save(resolveFilename(SCOPE_PLAYLIST) + name)
623 def load_playlist(self):
625 playlistdir = resolveFilename(SCOPE_PLAYLIST)
627 for i in os_listdir(playlistdir):
628 listpath.append((i,playlistdir + i))
630 print "Error while scanning subdirs ",e
631 self.session.openWithCallback(self.PlaylistSelected, ChoiceBox, title=_("Please select a playlist..."), list = listpath)
633 def PlaylistSelected(self,path):
635 self.clear_playlist()
636 extension = path[0].rsplit('.',1)[-1]
637 if self.playlistparsers.has_key(extension):
638 playlist = self.playlistparsers[extension]()
639 list = playlist.open(path[1])
641 self.playlist.addFile(x.ref)
642 self.playlist.updateList()
644 def delete_saved_playlist(self):
646 playlistdir = resolveFilename(SCOPE_PLAYLIST)
648 for i in os_listdir(playlistdir):
649 listpath.append((i,playlistdir + i))
651 print "Error while scanning subdirs ",e
652 self.session.openWithCallback(self.DeletePlaylistSelected, ChoiceBox, title=_("Please select a playlist to delete..."), list = listpath)
654 def DeletePlaylistSelected(self,path):
656 self.delname = path[1]
657 self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (path[1]))
659 def deleteConfirmed(self, confirmed):
662 os_remove(self.delname)
664 print "delete failed:", e
665 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
667 def clear_playlist(self):
668 self.isAudioCD = False
670 self.playlist.clear()
671 self.switchToFileList()
673 def copyDirectory(self, directory, recursive = True):
674 print "copyDirectory", directory
676 print "refusing to operate on /"
678 filelist = FileList(directory, useServiceRef = True, showMountpoints = False, isTop = True)
680 for x in filelist.getFileList():
681 if x[0][1] == True: #isDir
683 if x[0][0] != directory:
684 self.copyDirectory(x[0][0])
685 elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097:
686 self.playlist.addFile(x[0][0])
687 self.playlist.updateList()
689 def deleteFile(self):
690 if self.currList == "filelist":
691 self.service = self.filelist.getServiceRef()
693 self.service = self.playlist.getSelection()
694 if self.service is None:
696 if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None:
697 if self.service == self.session.nav.getCurrentlyPlayingServiceReference():
700 serviceHandler = eServiceCenter.getInstance()
701 offline = serviceHandler.offlineOperations(self.service)
702 info = serviceHandler.info(self.service)
703 name = info and info.getName(self.service)
705 if offline is not None:
707 if not offline.deleteFromDisk(1):
710 self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name))
712 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
714 def deleteConfirmed_offline(self, confirmed):
716 serviceHandler = eServiceCenter.getInstance()
717 offline = serviceHandler.offlineOperations(self.service)
719 if offline is not None:
721 if not offline.deleteFromDisk(0):
724 self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
726 self.removeListEntry()
728 def removeListEntry(self):
729 currdir = self.filelist.getCurrentDirectory()
730 self.filelist.changeDir(currdir)
735 if len(self.playlist) > 0:
736 for x in self.playlist.list:
737 if self.service == x[0]:
738 self.playlist.deleteFile(index)
742 self.playlist.updateList()
743 if self.currList == "playlist":
744 if len(self.playlist) == 0:
745 self.switchToFileList()
748 if self.filelist.getServiceRef().type == 4098: # playlist
749 ServiceRef = self.filelist.getServiceRef()
750 extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:]
751 if self.playlistparsers.has_key(extension):
752 playlist = self.playlistparsers[extension]()
753 list = playlist.open(ServiceRef.getPath())
755 self.playlist.addFile(x.ref)
756 self.playlist.updateList()
758 self.playlist.addFile(self.filelist.getServiceRef())
759 self.playlist.updateList()
760 if len(self.playlist) == 1:
763 def addPlaylistParser(self, parser, extension):
764 self.playlistparsers[extension] = parser
767 next = self.playlist.getCurrentIndex() + 1
768 if next < len(self.playlist):
769 self.changeEntry(next)
770 elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ):
774 def nextMarkOrEntry(self):
775 if not self.jumpPreviousNextMark(lambda x: x):
776 next = self.playlist.getCurrentIndex() + 1
777 if next < len(self.playlist):
778 self.changeEntry(next)
782 def previousMarkOrEntry(self):
783 if not self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True):
784 next = self.playlist.getCurrentIndex() - 1
786 self.changeEntry(next)
788 def deleteEntry(self):
789 self.playlist.deleteFile(self.playlist.getSelectionIndex())
790 self.playlist.updateList()
791 if len(self.playlist) == 0:
792 self.switchToFileList()
794 def changeEntry(self, index):
795 self.playlist.setCurrentPlaying(index)
798 def playServiceRefEntry(self, serviceref):
799 serviceRefList = self.playlist.getServiceRefList()
800 for count in range(len(serviceRefList)):
801 if serviceRefList[count] == serviceref:
802 self.changeEntry(count)
805 def xplayEntry(self):
806 if self.currList == "playlist":
810 self.playlist.clear()
811 self.isAudioCD = False
812 sel = self.filelist.getSelection()
814 if sel[1]: # can descent
815 # add directory to playlist
816 self.copyDirectory(sel[0])
818 # add files to playlist
819 self.copyDirectory(os_path.dirname(sel[0].getPath()) + "/", recursive = False)
820 if len(self.playlist) > 0:
824 if len(self.playlist.getServiceRefList()):
825 audio_extensions = (".mp2", ".mp3", ".wav", ".ogg", ".flac", ".m4a", ".dts")
826 needsInfoUpdate = False
827 currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]
828 if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference():
829 self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()])
830 info = eServiceCenter.getInstance().info(currref)
831 description = info and info.getInfoString(currref, iServiceInformation.sDescription) or ""
832 self["title"].setText(description)
833 # display just playing musik on LCD
834 idx = self.playlist.getCurrentIndex()
835 currref = self.playlist.getServiceRefList()[idx]
836 text = self.getIdentifier(currref)
840 nameext = os.path.splitext(text)
842 except: ext = text[-4:].lower()
844 # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead
845 if ext not in audio_extensions and not self.isAudioCD:
848 needsInfoUpdate = True
849 self.summaries.setText(text,1)
851 # get the next two entries
853 if idx < len(self.playlist):
854 currref = self.playlist.getServiceRefList()[idx]
855 text = self.getIdentifier(currref)
856 self.summaries.setText(text,3)
858 self.summaries.setText(" ",3)
861 if idx < len(self.playlist):
862 currref = self.playlist.getServiceRefList()[idx]
863 text = self.getIdentifier(currref)
864 self.summaries.setText(text,4)
866 self.summaries.setText(" ",4)
868 idx = self.playlist.getCurrentIndex()
869 currref = self.playlist.getServiceRefList()[idx]
870 text = currref.getPath()
871 ext = text[-4:].lower()
872 if ext not in audio_extensions and not self.isAudioCD:
875 needsInfoUpdate = True
877 self.unPauseService()
878 if needsInfoUpdate == True:
879 path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath()
880 self["coverArt"].updateCoverArt(path)
882 self["coverArt"].showDefaultCover()
883 self.readTitleInformation()
885 def updatedSeekState(self):
886 if self.seekstate == self.SEEK_STATE_PAUSE:
887 self.playlist.pauseFile()
888 elif self.seekstate == self.SEEK_STATE_PLAY:
889 self.playlist.playFile()
890 elif self.isStateForward(self.seekstate):
891 self.playlist.forwardFile()
892 elif self.isStateBackward(self.seekstate):
893 self.playlist.rewindFile()
895 def pauseEntry(self):
897 if self.seekstate == self.SEEK_STATE_PAUSE:
903 self.playlist.stopFile()
904 self.session.nav.playService(None)
905 self.updateMusicInformation(clear=True)
908 def unPauseService(self):
909 self.setSeekState(self.SEEK_STATE_PLAY)
911 def subtitleSelection(self):
912 from Screens.AudioSelection import SubtitleSelection
913 self.session.open(SubtitleSelection, self)
915 def hotplugCB(self, dev, media_state):
916 if dev == harddiskmanager.getCD():
917 if media_state == "1":
918 from Components.Scanner import scanDevice
919 devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD())
920 self.cdAudioTrackFiles = []
921 res = scanDevice(devpath)
922 list = [ (r.description, r, res[r], self.session) for r in res ]
924 (desc, scanner, files, session) = list[0]
926 if file.mimetype == "audio/x-cda":
927 self.cdAudioTrackFiles.append(file.path)
929 self.cdAudioTrackFiles = []
931 self.clear_playlist()
933 class MediaPlayerLCDScreen(Screen):
935 """<screen name="MediaPlayerLCDScreen" position="0,0" size="132,64" id="1">
936 <widget name="text1" position="4,0" size="132,35" font="Regular;16"/>
937 <widget name="text3" position="4,36" size="132,14" font="Regular;10"/>
938 <widget name="text4" position="4,49" size="132,14" font="Regular;10"/>
940 """<screen name="MediaPlayerLCDScreen" position="0,0" size="96,64" id="2">
941 <widget name="text1" position="0,0" size="96,35" font="Regular;14"/>
942 <widget name="text3" position="0,36" size="96,14" font="Regular;10"/>
943 <widget name="text4" position="0,49" size="96,14" font="Regular;10"/>
946 def __init__(self, session, parent):
947 Screen.__init__(self, session)
948 self["text1"] = Label("Mediaplayer")
949 self["text3"] = Label("")
950 self["text4"] = Label("")
952 def setText(self, text, line):
954 if text[-4:] == ".mp3":
957 text = text + textleer*10
959 self["text1"].setText(text)
961 self["text3"].setText(text)
963 self["text4"].setText(text)
965 def main(session, **kwargs):
966 session.open(MediaPlayer)
968 def menu(menuid, **kwargs):
969 if menuid == "mainmenu":
970 return [(_("Media player"), main, "media_player", 45)]
973 def filescan_open(list, session, **kwargs):
974 from enigma import eServiceReference
976 mp = session.open(MediaPlayer)
978 mp.savePlaylistOnExit = False
981 if file.mimetype == "video/MP2T":
985 ref = eServiceReference(stype, 0, file.path)
986 mp.playlist.addFile(ref)
989 mp.switchToPlayList()
991 def audioCD_open(list, session, **kwargs):
992 from enigma import eServiceReference
994 mp = session.open(MediaPlayer)
995 mp.cdAudioTrackFiles = []
997 mp.cdAudioTrackFiles.append(file.path)
1000 def filescan(**kwargs):
1001 from Components.Scanner import Scanner, ScanPath
1003 Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"],
1006 ScanPath(path = "", with_subdirs = False),
1009 description = _("View Movies..."),
1010 openfnc = filescan_open,
1012 Scanner(mimetypes = ["video/x-vcd"],
1015 ScanPath(path = "mpegav", with_subdirs = False),
1016 ScanPath(path = "MPEGAV", with_subdirs = False),
1019 description = _("View Video CD..."),
1020 openfnc = filescan_open,
1022 Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"],
1025 ScanPath(path = "", with_subdirs = False),
1028 description = _("Play Music..."),
1029 openfnc = filescan_open,
1032 from Plugins.Extensions.CDInfo.plugin import Query
1034 Scanner(mimetypes = ["audio/x-cda"],
1037 ScanPath(path = "", with_subdirs = False),
1040 description = _("Play Audio-CD..."),
1041 openfnc = audioCD_open,
1047 from Plugins.Plugin import PluginDescriptor
1048 def Plugins(**kwargs):
1050 PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, needsRestart = False, fnc = menu),
1051 PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, needsRestart = False, fnc = filescan)