From d58993d57db2ed3b37b6e062b71fb0d47bcd6b4e Mon Sep 17 00:00:00 2001 From: Andreas Frisch Date: Fri, 25 Jul 2008 13:09:51 +0000 Subject: [PATCH 1/1] Display actual song names for Audio CDs with CD-Text feature (requires libcdio) --- lib/python/Components/MediaPlayer.py | 5 +- .../Plugins/Extensions/MediaPlayer/plugin.py | 96 +++++++++++++------ lib/service/servicemp3.cpp | 33 ++++++- 3 files changed, 99 insertions(+), 35 deletions(-) diff --git a/lib/python/Components/MediaPlayer.py b/lib/python/Components/MediaPlayer.py index 84f7bec7..50de290d 100644 --- a/lib/python/Components/MediaPlayer.py +++ b/lib/python/Components/MediaPlayer.py @@ -22,7 +22,10 @@ ForwardIcon = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/i def PlaylistEntryComponent(serviceref, state): res = [ serviceref ] - res.append((eListboxPythonMultiContent.TYPE_TEXT,25, 0, 470, 32, 0, RT_VALIGN_CENTER, path.split(serviceref.getPath().split('/')[-1])[1])) + text = serviceref.getName() + if text is "": + text = path.split(serviceref.getPath().split('/')[-1])[1] + res.append((eListboxPythonMultiContent.TYPE_TEXT,25, 0, 470, 32, 0, RT_VALIGN_CENTER, text)) png = None if state == STATE_PLAY: png = PlayIcon diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index 0613ed0a..f87978bd 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -1,6 +1,6 @@ -from os import path as os_path, remove as os_remove, listdir as os_listdir +from os import path as os_path, remove as os_remove, listdir as os_listdir, popen from time import strftime -from enigma import eTimer, eServiceCenter, iServiceInformation +from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation from Screens.Screen import Screen from Screens.MessageBox import MessageBox from Screens.InputBox import InputBox @@ -12,7 +12,7 @@ from Components.FileList import FileList from Components.MediaPlayer import PlayList from Tools.Directories import resolveFilename, SCOPE_CONFIG, SCOPE_PLAYLIST, SCOPE_SKIN_IMAGE from Components.ServicePosition import ServicePositionGauge -from Components.ServiceEventTracker import InfoBarBase +from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase from Components.Playlist import PlaylistIOInternal, PlaylistIOM3U, PlaylistIOPLS from Screens.InfoBarGenerics import InfoBarSeek, InfoBarAudioSelection, InfoBarCueSheetSupport, InfoBarNotifications from ServiceReference import ServiceReference @@ -162,6 +162,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.coverArtFileName = "" self.isAudioCD = False + self.AudioCD_albuminfo = {} self.playlistIOInternal = PlaylistIOInternal() list = self.playlistIOInternal.open(resolveFilename(SCOPE_CONFIG, "playlist.e2pls")) @@ -170,6 +171,11 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB self.playlist.addFile(x.ref) self.playlist.updateList() + self.__event_tracker = ServiceEventTracker(screen=self, eventmap= + { + iPlayableService.evUpdatedInfo: self.__evUpdatedInfo + }) + def doNothing(self): pass @@ -200,6 +206,14 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB def __onClose(self): self.session.nav.playService(self.oldService) + 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) + self.readTitleInformation() + def delMPTimer(self): del self.rightKeyTimer del self.leftKeyTimer @@ -207,15 +221,23 @@ 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) - if stitle == "": - stitle = currPlay.info().getName().split('/')[-1] - - self.updateMusicInformation( artist = currPlay.info().getInfoString(iServiceInformation.sArtist), - title = stitle, - album = currPlay.info().getInfoString(iServiceInformation.sAlbum), - genre = currPlay.info().getInfoString(iServiceInformation.sGenre), - clear = True) + sTitle = currPlay.info().getInfoString(iServiceInformation.sTitle) + sAlbum = currPlay.info().getInfoString(iServiceInformation.sAlbum) + sGenre = currPlay.info().getInfoString(iServiceInformation.sGenre) + sArtist = currPlay.info().getInfoString(iServiceInformation.sArtist) + + if sTitle == "": + sTitle = currPlay.info().getName().split('/')[-1] + + 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 "PERFORMER" in self.AudioCD_albuminfo: + sArtist = self.AudioCD_albuminfo["PERFORMER"] + + self.updateMusicInformation( artist = sArtist, title = sTitle, album = sAlbum, genre = sGenre, clear = True ) else: self.updateMusicInformation() @@ -304,6 +326,13 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB 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 = "" @@ -351,16 +380,14 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB if t is None: return #display current selected entry on LCD - text = t.getPath() - text = text.split('/')[-1] + 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 = currref.getPath() - text = text.split('/')[-1] + text = self.getIdentifier(currref) self.summaries.setText(text,3) else: self.summaries.setText(" ",3) @@ -368,8 +395,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB idx += 1 if idx < len(self.playlist): currref = self.playlist.getServiceRefList()[idx] - text = currref.getPath() - text = text.split('/')[-1] + text = self.getIdentifier(currref) self.summaries.setText(text,4) else: self.summaries.setText(" ",4) @@ -628,13 +654,12 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB # display just playing musik on LCD idx = self.playlist.getCurrentIndex() currref = self.playlist.getServiceRefList()[idx] - text = currref.getPath() - text = text.split('/')[-1] + text = self.getIdentifier(currref) text = ">"+text ext = text[-3:].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 ["mp3", "wav", "ogg"]: + if ext not in ["mp3", "wav", "ogg"] and not self.isAudioCD: self.hide() else: needsInfoUpdate = True @@ -644,8 +669,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB idx += 1 if idx < len(self.playlist): currref = self.playlist.getServiceRefList()[idx] - text = currref.getPath() - text = text.split('/')[-1] + text = self.getIdentifier(currref) self.summaries.setText(text,3) else: self.summaries.setText(" ",3) @@ -653,8 +677,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB idx += 1 if idx < len(self.playlist): currref = self.playlist.getServiceRefList()[idx] - text = currref.getPath() - text = text.split('/')[-1] + text = self.getIdentifier(currref) self.summaries.setText(text,4) else: self.summaries.setText(" ",4) @@ -663,7 +686,7 @@ class MediaPlayer(Screen, InfoBarBase, InfoBarSeek, InfoBarAudioSelection, InfoB currref = self.playlist.getServiceRefList()[idx] text = currref.getPath() ext = text[-3:].lower() - if ext not in ["mp3", "wav", "ogg"]: + if ext not in ["mp3", "wav", "ogg"] and not self.isAudioCD: self.hide() else: needsInfoUpdate = True @@ -760,14 +783,29 @@ def audioCD_open(list, session, **kwargs): mp.isAudioCD = True mp.switchToPlayList() + cdtext = popen('cdtextinfo -l').read() + tracklist = [] + if cdtext is not "": + tracklist = cdtext.splitlines() + cdtext = popen('cdtextinfo -a').read() + if cdtext is not "": + albumtags = cdtext.splitlines() + for tag in albumtags: + tag = tag.split(':',1) + mp.AudioCD_albuminfo[tag[0]] = tag[1] + print mp.AudioCD_albuminfo + idx = 0 for file in list: ref = eServiceReference(4097, 0, file.path) + if idx < len(tracklist): + track = tracklist[idx] + ref.setName("%d - %s" % (int(track.split(':',1)[0]), track.split(':')[1])) + idx += 1 mp.playlist.addFile(ref) - # TODO: rather play first than last file? - mp.playServiceRefEntry(ref) - mp.playlist.updateList() mp.changeEntry(0) + mp.playlist.updateList() + mp.switchToPlayList() def filescan(**kwargs): from Components.Scanner import Scanner, ScanPath diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp index c004d038..fb767281 100644 --- a/lib/service/servicemp3.cpp +++ b/lib/service/servicemp3.cpp @@ -140,8 +140,9 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp int is_mp3 = !strcasecmp(ext, ".mp3"); /* force mp3 instead of decodebin */ int is_video = is_mpeg_ps || is_mpeg_ts || is_matroska || is_avi; int is_streaming = !strncmp(filename, "http://", 7); + int is_AudioCD = !(strncmp(filename, "/autofs/hda/track-", 18) || strcasecmp(ext, ".wav")); - eDebug("filename: %s, is_mpeg_ps: %d, is_mpeg_ts: %d, is_video: %d, is_streaming: %d, is_mp3: %d, is_matroska: %d, is_avi: %d", filename, is_mpeg_ps, is_mpeg_ts, is_video, is_streaming, is_mp3, is_matroska, is_avi); + eDebug("filename: %s, is_mpeg_ps: %d, is_mpeg_ts: %d, is_video: %d, is_streaming: %d, is_mp3: %d, is_matroska: %d, is_avi: %d, is_AudioCD: %d", filename, is_mpeg_ps, is_mpeg_ts, is_video, is_streaming, is_mp3, is_matroska, is_avi, is_AudioCD); int is_audio = !is_video; @@ -151,9 +152,17 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp if (!m_gst_pipeline) eWarning("failed to create pipeline"); - if (!is_streaming) + if (is_AudioCD) + { + source = gst_element_factory_make ("cdiocddasrc", "cda-source"); + if (source) + g_object_set (G_OBJECT (source), "device", "/dev/cdroms/cdrom0", NULL); + else + is_AudioCD = 0; + } + if ( !is_streaming && !is_AudioCD ) source = gst_element_factory_make ("filesrc", "file-source"); - else + else if ( is_streaming ) { source = gst_element_factory_make ("neonhttpsrc", "http-source"); if (source) @@ -162,9 +171,16 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp if (!source) eWarning("failed to create %s", is_streaming ? "neonhttpsrc" : "filesrc"); - else /* configure source */ + else if (!is_AudioCD) g_object_set (G_OBJECT (source), "location", filename, NULL); + else + { + int track = atoi(filename+18); + eDebug("play audio CD track #%i",track); + if (track > 0) + g_object_set (G_OBJECT (source), "track", track, NULL); + } if (is_audio) { @@ -249,7 +265,14 @@ eServiceMP3::eServiceMP3(const char *filename): m_filename(filename), m_pump(eAp { gst_bus_set_sync_handler(gst_pipeline_get_bus (GST_PIPELINE (m_gst_pipeline)), gstBusSyncHandler, this); - if (is_audio) + if (is_AudioCD) + { + queue_audio = gst_element_factory_make("queue", "queue_audio"); + g_object_set (G_OBJECT (sink), "preroll-queue-len", 80, NULL); + gst_bin_add_many (GST_BIN (m_gst_pipeline), source, queue_audio, conv, sink, NULL); + gst_element_link_many(source, queue_audio, conv, sink, NULL); + } + else if (is_audio) { queue_audio = gst_element_factory_make("queue", "queue_audio"); -- 2.30.2