X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/e09c5aad8f93dab13e7b981a75c4d5473ea1376c..932f1ec948f517d2cf739cba5ac564fcac618aa9:/lib/python/Plugins/Extensions/MediaPlayer/plugin.py diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py old mode 100644 new mode 100755 index 981f08cb..9ae886fc --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -19,9 +19,8 @@ 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 Tools.Directories import fileExists, pathExists, resolveFilename, SCOPE_CONFIG, SCOPE_PLAYLIST, SCOPE_CURRENT_SKIN from settings import MediaPlayerSettings -from Plugins.SystemPlugins.Hotplug.plugin import hotplugNotifier import random class MyPlayList(PlayList): @@ -35,18 +34,59 @@ class MyPlayList(PlayList): 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): - self.default_pixmap = None + from Tools.LoadPixmap import LoadPixmap + noCoverFile = None if self.skinAttributes is not None: for (attrib, value) in self.skinAttributes: if attrib == "pixmap": - self.default_pixmap = value + noCoverFile = value break - if self.default_pixmap is None: - self.default_pixmap = resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/no_coverArt.png") - self.coverFileNames = ["folder.png", "folder.jpg"] + if noCoverFile is None: + noCoverFile = resolveFilename(SCOPE_CURRENT_SKIN, "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 @@ -70,11 +110,10 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB # '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|mkv|mp4|dat|flac)", useServiceRef = True, additionalExtensions = "4098:m3u 4098:e2pls 4098:pls") + 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.playlist = PlayList() self.is_closing = False self.delname = "" self["playlist"] = self.playlist @@ -83,20 +122,22 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self["currenttext"] = Label("") - self["artisttext"] = Label(_("Artist:")) + self["artisttext"] = Label(_("Artist")+':') self["artist"] = Label("") - self["titletext"] = Label(_("Title:")) + self["titletext"] = Label(_("Title")+':') self["title"] = Label("") - self["albumtext"] = Label(_("Album:")) + self["albumtext"] = Label(_("Album")+':') self["album"] = Label("") - self["yeartext"] = Label(_("Year:")) + self["yeartext"] = Label(_("Year")+':') self["year"] = Label("") - self["genretext"] = Label(_("Genre:")) + 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): @@ -108,7 +149,6 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.player.show() return NumberActionMap.action(self, contexts, action) - self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", { "ok": (self.ok, _("add file to playlist")), @@ -169,15 +209,10 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.leftKeyTimer.callback.append(self.leftTimerFire) self.currList = "filelist" - - self.coverArtFileName = "" - self.picload = ePicLoad() - self.picload.PictureData.get().append(self.paintCoverArtPixmapCB) - self.isAudioCD = False self.AudioCD_albuminfo = {} self.cdAudioTrackFiles = [] - self.applySettings() + self.onShown.append(self.applySettings) self.playlistIOInternal = PlaylistIOInternal() list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls")) @@ -189,8 +224,10 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.__event_tracker = ServiceEventTracker(screen=self, eventmap= { iPlayableService.evUpdatedInfo: self.__evUpdatedInfo, - iPlayableService.evUser+11: self.__evDecodeError, - iPlayableService.evUser+12: self.__evPluginError + iPlayableService.evUser+10: self.__evAudioDecodeError, + iPlayableService.evUser+11: self.__evVideoDecodeError, + iPlayableService.evUser+12: self.__evPluginError, + iPlayableService.evUser+13: self["coverArt"].embeddedCoverArt }) def doNothing(self): @@ -204,12 +241,16 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB for x in self.playlist.list: self.playlistIOInternal.addService(ServiceReference(x[0])) if self.savePlaylistOnExit: - self.playlistIOInternal.save(resolveFilename(SCOPE_CONFIG, "playlist.e2pls")) + 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.picload + del self["coverArt"].picload self.close() def checkSkipShowHideLock(self): @@ -226,17 +267,23 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB def __evUpdatedInfo(self): currPlay = self.session.nav.getCurrentService() - currenttitle = currPlay.info().getInfo(iServiceInformation.sCurrentTitle) - totaltitles = currPlay.info().getInfo(iServiceInformation.sTotalTitles) - sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle) - print "[__evUpdatedInfo] title %d of %d (%s)" % (currenttitle, totaltitles, sTitle) + 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 __evDecodeError(self): + def __evAudioDecodeError(self): currPlay = self.session.nav.getCurrentService() - sVideoType = currPlay.info().getInfoString(iServiceInformation.sVideoType) - print "[__evDecodeError] video-codec %s can't be decoded by hardware" % (sVideoType) - self.session.open(MessageBox, _("This Dreambox can't decode %s video streams!") % sVideoType, type = MessageBox.TYPE_INFO,timeout = 20 ) + 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() @@ -251,11 +298,11 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB def readTitleInformation(self): currPlay = self.session.nav.getCurrentService() if currPlay is not None: - sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle) - sAlbum = currPlay.info().getInfoString(iServiceInformation.sAlbum) - sGenre = currPlay.info().getInfoString(iServiceInformation.sGenre) - sArtist = currPlay.info().getInfoString(iServiceInformation.sArtist) - sYear = currPlay.info().getInfoString(iServiceInformation.sTimeCreate) + 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: @@ -289,25 +336,6 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB if self[name].getText() != info: self[name].setText(info) - def updateCoverArtPixmap(self, path): - while not path.endswith("/"): - path = path[:-1] - new_coverArtFileName = self["coverArt"].default_pixmap - for filename in self["coverArt"].coverFileNames: - if fileExists(path + filename): - new_coverArtFileName = path + filename - if self.coverArtFileName != new_coverArtFileName: - self.coverArtFileName = new_coverArtFileName - sc = AVSwitch().getFramebufferScale() - #0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB) - self.picload.setPara((self["coverArt"].instance.size().width(), self["coverArt"].instance.size().height(), sc[0], sc[1], False, 1, "#ff000000")) - self.picload.startDecode(self.coverArtFileName) - - def paintCoverArtPixmapCB(self, picInfo=None): - ptr = self.picload.getData() - if ptr != None: - self["coverArt"].instance.setPixmap(ptr.__deref__()) - def leftDown(self): self.lefttimer = True self.leftKeyTimer.start(1000) @@ -362,7 +390,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.updateCurrentInfo() def showAfterSeek(self): - self.show() + pass def showAfterCuesheetOperation(self): self.show() @@ -466,17 +494,20 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB else: menu.append((_("add files to playlist"), "copyfiles")) menu.append((_("switch to playlist"), "playlist")) - menu.append((_("delete file"), "deletefile")) + if config.usage.setup_level.index >= 1: # intermediate+ + menu.append((_("delete file"), "deletefile")) else: menu.append((_("switch to filelist"), "filelist")) - menu.append((_("shuffle playlist"), "shuffle")) - menu.append((_("Delete entry"), "deleteentry")) 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((_("save playlist"), "saveplaylist")); menu.append((_("load playlist"), "loadplaylist")); - menu.append((_("delete saved playlist"), "deleteplaylist")); - menu.append((_("Edit settings"), "settings")) + 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): @@ -639,12 +670,16 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB def copyDirectory(self, directory, recursive = True): print "copyDirectory", directory - filelist = FileList(directory, useServiceRef = True, isTop = True) + 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: - self.copyDirectory(x[0][0]) + 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() @@ -785,6 +820,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB 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(): @@ -800,7 +836,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB 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 [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD: + if ext not in audio_extensions and not self.isAudioCD: self.hide() else: needsInfoUpdate = True @@ -827,7 +863,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB currref = self.playlist.getServiceRefList()[idx] text = currref.getPath() ext = text[-4:].lower() - if ext not in [".mp2", ".mp3", ".wav", ".ogg", "flac"] and not self.isAudioCD: + if ext not in audio_extensions and not self.isAudioCD: self.hide() else: needsInfoUpdate = True @@ -835,11 +871,9 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.unPauseService() if needsInfoUpdate == True: path = self.playlist.getServiceRefList()[self.playlist.getCurrentIndex()].getPath() - self.updateCoverArtPixmap(path) + self["coverArt"].updateCoverArt(path) else: - pngname = self["coverArt"].default_pixmap - self.coverArtFileName = pngname - self["coverArt"].instance.setPixmapFromFile(self.coverArtFileName) + self["coverArt"].showDefaultCover() self.readTitleInformation() def updatedSeekState(self): @@ -867,11 +901,11 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB def unPauseService(self): self.setSeekState(self.SEEK_STATE_PLAY) - + def subtitleSelection(self): - from Screens.Subtitles import Subtitles - self.session.open(Subtitles) - + from Screens.AudioSelection import SubtitleSelection + self.session.open(SubtitleSelection, self) + def hotplugCB(self, dev, media_state): if dev == harddiskmanager.getCD(): if media_state == "1": @@ -891,12 +925,17 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.clear_playlist() class MediaPlayerLCDScreen(Screen): - skin = """ - + skin = ( + """ - """ + """, + """ + + + + """) def __init__(self, session, parent): Screen.__init__(self, session) @@ -961,7 +1000,7 @@ def filescan(**kwargs): ScanPath(path = "", with_subdirs = False), ], name = "Movie", - description = "View Movies...", + description = _("View Movies..."), openfnc = filescan_open, ), Scanner(mimetypes = ["video/x-vcd"], @@ -971,7 +1010,7 @@ def filescan(**kwargs): ScanPath(path = "MPEGAV", with_subdirs = False), ], name = "Video CD", - description = "View Video CD...", + description = _("View Video CD..."), openfnc = filescan_open, ), Scanner(mimetypes = ["audio/mpeg", "audio/x-wav", "application/ogg", "audio/x-flac"], @@ -980,7 +1019,7 @@ def filescan(**kwargs): ScanPath(path = "", with_subdirs = False), ], name = "Music", - description = "Play Music...", + description = _("Play Music..."), openfnc = filescan_open, )] try: @@ -992,7 +1031,7 @@ def filescan(**kwargs): ScanPath(path = "", with_subdirs = False), ], name = "Audio-CD", - description = "Play Audio-CD...", + description = _("Play Audio-CD..."), openfnc = audioCD_open, )) return mediatypes