mirror of
https://github.com/owntone/owntone-server.git
synced 2025-02-03 01:46:02 -05:00
Modifications to the playqueue-clear command:
- do not stop playback when clearing the UpNext queue - clear history, if mode=0x68697374 ("hist")
This commit is contained in:
parent
ce209bae7a
commit
b7cb0da2c2
103
src/httpd_dacp.c
103
src/httpd_dacp.c
@ -1219,51 +1219,50 @@ dacp_reply_playqueuecontents(struct evhttp_request *req, struct evbuffer *evbuf,
|
|||||||
DPRINTF(E_LOG, L_DACP, "Invalid span value in playqueue-contents request\n");
|
DPRINTF(E_LOG, L_DACP, "Invalid span value in playqueue-contents request\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
songlist = NULL;
|
|
||||||
i = 0;
|
i = 0;
|
||||||
n = 0; // count of songs in songlist
|
n = 0; // count of songs in songlist
|
||||||
player_get_status(&status);
|
songlist = evbuffer_new();
|
||||||
|
if (!songlist)
|
||||||
/* Get queue and make songlist only if playing or paused */
|
|
||||||
if (status.status != PLAY_STOPPED)
|
|
||||||
{
|
{
|
||||||
songlist = evbuffer_new();
|
DPRINTF(E_LOG, L_DACP, "Could not allocate songlist evbuffer for playqueue-contents\n");
|
||||||
if (!songlist)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DACP, "Could not allocate songlist evbuffer for playqueue-contents\n");
|
|
||||||
|
|
||||||
dmap_send_error(req, "ceQR", "Out of memory");
|
dmap_send_error(req, "ceQR", "Out of memory");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the span parameter is negativ make song list for Previously Played,
|
* If the span parameter is negativ make song list for Previously Played,
|
||||||
* otherwise make song list for Up Next and begin with first song after playlist position.
|
* otherwise make song list for Up Next and begin with first song after playlist position.
|
||||||
*/
|
*/
|
||||||
if (span < 0)
|
if (span < 0)
|
||||||
|
{
|
||||||
|
history = player_history_get();
|
||||||
|
if (abs(span) > history->count)
|
||||||
{
|
{
|
||||||
history = player_history_get();
|
start_index = history->start_index;
|
||||||
if (abs(span) > history->count)
|
|
||||||
{
|
|
||||||
start_index = history->start_index;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
start_index = (history->start_index + history->count - abs(span)) % MAX_HISTORY_COUNT;
|
|
||||||
}
|
|
||||||
for (n = 0; n < history->count && n < abs(span); n++)
|
|
||||||
{
|
|
||||||
ret = playqueuecontents_add_source(songlist, history->id[(start_index + n) % MAX_HISTORY_COUNT], (n + 1), status.plid);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
DPRINTF(E_LOG, L_DACP, "Could not add song to songlist for playqueue-contents\n");
|
|
||||||
|
|
||||||
dmap_send_error(req, "ceQR", "Out of memory");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
start_index = (history->start_index + history->count - abs(span)) % MAX_HISTORY_COUNT;
|
||||||
|
}
|
||||||
|
for (n = 0; n < history->count && n < abs(span); n++)
|
||||||
|
{
|
||||||
|
ret = playqueuecontents_add_source(songlist, history->id[(start_index + n) % MAX_HISTORY_COUNT], (n + 1), status.plid);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_DACP, "Could not add song to songlist for playqueue-contents\n");
|
||||||
|
|
||||||
|
dmap_send_error(req, "ceQR", "Out of memory");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player_get_status(&status);
|
||||||
|
|
||||||
|
/* Get queue and make songlist only if playing or paused */
|
||||||
|
if (status.status != PLAY_STOPPED)
|
||||||
{
|
{
|
||||||
/* Fast forward to song currently being played */
|
/* Fast forward to song currently being played */
|
||||||
head = player_queue_get();
|
head = player_queue_get();
|
||||||
@ -1271,7 +1270,7 @@ dacp_reply_playqueuecontents(struct evhttp_request *req, struct evbuffer *evbuf,
|
|||||||
{
|
{
|
||||||
ps = head;
|
ps = head;
|
||||||
while ((ps->id != status.id) && (ps = next_ps(ps, status.shuffle)) && (ps != head))
|
while ((ps->id != status.id) && (ps = next_ps(ps, status.shuffle)) && (ps != head))
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
while ((n < abs(span)) && (ps = next_ps(ps, status.shuffle)) && (ps != head))
|
while ((n < abs(span)) && (ps = next_ps(ps, status.shuffle)) && (ps != head))
|
||||||
{
|
{
|
||||||
@ -1365,6 +1364,32 @@ dacp_reply_playqueuecontents(struct evhttp_request *req, struct evbuffer *evbuf,
|
|||||||
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
|
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dacp_reply_playqueueedit_clear(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query)
|
||||||
|
{
|
||||||
|
const char *param;
|
||||||
|
int clear_hist;
|
||||||
|
|
||||||
|
clear_hist = 0;
|
||||||
|
param = evhttp_find_header(query, "mode");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The mode parameter contains the playlist to be cleared.
|
||||||
|
* If mode=0x68697374 (hex representation of the ascii string "hist") clear the history,
|
||||||
|
* otherwise the current playlist.
|
||||||
|
*/
|
||||||
|
if (strcmp(param,"0x68697374") == 0)
|
||||||
|
clear_hist = 1;
|
||||||
|
|
||||||
|
player_queue_empty(clear_hist);
|
||||||
|
|
||||||
|
dmap_add_container(evbuf, "cacr", 24); /* 8 + len */
|
||||||
|
dmap_add_int(evbuf, "mstt", 200); /* 12 */
|
||||||
|
dmap_add_int(evbuf, "miid", 0); /* 12 */
|
||||||
|
|
||||||
|
httpd_send_reply(req, HTTP_OK, "OK", evbuf);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dacp_reply_playqueueedit_add(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query)
|
dacp_reply_playqueueedit_add(struct evhttp_request *req, struct evbuffer *evbuf, char **uri, struct evkeyvalq *query)
|
||||||
{
|
{
|
||||||
@ -1630,7 +1655,7 @@ dacp_reply_playqueueedit(struct evhttp_request *req, struct evbuffer *evbuf, cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(param, "clear") == 0)
|
if (strcmp(param, "clear") == 0)
|
||||||
dacp_reply_cue_clear(req, evbuf, uri, query);
|
dacp_reply_playqueueedit_clear(req, evbuf, uri, query);
|
||||||
else if (strcmp(param, "playnow") == 0)
|
else if (strcmp(param, "playnow") == 0)
|
||||||
dacp_reply_cue_play(req, evbuf, uri, query);
|
dacp_reply_cue_play(req, evbuf, uri, query);
|
||||||
else if (strcmp(param, "add") == 0)
|
else if (strcmp(param, "add") == 0)
|
||||||
|
60
src/player.c
60
src/player.c
@ -3588,6 +3588,50 @@ queue_clear(struct player_command *cmd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
queue_empty(struct player_command *cmd)
|
||||||
|
{
|
||||||
|
int clear_hist;
|
||||||
|
struct player_source *ps;
|
||||||
|
|
||||||
|
clear_hist = cmd->arg.intval;
|
||||||
|
if (clear_hist)
|
||||||
|
{
|
||||||
|
memset(history, 0, sizeof(struct player_history));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!source_head || !cur_streaming)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Stop playback if playing and streaming song are not the same
|
||||||
|
if (!cur_playing || cur_playing != cur_streaming)
|
||||||
|
{
|
||||||
|
playback_stop(cmd);
|
||||||
|
queue_clear(cmd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set head to the current playing song
|
||||||
|
shuffle_head = cur_playing;
|
||||||
|
source_head = cur_playing;
|
||||||
|
|
||||||
|
// Free all items in the queue except the current playing song
|
||||||
|
for (ps = source_head->pl_next; ps != source_head; ps = ps->pl_next)
|
||||||
|
{
|
||||||
|
source_free(ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the queue circular again
|
||||||
|
source_head->pl_next = source_head;
|
||||||
|
source_head->pl_prev = source_head;
|
||||||
|
source_head->shuffle_next = source_head;
|
||||||
|
source_head->shuffle_prev = source_head;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
queue_plid(struct player_command *cmd)
|
queue_plid(struct player_command *cmd)
|
||||||
{
|
{
|
||||||
@ -4111,6 +4155,22 @@ player_queue_clear(void)
|
|||||||
command_deinit(&cmd);
|
command_deinit(&cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
player_queue_empty(int clear_hist)
|
||||||
|
{
|
||||||
|
struct player_command cmd;
|
||||||
|
|
||||||
|
command_init(&cmd);
|
||||||
|
|
||||||
|
cmd.func = queue_empty;
|
||||||
|
cmd.func_bh = NULL;
|
||||||
|
cmd.arg.intval = clear_hist;
|
||||||
|
|
||||||
|
sync_command(&cmd);
|
||||||
|
|
||||||
|
command_deinit(&cmd);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
player_queue_plid(uint32_t plid)
|
player_queue_plid(uint32_t plid)
|
||||||
{
|
{
|
||||||
|
@ -173,6 +173,9 @@ player_queue_remove(int ps_pos_remove);
|
|||||||
void
|
void
|
||||||
player_queue_clear(void);
|
player_queue_clear(void);
|
||||||
|
|
||||||
|
void
|
||||||
|
player_queue_empty(int clear_hist);
|
||||||
|
|
||||||
void
|
void
|
||||||
player_queue_plid(uint32_t plid);
|
player_queue_plid(uint32_t plid);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user