diff --git a/src/scrobbler/plugin.c b/src/scrobbler/plugin.c
index 5924b56..909d8f8 100644
--- a/src/scrobbler/plugin.c
+++ b/src/scrobbler/plugin.c
@@ -40,8 +40,6 @@ static GMutex *m_scrobbler;
 
 guint track_timeout = 0;
 
-Tuple *submit_tuple = NULL;
-
 static gboolean ishttp(const char *a)
 {
     g_return_val_if_fail(a != NULL, FALSE);
@@ -53,37 +51,40 @@ static void aud_hook_playback_begin(gpointer hook_data, gpointer user_data)
     gint playlist = aud_playlist_get_playing();
     gint pos = aud_playlist_get_position(playlist);
 
-    if (aud_playlist_entry_get_length (playlist, pos, FALSE) < 30)
-    {
-        AUDDBG(" *** not submitting due to entry->length < 30");
+    char *filename = aud_playlist_entry_get_filename(playlist, pos);
+    bool_t is_http_source = ishttp(filename);
+    str_unref(filename);
+
+    Tuple *tuple = aud_playlist_entry_get_tuple(playlist, pos, FALSE);
+    if (!tuple)
         return;
-    }
 
-    gchar * filename = aud_playlist_entry_get_filename (playlist, pos);
-    if (ishttp (filename))
+    int len = tuple_get_int(tuple, FIELD_LENGTH, NULL) / 1000;
+
+    /* Make up a length when we submit streaming to now playing.
+     * We will change it before we actually scrobble the track. */
+    if (len < 1 && is_http_source)
+        len = 240;
+
+    if (len < 30)
     {
-        AUDDBG(" *** not submitting due to HTTP source");
-        str_unref (filename);
+        AUDDBG("Length less than 30 seconds; not submitting\n");
+        tuple_unref(tuple);
         return;
     }
-    str_unref (filename);
 
     sc_idle(m_scrobbler);
 
-    if (submit_tuple)
-        tuple_unref (submit_tuple);
-    submit_tuple = aud_playlist_entry_get_tuple (playlist, pos, FALSE);
-    if (! submit_tuple)
-        return;
-
-    sc_addentry(m_scrobbler, submit_tuple, tuple_get_int(submit_tuple, FIELD_LENGTH, NULL) / 1000);
+    sc_addentry(m_scrobbler, tuple, len, is_http_source);
+    tuple_unref(tuple);
 
     if (!track_timeout)
-        track_timeout = g_timeout_add_seconds(1, sc_timeout, NULL);
+        track_timeout = g_timeout_add_seconds(1, sc_timeout, (gpointer)m_scrobbler);
 }
 
 static void aud_hook_playback_end(gpointer aud_hook_data, gpointer user_data)
 {
+    sc_playback_end();
     sc_idle(m_scrobbler);
 
     if (track_timeout)
@@ -91,12 +92,6 @@ static void aud_hook_playback_end(gpointer aud_hook_data, gpointer user_data)
         g_source_remove(track_timeout);
         track_timeout = 0;
     }
-
-    if (submit_tuple != NULL)
-    {
-        tuple_unref (submit_tuple);
-        submit_tuple = NULL;
-    }
 }
 
 void start(void) {
diff --git a/src/scrobbler/scrobbler.c b/src/scrobbler/scrobbler.c
index 1ac17ee..d71be8c 100644
--- a/src/scrobbler/scrobbler.c
+++ b/src/scrobbler/scrobbler.c
@@ -13,6 +13,7 @@
 #include <audacious/drct.h>
 #include <audacious/debug.h>
 #include <audacious/misc.h>
+#include <audacious/playlist.h>
 #include <audacious/plugin.h>
 
 #define SCROBBLER_CLI_ID "aud"
@@ -48,6 +49,7 @@ static char     *sc_submit_url, /* queue */
         sc_curl_errbuf[CURL_ERROR_SIZE],
         *sc_major_error;
 
+static int sc_submit_np(Tuple *tuple, int len);
 static void dump_queue();
 
 /**** Queue stuff ****/
@@ -63,6 +65,7 @@ typedef struct {
     int utctime, track, len;
     int timeplayed;
     int numtries;
+    bool_t is_http_source;
     void *next;
 } item_t;
 
@@ -137,7 +140,7 @@ static item_t *q_additem(item_t *newitem)
     return newitem;
 }
 
-static item_t *create_item(Tuple *tuple, int len)
+static item_t *create_item(Tuple *tuple, int len, bool_t is_http_source)
 {
     item_t *item;
     gchar *album, *artist, *title;
@@ -172,6 +175,8 @@ static item_t *create_item(Tuple *tuple, int len)
     else
         item->album = fmt_escape("");
 
+    item->is_http_source = is_http_source;
+
     item->next = NULL;
 
     return item;
@@ -181,7 +186,7 @@ static item_t *q_put(Tuple *tuple, int t, int len)
 {
     item_t *item;
 
-    if ((item = create_item (tuple, len)) == NULL)
+    if (!(item = create_item(tuple, len, FALSE)))
         return NULL;
 
     item->timeplayed = len;
@@ -190,12 +195,12 @@ static item_t *q_put(Tuple *tuple, int t, int len)
     return q_additem(item);
 }
 
-static item_t *set_np(Tuple *tuple, int len)
+static item_t *set_np(Tuple *tuple, int len, bool_t is_http_source)
 {
     if (np_item != NULL)
         q_item_free (np_item);
 
-    if ((np_item = create_item (tuple, len)) != NULL)
+    if ((np_item = create_item(tuple, len, is_http_source)))
         AUDDBG ("Tracking now-playing track: %s - %s\n", np_item->artist,
          np_item->title);
 
@@ -266,11 +271,72 @@ static void q_free(void)
 /* isn't there better way for that? --desowin */
 gboolean sc_timeout(gpointer data)
 {
-    if (np_item)
+    if (!np_item)
+        return TRUE;
+
+    if (aud_drct_get_playing() && !aud_drct_get_paused())
+        np_item->timeplayed++;
+
+    if (np_item->is_http_source)
     {
-        if (aud_drct_get_playing() && !aud_drct_get_paused())
-            np_item->timeplayed+=1;
+        /* This might be a stream, so check if the track info has changed. */
+        int playlist = aud_playlist_get_playing();
+        int pos = aud_playlist_get_position(playlist);
+        Tuple *tuple = aud_playlist_entry_get_tuple(playlist, pos, FALSE);
+
+        if (!tuple)
+            return TRUE;
+
+        int len = tuple_get_int(tuple, FIELD_LENGTH, NULL) / 1000;
+
+        /* Make up a length when we submit streaming to now playing.
+         * We will change it before we actually scrobble the track. */
+        if (len < 1)
+            len = 240;
+
+        item_t *current_item = create_item(tuple, len, TRUE);
+
+        if (!current_item)
+        {
+            tuple_unref(tuple);
+            return TRUE;
+        }
+
+        if (strcmp(np_item->artist, current_item->artist)
+         || strcmp(np_item->title, current_item->title)
+         || strcmp (np_item->album, current_item->album)
+         || np_item->track != current_item->track)
+        {
+            /* Now set the real length of the track. */
+            np_item->len = np_item->timeplayed;
 
+            AUDDBG ("Submitting\n");
+
+            q_additem(np_item);
+            np_item = current_item;
+            dump_queue();
+
+            sc_idle((GMutex*)data); // actually submit the queue
+
+            sc_submit_np(tuple, len);
+        }
+        else
+        {
+            q_item_free(current_item);
+
+            if (np_item->timeplayed > np_item->len)
+            {
+                /* Submit the track again to make sure it stays on now playing.
+                 * This doubles the total length we have submitted. */
+                sc_submit_np(tuple, np_item->len);
+                np_item->len *= 2;
+            }
+        }
+
+        tuple_unref(tuple);
+    }
+    else
+    {
         /*
          * Check our now-playing track to see if it should go into the queue
          */
@@ -288,6 +354,21 @@ gboolean sc_timeout(gpointer data)
     return TRUE;
 }
 
+void sc_playback_end(void)
+{
+    if (np_item && np_item->is_http_source)
+    {
+        /* Now set the real length of the track. */
+        np_item->len = np_item->timeplayed;
+
+        AUDDBG ("Submitting\n");
+
+        q_additem(np_item);
+        np_item = NULL;
+        dump_queue();
+    }
+}
+
 /* Error functions */
 
 static void sc_throw_error(char *errortxt)
@@ -778,7 +859,7 @@ static int sc_generateentry(GString *submission)
     return i;
 }
 
-static int sc_submit_np(Tuple *tuple)
+static int sc_submit_np(Tuple *tuple, int len)
 {
     CURL *curl;
     /* struct HttpPost *post = NULL , *last = NULL; */
@@ -810,7 +891,7 @@ static int sc_submit_np(Tuple *tuple)
         field_artist,
         field_title,
         field_album,
-        tuple_get_int(tuple, FIELD_LENGTH, NULL) / 1000,
+        len,
         tuple_get_int(tuple, FIELD_TRACK_NUMBER, NULL));
         curl_free(field_artist);
         curl_free(field_title);
@@ -1126,12 +1207,12 @@ void sc_init(char *uname, char *pwd, char *url)
     AUDDBG("scrobbler starting up\n");
 }
 
-void sc_addentry(GMutex *mutex, Tuple *tuple, int len)
+void sc_addentry(GMutex *mutex, Tuple *tuple, int len, bool_t is_http_source)
 {
     g_mutex_lock(mutex);
 
-    sc_submit_np(tuple);
-    set_np(tuple, len);
+    sc_submit_np(tuple, len);
+    set_np(tuple, len, is_http_source);
 
     /*
      * This will help make sure the queue will be saved on a nasty
diff --git a/src/scrobbler/scrobbler.h b/src/scrobbler/scrobbler.h
index 2203696..038c1f3 100644
--- a/src/scrobbler/scrobbler.h
+++ b/src/scrobbler/scrobbler.h
@@ -14,9 +14,11 @@ gboolean sc_timeout(gpointer data);
 
 int sc_idle(GMutex *);
 void sc_init(char *, char *, char *);
-void sc_addentry(GMutex *, Tuple *, int);
+void sc_addentry(GMutex *mutex, Tuple *tuple, int len, bool_t is_http_source);
 void sc_cleaner(void);
 int sc_catch_error(void);
 char *sc_fetch_error(void);
 void sc_clear_error(void);
+void sc_playback_end(void);
+
 #endif
