I've found a couple of problems with the Scrobble Free plugin, and so here's a pair of patches to fix them:
First, the scrobbler always scrobbles the track, regardless of how much has been played. This is because the "tick" signal uses nanoseconds for its elapsed time value, and the elapsed time in nanoseconds is practically always greater than half the track duration in seconds. Maybe if you had a really long track, or managed to play only a *very* short bit of the track... The solution is to use the shell's elapsed-changed signal instead of the player's tick signal. An alternative would be to divide the tick 'elapsed' parameter by 1000000000 (one billion). The fix is in tick-elapsed_changed.patch (attached) The second problem is that Scrobble Free uses the player's current position in the track as the elapsed play time, rather than using the actual amount of time that the track has been playing. This means that if you seek past the halfway point and then skip to the next track, the track will be scrobbled regardless of how much was actually played. Conversely, if you play more than halfway through and then seek to the beginning and then skip, the track will not be scrobbled. This may be useful for forcing a track to be scrobbled or not, but is IMO incorrect behaviour. Third, tracks of 30 seconds or less are scrobbled, which is incorrect. Fourth, a minor spelling error was corrected (in debug output; "scrobbing" -> "scrobbling" Fixes for these last three problems can be found in "elapsedplaytime.patch" (attached) Hopefully someone will find these useful.
--- __init__.py 2009-05-12 08:28:47.000000000 -0500
+++ __init__new.py 2009-08-06 20:21:05.000000000 -0500
@@ -71,14 +71,13 @@
self.current_track = None
self.queue = []
- self.player_cb_ids = (
- self.player.props.player.connect('tick', self._tick_cb),
- )
self.shellplayer_cb_ids = (
self.player.connect('playing-song-changed',
self._playing_entry_changed_cb),
self.player.connect('playing-changed',
- self._playing_changed_cb)
+ self._playing_changed_cb),
+ self.player.connect('elapsed-changed',
+ self._elapsed_changed_cb)
)
self.db_cb_ids = (
self.db.connect('entry-extra-metadata-notify',
@@ -103,9 +102,6 @@
return [s for s in self.scrobblers if s.enabled]
def deactivate(self, shell):
- for id in self.player_cb_ids:
- self.player.props.player.disconnect(id)
-
for id in self.shellplayer_cb_ids:
self.player.disconnect(id)
@@ -210,7 +206,7 @@
print e
return False # don't run again
- def _tick_cb(self, player, stream_data, elapsed, duration):
+ def _elapsed_changed_cb(self, player, elapsed):
track = self.current_track
# the reported elapsed time occasionally jumps to zero at the
--- __init__new.py 2009-08-06 20:21:05.000000000 -0500
+++ __init__new2.py 2009-08-06 20:58:59.000000000 -0500
@@ -37,6 +37,7 @@
MAX_CONNECT_RETRY = 3
PLAY_DELAY = 10
SCROBBLE_DELAY = 240
+SCROBBLE_MINLENGTH = 30
CLIENT_ID='rbx'
CLIENT_VER=str(rb.__version__)
@@ -75,9 +76,7 @@
self.player.connect('playing-song-changed',
self._playing_entry_changed_cb),
self.player.connect('playing-changed',
- self._playing_changed_cb),
- self.player.connect('elapsed-changed',
- self._elapsed_changed_cb)
+ self._playing_changed_cb)
)
self.db_cb_ids = (
self.db.connect('entry-extra-metadata-notify',
@@ -198,7 +197,7 @@
queue = self.queue
while queue:
track = queue.pop(0)
- print 'scrobbing: %s' % track
+ print 'scrobbling: %s' % track
for scrobbler in self.enabled_scrobblers:
try:
scrobbler.sendScrobble(track)
@@ -214,17 +213,21 @@
if track.elapsed < elapsed:
track.elapsed = elapsed
+
+ def _playing_changed_cb(self, player, playing):
+ track = self.current_track
if track.shouldPlay:
track.played = True
gobject.idle_add(self._process_playing, track)
-
- def _playing_changed_cb(self, player, playing):
- # XXX not sure we care
- pass
+ if playing:
+ track.started_play = int(time.time())
+ else:
+ if int(time.time()) > self.started_play:
+ track.elapsed += int(time.time()) - track.started_play
def _playing_entry_changed_cb(self, player, entry):
print 'entry changed'
-
+
# queue the current track for scrobbling, if needed
track = self.current_track
if track and track.shouldScrobble:
@@ -417,7 +420,8 @@
def __init__(self, artist, album, title, track, duration, mbid):
- self.started = int(time.time())
+ self.started = int(time.time()) # time the track was started
+ self.started_play = 0 # most recent time 'play' was pressed in current track
self.elapsed = 0
self.played = False
@@ -435,9 +439,21 @@
@property
def shouldScrobble(self):
+ if self.started_play > self.started:
+ # The track was paused at some point
+ if int(time.time()) > self.started_play:
+ # The clock hasn't gone backwards...
+ self.elapsed += int(time.time()) - self.started_play
+ else:
+ if int(time.time()) > self.started:
+ self.elapsed += int(time.time()) - self.started
+ print 'elapsed: %d' % self.elapsed
+ print 'duration: %d' % self.duration
+
# XXX also ensure wall clock elapsed time is reasonable
- return (self.elapsed > (self.duration // 2) or
- self.elapsed > SCROBBLE_DELAY)
+ return ((self.elapsed > (self.duration // 2) or
+ self.elapsed > SCROBBLE_DELAY) and
+ self.duration > SCROBBLE_MINLENGTH)
def __str__(self):
return '<Track %s>' % self.__dict__
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Libre-fm mailing list [email protected] http://lists.autonomo.us/mailman/listinfo/libre-fm
