29 #include <taglib/fileref.h>
30 #include <taglib/flacfile.h>
31 #include <taglib/id3v2tag.h>
32 #include <taglib/id3v1genres.h>
33 #include <taglib/mpegfile.h>
34 #include <taglib/oggfile.h>
35 #include <taglib/taglib.h>
36 #include <taglib/tag.h>
37 #include <taglib/vorbisfile.h>
38 #include <taglib/xiphcomment.h>
41 using namespace Nepomuk2::Vocabulary;
55 types << QLatin1String(
"audio/mpeg");
56 types << QLatin1String(
"audio/mpeg3"); types << QLatin1String(
"audio/x-mpeg");
59 types << QLatin1String(
"audio/flac");
62 types << QLatin1String(
"audio/ogg"); types << QLatin1String(
"audio/x-vorbis+ogg");
65 types << QLatin1String(
"audio/wav");
68 types << QLatin1String(
"audio/x-aiff");
71 types << QLatin1String(
"audio/x-ape");
74 types << QLatin1String(
"audio/x-wavpack");
83 TagLib::FileRef file( fileUrl.toLocalFile().toUtf8().data(), true );
91 TagLib::Tag* tags = file.tag();
92 if( !tags->isEmpty() ) {
93 fileRes.
addType( NMM::MusicPiece() );
95 fileRes.
addType( NFO::Audio() );
98 TagLib::String artists;
99 TagLib::String albumArtists;
100 TagLib::String composers;
101 TagLib::String lyricists;
102 TagLib::StringList genres;
105 if( (mimeType ==
"audio/mpeg") || (mimeType ==
"audio/mpeg3") || (mimeType ==
"audio/x-mpeg") ) {
106 TagLib::MPEG::File mpegFile( fileUrl.toLocalFile().toUtf8().data(), true );
107 if( mpegFile.ID3v2Tag() && !mpegFile.ID3v2Tag()->isEmpty() ) {
108 TagLib::ID3v2::FrameList lstID3v2;
111 lstID3v2 = mpegFile.ID3v2Tag()->frameListMap()[
"TPE1"];
112 if ( !lstID3v2.isEmpty() ) {
113 for (TagLib::ID3v2::FrameList::ConstIterator it = lstID3v2.begin(); it != lstID3v2.end(); ++it) {
114 if( !artists.isEmpty() ) {
117 artists += (*it)->toString();
122 lstID3v2 = mpegFile.ID3v2Tag()->frameListMap()[
"TPE2"];
123 if ( !lstID3v2.isEmpty() ) {
124 for (TagLib::ID3v2::FrameList::ConstIterator it = lstID3v2.begin(); it != lstID3v2.end(); ++it) {
125 if( !albumArtists.isEmpty() ) {
126 albumArtists +=
", ";
128 albumArtists += (*it)->toString();
133 lstID3v2 = mpegFile.ID3v2Tag()->frameListMap()[
"TCOM"];
134 if ( !lstID3v2.isEmpty() ) {
135 for (TagLib::ID3v2::FrameList::ConstIterator it = lstID3v2.begin(); it != lstID3v2.end(); ++it) {
136 if( !composers.isEmpty() ) {
139 composers += (*it)->toString();
144 lstID3v2 = mpegFile.ID3v2Tag()->frameListMap()[
"TEXT"];
145 if ( !lstID3v2.isEmpty() ) {
146 for (TagLib::ID3v2::FrameList::ConstIterator it = lstID3v2.begin(); it != lstID3v2.end(); ++it) {
147 if( !lyricists.isEmpty() ) {
150 lyricists += (*it)->toString();
155 lstID3v2 = mpegFile.ID3v2Tag()->frameListMap()[
"TCON"];
156 if ( !lstID3v2.isEmpty() ) {
157 for (TagLib::ID3v2::FrameList::ConstIterator it = lstID3v2.begin(); it != lstID3v2.end(); ++it) {
158 genres.append((*it)->toString());
166 if( mimeType ==
"audio/flac" ) {
167 TagLib::FLAC::File flacFile( fileUrl.toLocalFile().toUtf8().data(), true );
168 if( flacFile.xiphComment() && !flacFile.xiphComment()->isEmpty() ) {
169 TagLib::Ogg::FieldListMap lstFLAC = flacFile.xiphComment()->fieldListMap();
170 TagLib::Ogg::FieldListMap::ConstIterator itFLAC;
173 itFLAC = lstFLAC.find(
"ARTIST");
174 if( itFLAC != lstFLAC.end() ) {
175 if( !artists.isEmpty() ) {
178 artists += (*itFLAC).second.toString(
", ");
182 itFLAC = lstFLAC.find(
"ALBUMARTIST");
183 if( itFLAC != lstFLAC.end() ) {
184 if( !albumArtists.isEmpty() ) {
185 albumArtists +=
", ";
187 albumArtists += (*itFLAC).second.toString(
", ");
191 itFLAC = lstFLAC.find(
"COMPOSER");
192 if( itFLAC != lstFLAC.end() ) {
193 if( !composers.isEmpty() ) {
196 composers += (*itFLAC).second.toString(
", ");
200 itFLAC = lstFLAC.find(
"LYRICIST");
201 if( itFLAC != lstFLAC.end() ) {
202 if( !lyricists.isEmpty() ) {
205 lyricists += (*itFLAC).second.toString(
", ");
209 itFLAC = lstFLAC.find(
"GENRE");
210 if( itFLAC != lstFLAC.end() ) {
211 genres.append((*itFLAC).second);
217 if( mimeType ==
"audio/ogg" || mimeType ==
"audio/x-vorbis+ogg" ) {
218 TagLib::Ogg::Vorbis::File oggFile( fileUrl.toLocalFile().toUtf8().data(), true );
219 if( oggFile.tag() && !oggFile.tag()->isEmpty() ) {
220 TagLib::Ogg::FieldListMap lstOGG = oggFile.tag()->fieldListMap();
221 TagLib::Ogg::FieldListMap::ConstIterator itOGG;
224 itOGG = lstOGG.find(
"ARTIST");
225 if( itOGG != lstOGG.end() ) {
226 if( !artists.isEmpty() ) {
229 artists += (*itOGG).second.toString(
", ");
233 itOGG = lstOGG.find(
"ALBUMARTIST");
234 if( itOGG != lstOGG.end() ) {
235 if( !albumArtists.isEmpty() ) {
236 albumArtists +=
", ";
238 albumArtists += (*itOGG).second.toString(
", ");
242 itOGG = lstOGG.find(
"COMPOSER");
243 if( itOGG != lstOGG.end() ) {
244 if( !composers.isEmpty() ) {
247 composers += (*itOGG).second.toString(
", ");
251 itOGG = lstOGG.find(
"LYRICIST");
252 if( itOGG != lstOGG.end() ) {
253 if( !lyricists.isEmpty() ) {
256 lyricists += (*itOGG).second.toString(
", ");
260 itOGG = lstOGG.find(
"GENRE");
261 if( itOGG != lstOGG.end() ) {
262 genres.append((*itOGG).second);
267 if( !tags->isEmpty() ) {
268 QString title = QString::fromUtf8( tags->title().toCString(
true ) );
269 if( !title.isEmpty() ) {
273 QString comment = QString::fromUtf8( tags->comment().toCString(
true ) );
274 if( !comment.isEmpty() ) {
278 if( genres.isEmpty() ) {
279 genres.append( tags->genre() );
282 for( uint i = 0; i < genres.size(); i++ ) {
283 QString genre = QString::fromUtf8( genres[i].toCString(
true ) ).trimmed();
287 int genreNum = genre.toInt( &ok );
289 genre = QString::fromUtf8( TagLib::ID3v1::genre(genreNum).toCString(
true ) );
295 QString artistString;
296 if( artists.isEmpty() ) {
297 artistString = QString::fromUtf8( tags->artist().toCString(
true ) );
299 artistString = QString::fromUtf8( artists.toCString(
true ) ).trimmed();
308 QString composersString = QString::fromUtf8( composers.toCString(
true ) ).trimmed();
315 QString lyricistsString = QString::fromUtf8( lyricists.toCString(
true ) ).trimmed();
322 QString album = QString::fromUtf8( tags->album().toCString(
true ) );
323 if( !album.isEmpty() ) {
325 albumRes.
addType( NMM::MusicAlbum() );
328 QString albumArtistsString = QString::fromUtf8( albumArtists.toCString(
true ) ).trimmed();
335 fileRes.
setProperty( NMM::musicAlbum(), albumRes );
339 if( tags->track() ) {
340 fileRes.
setProperty( NMM::trackNumber(), tags->track() );
346 QDate date = dt.date();
348 date.setDate( tags->year(), 1, 1 );
349 if( date.year() < 0 ) {
350 date.setDate( 1, 1, 1 );
357 TagLib::AudioProperties* audioProp = file.audioProperties();
359 if( audioProp->length() ) {
361 fileRes.
setProperty( NFO::duration(), audioProp->length() );
364 if( audioProp->bitrate() ) {
365 fileRes.
setProperty( NFO::averageBitrate(), audioProp->bitrate() * 1000 );
368 if( audioProp->channels() ) {
369 fileRes.
setProperty( NFO::channels(), audioProp->channels() );
372 if( audioProp->sampleRate() ) {
373 fileRes.
setProperty( NFO::sampleRate(), audioProp->sampleRate() );
void setProperty(const QUrl &property, const QVariant &value)
Set a property overwriting existing values.
Represents a snapshot of one Nepomuk resource.
void addProperty(const QUrl &property, const QVariant &value)
Add a property.
void addType(const QUrl &type)
A convenience method which adds a property of type rdf:type.