diff options
| author | Adrien Bustany <abustany@gnome.org> | 2010-04-14 18:18:07 (GMT) |
|---|---|---|
| committer | Adrien Bustany <abustany@gnome.org> | 2010-04-15 14:32:14 (GMT) |
| commit | 07390b17851d379fc2e1cec46bfab1e0bf7316dc (patch) | |
| tree | 753d4cddf83cc5b8b3d69ea791f5d0be0913544c | |
| parent | 73e2214d8b1a3e533f2c13cae4f6f09c4a172884 (diff) | |
| download | tracker-07390b17851d379fc2e1cec46bfab1e0bf7316dc.zip tracker-07390b17851d379fc2e1cec46bfab1e0bf7316dc.tar.xz | |
tracker-writeback: Add taglib based module
The taglib based module allows doing writeback to a wide variety of audio
formats. Currently, the modules writebacks the following rdf properties:
- nie:title
- nmm:artist (fetching nmm:artistName)
- nmm:musicAlbum (fetching dc:title)
- rdfs:comment
- nmm:genre
- nmm:trackerNumber.
The supported file formats are MP3, MPC, FLAC, MP4, ASF, AIFF, WAV, TrueAudio,
WavPack, Ogg FLAC, Ogg Vorbis and Speex.
| -rw-r--r-- | configure.ac | 24 | ||||
| -rw-r--r-- | src/tracker-writeback/Makefile.am | 10 | ||||
| -rw-r--r-- | src/tracker-writeback/tracker-writeback-taglib.c | 304 |
3 files changed, 338 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac index 5a3e67f..c0b4d05 100644 --- a/configure.ac +++ b/configure.ac @@ -158,6 +158,7 @@ EDS_REQUIRED=2.25.5 LIBSTREAMANALYZER_REQUIRED=0.7.0 GEE_REQUIRED=0.3 ID3LIB_REQUIRED=3.8.3 +TAGLIB_REQUIRED=1.6 GNOME_KEYRING_REQUIRED=2.26 LIBGRSS_REQUIRED=0.3 @@ -283,6 +284,28 @@ CFLAGS="$OLD_CFLAGS" LIBS="$OLD_LIBS" #################################################################### +# Taglib for audio writeback support +#################################################################### + +AC_ARG_ENABLE(taglib, + AS_HELP_STRING([--enable-taglib], + [enable writeback for audio files [[default=auto]]]),, + [enable_taglib=auto]) + +if test "x$enable_taglib" != "xno" ; then + PKG_CHECK_MODULES(TAGLIB, + [taglib_c >= $TAGLIB_REQUIRED], + [have_taglib=yes], + [have_taglib=no]) + AC_SUBST(TAGLIB_CFLAGS) + AC_SUBST(TAGLIB_LIBS) +else + have_taglib="no (disabled)" +fi + +AM_CONDITIONAL(HAVE_TAGLIB, test "x$have_taglib" = "xyes") + +#################################################################### # Stream Analyzer #################################################################### @@ -1815,6 +1838,7 @@ Plugins: Writeback: MP3: $have_id3lib + Audio files using Taglib: $have_taglib XMP: $have_exempi Warning: diff --git a/src/tracker-writeback/Makefile.am b/src/tracker-writeback/Makefile.am index 5c02c8c..38c11e5 100644 --- a/src/tracker-writeback/Makefile.am +++ b/src/tracker-writeback/Makefile.am @@ -17,6 +17,7 @@ INCLUDES = \ $(GMODULE_CFLAGS) \ $(DBUS_CFLAGS) \ $(ID3LIB_CFLAGS) \ + $(TAGLIB_CFLAGS) \ $(EXEMPI_CFLAGS) \ $(TOTEM_PL_PARSER_CFLAGS) @@ -30,6 +31,15 @@ modules_LTLIBRARIES = #libwriteback_mp3_la_LIBADD = $(GLIB2_LIBS) $(GCOV_LIBS) $(ID3LIB_LIBS) #endif +# Audio files (MP3, MPC, FLAC, MP4, ASF, AIFF, WAV, TrueAudio, WavPack, +# Ogg FLAC, Ogg Vorbis and Speex) +if HAVE_TAGLIB +modules_LTLIBRARIES += libwriteback-taglib.la +libwriteback_taglib_la_SOURCES = tracker-writeback-taglib.c +libwriteback_taglib_la_LDFLAGS = $(module_flags) +libwriteback_taglib_la_LIBADD = $(GLIB2_LIBS) $(GCOV_LIBS) $(TAGLIB_LIBS) +endif + # XMP if HAVE_EXEMPI modules_LTLIBRARIES += libwriteback-xmp.la diff --git a/src/tracker-writeback/tracker-writeback-taglib.c b/src/tracker-writeback/tracker-writeback-taglib.c new file mode 100644 index 0000000..126b581 --- /dev/null +++ b/src/tracker-writeback/tracker-writeback-taglib.c @@ -0,0 +1,304 @@ +/* + * Copyright (C) 2010, Adrien Bustany <abustany@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" + +#include <glib-object.h> +#include <taglib/tag_c.h> +#include <stdlib.h> + +#include <libtracker-common/tracker-ontologies.h> + +#include "tracker-writeback-file.h" + +#define TRACKER_TYPE_WRITEBACK_TAGLIB (tracker_writeback_taglib_get_type ()) + +typedef struct TrackerWritebackTaglib TrackerWritebackTaglib; +typedef struct TrackerWritebackTaglibClass TrackerWritebackTaglibClass; + +struct TrackerWritebackTaglib { + TrackerWritebackFile parent_instance; +}; + +struct TrackerWritebackTaglibClass { + TrackerWritebackFileClass parent_class; +}; + +static GType tracker_writeback_taglib_get_type (void) G_GNUC_CONST; +static gboolean writeback_taglib_update_file_metadata (TrackerWritebackFile *wbf, + GFile *file, + GPtrArray *values, + TrackerClient *client); +static const gchar * const *writeback_taglib_content_types (TrackerWritebackFile *wbf); +static gchar* writeback_taglib_get_artist_name (TrackerClient *client, + const gchar *urn); +static gchar* writeback_taglib_get_album_name (TrackerClient *client, + const gchar *urn); + +G_DEFINE_DYNAMIC_TYPE (TrackerWritebackTaglib, tracker_writeback_taglib, TRACKER_TYPE_WRITEBACK_FILE); + +static void +tracker_writeback_taglib_class_init (TrackerWritebackTaglibClass *klass) +{ + TrackerWritebackFileClass *writeback_file_class = TRACKER_WRITEBACK_FILE_CLASS (klass); + + writeback_file_class->update_file_metadata = writeback_taglib_update_file_metadata; + writeback_file_class->content_types = writeback_taglib_content_types; +} + +static void +tracker_writeback_taglib_class_finalize (TrackerWritebackTaglibClass *klass) +{ +} + +static void +tracker_writeback_taglib_init (TrackerWritebackTaglib *wbt) +{ +} + +static const gchar * const * +writeback_taglib_content_types (TrackerWritebackFile *wbf) +{ + static const gchar *content_types [] = { + "audio/x-mpc", + "audio/x-musepack", + "audio/mpc", + "audio/musepack", + "audio/mpeg", + "audio/x-mpeg", + "audio/mp3", + "audio/x-mp3", + "audio/mpeg3", + "audio/x-mpeg3", + "audio/mpg", + "audio/x-mpg", + "audio/x-mpegaudio", + "audio/flac", + "audio/mp4", + "audio/asf", + "application/asx", + "video/x-ms-asf-plugin", + "application/x-mplayer2", + "video/x-ms-asf", + "application/vnd.ms-asf", + "video/x-ms-asf-plugin", + "video/x-ms-wm", + "video/x-ms-wmx", + "audio/aiff", + "audio/x-aiff", + "sound/aiff", + "audio/rmf", + "audio/x-rmf", + "audio/x-pn-aiff", + "audio/x-gsm", + "audio/mid", + "audio/x-midi", + "audio/vnd.qcelp", + "audio/wav", + "audio/x-wav", + "audio/wave", + "audio/x-pn-wav", + "audio/tta", + "audio/x-tta", + "audio/ogg", + "application/ogg", + "audio/x-ogg", + "application/x-ogg", + "audio/x-speex", + NULL + }; + + return content_types; +} + +static gboolean +writeback_taglib_update_file_metadata (TrackerWritebackFile *writeback_file, + GFile *file, + GPtrArray *values, + TrackerClient *client) +{ + gboolean ret; + gchar *path; + TagLib_File *taglib_file = NULL; + TagLib_Tag *tag; + guint n; + + ret = FALSE; + path = g_file_get_path (file); + taglib_file = taglib_file_new (path); + + if (!taglib_file || !taglib_file_is_valid (taglib_file)) { + goto out; + } + + tag = taglib_file_tag (taglib_file); + + for (n = 0; n < values->len; n++) { + const GStrv row = g_ptr_array_index (values, n); + + if (g_strcmp0 (row[2], TRACKER_NIE_PREFIX "title") == 0) { + taglib_tag_set_title (tag, row[3]); + } + + if (g_strcmp0 (row[2], TRACKER_NMM_PREFIX "performer") == 0) { + gchar *artist_name = writeback_taglib_get_artist_name (client, row[3]); + + if (artist_name) { + taglib_tag_set_artist (tag, artist_name); + g_free (artist_name); + } + } + + if (g_strcmp0 (row[2], TRACKER_NMM_PREFIX "musicAlbum") == 0) { + gchar *album_name = writeback_taglib_get_album_name (client, row[3]); + + if (album_name) { + taglib_tag_set_album (tag, album_name); + g_free (album_name); + } + } + + if (g_strcmp0 (row[2], TRACKER_RDFS_PREFIX "comment") == 0) { + taglib_tag_set_comment (tag, row[3]); + } + + if (g_strcmp0 (row[2], TRACKER_NMM_PREFIX "genre") == 0) { + taglib_tag_set_genre (tag, row[3]); + } + + if (g_strcmp0 (row[2], TRACKER_NMM_PREFIX "trackNumber") == 0) { + taglib_tag_set_track (tag, atoi (row[3])); + } + } + + taglib_file_save (taglib_file); + taglib_file_free (taglib_file); + + ret = TRUE; + + out: + g_free (path); + if (taglib_file) { + taglib_file_free (taglib_file); + } + + return ret; +} + +static gchar* +writeback_taglib_get_artist_name (TrackerClient *client, + const gchar *urn) +{ + gchar *query; + GPtrArray *query_results; + GError *error = NULL; + GError *inner_error = NULL; + gchar *artist_name; + + artist_name = NULL; + + query = g_strdup_printf ("SELECT ?artistName WHERE {<%s> nmm:artistName ?artistName}", + urn); + + query_results = tracker_resources_sparql_query (client, + query, + &inner_error); + + if (error || query_results->len != 1) { + g_warning ("Couldn't find artist name for artist with urn '%s', %s", + urn, + error ? error->message : "no such artist was found"); + + if (error) { + g_error_free (error); + } + } else { + gchar **data; + + data = g_ptr_array_index (query_results, 0); + artist_name = g_strdup (data[0]); + } + + g_free (query); + g_ptr_array_foreach (query_results, (GFunc) g_strfreev, NULL); + g_ptr_array_free (query_results, TRUE); + + return artist_name; +} + +static gchar* +writeback_taglib_get_album_name (TrackerClient *client, + const gchar *urn) +{ + gchar *query; + GPtrArray *query_results; + GError *error = NULL; + GError *inner_error = NULL; + gchar *album_name; + + album_name = NULL; + + query = g_strdup_printf ("SELECT ?albumName WHERE {<%s> dc:title ?albumName}", + urn); + + query_results = tracker_resources_sparql_query (client, + query, + &inner_error); + + if (error || query_results->len != 1) { + g_warning ("Couldn't find album name for album with urn '%s', %s", + urn, + error ? error->message : "no such album was found"); + + if (error) { + g_error_free (error); + } + } else { + gchar **data; + + data = g_ptr_array_index (query_results, 0); + album_name = g_strdup (data[0]); + } + + g_free (query); + g_ptr_array_foreach (query_results, (GFunc) g_strfreev, NULL); + g_ptr_array_free (query_results, TRUE); + + return album_name; +} + +TrackerWriteback * +writeback_module_create (GTypeModule *module) +{ + tracker_writeback_taglib_register_type (module); + + return g_object_new (TRACKER_TYPE_WRITEBACK_TAGLIB, NULL); +} + +const gchar * const * +writeback_module_get_rdf_types (void) +{ + static const gchar *rdftypes[] = { + TRACKER_NFO_PREFIX "Audio", + NULL + }; + + return rdftypes; +} |
