Fix Last.fm scrobbling after seek

Fixes #4836
Last.fm defines a scrobble should be sent if:
-the track is longer than 30 seconds.
-the track has been played for at least half its duration, or for 4 minutes (whichever occurs earlier.)

Clementine has treated this as seconds from the start of the track, and if any seeking occurs, it nullifies the scrobble.
This IMO is incorrect. If I skip the first 10 seconds of a song, but listen to the rest (still meeting the time requirements),
I should still be able to scrobble the play. This change moves the scrobble point with every seek, requiring continuous playback
from any point that satisfies the time criteria.
This commit is contained in:
Mark Furneaux 2015-05-18 12:53:07 -04:00
parent 1714d0be8a
commit 99dffe216c
3 changed files with 20 additions and 13 deletions

View File

@ -436,13 +436,9 @@ void Player::SeekTo(int seconds) {
qBound(0ll, qint64(seconds) * kNsecPerSec, length_nanosec);
engine_->Seek(nanosec);
// If we seek the track we don't want to submit it to last.fm
qLog(Info) << "Track seeked to" << nanosec << "ns - not scrobbling";
if (app_->playlist_manager()->active()->get_lastfm_status() ==
Playlist::LastFM_New) {
app_->playlist_manager()->active()->set_lastfm_status(
Playlist::LastFM_Seeked);
}
// If we seek the track we need to move the scrobble point
qLog(Info) << "Track seeked to" << nanosec << "ns - updating srobble point";
app_->playlist_manager()->active()->UpdateScrobblePoint(nanosec);
emit Seeked(nanosec / 1000);
}

View File

@ -1705,14 +1705,25 @@ Song Playlist::current_item_metadata() const {
return current_item()->Metadata();
}
void Playlist::UpdateScrobblePoint() {
void Playlist::UpdateScrobblePoint(qint64 seek_point) {
const qint64 length = current_item_metadata().length_nanosec();
if (length == 0) {
scrobble_point_ = 240ll * kNsecPerSec; // 4 minutes
if (seek_point == 0) {
if (length == 0) {
scrobble_point_ = 240ll * kNsecPerSec; // 4 minutes
} else {
scrobble_point_ =
qBound(31ll * kNsecPerSec, length / 2, 240ll * kNsecPerSec);
}
} else {
scrobble_point_ =
qBound(31ll * kNsecPerSec, length / 2, 240ll * kNsecPerSec);
if (length == 0) {
// current time + 4 minutes
scrobble_point_ = seek_point + (240ll * kNsecPerSec);
} else {
scrobble_point_ =
qBound(seek_point + (31ll * kNsecPerSec), seek_point + (length / 2),
seek_point + (240ll * kNsecPerSec));
}
}
set_lastfm_status(LastFM_New);

View File

@ -227,6 +227,7 @@ class Playlist : public QAbstractListModel {
}
void set_lastfm_status(LastFMStatus status) { lastfm_status_ = status; }
void set_have_incremented_playcount() { have_incremented_playcount_ = true; }
void UpdateScrobblePoint(qint64 seek_point = 0);
// Changing the playlist
void InsertItems(const PlaylistItemList& items, int pos = -1,
@ -351,7 +352,6 @@ signals:
private:
void SetCurrentIsPaused(bool paused);
void UpdateScrobblePoint();
int NextVirtualIndex(int i, bool ignore_repeat_track) const;
int PreviousVirtualIndex(int i, bool ignore_repeat_track) const;
bool FilterContainsVirtualIndex(int i) const;