Index: apps/playback.c
===================================================================
--- apps/playback.c	(revision 13324)
+++ apps/playback.c	(working copy)
@@ -3308,6 +3308,8 @@
         playlist_update_resume_info(
             (playlist_end && ci.stop_codec)?NULL:audio_current_track());
 
+        prev_track_elapsed = CUR_TI->id3.elapsed;
+
         /* Increment index so runtime info is saved in audio_clear_track_entries().
          * Done here, as audio_stop_playback() may be called more than once.
          * Don't update runtime unless playback is stopped because of end of playlist.
Index: apps/scrobbler.c
===================================================================
--- apps/scrobbler.c	(revision 13324)
+++ apps/scrobbler.c	(working copy)
@@ -139,7 +139,7 @@
     return true;
 }
 
-static void add_to_cache(void)
+static void add_to_cache(unsigned long play_length)
 {
     if ( cache_pos >= SCROBBLER_MAX_CACHE )
         write_cache();
@@ -149,8 +149,7 @@
 
     logf("SCROBBLER: add_to_cache[%d]", cache_pos);
 
-    if ( audio_prev_elapsed() >
-        (scrobbler_entry.length/2) )
+    if ( play_length > (scrobbler_entry.length/2) )
         rating = 'L'; /* Listened */
 
     if (scrobbler_entry.tracknum > 0)
@@ -193,7 +192,7 @@
 {
     /* add entry using the previous scrobbler_entry and timestamp */
     if (pending)
-        add_to_cache();
+        add_to_cache(audio_prev_elapsed());
 
     /*  check if track was resumed > %50 played
         check for blank artist or track name */
@@ -219,7 +218,7 @@
 int scrobbler_init(void)
 {
     logf("SCROBBLER: init %d", global_settings.audioscrobbler);
-    
+
     if(!global_settings.audioscrobbler)
         return -1;
 
@@ -239,8 +238,8 @@
     {
         /* Add any pending entries to the cache */
         if(pending)
-            add_to_cache();
-        
+            add_to_cache(audio_prev_elapsed());
+
         /* Write the cache to disk if needed */
         if (cache_pos)
             write_cache();
@@ -257,7 +256,7 @@
 #endif
 
     scrobbler_flush_cache();
-    
+
     if (scrobbler_initialised)
     {
         audio_set_track_changed_event(NULL);
@@ -265,6 +264,21 @@
     }
 }
 
+void scrobbler_poweroff(void)
+{
+    if (scrobbler_initialised && pending)
+    {
+        if ( audio_status() )
+            add_to_cache(audio_current_track()->elapsed);
+        else
+            add_to_cache(audio_prev_elapsed());
+
+        /* scrobbler_shutdown is called later, the cache will be written
+        *  make sure the final track isn't added twice when that happens */
+        pending = false;
+    }
+}
+
 bool scrobbler_is_enabled(void)
 {
     return scrobbler_initialised;
Index: apps/scrobbler.h
===================================================================
--- apps/scrobbler.h	(revision 13324)
+++ apps/scrobbler.h	(working copy)
@@ -21,4 +21,5 @@
 int scrobbler_init(void);
 void scrobbler_flush_cache(void);
 void scrobbler_shutdown(void);
+void scrobbler_poweroff(void);
 bool scrobbler_is_enabled(void);
Index: apps/misc.c
===================================================================
--- apps/misc.c	(revision 13324)
+++ apps/misc.c	(working copy)
@@ -604,6 +604,8 @@
 #else
     int i;
 
+    scrobbler_poweroff();
+
 #if CONFIG_CHARGING && !defined(HAVE_POWEROFF_WHILE_CHARGING)
     if(!charger_inserted())
 #endif
Index: firmware/mpeg.c
===================================================================
--- firmware/mpeg.c	(revision 13324)
+++ firmware/mpeg.c	(working copy)
@@ -2727,6 +2727,11 @@
 void audio_stop(void)
 {
 #ifndef SIMULATOR
+    if (playing)
+    {
+        struct trackdata *track = get_trackdata(0);
+        prev_track_elapsed = track->id3.elapsed;
+    }
     mpeg_stop_done = false;
     queue_post(&mpeg_queue, MPEG_STOP, 0);
     while(!mpeg_stop_done)
