diff --git a/modules/misc/audioscrobbler.c b/modules/misc/audioscrobbler.c
index fbdd499..22bf1df 100644
--- a/modules/misc/audioscrobbler.c
+++ b/modules/misc/audioscrobbler.c
@@ -64,6 +64,7 @@ typedef struct audioscrobbler_song_t
     char        *psz_b;             /**< track album      */
     char        *psz_n;             /**< track number     */
     int         i_l;                /**< track length     */
+    char        *psz_p;             /**< track path       */
     char        *psz_m;             /**< musicbrainz id   */
     time_t      date;               /**< date since epoch */
     mtime_t     i_start;            /**< playing start    */
@@ -107,6 +108,9 @@ struct intf_sys_t
 
     bool              b_meta_read;        /**< if we read the song's
                                                  * metadata already         */
+
+    bool                    b_official_scrobble;/**< do we scrobble through 
+                                                  *  the official client?   */
 };
 
 static int  Open            ( vlc_object_t * );
@@ -126,6 +130,14 @@ static void DeleteSong      ( audioscrobbler_song_t* );
 static int ParseURL         ( char *, char **, char **, int * );
 static void HandleInterval  ( mtime_t *, unsigned int * );
 
+static char* EncodeAmp( const char* );
+
+static int TransmitStart    ( intf_thread_t * );
+static int TransmitStop     ( intf_thread_t * );
+static int TransmitResume   ( intf_thread_t * );
+static int TransmitPause    ( intf_thread_t * );
+static int Transmit         ( intf_thread_t *, const char * );
+
 /*****************************************************************************
  * Module descriptor
  ****************************************************************************/
@@ -138,6 +150,8 @@ static void HandleInterval  ( mtime_t *, unsigned int * );
 /* This error value is used when last.fm plugin has to be unloaded. */
 #define VLC_AUDIOSCROBBLER_EFATAL -69
 
+#define OFFICIAL_CLIENT_PORT 33367
+
 /* last.fm client identifier */
 #define CLIENT_NAME     PACKAGE
 #define CLIENT_VERSION  VERSION
@@ -265,6 +279,9 @@ static void Run( intf_thread_t *p_intf )
     uint8_t                 p_buffer[1024];
     char                    *p_buffer_pos;
     int                     i_post_socket;
+    char                    *psz_artist;
+    char                    *psz_title;
+    char                    *psz_album;
 
     intf_sys_t *p_sys = p_intf->p_sys;
 
@@ -292,6 +309,9 @@ static void Run( intf_thread_t *p_intf )
         if( b_wait )
             continue; /* holding on until next_exchange */
 
+        if( p_sys->b_official_scrobble ) /* Don't handshake if official client is scrobbling */
+            continue;
+
         /* handshake if needed */
         if( p_sys->b_handshaked == false )
         {
@@ -351,21 +371,33 @@ static void Run( intf_thread_t *p_intf )
         for( i_song = 0 ; i_song < p_sys->i_songs ; i_song++ )
         {
             p_song = &p_sys->p_queue[i_song];
+
+            psz_artist = encode_URI_component( p_song->psz_a );
+            psz_title = encode_URI_component( p_song->psz_t );
+            psz_album = encode_URI_component( p_song->psz_b );
+
             if( !asprintf( &psz_submit_song,
                     "&a%%5B%d%%5D=%s&t%%5B%d%%5D=%s"
                     "&i%%5B%d%%5D=%llu&o%%5B%d%%5D=P&r%%5B%d%%5D="
                     "&l%%5B%d%%5D=%d&b%%5B%d%%5D=%s"
                     "&n%%5B%d%%5D=%s&m%%5B%d%%5D=%s",
-                    i_song, p_song->psz_a,           i_song, p_song->psz_t,
+                    i_song, psz_artist,              i_song, psz_title,
                     i_song, (uintmax_t)p_song->date, i_song, i_song,
-                    i_song, p_song->i_l,             i_song, p_song->psz_b,
+                    i_song, p_song->i_l,             i_song, psz_album,
                     i_song, p_song->psz_n,           i_song, p_song->psz_m
             ) )
             {   /* Out of memory */
                 vlc_mutex_unlock( &p_sys->lock );
+                free( psz_artist );
+                free( psz_title );
+                free( psz_album );
                 Unload( p_intf );
                 return;
             }
+            free( psz_artist );
+            free( psz_title );
+            free( psz_album );
+
             psz_submit_tmp = psz_submit;
             if( !asprintf( &psz_submit, "%s%s",
                     psz_submit_tmp, psz_submit_song ) )
@@ -481,11 +513,24 @@ static int PlayingChange( vlc_object_t *p_this, const char *psz_var,
     }
 
     if( newval.i_int >= END_S )
-        AddToQueue( p_intf );
+    {
+        if( p_sys->b_official_scrobble )
+            TransmitStop( p_intf );
+        else
+            AddToQueue( p_intf );
+    }
     else if( oldval.i_int == PLAYING_S && newval.i_int == PAUSE_S )
+    {
         p_sys->time_pause = mdate();
+        if( p_sys->b_official_scrobble )
+            TransmitPause( p_intf );
+    }
     else if( oldval.i_int == PAUSE_S && newval.i_int == PLAYING_S )
+    {
         p_sys->time_total_pauses += ( mdate() - p_sys->time_pause );
+        if( p_sys->b_official_scrobble )
+            TransmitResume( p_intf );
+    }
 
     return VLC_SUCCESS;
 }
@@ -907,6 +952,7 @@ static void DeleteSong( audioscrobbler_song_t* p_song )
     FREENULL( p_song->psz_t );
     FREENULL( p_song->psz_m );
     FREENULL( p_song->psz_n );
+    FREENULL( p_song->psz_p );
 }
 
 /*****************************************************************************
@@ -943,13 +989,7 @@ static int ReadMetaData( intf_thread_t *p_this )
     psz_meta = input_item_Get##b( p_item ); \
     if( psz_meta && *psz_meta ) \
     { \
-        a = encode_URI_component( psz_meta ); \
-        if( !a ) \
-        { \
-            free( psz_meta ); \
-            return VLC_ENOMEM; \
-        } \
-        free( psz_meta ); \
+        a = psz_meta; \
     }
 
     vlc_mutex_lock( &p_sys->lock );
@@ -993,12 +1033,26 @@ static int ReadMetaData( intf_thread_t *p_this )
     ALLOC_ITEM_META( p_sys->p_current_song.psz_n, TrackNum )
     else
         p_sys->p_current_song.psz_n = calloc( 1, 1 );
+
+    ALLOC_ITEM_META( p_sys->p_current_song.psz_p, URL )
+    else
+        p_sys->p_current_song.psz_p = calloc( 1, 1 );
 #undef ALLOC_ITEM_META
 
     msg_Dbg( p_this, "Meta data registered" );
 
     vlc_mutex_unlock( &p_sys->lock );
     vlc_object_release( p_input );
+
+    if ( TransmitStart( p_this ) )
+    {
+        /* If we send the start command to the official client it will handshake. */
+        p_sys->b_handshaked = false;
+        p_sys->b_official_scrobble = true;
+    }
+    else
+        p_sys->b_official_scrobble = false;
+
     return VLC_SUCCESS;
 
 }
@@ -1020,3 +1074,185 @@ static void HandleInterval( mtime_t *next, unsigned int *i_interval )
     *next = mdate() + ( *i_interval * 1000000 * 60 );
 }
 
+/*****************************************************************************
+ * EncodeAmp : Replace &'s with &&'s
+ *****************************************************************************/
+
+static char* EncodeAmp( const char* psz_in )
+{
+    int i_in_len = strlen( psz_in );
+    int i_out_len = i_in_len;
+    char *psz_out;
+    int i_in_iter, i_out_iter;
+
+    for ( i_in_iter = 0; i_in_iter  < i_in_len; i_in_iter++ )
+    {
+        if ( psz_in[i_in_iter ] == '&' )
+            i_out_len += 1; /* & -> && */
+    }
+
+    psz_out = malloc( i_out_len + 1 );
+
+    i_out_iter = 0;
+    for ( i_in_iter = 0; i_in_iter <= i_in_len; i_in_iter++ )
+    {
+        if ( psz_in[i_in_iter] == '&' )
+        {
+            psz_out[  i_out_iter  ] = '&';
+            psz_out[i_out_iter + 1] = '&';
+
+            i_out_iter += 2;
+        }
+        else
+        {
+            psz_out[i_out_iter] = psz_in[i_in_iter];
+            i_out_iter++;
+        }
+    }
+
+    return psz_out;
+}
+
+/*****************************************************************************
+ * TransmitStart : Transmit start of song command to the Official Last.fm Client
+ *****************************************************************************/
+
+static int TransmitStart( intf_thread_t *p_this )
+{
+    char                  *psz_submit_song;
+    audioscrobbler_song_t *p_song;
+    int                   i_res;
+    char                  *psz_artist;
+    char                  *psz_title;
+    char                  *psz_album;
+    char                  *psz_path;
+
+    intf_sys_t            *p_sys = p_this->p_sys;
+
+    vlc_mutex_lock( &p_sys->lock );
+
+    p_song = &p_sys->p_current_song;
+
+    psz_artist = EncodeAmp( p_song->psz_a );
+    psz_title =  EncodeAmp( p_song->psz_t );
+    psz_album =  EncodeAmp( p_song->psz_b );
+    psz_path =   EncodeAmp( p_song->psz_p );
+
+    if ( !asprintf( &psz_submit_song,
+                    "START c=vlc&a=%s&t=%s&b=%s&l=%i&p=%s\n",
+                    psz_artist,
+                    psz_title,
+                    psz_album,
+                    p_song->i_l,
+                    psz_path
+            ) )
+    {   /* Out of memory */
+        vlc_mutex_unlock( &p_sys->lock );
+        Unload( p_this );
+        return false;
+    }
+
+    free( psz_artist );
+    free( psz_title );
+    free( psz_album );
+    free( psz_path );
+
+    vlc_mutex_unlock( &p_sys->lock );
+
+    i_res = Transmit( p_this, psz_submit_song );
+
+    free( psz_submit_song );
+
+    return i_res;
+}
+
+/*****************************************************************************
+ * TransmitStart : Transmit stop command to the Official Last.fm Client
+ *****************************************************************************/
+
+static int TransmitStop( intf_thread_t *p_this )
+{
+    return Transmit( p_this, "STOP c=vlc\n" );
+}
+
+/*****************************************************************************
+ * TransmitStart : Transmit resume command to the Official Last.fm Client
+ *****************************************************************************/
+
+static int TransmitResume( intf_thread_t *p_this )
+{
+    return Transmit( p_this, "RESUME c=vlc\n" );
+}
+
+/*****************************************************************************
+ * TransmitStart : Transmit pause command to the Official Last.fm Client
+ *****************************************************************************/
+
+static int TransmitPause( intf_thread_t *p_this )
+{
+    return Transmit( p_this, "PAUSE c=vlc\n" );
+}
+
+
+/*****************************************************************************
+ * transmit : Transmit data to the Official Last.fm Client
+ *****************************************************************************/
+
+static int Transmit( intf_thread_t *p_this, const char *message )
+{
+    int     i_net_ret;
+    int     i_post_socket;
+    uint8_t p_buffer[1024];
+
+    msg_Dbg( p_this, message );
+
+    vlc_object_lock( p_this );
+
+    i_post_socket = net_ConnectTCP( p_this, "localhost", OFFICIAL_CLIENT_PORT );
+
+    if( i_post_socket == -1 )
+    {
+        /* If connection fails, we assume client is not running */
+        msg_Dbg( p_this, "Connection faild, we assume client is not running" );
+        vlc_object_unlock( p_this );     
+        return false;
+    }
+
+    /* we transmit the data */
+    i_net_ret = net_Write( VLC_OBJECT( p_this ), i_post_socket, NULL,
+                            (unsigned char*)message, strlen( message ) );
+
+    if( i_net_ret == -1 )
+    {
+        /* If connection fails, we assume client is not running */
+        msg_Dbg( p_this, "Socket write failed, we assume client is not running" );
+        vlc_object_unlock( p_this );
+        return false;
+    }
+
+    i_net_ret = net_Read( p_this, i_post_socket, NULL,
+                    p_buffer, 1023, false );
+
+    p_buffer[i_net_ret] = '\0';
+
+    if( i_net_ret <= 0 )
+    {
+        /* We got no response or it wasn't "OK\n" */
+        msg_Dbg( p_this, "Client failed to respond." );
+        return false;
+    }
+
+    if( strcmp( ( char * ) p_buffer, "OK\n" ) != 0 )
+    {
+        msg_Dbg( p_this, "Client did not respond with OK." );
+        msg_Dbg( p_this, ( char * ) p_buffer );
+        return false;
+    }
+
+    net_Close( i_post_socket );
+
+    vlc_object_unlock( p_this );
+
+    return true;
+}
+
