1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
/*****************************************************************************
* Copyright © 2012 John Maguire <john.maguire@gmail.com> *
* David Sansome <me@davidsansome.com> *
* This work is free. You can redistribute it and/or modify it under the *
* terms of the Do What The Fuck You Want To Public License, Version 2, *
* as published by Sam Hocevar. *
* See http://www.wtfpl.net/ for more details. *
*****************************************************************************/
#include <QFuture>
#include <QUrl>
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
#include <QtConcurrent>
#endif
#include <QtConcurrentMap>
#include "musicbrainz/tagfetcher.h"
#include "musicbrainz/chromaprinter.h"
#include "musicbrainz/musicbrainzclient.h"
TagFetcher::TagFetcher(QObject* parent)
: QObject(parent),
m_pFingerprintWatcher(NULL),
m_AcoustidClient(this),
m_MusicbrainzClient(this) {
connect(&m_AcoustidClient, SIGNAL(finished(int,QString)),
this, SLOT(mbidFound(int,QString)));
connect(&m_MusicbrainzClient, SIGNAL(finished(int,MusicBrainzClient::ResultList)),
this, SLOT(tagsFetched(int,MusicBrainzClient::ResultList)));
connect(&m_AcoustidClient, SIGNAL(networkError(int, QString)),
this, SIGNAL(networkError(int, QString)));
connect(&m_MusicbrainzClient, SIGNAL(networkError(int, QString)),
this, SIGNAL(networkError(int, QString)));
}
QString TagFetcher::getFingerprint(const TrackPointer tio) {
return ChromaPrinter(NULL).getFingerprint(tio);
}
void TagFetcher::startFetch(const TrackPointer track) {
cancel();
// qDebug() << "start to fetch track metadata";
QList<TrackPointer> tracks;
tracks.append(track);
m_tracks = tracks;
QFuture<QString> future = QtConcurrent::mapped(m_tracks, getFingerprint);
m_pFingerprintWatcher = new QFutureWatcher<QString>(this);
m_pFingerprintWatcher->setFuture(future);
connect(m_pFingerprintWatcher, SIGNAL(resultReadyAt(int)),
SLOT(fingerprintFound(int)));
foreach (const TrackPointer ptrack, m_tracks) {
emit(fetchProgress(tr("Fingerprinting track")));
}
}
void TagFetcher::cancel() {
// qDebug()<< "Cancel tagfetching";
if (m_pFingerprintWatcher) {
m_pFingerprintWatcher->cancel();
delete m_pFingerprintWatcher;
m_pFingerprintWatcher = NULL;
}
m_AcoustidClient.cancelAll();
m_MusicbrainzClient.cancelAll();
m_tracks.clear();
}
void TagFetcher::fingerprintFound(int index) {
QFutureWatcher<QString>* watcher = reinterpret_cast<QFutureWatcher<QString>*>(sender());
if (!watcher || index >= m_tracks.count()) {
return;
}
const QString fingerprint = watcher->resultAt(index);
const TrackPointer ptrack = m_tracks[index];
if (fingerprint.isEmpty()) {
emit(resultAvailable(ptrack, QList<TrackPointer>()));
return;
}
emit(fetchProgress(tr("Identifying track")));
// qDebug() << "start to look up the MBID";
m_AcoustidClient.start(index, fingerprint, ptrack->getDurationInt());
}
void TagFetcher::mbidFound(int index, const QString& mbid) {
if (index >= m_tracks.count()) {
return;
}
const TrackPointer pTrack = m_tracks[index];
if (mbid.isEmpty()) {
emit(resultAvailable(pTrack, QList<TrackPointer>()));
return;
}
emit fetchProgress(tr("Downloading Metadata"));
//qDebug() << "start to fetch tags from MB";
m_MusicbrainzClient.start(index, mbid);
}
void TagFetcher::tagsFetched(int index, const MusicBrainzClient::ResultList& results) {
if (index >= m_tracks.count()) {
return;
}
// qDebug() << "Tagfetcher got musicbrainz results and now parses them";
const TrackPointer originalTrack = m_tracks[index];
QList<TrackPointer> tracksGuessed;
foreach (const MusicBrainzClient::Result& result, results) {
TrackPointer track(
Track::newTemporary(
originalTrack->getFileInfo(),
originalTrack->getSecurityToken()));
track->setTitle(result.m_title);
track->setArtist(result.m_artist);
track->setAlbum(result.m_album);
track->setDuration(result.m_duration);
track->setTrackNumber(QString::number(result.m_track));
track->setYear(QString::number(result.m_year));
tracksGuessed << track;
}
emit(resultAvailable(originalTrack, tracksGuessed));
}
|