[vlc-devel] [PATCH v3 3/4] audioscrobbler: implement Now Playing feature

Jonas Lundqvist jonas at gannon.se
Mon Nov 9 16:39:41 CET 2015


Submission of the currently playing song will show up on last.fm as
"Now Playing".
---
 modules/misc/audioscrobbler.c | 150 ++++++++++++++++++++++++++++--------------
 1 file changed, 102 insertions(+), 48 deletions(-)

diff --git a/modules/misc/audioscrobbler.c b/modules/misc/audioscrobbler.c
index 37228f3..fc08687 100644
--- a/modules/misc/audioscrobbler.c
+++ b/modules/misc/audioscrobbler.c
@@ -25,8 +25,7 @@
 /* Last.fm Submissions protocol version: 1.2
  * http://www.last.fm/api/submissions
  *
- * TODO:    "Now Playing" feature (not mandatory)
- *          Update to new API? http://www.last.fm/api/scrobbling
+ * TODO:    Update to new API? http://www.last.fm/api/scrobbling
  */
 /*****************************************************************************
  * Preamble
@@ -87,6 +86,9 @@ struct intf_sys_t
     /* submission of played songs */
     vlc_url_t               p_submit_url;       /**< where to submit data   */
 
+    /* submission of playing song */
+    vlc_url_t               p_nowp_url;         /**< where to submit data   */
+
     char                    psz_auth_token[33]; /**< Authentication token */
 
     /* data about song currently playing */
@@ -95,7 +97,7 @@ struct intf_sys_t
     mtime_t                 time_pause;         /**< time when vlc paused   */
     mtime_t                 time_total_pauses;  /**< total time in pause    */
 
-    bool                    b_submit;           /**< do we have to submit ? */
+    bool                    b_submit_nowp;      /**< do we have to submit ? */
 
     bool                    b_meta_read;        /**< if we read the song's
                                                  * metadata already         */
@@ -191,7 +193,7 @@ static void ReadMetaData(intf_thread_t *p_this, input_thread_t *p_input)
     }
 
     /* Now we have read the mandatory meta data, so we can submit that info */
-    p_sys->b_submit = true;
+    p_sys->b_submit_nowp = true;
 
     ALLOC_ITEM_META(p_sys->p_current_song.psz_b, Album);
     if (!p_sys->p_current_song.psz_b)
@@ -210,6 +212,8 @@ static void ReadMetaData(intf_thread_t *p_this, input_thread_t *p_input)
 
     msg_Dbg(p_this, "Meta data registered");
 
+    vlc_cond_signal(&p_sys->wait);
+
 end:
     vlc_mutex_unlock(&p_sys->lock);
 }
@@ -223,7 +227,9 @@ static void AddToQueue (intf_thread_t *p_this)
     intf_sys_t                  *p_sys = p_this->p_sys;
 
     vlc_mutex_lock(&p_sys->lock);
-    if (!p_sys->b_submit)
+
+    /* Check that we have the mandatory meta data */
+    if (!p_sys->p_current_song.psz_t || !p_sys->p_current_song.psz_a)
         goto end;
 
     /* wait for the user to listen enough before submitting */
@@ -291,7 +297,6 @@ static void AddToQueue (intf_thread_t *p_this)
 
 end:
     DeleteSong(&p_sys->p_current_song);
-    p_sys->b_submit = false;
     vlc_mutex_unlock(&p_sys->lock);
 }
 
@@ -354,7 +359,6 @@ static int ItemChange(vlc_object_t *p_this, const char *psz_var,
     VLC_UNUSED(oldval);
 
     p_sys->b_meta_read      = false;
-    p_sys->b_submit         = false;
 
     if (p_sys->p_input != NULL)
     {
@@ -403,6 +407,7 @@ static int Open(vlc_object_t *p_this)
         return VLC_ENOMEM;
 
     p_intf->p_sys = p_sys;
+    p_sys->b_submit_nowp = false;
 
     vlc_mutex_init(&p_sys->lock);
     vlc_cond_init(&p_sys->wait);
@@ -443,6 +448,7 @@ static void Close(vlc_object_t *p_this)
     for (i = 0; i < p_sys->i_songs; i++)
         DeleteSong(&p_sys->p_queue[i]);
     vlc_UrlClean(&p_sys->p_submit_url);
+    vlc_UrlClean(&p_sys->p_nowp_url);
     vlc_cond_destroy(&p_sys->wait);
     vlc_mutex_destroy(&p_sys->lock);
     free(p_sys);
@@ -606,6 +612,13 @@ static int Handshake(intf_thread_t *p_this)
 
     /* We need to read the nowplaying url */
     p_buffer_pos += 7; /* we skip "http://" */
+    psz_url = strndup(p_buffer_pos, strcspn(p_buffer_pos, "\n"));
+    if (!psz_url)
+        goto oom;
+
+    vlc_UrlParse(&p_sys->p_nowp_url, psz_url);
+    free(psz_url);
+
     p_buffer_pos = strstr(p_buffer_pos, "http://");
     if (!p_buffer_pos || strlen(p_buffer_pos) == 7)
         goto proto;
@@ -656,6 +669,7 @@ static void *Run(void *data)
     uint8_t                 p_buffer[1024];
     int                     canc = vlc_savecancel();
     bool                    b_handshaked = false;
+    bool                    b_nowp_submission_ongoing = false;
 
     /* data about audioscrobbler session */
     mtime_t                 next_exchange = 0; /**< when can we send data  */
@@ -672,7 +686,7 @@ static void *Run(void *data)
         vlc_mutex_lock(&p_sys->lock);
         mutex_cleanup_push(&p_sys->lock);
 
-        while (p_sys->i_songs == 0)
+        while (p_sys->i_songs == 0 && p_sys->b_submit_nowp == false)
             vlc_cond_wait(&p_sys->wait, &p_sys->lock);
 
         vlc_cleanup_pop();
@@ -722,56 +736,87 @@ static void *Run(void *data)
 
         msg_Dbg(p_intf, "Going to submit some data...");
         char *psz_submit;
+        vlc_url_t *url;
+        char *psz_submit_song, *psz_submit_tmp;
+
         if (asprintf(&psz_submit, "s=%s", p_sys->psz_auth_token) == -1)
             break;
 
         /* forge the HTTP POST request */
         vlc_mutex_lock(&p_sys->lock);
-        audioscrobbler_song_t *p_song;
-        for (int i_song = 0 ; i_song < p_sys->i_songs ; i_song++)
+
+        if (p_sys->b_submit_nowp)
         {
-            char *psz_submit_song, *psz_submit_tmp;
-            p_song = &p_sys->p_queue[i_song];
+            b_nowp_submission_ongoing = true;
+            url = &p_sys->p_nowp_url;
             if (asprintf(&psz_submit_song,
-                    "&a%%5B%d%%5D=%s"
-                    "&t%%5B%d%%5D=%s"
-                    "&i%%5B%d%%5D=%u"
-                    "&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, (unsigned)p_song->date, /* HACK: %ju (uintmax_t) unsupported on Windows */
-                    i_song,
-                    i_song,
-                    i_song, p_song->i_l,
-                    i_song, p_song->psz_b,
-                    i_song, p_song->psz_n,
-                    i_song, p_song->psz_m
-           ) == -1)
+                "&a=%s"
+                "&t=%s"
+                "&b=%s"
+                "&l=%d"
+                "&n=%s"
+                "&m=%s",
+                p_sys->p_current_song.psz_a,
+                p_sys->p_current_song.psz_t,
+                p_sys->p_current_song.psz_b,
+                p_sys->p_current_song.i_l,
+                p_sys->p_current_song.psz_n,
+                p_sys->p_current_song.psz_m
+                ) == -1)
             {   /* Out of memory */
                 vlc_mutex_unlock(&p_sys->lock);
                 goto out;
             }
-            psz_submit_tmp = psz_submit;
-            if (asprintf(&psz_submit, "%s%s",
-                    psz_submit_tmp, psz_submit_song) == -1)
-            {   /* Out of memory */
-                free(psz_submit_tmp);
-                free(psz_submit_song);
-                vlc_mutex_unlock(&p_sys->lock);
-                goto out;
+
+        }
+        else
+        {
+            url = &p_sys->p_submit_url;
+            audioscrobbler_song_t *p_song;
+            for (int i_song = 0 ; i_song < p_sys->i_songs ; i_song++)
+            {
+                p_song = &p_sys->p_queue[i_song];
+                if (asprintf(&psz_submit_song,
+                        "&a%%5B%d%%5D=%s"
+                        "&t%%5B%d%%5D=%s"
+                        "&i%%5B%d%%5D=%u"
+                        "&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, (unsigned)p_song->date, /* HACK: %ju (uintmax_t) unsupported on Windows */
+                        i_song,
+                        i_song,
+                        i_song, p_song->i_l,
+                        i_song, p_song->psz_b,
+                        i_song, p_song->psz_n,
+                        i_song, p_song->psz_m
+                       ) == -1)
+                {   /* Out of memory */
+                        vlc_mutex_unlock(&p_sys->lock);
+                        goto out;
+                }
             }
-            free(psz_submit_song);
-            free(psz_submit_tmp);
         }
+
+        psz_submit_tmp = psz_submit;
+        int print_ret = asprintf(&psz_submit, "%s%s",
+                                 psz_submit_tmp, psz_submit_song);
+        free(psz_submit_tmp);
+        free(psz_submit_song);
         vlc_mutex_unlock(&p_sys->lock);
 
-        int i_post_socket = net_ConnectTCP(p_intf, p_sys->p_submit_url.psz_host,
-                                        p_sys->p_submit_url.i_port);
+        if (print_ret == -1)
+        {   /* Out of memory */
+            goto out;
+        }
+
+        int i_post_socket = net_ConnectTCP(p_intf, url->psz_host,
+                                        url->i_port);
 
         if (i_post_socket == -1)
         {
@@ -794,8 +839,8 @@ static void *Run(void *data)
             "\r\n"
             "%s\r\n"
             "\r\n",
-            p_sys->p_submit_url.psz_path, strlen(psz_submit),
-            p_sys->p_submit_url.psz_host, psz_submit
+            url->psz_path, strlen(psz_submit),
+            url->psz_host, psz_submit
        );
 
         free(psz_submit);
@@ -841,9 +886,18 @@ static void *Run(void *data)
 
         if (strstr((char *) p_buffer, "OK"))
         {
-            for (int i = 0; i < p_sys->i_songs; i++)
-                DeleteSong(&p_sys->p_queue[i]);
-            p_sys->i_songs = 0;
+            if (b_nowp_submission_ongoing)
+            {
+                b_nowp_submission_ongoing = false;
+                p_sys->b_submit_nowp = false;
+            }
+            else
+            {
+                for (int i = 0; i < p_sys->i_songs; i++)
+                    DeleteSong(&p_sys->p_queue[i]);
+                p_sys->i_songs = 0;
+            }
+
             i_interval = 0;
             next_exchange = 0;
             msg_Dbg(p_intf, "Submission successful!");
-- 
2.6.2



More information about the vlc-devel mailing list