[sound-juicer] Get composer metadata from musicbrainz relations
- From: Christophe Fergeau <teuf src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sound-juicer] Get composer metadata from musicbrainz relations
- Date: Sat, 16 Jun 2012 11:28:39 +0000 (UTC)
commit 10d6dba86ca2a31d28760dad9e69e2c3f8df1874
Author: Phillip Wood <phillip wood dunelm org uk>
Date: Wed Mar 28 14:01:57 2012 +0100
Get composer metadata from musicbrainz relations
In Musicbrainz composers are related to works via composer relationships
and works are in turn related to recordings via performance
relationships. Use these to fill the composer metadata. This could
easily be extended to arrangers and lyricists.
Musicbrainz allows more than one relationship list to be associated with
any given object, however libmusicbrainz 4.0.0 only supported retrieving
one of them. This lead to problems getting the composer data for some
albums. Thanks go Andy Hawkins, the libmusicbrainz maintainer for
extending the API in version 4.0.1 to support retrieving all
relationship lists for an object.
Get track duration data from Mb4Track instead of Mb4Recording as the
track data is more accurate. (During testing several albums had no
duration data in their recording objects and some had incorrect data.)
This is how we got the track duration when we used libmusicbrainz3 and
it was reliable then.
https://bugzilla.gnome.org/show_bug.cgi?id=661646
libjuicer/sj-metadata-musicbrainz4.c | 125 +++++++++++++++++++++++++++++++---
1 files changed, 115 insertions(+), 10 deletions(-)
---
diff --git a/libjuicer/sj-metadata-musicbrainz4.c b/libjuicer/sj-metadata-musicbrainz4.c
index 573ef64..e6b7485 100644
--- a/libjuicer/sj-metadata-musicbrainz4.c
+++ b/libjuicer/sj-metadata-musicbrainz4.c
@@ -229,6 +229,95 @@ fill_relations (Mb4RelationList relations, AlbumDetails *album)
}
static void
+fill_work_relations (Mb4Work work, TrackDetails *track)
+{
+ Mb4RelationListList relation_lists;
+ unsigned int j;
+
+ if (work == NULL)
+ return;
+
+ relation_lists = mb4_work_get_relationlistlist (work);
+ if (relation_lists == NULL)
+ return;
+
+ for (j = 0; j < mb4_relationlist_list_size (relation_lists); j++) {
+ Mb4RelationList relations;
+ char buffer[512]; /* for the GET() macro */
+ unsigned int i;
+
+ relations = mb4_relationlist_list_item (relation_lists, j);
+ if (relations == NULL)
+ return;
+
+ mb4_relation_list_get_targettype (relations, buffer, sizeof (buffer));
+ if (!g_str_equal (buffer, "artist"))
+ continue;
+
+ for (i = 0; i < mb4_relation_list_size (relations); i++) {
+ Mb4Relation relation;
+ Mb4Artist composer;
+
+ relation = mb4_relation_list_item (relations, i);
+ if (relation == NULL)
+ continue;
+
+ mb4_relation_get_type (relation, buffer, sizeof (buffer));
+ if (!g_str_equal (buffer, "composer"))
+ continue;
+
+ composer = mb4_relation_get_artist (relation);
+ if (composer == NULL)
+ continue;
+
+ GET (track->composer, mb4_artist_get_name, composer);
+ GET (track->composer_sortname, mb4_artist_get_sortname, composer);
+ }
+ }
+}
+
+static void
+fill_recording_relations (Mb4Recording recording, TrackDetails *track)
+{
+ Mb4RelationListList relation_lists;
+ unsigned int j;
+
+ relation_lists = mb4_recording_get_relationlistlist (recording);
+ if (relation_lists == NULL)
+ return;
+
+ for (j = 0; j < mb4_relationlist_list_size (relation_lists); j++) {
+ Mb4RelationList relations;
+ char type[512]; /* To hold relationlist target-type and relation type */
+ unsigned int i;
+
+ relations = mb4_relationlist_list_item (relation_lists, j);
+ if (relations == NULL)
+ return;
+
+ mb4_relation_list_get_targettype (relations, type, sizeof (type));
+ if (!g_str_equal (type, "work"))
+ continue;
+
+ for (i = 0; i < mb4_relation_list_size (relations); i++) {
+ Mb4Relation relation;
+ Mb4Work work;
+
+ relation = mb4_relation_list_item (relations, i);
+ if (relation == NULL)
+ continue;
+
+ mb4_relation_get_type (relation, type, sizeof (type));
+ if (!g_str_equal (type, "performance"))
+ continue;
+
+ work = mb4_relation_get_work (relation);
+ fill_work_relations (work, track);
+ }
+ }
+}
+
+static void
fill_tracks_from_medium (Mb4Medium medium, AlbumDetails *album)
{
Mb4TrackList track_list;
@@ -259,15 +348,20 @@ fill_tracks_from_medium (Mb4Medium medium, AlbumDetails *album)
track->album = album;
track->number = mb4_track_get_position (mbt);
+
+ /* duration from track is more reliable than from recording */
+ track->duration = mb4_track_get_length (mbt) / 1000;
+
recording = mb4_track_get_recording (mbt);
if (recording != NULL) {
GET (track->title, mb4_recording_get_title, recording);
GET (track->track_id, mb4_recording_get_id, recording);
- track->duration = mb4_recording_get_length (recording) / 1000;
+ fill_recording_relations (recording, track);
+ if (track->duration == 0)
+ track->duration = mb4_recording_get_length (recording) / 1000;
credit = mb4_recording_get_artistcredit (recording);
} else {
GET (track->title, mb4_track_get_title, mbt);
- track->duration = mb4_track_get_length (mbt) / 1000;
credit = mb4_track_get_artistcredit (mbt);
}
@@ -386,13 +480,11 @@ mb4_list_albums (SjMetadata *metadata, char **url, GError **error)
releases = mb4_query_lookup_discid(priv->mb, discid);
- if (releases == NULL) {
+ if (releases == NULL)
return NULL;
- }
- if (mb4_release_list_size (releases) == 0) {
+ if (mb4_release_list_size (releases) == 0)
return NULL;
- }
for (i = 0; i < mb4_release_list_size (releases); i++) {
AlbumDetails *album;
@@ -400,13 +492,26 @@ mb4_list_albums (SjMetadata *metadata, char **url, GError **error)
release = mb4_release_list_item (releases, i);
if (release) {
char *releaseid = NULL;
- Mb4Release full_release;
+ Mb4Release full_release = NULL;
+ Mb4Metadata release_md = NULL;
+ const char *query_entity = "release";
+ char *params_names[] = { "inc" };
+ char *params_values[] = { "artists artist-credits labels recordings \
+release-groups url-rels discids recording-level-rels work-level-rels work-rels \
+artist-rels" };
releaseid = NULL;
GET(releaseid, mb4_release_get_id, release);
-
- full_release = mb4_query_lookup_release (priv->mb, releaseid);
+ /* Inorder to get metadata from work and composer relationships
+ * we need to perform a custom query
+ */
+ release_md = mb4_query_query (priv->mb, query_entity, releaseid, "", 1,
+ params_names, params_values);
+
+ if (release_md && mb4_metadata_get_release (release_md))
+ full_release = mb4_metadata_get_release (release_md);
g_free (releaseid);
+
if (full_release) {
Mb4MediumList media;
Mb4Metadata metadata = NULL;
@@ -444,8 +549,8 @@ mb4_list_albums (SjMetadata *metadata, char **url, GError **error)
}
mb4_metadata_delete (metadata);
mb4_medium_list_delete (media);
- mb4_release_delete (full_release);
}
+ mb4_metadata_delete (release_md);
}
}
mb4_release_list_delete (releases);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]