~jamesh/mediascanner/qml-plugin

« back to all changes in this revision

Viewing changes to src/daemon/MetadataExtractor.cc

  • Committer: Tarmac
  • Author(s): James Henstridge
  • Date: 2013-11-28 14:24:00 UTC
  • mfrom: (186.1.14 etag)
  • Revision ID: tarmac-20131128142400-72plan6tn4bl9dlr
Store the etag of files in the MediaStore so the scanner can detect whether it is necessary to redo the metadata extraction on files on start up.

Approved by PS Jenkins bot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 
20
20
#include "../mediascanner/MediaFile.hh"
21
21
#include "MetadataExtractor.hh"
22
 
#include "FileTypeDetector.hh"
23
22
 
24
 
#include<gst/gst.h>
25
 
#include<gst/pbutils/pbutils.h>
 
23
#include <glib-object.h>
 
24
#include <gio/gio.h>
 
25
#include <gst/gst.h>
 
26
#include <gst/pbutils/pbutils.h>
26
27
 
27
28
#include<cstdio>
28
29
#include<string>
55
56
    delete p;
56
57
}
57
58
 
 
59
DetectedFile MetadataExtractor::detect(const std::string &filename) {
 
60
    std::unique_ptr<GFile, void(*)(void *)> file(
 
61
        g_file_new_for_path(filename.c_str()), g_object_unref);
 
62
    if (!file) {
 
63
        throw runtime_error("Could not create file object");
 
64
    }
 
65
 
 
66
    GError *error = nullptr;
 
67
    std::unique_ptr<GFileInfo, void(*)(void *)> info(
 
68
        g_file_query_info(
 
69
            file.get(),
 
70
            G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE ","
 
71
            G_FILE_ATTRIBUTE_ETAG_VALUE,
 
72
            G_FILE_QUERY_INFO_NONE, /* cancellable */ NULL, &error),
 
73
        g_object_unref);
 
74
    if (!info) {
 
75
        string errortxt(error->message);
 
76
        g_error_free(error);
 
77
 
 
78
        string msg("Query of file info for ");
 
79
        msg += filename;
 
80
        msg += " failed: ";
 
81
        msg += errortxt;
 
82
        throw runtime_error(msg);
 
83
    }
 
84
 
 
85
    string etag(g_file_info_get_etag(info.get()));
 
86
    string content_type(g_file_info_get_attribute_string(
 
87
        info.get(), G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE));
 
88
    if (content_type.empty()) {
 
89
        throw runtime_error("Could not determine content type.");
 
90
    }
 
91
 
 
92
    MediaType type;
 
93
    if (content_type.find("audio/") == 0) {
 
94
        type = AudioMedia;
 
95
    } else if (content_type.find("video/") == 0) {
 
96
        type = VideoMedia;
 
97
    } else {
 
98
        throw runtime_error(string("File ") + filename + " is not audio or video");
 
99
    }
 
100
    return DetectedFile(filename, etag, content_type, type);
 
101
}
 
102
 
58
103
static void
59
104
extract_tag_info (const GstTagList * list, const gchar * tag, gpointer user_data) {
60
105
    MediaFile *mf = (MediaFile *) user_data;
91
136
    }
92
137
}
93
138
 
94
 
MediaFile MetadataExtractor::extract(const std::string &filename) {
95
 
    FileTypeDetector d;
96
 
    MediaType media_type = d.detect(filename);
97
 
    if (media_type == UnknownMedia) {
98
 
        throw runtime_error("Tried to create an invalid media type.");
99
 
    }
100
 
 
101
 
    MediaFile mf(filename);
102
 
    mf.setType(media_type);
103
 
 
 
139
MediaFile MetadataExtractor::extract(const DetectedFile &d) {
 
140
    MediaFile mf(d.filename);
 
141
    mf.setETag(d.etag);
 
142
    mf.setContentType(d.content_type);
 
143
    mf.setType(d.type);
104
144
    string uri = mf.getUri();
105
145
    GError *error = nullptr;
106
146
    unique_ptr<GstDiscovererInfo, void(*)(void *)> info(
111
151
        g_error_free(error);
112
152
 
113
153
        string msg = "Discovery of file ";
114
 
        msg += filename;
 
154
        msg += mf.getFileName();
115
155
        msg += " failed: ";
116
156
        msg += errortxt;
117
157
        throw runtime_error(msg);
118
158
    }
119
159
 
120
160
    if (gst_discoverer_info_get_result(info.get()) != GST_DISCOVERER_OK) {
121
 
        throw runtime_error("Unable to discover file " + filename);
 
161
        throw runtime_error("Unable to discover file " + mf.getFileName());
122
162
    }
123
163
 
124
164
    const GstTagList *tags = gst_discoverer_info_get_tags(info.get());
127
167
    }
128
168
    mf.setDuration(static_cast<int>(
129
169
        gst_discoverer_info_get_duration(info.get())/GST_SECOND));
130
 
 
131
170
    return mf;
132
171
}