Delay writing WMA ratings and play counts until playback has finished. Fixes #3593

This commit is contained in:
David Sansome 2014-06-07 15:28:35 +10:00
parent f6a72828a9
commit 01ae151f8a
2 changed files with 56 additions and 2 deletions

View File

@ -21,6 +21,7 @@
#include "librarybackend.h"
#include "core/application.h"
#include "core/database.h"
#include "core/player.h"
#include "core/tagreaderclient.h"
#include "core/taskmanager.h"
#include "smartplaylists/generator.h"
@ -160,6 +161,9 @@ void Library::Init() {
SLOT(AddOrUpdateSubdirs(SubdirectoryList)));
connect(watcher_, SIGNAL(CompilationsNeedUpdating()), backend_,
SLOT(UpdateCompilations()));
connect(app_->playlist_manager(), SIGNAL(CurrentSongChanged(Song)),
SLOT(CurrentSongChanged(Song)));
connect(app_->player(), SIGNAL(Stopped()), SLOT(Stopped()));
// This will start the watcher checking for updates
backend_->LoadDirectoriesAsync();
@ -202,14 +206,51 @@ void Library::WriteAllSongsStatisticsToFiles() {
app_->task_manager()->SetTaskFinished(task_id);
}
void Library::Stopped() {
CurrentSongChanged(Song());
}
void Library::CurrentSongChanged(const Song& song) {
TagReaderReply* reply = nullptr;
if (queued_rating_.is_valid()) {
reply = app_->tag_reader_client()->UpdateSongRating(queued_rating_);
queued_rating_ = Song();
} else if (queued_statistics_.is_valid()) {
reply = app_->tag_reader_client()->UpdateSongStatistics(queued_statistics_);
queued_statistics_ = Song();
}
if (reply) {
connect(reply, SIGNAL(Finished(bool)), reply, SLOT(deleteLater()));
}
if (song.filetype() == Song::Type_Asf) {
current_wma_song_url_ = song.url();
}
}
void Library::SongsRatingChanged(const SongList& songs) {
if (save_ratings_in_files_) {
app_->tag_reader_client()->UpdateSongsRating(songs);
app_->tag_reader_client()->UpdateSongsRating(
FilterCurrentWMASong(songs, &queued_rating_));
}
}
void Library::SongsStatisticsChanged(const SongList& songs) {
if (save_statistics_in_files_) {
app_->tag_reader_client()->UpdateSongsStatistics(songs);
app_->tag_reader_client()->UpdateSongsStatistics(
FilterCurrentWMASong(songs, &queued_statistics_));
}
}
SongList Library::FilterCurrentWMASong(SongList songs, Song* queued) {
for (SongList::iterator it = songs.begin(); it != songs.end(); ) {
if (it->url() == current_wma_song_url_) {
*queued = *it;
it = songs.erase(it);
} else {
++it;
}
}
return songs;
}

View File

@ -20,6 +20,7 @@
#include <QHash>
#include <QObject>
#include <QUrl>
#include "core/song.h"
@ -66,6 +67,11 @@ class Library : public QObject {
void SongsStatisticsChanged(const SongList& songs);
void SongsRatingChanged(const SongList& songs);
void CurrentSongChanged(const Song& song);
void Stopped();
private:
SongList FilterCurrentWMASong(SongList songs, Song* queued);
private:
Application* app_;
@ -78,6 +84,13 @@ class Library : public QObject {
bool save_statistics_in_files_;
bool save_ratings_in_files_;
// Hack: Gstreamer doesn't cope well with WMA files being rewritten while
// being played, so we delay statistics and rating changes until the current
// song has finished playing.
QUrl current_wma_song_url_;
Song queued_statistics_;
Song queued_rating_;
// DB schema versions which should trigger a full library rescan (each of
// those with a short reason why).
QHash<int, QString> full_rescan_revisions_;