Re: [Tracker] [PATCH] Moving towards internal metadata extractors



Edward Duffy wrote:
Here's a patch for src/trackerd/tracker-metadata.c that can use
internal metadata extractors, depending on mimetype.  If no internal
extractor is provided, it falls back to the old method using
tracker-extract.  I've included extractors for Oasis (Open Office
files), postscript, and AbiWord.

cool - thanks for these. Will try and review your patch tonight.

Btw libgsf has metadata extraction for open Docuemnt stuff but never mind as your stuff looks good enough (although we will want libgsf for ms office stuff)

I'm looking at the PDF parser in
libextractor's repos, and will hopefully have a patch for that soon.

The libextractor's one is crap by the way and does not work properly if you have evince/poppler installed (at least on ubuntu as it replaces some of the pdf libs when evince is installed)

libpoppler has c glib bindings so I think thats the way to go.

(when you donwload poppler, there a test-poppler-glib.c example that gets the metadata - should be a fairly simple cut and paste job)

The libextractor ones that might be useful are for things like gif and tiff. For png, libpng would be better and libexif for jpeg (as these allow metadata to be written).

Bear in mind, keeping memory low and avoiding leaks is paramount in tracker so potentially large files need to be either mmap'ed (like libextractor does) or extracted externally.


Attached is ogg extractors which I modified from source that Fabien did (I have not tested these nor integrated them in yet). Feel free to test and add them. We need equivalent for mp3 and flac.

Thanks for your work in this area - its saving me lots of time :)

--
Mr Jamie McCracken
http://jamiemcc.livejournal.com/

#include <vorbis/vorbisfile.h>
#include <stdio.h>

#include "tracker-metadata-ogg.h"
#include "tracker-utils.h"


static struct {
        char * name;
        char *meta_name;
        gboolean writable;
} tags[] = {
         {"title", "Audio.Title", FALSE},
         {"artist", "Audio.Artist", FALSE},
         {"album", "Audio.Album", FALSE},
         {"albumartist", "Audio.AlbumArtist", FALSE},
         {"trackcount", "Audio.AlbumTrackCount", FALSE},
         {"tracknumber", "Audio.TrackNo", FALSE},
         {"DiscNo", "Audio.DiscNo", FALSE},
         {"Performer", "Audio.Performer", FALSE},
         {"TrackGain", "Audio.TrackGain", FALSE},
         {"TrackPeakGain", "Audio.TrackPeakGain", FALSE},
         {"AlbumGain", "Audio.AlbumGain", FALSE},
         {"AlbumPeakGain", "Audio.AlbumPeakGain", FALSE},
         {"date", "Audio.ReleaseDate", FALSE},
         {"comment", "Audio.Comment", FALSE},
         {"genre", "Audio.Genre", FALSE},
         {"Codec", "Audio.Codec", FALSE},
         {"CodecVersion", "Audio.CodecVersion", FALSE},
         {"Samplerate", "Audio.Samplerate", FALSE},
         {"Channels", "Audio.Channels", FALSE},
         {"MBAlbumID", "Audio.MBAlbumID", FALSE},
         {"MBArtistID", "Audio.MBArtistID", FALSE},
         {"MBAlbumArtistID", "Audio.MBAlbumArtistID", FALSE},
         {"MBTrackID", "Audio.MBTrackID", FALSE},
         {"Lyrics", "Audio.Lyrics", FALSE},
         {"Copyright", "File.Copyright", FALSE},
         {"License", "File.License", FALSE},
         {"Organization", "File.Organization", FALSE},
         {"Location", "File.Location", FALSE},
         {"Publisher", "File.Publisher", FALSE},
         {NULL, NULL, FALSE},
};


static char* 
get_comment (vorbis_comment *vc, char *label)
{
        char *tag;
        char *utf_tag;

        if (vc && (tag = vorbis_comment_query (vc, label, 0)) != NULL) {

                utf_tag = g_locale_to_utf8 (tag, -1, NULL, NULL, NULL);         

                g_free (tag);

                return utf_tag;

        } else {
                return NULL;
        }

}

gboolean
tracker_metadata_ogg_is_writable (const char *meta)
{
        int i;

        i = 0;
        while (tags[i].name != NULL) {
                
                if (strcmp (tags[i].meta_name, meta) == 0) {
                        return tags[i].writable;
                }
                
                i++;
        }

        return FALSE;

}


gboolean
tracker_metadata_ogg_write (const char *meta_name, const char *value) 
{
        /* to do */
        return FALSE;
}


GHashTable * 
tracker_metadata_ogg_extract (const char *filename)
{
        FILE *oggFile;
        OggVorbis_File vf;
        GHashTable *hash;
        int i;

        hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
        
        oggFile = fopen (filename,"r");
        
        if (!oggFile) {
                g_hash_table_destroy (hash);
                return NULL;
        }

        if ( ov_open (oggFile, &vf, NULL, 0) < 0 ) {
                g_hash_table_destroy (hash);
                fclose (oggFile);
                return NULL;
        }
        
        char *tmpComment;

        vorbis_comment *comment;

        if ((comment  = ov_comment (&vf, -1)) == NULL) {
                g_hash_table_destroy (hash);
                ov_clear (&vf); 
                return NULL;
        }

        i = 0;
        while (tags[i].name != NULL) {
                tmpComment = get_comment (comment, tags[i].name);
                
                if (tmpComment) {
                        g_hash_table_insert (hash, g_strdup (tags[i].meta_name), tmpComment);
                }

                i++;
        }

        vorbis_comment_clear(comment);

        /* Bitrate */

        vorbis_info *vi;
        unsigned int bitrate;
        char *str_bitrate;

        if ( ( vi = ov_info(&vf, 0)) != NULL ) {
                bitrate = vi->bitrate_nominal/1000;
                str_bitrate = tracker_int_to_str (bitrate);
                g_hash_table_insert (hash, g_strdup ("Audio.Bitrate"), str_bitrate);
        }

        
                
        /* Duration */

        int time;
        char *str_time;
        if ( ( time = ov_time_total(&vf, -1) ) != OV_EINVAL ) {
                str_time = tracker_int_to_str (time);   
                g_hash_table_insert (hash, g_strdup ("Audio.Duration"), str_time);
        }

        ov_clear(&vf);  
        
        return hash;
}
#ifndef _TRACKER_METADATE_OGG_H_
#define _TRACKER_METADATE_OGG_H_

#include <glib.h>

gboolean        tracker_metadata_ogg_is_writable (const char *meta);
GHashTable *    tracker_metadata_ogg_extract     (const char *filename); 
gboolean        tracker_metadata_ogg_write       (const char *meta_name, const char* value);

#endif /* _TRACKER_METADATE_OGG_H_ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]