from os import path as os_path, remove as os_remove, listdir as os_listdir from time import strftime from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation, ePicLoad from ServiceReference import ServiceReference from Screens.Screen import Screen from Screens.HelpMenu import HelpableScreen from Screens.MessageBox import MessageBox from Screens.InputBox import InputBox from Screens.ChoiceBox import ChoiceBox from Screens.InfoBarGenerics import InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport from Components.ActionMap import NumberActionMap, HelpableActionMap from Components.Label import Label from Components.Pixmap import Pixmap,MultiPixmap from Components.FileList import FileList from Components.MediaPlayer import PlayList from Components.ServicePosition import ServicePositionGauge from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase from Components.Playlist import PlaylistIOInternal, PlaylistIOM3U, PlaylistIOPLS from Components.AVSwitch import AVSwitch from Components.Harddisk import harddiskmanager from Components.config import config from Tools.Directories import fileExists, pathExists, resolveFilename, SCOPE_CONFIG, SCOPE_PLAYLIST, SCOPE_SKIN_IMAGE from settings import MediaPlayerSettings import random class MyPlayList(PlayList): def __init__(self): PlayList.__init__(self) def PlayListShuffle(self): random.shuffle(self.list) self.l.setList(self.list) self.currPlaying = -1 self.oldCurrPlaying = -1 class MediaPixmap(Pixmap): def __init__(self): Pixmap.__init__(self) self.coverArtFileName = "" self.picload = ePicLoad() self.picload.PictureData.get().append(self.paintCoverArtPixmapCB) self.coverFileNames = ["folder.png", "folder.jpg"] def applySkin(self, desktop, screen): from Tools.LoadPixmap import LoadPixmap noCoverFile = None if self.skinAttributes is not None: for (attrib, value) in self.skinAttributes: if attrib == "pixmap": noCoverFile = value break if noCoverFile is None: noCoverFile = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png") self.noCoverPixmap = LoadPixmap(noCoverFile) return Pixmap.applySkin(self, desktop, screen) def onShow(self): Pixmap.onShow(self) sc = AVSwitch().getFramebufferScale() #0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB) self.picload.setPara((self.instance.size().width(), self.instance.size().height(), sc[0], sc[1], False, 1, "#00000000")) def paintCoverArtPixmapCB(self, picInfo=None): ptr = self.picload.getData() if ptr != None: self.instance.setPixmap(ptr.__deref__()) def updateCoverArt(self, path): while not path.endswith("/"): path = path[:-1] new_coverArtFileName = None for filename in self.coverFileNames: if fileExists(path + filename): new_coverArtFileName = path + filename if self.coverArtFileName != new_coverArtFileName: self.coverArtFileName = new_coverArtFileName if new_coverArtFileName: self.picload.startDecode(self.coverArtFileName) else: self.showDefaultCover() def showDefaultCover(self): self.instance.setPixmap(self.noCoverPixmap) def embeddedCoverArt(self): print "[embeddedCoverArt] found" self.coverArtFileName = "/tmp/.id3coverart" self.picload.startDecode(self.coverArtFileName) class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications, InfoBarSubtitleSupport, HelpableScreen): ALLOW_SUSPEND = True ENABLE_RESUME_SUPPORT = True def __init__(self, session, args = None): Screen.__init__(self, session) InfoBarAudioSelection.__init__(self) InfoBarCueSheetSupport.__init__(self, actionmap = "MediaPlayerCueSheetActions") InfoBarNotifications.__init__(self) InfoBarBase.__init__(self) InfoBarSubtitleSupport.__init__(self) HelpableScreen.__init__(self) self.summary = None self.oldService = self.session.nav.getCurrentlyPlayingServiceReference() self.session.nav.stopService() self.playlistparsers = {} self.addPlaylistParser(PlaylistIOM3U, "m3u") self.addPlaylistParser(PlaylistIOPLS, "pls") self.addPlaylistParser(PlaylistIOInternal, "e2pls") # 'None' is magic to start at the list of mountpoints defaultDir = config.mediaplayer.defaultDir.getValue() 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)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls") self["filelist"] = self.filelist self.playlist = MyPlayList() self.is_closing = False self.delname = "" self["playlist"] = self.playlist self["PositionGauge"] = ServicePositionGauge(self.session.nav) self["currenttext"] = Label("") self["artisttext"] = Label(_("Artist")+':') self["artist"] = Label("") self["titletext"] = Label(_("Title")+':') self["title"] = Label("") self["albumtext"] = Label(_("Album")+':') self["album"] = Label("") self["yeartext"] = Label(_("Year")+':') self["year"] = Label("") self["genretext"] = Label(_("Genre")+':') self["genre"] = Label("") self["coverArt"] = MediaPixmap() self["repeat"] = MultiPixmap() self.seek_target = None from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier hotplugNotifier.append(self.hotplugCB) class MoviePlayerActionMap(NumberActionMap): def __init__(self, player, contexts = [ ], actions = { }, prio=0): NumberActionMap.__init__(self, contexts, actions, prio) self.player = player def action(self, contexts, action): self.player.show() return NumberActionMap.action(self, contexts, action) self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", { "ok": (self.ok, _("add file to playlist")), "cancel": (self.exit, _("exit mediaplayer")), }, -2) self["MediaPlayerActions"] = HelpableActionMap(self, "MediaPlayerActions", { "play": (self.xplayEntry, _("play entry")), "pause": (self.pauseEntry, _("pause")), "stop": (self.stopEntry, _("stop entry")), "previous": (self.previousMarkOrEntry, _("play from previous mark or playlist entry")), "next": (self.nextMarkOrEntry, _("play from next mark or playlist entry")), "menu": (self.showMenu, _("menu")), "skipListbegin": (self.skip_listbegin, _("jump to listbegin")), "skipListend": (self.skip_listend, _("jump to listend")), "prevBouquet": (self.switchToPlayList, _("switch to playlist")), "nextBouquet": (self.switchToFileList, _("switch to filelist")), "delete": (self.deletePlaylistEntry, _("delete playlist entry")), "shift_stop": (self.clear_playlist, _("clear playlist")), "shift_record": (self.playlist.PlayListShuffle, _("shuffle playlist")), "subtitles": (self.subtitleSelection, _("Subtitle selection")), }, -2) self["InfobarEPGActions"] = HelpableActionMap(self, "InfobarEPGActions", { "showEventInfo": (self.showEventInformation, _("show event details")), }) self["actions"] = MoviePlayerActionMap(self, ["DirectionActions"], { "right": self.rightDown, "rightRepeated": self.doNothing, "rightUp": self.rightUp, "left": self.leftDown, "leftRepeated": self.doNothing, "leftUp": self.leftUp, "up": self.up, "upRepeated": self.up, "upUp": self.doNothing, "down": self.down, "downRepeated": self.down, "downUp": self.doNothing, }, -2) InfoBarSeek.__init__(self, actionmap = "MediaPlayerSeekActions") self.onClose.append(self.delMPTimer) self.onClose.append(self.__onClose) self.righttimer = False self.rightKeyTimer = eTimer() self.rightKeyTimer.callback.append(self.rightTimerFire) self.lefttimer = False self.leftKeyTimer = eTimer() self.leftKeyTimer.callback.append(self.leftTimerFire) self.currList = "filelist" self.isAudioCD = False self.AudioCD_albuminfo = {} self.cdAudioTrackFiles = [] self.onShown.append(self.applySettings) self.playlistIOInternal = PlaylistIOInternal() list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls")) if list: for x in list: self.playlist.addFile(x.ref) self.playlist.updateList() self.__event_tracker = ServiceEventTracker(screen=self, eventmap= { iPlayableService.evUpdatedInfo: self.__evUpdatedInfo, iPlayableService.evUser+10: self.__evAudioDecodeError, iPlayableService.evUser+11: self.__evVideoDecodeError, iPlayableService.evUser+12: self.__evPluginError, iPlayableService.evUser+13: self["coverArt"].embeddedCoverArt }) def doNothing(self): pass def createSummary(self): return MediaPlayerLCDScreen def exit(self): self.playlistIOInternal.clear() for x in self.playlist.list: self.playlistIOInternal.addService(ServiceReference(x[0])) if self.savePlaylistOnExit: try: self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls")) except IOError: print "couldn't save playlist.e2pls" if config.mediaplayer.saveDirOnExit.getValue(): config.mediaplayer.defaultDir.setValue(self.filelist.getCurrentDirectory()) config.mediaplayer.defaultDir.save() from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier hotplugNotifier.remove(self.hotplugCB) del self["coverArt"].picload self.close() def checkSkipShowHideLock(self): self.updatedSeekState() def doEofInternal(self, playing): if playing: self.nextEntry() else: self.show() def __onClose(self): self.session.nav.playService(self.oldService) def __evUpdatedInfo(self): currPlay = self.session.nav.getCurrentService() sTagTrackNumber = currPlay.info().getInfo(iServiceInformation.sTagTrackNumber) sTagTrackCount = currPlay.info().getInfo(iServiceInformation.sTagTrackCount) sTagTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle) print "[__evUpdatedInfo] title %d of %d (%s)" % (sTagTrackNumber, sTagTrackCount, sTagTitle) self.readTitleInformation() def __evAudioDecodeError(self): currPlay = self.session.nav.getCurrentService() sTagAudioCodec = currPlay.info().getInfoString(iServiceInformation.sTagAudioCodec) print "[__evAudioDecodeError] audio-codec %s can't be decoded by hardware" % (sTagAudioCodec) self.session.open(MessageBox, _("This Dreambox can't decode %s streams!") % sTagAudioCodec, type = MessageBox.TYPE_INFO,timeout = 20 ) def __evVideoDecodeError(self): currPlay = self.session.nav.getCurrentService() sTagVideoCodec = currPlay.info().getInfoString(iServiceInformation.sTagVideoCodec) print "[__evVideoDecodeError] video-codec %s can't be decoded by hardware" % (sTagVideoCodec) self.session.open(MessageBox, _("This Dreambox can't decode %s streams!") % sTagVideoCodec, type = MessageBox.TYPE_INFO,timeout = 20 ) def __evPluginError(self): currPlay = self.session.nav.getCurrentService() message = currPlay.info().getInfoString(iServiceInformation.sUser+12) print "[__evPluginError]" , message self.session.open(MessageBox, message, type = MessageBox.TYPE_INFO,timeout = 20 ) def delMPTimer(self): del self.rightKeyTimer del self.leftKeyTimer def readTitleInformation(self): currPlay = self.session.nav.getCurrentService() if currPlay is not None: sTitle = currPlay.info().getInfoString(iServiceInformation.sTagTitle) sAlbum = currPlay.info().getInfoString(iServiceInformation.sTagAlbum) sGenre = currPlay.info().getInfoString(iServiceInformation.sTagGenre) sArtist = currPlay.info().getInfoString(iServiceInformation.sTagArtist) sYear = currPlay.info().getInfoString(iServiceInformation.sTagDate) if sTitle == "": if not self.isAudioCD: sTitle = currPlay.info().getName().split('/')[-1] else: sTitle = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getName() if self.AudioCD_albuminfo: if sAlbum == "" and "title" in self.AudioCD_albuminfo: sAlbum = self.AudioCD_albuminfo["title"] if sGenre == "" and "genre" in self.AudioCD_albuminfo: sGenre = self.AudioCD_albuminfo["genre"] if sArtist == "" and "artist" in self.AudioCD_albuminfo: sArtist = self.AudioCD_albuminfo["artist"] if "year" in self.AudioCD_albuminfo: sYear = self.AudioCD_albuminfo["year"] self.updateMusicInformation( sArtist, sTitle, sAlbum, sYear, sGenre, clear = True ) else: self.updateMusicInformation() def updateMusicInformation(self, artist = "", title = "", album = "", year = "", genre = "", clear = False): self.updateSingleMusicInformation("artist", artist, clear) self.updateSingleMusicInformation("title", title, clear) self.updateSingleMusicInformation("album", album, clear) self.updateSingleMusicInformation("year", year, clear) self.updateSingleMusicInformation("genre", genre, clear) def updateSingleMusicInformation(self, name, info, clear): if info != "" or clear: if self[name].getText() != info: self[name].setText(info) def leftDown(self): self.lefttimer = True self.leftKeyTimer.start(1000) def rightDown(self): self.righttimer = True self.rightKeyTimer.start(1000) def leftUp(self): if self.lefttimer: self.leftKeyTimer.stop() self.lefttimer = False self[self.currList].pageUp() self.updateCurrentInfo() def rightUp(self): if self.righttimer: self.rightKeyTimer.stop() self.righttimer = False self[self.currList].pageDown() self.updateCurrentInfo() def leftTimerFire(self): self.leftKeyTimer.stop() self.lefttimer = False self.switchToFileList() def rightTimerFire(self): self.rightKeyTimer.stop() self.righttimer = False self.switchToPlayList() def switchToFileList(self): self.currList = "filelist" self.filelist.selectionEnabled(1) self.playlist.selectionEnabled(0) self.updateCurrentInfo() def switchToPlayList(self): if len(self.playlist) != 0: self.currList = "playlist" self.filelist.selectionEnabled(0) self.playlist.selectionEnabled(1) self.updateCurrentInfo() def up(self): self[self.currList].up() self.updateCurrentInfo() def down(self): self[self.currList].down() self.updateCurrentInfo() def showAfterSeek(self): pass def showAfterCuesheetOperation(self): self.show() def hideAfterResume(self): self.hide() def getIdentifier(self, ref): if self.isAudioCD: return ref.getName() else: text = ref.getPath() return text.split('/')[-1] # FIXME: maybe this code can be optimized def updateCurrentInfo(self): text = "" if self.currList == "filelist": idx = self.filelist.getSelectionIndex() r = self.filelist.list[idx] text = r[1][7] if r[0][1] == True: if len(text) < 2: text += " " if text[:2] != "..": text = "/" + text self.summaries.setText(text,1) idx += 1 if idx < len(self.filelist.list): r = self.filelist.list[idx] text = r[1][7] if r[0][1] == True: text = "/" + text self.summaries.setText(text,3) else: self.summaries.setText(" ",3) idx += 1 if idx < len(self.filelist.list): r = self.filelist.list[idx] text = r[1][7] if r[0][1] == True: text = "/" + text self.summaries.setText(text,4) else: self.summaries.setText(" ",4) text = "" if not self.filelist.canDescent(): r = self.filelist.getServiceRef() if r is None: return text = r.getPath() self["currenttext"].setText(os_path.basename(text)) if self.currList == "playlist": t = self.playlist.getSelection() if t is None: return #display current selected entry on LCD text = self.getIdentifier(t) self.summaries.setText(text,1) self["currenttext"].setText(text) idx = self.playlist.getSelectionIndex() idx += 1 if idx < len(self.playlist): currref = self.playlist.getServiceRefList()[idx] text = self.getIdentifier(currref) self.summaries.setText(text,3) else: self.summaries.setText(" ",3) idx += 1 if idx < len(self.playlist): currref = self.playlist.getServiceRefList()[idx] text = self.getIdentifier(currref) self.summaries.setText(text,4) else: self.summaries.setText(" ",4) def ok(self): if self.currList == "filelist": if self.filelist.canDescent(): self.filelist.descent() self.updateCurrentInfo() else: self.copyFile() if self.currList == "playlist": selection = self["playlist"].getSelection() self.changeEntry(self.playlist.getSelectionIndex()) def showMenu(self): menu = [] if len(self.cdAudioTrackFiles): menu.insert(0,(_("Play Audio-CD..."), "audiocd")) if self.currList == "filelist": if self.filelist.canDescent(): menu.append((_("add directory to playlist"), "copydir")) else: menu.append((_("add files to playlist"), "copyfiles")) menu.append((_("switch to playlist"), "playlist")) if config.usage.setup_level.index >= 1: # intermediate+ menu.append((_("delete file"), "deletefile")) else: menu.append((_("switch to filelist"), "filelist")) menu.append((_("clear playlist"), "clear")) menu.append((_("Delete entry"), "deleteentry")) if config.usage.setup_level.index >= 1: # intermediate+ menu.append((_("shuffle playlist"), "shuffle")) menu.append((_("hide player"), "hide")); menu.append((_("load playlist"), "loadplaylist")); if config.usage.setup_level.index >= 1: # intermediate+ menu.append((_("save playlist"), "saveplaylist")); menu.append((_("delete saved playlist"), "deleteplaylist")); menu.append((_("Edit settings"), "settings")) self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu) def menuCallback(self, choice): if choice is None: return if choice[1] == "copydir": self.copyDirectory(self.filelist.getSelection()[0]) elif choice[1] == "copyfiles": self.stopEntry() self.playlist.clear() self.isAudioCD = False self.copyDirectory(os_path.dirname(self.filelist.getSelection()[0].getPath()) + "/", recursive = False) self.playServiceRefEntry(self.filelist.getServiceRef()) elif choice[1] == "playlist": self.switchToPlayList() elif choice[1] == "filelist": self.switchToFileList() elif choice[1] == "deleteentry": if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex(): self.stopEntry() self.deleteEntry() elif choice[1] == "clear": self.clear_playlist() elif choice[1] == "hide": self.hide() elif choice[1] == "saveplaylist": self.save_playlist() elif choice[1] == "loadplaylist": self.load_playlist() elif choice[1] == "deleteplaylist": self.delete_saved_playlist() elif choice[1] == "shuffle": self.playlist.PlayListShuffle() elif choice[1] == "deletefile": self.deleteFile() elif choice[1] == "settings": self.session.openWithCallback(self.applySettings, MediaPlayerSettings, self) elif choice[1] == "audiocd": self.playAudioCD() def playAudioCD(self): from enigma import eServiceReference from Plugins.Extensions.CDInfo.plugin import Query if len(self.cdAudioTrackFiles): self.playlist.clear() self.savePlaylistOnExit = False self.isAudioCD = True for file in self.cdAudioTrackFiles: ref = eServiceReference(4097, 0, file) self.playlist.addFile(ref) cdinfo = Query(self) cdinfo.scan() self.changeEntry(0) self.switchToPlayList() def applySettings(self): self.savePlaylistOnExit = config.mediaplayer.savePlaylistOnExit.getValue() if config.mediaplayer.repeat.getValue() == True: self["repeat"].setPixmapNum(1) else: self["repeat"].setPixmapNum(0) def showEventInformation(self): from Screens.EventView import EventViewSimple from ServiceReference import ServiceReference evt = self[self.currList].getCurrentEvent() if evt: self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent())) # also works on filelist (?) def getCurrent(self): return self["playlist"].getCurrent() def deletePlaylistEntry(self): if self.currList == "playlist": if self.playlist.getSelectionIndex() == self.playlist.getCurrentIndex(): self.stopEntry() self.deleteEntry() def skip_listbegin(self): if self.currList == "filelist": self.filelist.moveToIndex(0) else: self.playlist.moveToIndex(0) self.updateCurrentInfo() def skip_listend(self): if self.currList == "filelist": idx = len(self.filelist.list) self.filelist.moveToIndex(idx - 1) else: self.playlist.moveToIndex(len(self.playlist)-1) self.updateCurrentInfo() def save_playlist(self): self.session.openWithCallback(self.save_playlist2,InputBox, title=_("Please enter filename (empty = use current date)"),windowTitle = _("Save Playlist")) def save_playlist2(self, name): if name is not None: name = name.strip() if name == "": name = strftime("%y%m%d_%H%M%S") name += ".e2pls" self.playlistIOInternal.clear() for x in self.playlist.list: self.playlistIOInternal.addService(ServiceReference(x[0])) self.playlistIOInternal.save(resolveFilename(SCOPE_PLAYLIST) + name) def load_playlist(self): listpath = [] playlistdir = resolveFilename(SCOPE_PLAYLIST) try: for i in os_listdir(playlistdir): listpath.append((i,playlistdir + i)) except IOError,e: print "Error while scanning subdirs ",e self.session.openWithCallback(self.PlaylistSelected, ChoiceBox, title=_("Please select a playlist..."), list = listpath) def PlaylistSelected(self,path): if path is not None: self.clear_playlist() extension = path[0].rsplit('.',1)[-1] if self.playlistparsers.has_key(extension): playlist = self.playlistparsers[extension]() list = playlist.open(path[1]) for x in list: self.playlist.addFile(x.ref) self.playlist.updateList() def delete_saved_playlist(self): listpath = [] playlistdir = resolveFilename(SCOPE_PLAYLIST) try: for i in os_listdir(playlistdir): listpath.append((i,playlistdir + i)) except IOError,e: print "Error while scanning subdirs ",e self.session.openWithCallback(self.DeletePlaylistSelected, ChoiceBox, title=_("Please select a playlist to delete..."), list = listpath) def DeletePlaylistSelected(self,path): if path is not None: self.delname = path[1] self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (path[1])) def deleteConfirmed(self, confirmed): if confirmed: try: os_remove(self.delname) except OSError,e: print "delete failed:", e self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR) def clear_playlist(self): self.isAudioCD = False self.stopEntry() self.playlist.clear() self.switchToFileList() def copyDirectory(self, directory, recursive = True): print "copyDirectory", directory if directory == '/': print "refusing to operate on /" return filelist = FileList(directory, useServiceRef = True, showMountpoints = False, isTop = True) for x in filelist.getFileList(): if x[0][1] == True: #isDir if recursive: if x[0][0] != directory: self.copyDirectory(x[0][0]) elif filelist.getServiceRef() and filelist.getServiceRef().type == 4097: self.playlist.addFile(x[0][0]) self.playlist.updateList() def deleteFile(self): if self.currList == "filelist": self.service = self.filelist.getServiceRef() else: self.service = self.playlist.getSelection() if self.service is None: return if self.service.type != 4098 and self.session.nav.getCurrentlyPlayingServiceReference() is not None: if self.service == self.session.nav.getCurrentlyPlayingServiceReference(): self.stopEntry() serviceHandler = eServiceCenter.getInstance() offline = serviceHandler.offlineOperations(self.service) info = serviceHandler.info(self.service) name = info and info.getName(self.service) result = False if offline is not None: # simulate first if not offline.deleteFromDisk(1): result = True if result == True: self.session.openWithCallback(self.deleteConfirmed_offline, MessageBox, _("Do you really want to delete %s?") % (name)) else: self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR) def deleteConfirmed_offline(self, confirmed): if confirmed: serviceHandler = eServiceCenter.getInstance() offline = serviceHandler.offlineOperations(self.service) result = False if offline is not None: # really delete! if not offline.deleteFromDisk(0): result = True if result == False: self.session.open(MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR) else: self.removeListEntry() def removeListEntry(self): currdir = self.filelist.getCurrentDirectory() self.filelist.changeDir(currdir) deleteend = False while not deleteend: index = 0 deleteend = True if len(self.playlist) > 0: for x in self.playlist.list: if self.service == x[0]: self.playlist.deleteFile(index) deleteend = False break index += 1 self.playlist.updateList() if self.currList == "playlist": if len(self.playlist) == 0: self.switchToFileList() def copyFile(self): if self.filelist.getServiceRef().type == 4098: # playlist ServiceRef = self.filelist.getServiceRef() extension = ServiceRef.getPath()[ServiceRef.getPath().rfind('.') + 1:] if self.playlistparsers.has_key(extension): playlist = self.playlistparsers[extension]() list = playlist.open(ServiceRef.getPath()) for x in list: self.playlist.addFile(x.ref) self.playlist.updateList() else: self.playlist.addFile(self.filelist.getServiceRef()) self.playlist.updateList() if len(self.playlist) == 1: self.changeEntry(0) def addPlaylistParser(self, parser, extension): self.playlistparsers[extension] = parser def nextEntry(self): next = self.playlist.getCurrentIndex() + 1 if next < len(self.playlist): self.changeEntry(next) elif ( len(self.playlist) > 0 ) and ( config.mediaplayer.repeat.getValue() == True ): self.stopEntry() self.changeEntry(0) def nextMarkOrEntry(self): if not self.jumpPreviousNextMark(lambda x: x): next = self.playlist.getCurrentIndex() + 1 if next < len(self.playlist): self.changeEntry(next) else: self.doSeek(-1) def previousMarkOrEntry(self): if not self.jumpPreviousNextMark(lambda x: -x-5*90000, start=True): next = self.playlist.getCurrentIndex() - 1 if next >= 0: self.changeEntry(next) def deleteEntry(self): self.playlist.deleteFile(self.playlist.getSelectionIndex()) self.playlist.updateList() if len(self.playlist) == 0: self.switchToFileList() def changeEntry(self, index): self.playlist.setCurrentPlaying(index) self.playEntry() def playServiceRefEntry(self, serviceref): serviceRefList = self.playlist.getServiceRefList() for count in range(len(serviceRefList)): if serviceRefList[count] == serviceref: self.changeEntry(count) break def xplayEntry(self): if self.currList == "playlist": self.playEntry() else: self.stopEntry() self.playlist.clear() self.isAudioCD = False sel = self.filelist.getSelection() if sel: if sel[1]: # can descent # add directory to playlist self.copyDirectory(sel[0]) else: # add files to playlist self.copyDirectory(os_path.dirname(sel[0].getPath()) + "/", recursive = False) if len(self.playlist) > 0: self.changeEntry(0) def playEntry(self): if len(self.playlist.getServiceRefList()): audio_extensions = (".mp2", ".mp3", ".wav", ".ogg", "flac", "m4a") needsInfoUpdate = False currref = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()] if self.session.nav.getCurrentlyPlayingServiceReference() is None or currref != self.session.nav.getCurrentlyPlayingServiceReference(): self.session.nav.playService(self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()]) info = eServiceCenter.getInstance().info(currref) description = info and info.getInfoString(currref, iServiceInformation.sDescription) or "" self["title"].setText(description) # display just playing musik on LCD idx = self.playlist.getCurrentIndex() currref = self.playlist.getServiceRefList()[idx] text = self.getIdentifier(currref) text = ">"+text ext = text[-4:].lower() # FIXME: the information if the service contains video (and we should hide our window) should com from the service instead if ext not in audio_extensions and not self.isAudioCD: self.hide() else: needsInfoUpdate = True self.summaries.setText(text,1) # get the next two entries idx += 1 if idx < len(self.playlist): currref = self.playlist.getServiceRefList()[idx] text = self.getIdentifier(currref) self.summaries.setText(text,3) else: self.summaries.setText(" ",3) idx += 1 if idx < len(self.playlist): currref = self.playlist.getServiceRefList()[idx] text = self.getIdentifier(currref) self.summaries.setText(text,4) else: self.summaries.setText(" ",4) else: idx = self.playlist.getCurrentIndex() currref = self.playlist.getServiceRefList()[idx] text = currref.getPath() ext = text[-4:].lower() if ext not in audio_extensions and not self.isAudioCD: self.hide() else: needsInfoUpdate = True self.unPauseService() if needsInfoUpdate == True: path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath() self["coverArt"].updateCoverArt(path) else: self["coverArt"].showDefaultCover() self.readTitleInformation() def updatedSeekState(self): if self.seekstate == self.SEEK_STATE_PAUSE: self.playlist.pauseFile() elif self.seekstate == self.SEEK_STATE_PLAY: self.playlist.playFile() elif self.isStateForward(self.seekstate): self.playlist.forwardFile() elif self.isStateBackward(self.seekstate): self.playlist.rewindFile() def pauseEntry(self): self.pauseService() if self.seekstate == self.SEEK_STATE_PAUSE: self.show() else: self.hide() def stopEntry(self): self.playlist.stopFile() self.session.nav.playService(None) self.updateMusicInformation(clear=True) self.show() def unPauseService(self): self.setSeekState(self.SEEK_STATE_PLAY) def subtitleSelection(self): from Screens.Subtitles import Subtitles self.session.open(Subtitles, self) def hotplugCB(self, dev, media_state): if dev == harddiskmanager.getCD(): if media_state == "1": from Components.Scanner import scanDevice devpath = harddiskmanager.getAutofsMountpoint(harddiskmanager.getCD()) self.cdAudioTrackFiles = [] res = scanDevice(devpath) list = [ (r.description, r, res[r], self.session) for r in res ] if list: (desc, scanner, files, session) = list[0] for file in files: if file.mimetype == "audio/x-cda": self.cdAudioTrackFiles.append(file.path) else: self.cdAudioTrackFiles = [] if self.isAudioCD: self.clear_playlist() class MediaPlayerLCDScreen(Screen): skin = """ """ def __init__(self, session, parent): Screen.__init__(self, session) self["text1"] = Label("Mediaplayer") self["text3"] = Label("") self["text4"] = Label("") def setText(self, text, line): if len(text) > 10: if text[-4:] == ".mp3": text = text[:-4] textleer = " " text = text + textleer*10 if line == 1: self["text1"].setText(text) elif line == 3: self["text3"].setText(text) elif line == 4: self["text4"].setText(text) def main(session, **kwargs): session.open(MediaPlayer) def menu(menuid, **kwargs): if menuid == "mainmenu": return [(_("Media player"), main, "media_player", 45)] return [] def filescan_open(list, session, **kwargs): from enigma import eServiceReference mp = session.open(MediaPlayer) mp.playlist.clear() mp.savePlaylistOnExit = False for file in list: if file.mimetype == "video/MP2T": stype = 1 else: stype = 4097 ref = eServiceReference(stype, 0, file.path) mp.playlist.addFile(ref) mp.changeEntry(0) mp.switchToPlayList() def audioCD_open(list, session, **kwargs): from enigma import eServiceReference mp = session.open(MediaPlayer) mp.cdAudioTrackFiles = [] for file in list: mp.cdAudioTrackFiles.append(file.path) mp.playAudioCD() def filescan(**kwargs): from Components.Scanner import Scanner, ScanPath mediatypes = [ Scanner(mimetypes = ["video/mpeg", "video/MP2T", "video/x-msvideo"], paths_to_scan = [ ScanPath(path = "", with_subdirs = False), ], name = "Movie", description = _("View Movies..."), openfnc = filescan_open, ), Scanner(mimetypes = ["video/x-vcd"], paths_to_scan = [ ScanPath(path = "mpegav", with_subdirs = False), ScanPath(path = "MPEGAV", with_subdirs = False), ], name = "Video CD", description = _("View Video CD..."), openfnc = filescan_open, ), Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"], paths_to_scan = [ ScanPath(path = "", with_subdirs = False), ], name = "Music", description = _("Play Music..."), openfnc = filescan_open, )] try: from Plugins.Extensions.CDInfo.plugin import Query mediatypes.append( Scanner(mimetypes = ["audio/x-cda"], paths_to_scan = [ ScanPath(path = "", with_subdirs = False), ], name = "Audio-CD", description = _("Play Audio-CD..."), openfnc = audioCD_open, )) return mediatypes except ImportError: return mediatypes from Plugins.Plugin import PluginDescriptor def Plugins(**kwargs): return [ PluginDescriptor(name = "MediaPlayer", description = "Play back media files", where = PluginDescriptor.WHERE_MENU, fnc = menu), PluginDescriptor(name = "MediaPlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan) ]