Commit f016bce3 authored by Jonas Lundqvist's avatar Jonas Lundqvist Committed by Jean-Baptiste Kempf

audioscrobbler: implement Now Playing feature

Submission of the currently playing song will show up on last.fm as
"Now Playing".
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent d7dcada3
...@@ -25,8 +25,7 @@ ...@@ -25,8 +25,7 @@
/* Last.fm Submissions protocol version: 1.2 /* Last.fm Submissions protocol version: 1.2
* http://www.last.fm/api/submissions * http://www.last.fm/api/submissions
* *
* TODO: "Now Playing" feature (not mandatory) * TODO: Update to new API? http://www.last.fm/api/scrobbling
* Update to new API? http://www.last.fm/api/scrobbling
*/ */
/***************************************************************************** /*****************************************************************************
* Preamble * Preamble
...@@ -87,6 +86,9 @@ struct intf_sys_t ...@@ -87,6 +86,9 @@ struct intf_sys_t
/* submission of played songs */ /* submission of played songs */
vlc_url_t p_submit_url; /**< where to submit data */ 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 */ char psz_auth_token[33]; /**< Authentication token */
/* data about song currently playing */ /* data about song currently playing */
...@@ -95,7 +97,7 @@ struct intf_sys_t ...@@ -95,7 +97,7 @@ struct intf_sys_t
mtime_t time_pause; /**< time when vlc paused */ mtime_t time_pause; /**< time when vlc paused */
mtime_t time_total_pauses; /**< total time in pause */ 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 bool b_meta_read; /**< if we read the song's
* metadata already */ * metadata already */
...@@ -191,7 +193,7 @@ static void ReadMetaData(intf_thread_t *p_this, input_thread_t *p_input) ...@@ -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 */ /* 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); ALLOC_ITEM_META(p_sys->p_current_song.psz_b, Album);
if (!p_sys->p_current_song.psz_b) 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) ...@@ -210,6 +212,8 @@ static void ReadMetaData(intf_thread_t *p_this, input_thread_t *p_input)
msg_Dbg(p_this, "Meta data registered"); msg_Dbg(p_this, "Meta data registered");
vlc_cond_signal(&p_sys->wait);
end: end:
vlc_mutex_unlock(&p_sys->lock); vlc_mutex_unlock(&p_sys->lock);
} }
...@@ -223,7 +227,9 @@ static void AddToQueue (intf_thread_t *p_this) ...@@ -223,7 +227,9 @@ static void AddToQueue (intf_thread_t *p_this)
intf_sys_t *p_sys = p_this->p_sys; intf_sys_t *p_sys = p_this->p_sys;
vlc_mutex_lock(&p_sys->lock); 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; goto end;
/* wait for the user to listen enough before submitting */ /* wait for the user to listen enough before submitting */
...@@ -291,7 +297,6 @@ static void AddToQueue (intf_thread_t *p_this) ...@@ -291,7 +297,6 @@ static void AddToQueue (intf_thread_t *p_this)
end: end:
DeleteSong(&p_sys->p_current_song); DeleteSong(&p_sys->p_current_song);
p_sys->b_submit = false;
vlc_mutex_unlock(&p_sys->lock); vlc_mutex_unlock(&p_sys->lock);
} }
...@@ -354,7 +359,6 @@ static int ItemChange(vlc_object_t *p_this, const char *psz_var, ...@@ -354,7 +359,6 @@ static int ItemChange(vlc_object_t *p_this, const char *psz_var,
VLC_UNUSED(oldval); VLC_UNUSED(oldval);
p_sys->b_meta_read = false; p_sys->b_meta_read = false;
p_sys->b_submit = false;
if (p_sys->p_input != NULL) if (p_sys->p_input != NULL)
{ {
...@@ -443,6 +447,7 @@ static void Close(vlc_object_t *p_this) ...@@ -443,6 +447,7 @@ static void Close(vlc_object_t *p_this)
for (i = 0; i < p_sys->i_songs; i++) for (i = 0; i < p_sys->i_songs; i++)
DeleteSong(&p_sys->p_queue[i]); DeleteSong(&p_sys->p_queue[i]);
vlc_UrlClean(&p_sys->p_submit_url); vlc_UrlClean(&p_sys->p_submit_url);
vlc_UrlClean(&p_sys->p_nowp_url);
vlc_cond_destroy(&p_sys->wait); vlc_cond_destroy(&p_sys->wait);
vlc_mutex_destroy(&p_sys->lock); vlc_mutex_destroy(&p_sys->lock);
free(p_sys); free(p_sys);
...@@ -606,6 +611,13 @@ static int Handshake(intf_thread_t *p_this) ...@@ -606,6 +611,13 @@ static int Handshake(intf_thread_t *p_this)
/* We need to read the nowplaying url */ /* We need to read the nowplaying url */
p_buffer_pos += 7; /* we skip "http://" */ 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://"); p_buffer_pos = strstr(p_buffer_pos, "http://");
if (!p_buffer_pos || strlen(p_buffer_pos) == 7) if (!p_buffer_pos || strlen(p_buffer_pos) == 7)
goto proto; goto proto;
...@@ -656,6 +668,7 @@ static void *Run(void *data) ...@@ -656,6 +668,7 @@ static void *Run(void *data)
uint8_t p_buffer[1024]; uint8_t p_buffer[1024];
int canc = vlc_savecancel(); int canc = vlc_savecancel();
bool b_handshaked = false; bool b_handshaked = false;
bool b_nowp_submission_ongoing = false;
/* data about audioscrobbler session */ /* data about audioscrobbler session */
mtime_t next_exchange = 0; /**< when can we send data */ mtime_t next_exchange = 0; /**< when can we send data */
...@@ -672,7 +685,7 @@ static void *Run(void *data) ...@@ -672,7 +685,7 @@ static void *Run(void *data)
vlc_mutex_lock(&p_sys->lock); vlc_mutex_lock(&p_sys->lock);
mutex_cleanup_push(&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_cond_wait(&p_sys->wait, &p_sys->lock);
vlc_cleanup_pop(); vlc_cleanup_pop();
...@@ -722,15 +735,45 @@ static void *Run(void *data) ...@@ -722,15 +735,45 @@ static void *Run(void *data)
msg_Dbg(p_intf, "Going to submit some data..."); msg_Dbg(p_intf, "Going to submit some data...");
char *psz_submit; 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) if (asprintf(&psz_submit, "s=%s", p_sys->psz_auth_token) == -1)
break; break;
/* forge the HTTP POST request */ /* forge the HTTP POST request */
vlc_mutex_lock(&p_sys->lock); vlc_mutex_lock(&p_sys->lock);
if (p_sys->b_submit_nowp)
{
b_nowp_submission_ongoing = true;
url = &p_sys->p_nowp_url;
if (asprintf(&psz_submit_song,
"&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;
}
}
else
{
url = &p_sys->p_submit_url;
audioscrobbler_song_t *p_song; audioscrobbler_song_t *p_song;
for (int i_song = 0 ; i_song < p_sys->i_songs ; i_song++) for (int i_song = 0 ; i_song < p_sys->i_songs ; i_song++)
{ {
char *psz_submit_song, *psz_submit_tmp;
p_song = &p_sys->p_queue[i_song]; p_song = &p_sys->p_queue[i_song];
if (asprintf(&psz_submit_song, if (asprintf(&psz_submit_song,
"&a%%5B%d%%5D=%s" "&a%%5B%d%%5D=%s"
...@@ -756,22 +799,23 @@ static void *Run(void *data) ...@@ -756,22 +799,23 @@ static void *Run(void *data)
vlc_mutex_unlock(&p_sys->lock); vlc_mutex_unlock(&p_sys->lock);
goto out; goto out;
} }
}
}
psz_submit_tmp = psz_submit; psz_submit_tmp = psz_submit;
if (asprintf(&psz_submit, "%s%s", int print_ret = asprintf(&psz_submit, "%s%s",
psz_submit_tmp, psz_submit_song) == -1) psz_submit_tmp, psz_submit_song);
{ /* Out of memory */
free(psz_submit_tmp); free(psz_submit_tmp);
free(psz_submit_song); free(psz_submit_song);
vlc_mutex_unlock(&p_sys->lock); vlc_mutex_unlock(&p_sys->lock);
if (print_ret == -1)
{ /* Out of memory */
goto out; goto out;
} }
free(psz_submit_song);
free(psz_submit_tmp);
}
vlc_mutex_unlock(&p_sys->lock);
int i_post_socket = net_ConnectTCP(p_intf, p_sys->p_submit_url.psz_host, int i_post_socket = net_ConnectTCP(p_intf, url->psz_host,
p_sys->p_submit_url.i_port); url->i_port);
if (i_post_socket == -1) if (i_post_socket == -1)
{ {
...@@ -794,8 +838,8 @@ static void *Run(void *data) ...@@ -794,8 +838,8 @@ static void *Run(void *data)
"\r\n" "\r\n"
"%s\r\n" "%s\r\n"
"\r\n", "\r\n",
p_sys->p_submit_url.psz_path, strlen(psz_submit), url->psz_path, strlen(psz_submit),
p_sys->p_submit_url.psz_host, psz_submit url->psz_host, psz_submit
); );
free(psz_submit); free(psz_submit);
...@@ -840,10 +884,19 @@ static void *Run(void *data) ...@@ -840,10 +884,19 @@ static void *Run(void *data)
} }
if (strstr((char *) p_buffer, "OK")) if (strstr((char *) p_buffer, "OK"))
{
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++) for (int i = 0; i < p_sys->i_songs; i++)
DeleteSong(&p_sys->p_queue[i]); DeleteSong(&p_sys->p_queue[i]);
p_sys->i_songs = 0; p_sys->i_songs = 0;
}
i_interval = 0; i_interval = 0;
next_exchange = 0; next_exchange = 0;
msg_Dbg(p_intf, "Submission successful!"); msg_Dbg(p_intf, "Submission successful!");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment