mirror of
https://github.com/owntone/owntone-server.git
synced 2025-07-26 17:00:13 -04:00
[http] .pls playlists (#447)
This commit is contained in:
parent
dcc6fcf206
commit
8f899f2051
79
src/http.c
79
src/http.c
@ -44,6 +44,11 @@
|
|||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
|
/* Formats we can read so far */
|
||||||
|
#define PLAYLIST_UNK 0
|
||||||
|
#define PLAYLIST_PLS 1
|
||||||
|
#define PLAYLIST_M3U 2
|
||||||
|
|
||||||
/* ======================= libevent HTTP client =============================*/
|
/* ======================= libevent HTTP client =============================*/
|
||||||
|
|
||||||
// Number of seconds the client will wait for a response before aborting
|
// Number of seconds the client will wait for a response before aborting
|
||||||
@ -444,17 +449,42 @@ http_stream_setup(char **stream, const char *url)
|
|||||||
char *line;
|
char *line;
|
||||||
int ret;
|
int ret;
|
||||||
int n;
|
int n;
|
||||||
|
const char *pos;
|
||||||
|
char ch;
|
||||||
|
int pl_format;
|
||||||
|
bool in_playlist;
|
||||||
|
|
||||||
*stream = NULL;
|
*stream = NULL;
|
||||||
|
pl_format = PLAYLIST_UNK;
|
||||||
|
|
||||||
ext = strrchr(url, '.');
|
// Find last dot before query or fragment,
|
||||||
if (!ext || (strcasecmp(ext, ".m3u") != 0))
|
// e.g., http://yp.shoutcast.com/sbin/tunein-station.pls?id=99179772#Air Jazz
|
||||||
|
pos = url;
|
||||||
|
ext = NULL;
|
||||||
|
while ((ch = *pos) != '\0')
|
||||||
|
{
|
||||||
|
if (ch == '?' || ch == '#')
|
||||||
|
break;
|
||||||
|
if (ch == '.')
|
||||||
|
ext = pos;
|
||||||
|
++pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ext)
|
||||||
|
{
|
||||||
|
if (strncasecmp(ext, ".m3u", 4) == 0)
|
||||||
|
pl_format = PLAYLIST_M3U;
|
||||||
|
else if (strncasecmp(ext, ".pls", 4) == 0)
|
||||||
|
pl_format = PLAYLIST_PLS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pl_format==PLAYLIST_UNK)
|
||||||
{
|
{
|
||||||
*stream = strdup(url);
|
*stream = strdup(url);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// It was a m3u playlist, so now retrieve it
|
// It was a m3u or pls playlist, so now retrieve it
|
||||||
memset(&ctx, 0, sizeof(struct http_client_ctx));
|
memset(&ctx, 0, sizeof(struct http_client_ctx));
|
||||||
|
|
||||||
evbuf = evbuffer_new();
|
evbuf = evbuffer_new();
|
||||||
@ -479,10 +509,52 @@ http_stream_setup(char **stream, const char *url)
|
|||||||
/* Read the playlist until the first stream link is found, but give up if
|
/* Read the playlist until the first stream link is found, but give up if
|
||||||
* nothing is found in the first 10 lines
|
* nothing is found in the first 10 lines
|
||||||
*/
|
*/
|
||||||
|
in_playlist = false;
|
||||||
n = 0;
|
n = 0;
|
||||||
while ((line = evbuffer_readln(ctx.input_body, NULL, EVBUFFER_EOL_ANY)) && (n < 10))
|
while ((line = evbuffer_readln(ctx.input_body, NULL, EVBUFFER_EOL_ANY)) && (n < 10))
|
||||||
{
|
{
|
||||||
|
// Skip comments and blank lines without counting for the limit
|
||||||
|
if (pl_format == PLAYLIST_M3U && (line[0] == '#' || line[0] == '\0'))
|
||||||
|
goto line_done;
|
||||||
|
|
||||||
n++;
|
n++;
|
||||||
|
|
||||||
|
if (pl_format == PLAYLIST_PLS && !in_playlist)
|
||||||
|
{
|
||||||
|
if (strncasecmp(line, "[playlist]", strlen("[playlist]")) == 0)
|
||||||
|
{
|
||||||
|
in_playlist = true;
|
||||||
|
n = 0;
|
||||||
|
}
|
||||||
|
goto line_done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pl_format == PLAYLIST_PLS)
|
||||||
|
{
|
||||||
|
pos = line;
|
||||||
|
while (*pos == ' ')
|
||||||
|
++pos;
|
||||||
|
|
||||||
|
// We are only interested in `FileN=http://foo/bar.mp3` entries
|
||||||
|
if (strncasecmp(pos, "file", strlen("file")) != 0)
|
||||||
|
goto line_done;
|
||||||
|
|
||||||
|
while (*pos != '=' && *pos != '\0')
|
||||||
|
++pos;
|
||||||
|
|
||||||
|
if (*pos == '\0')
|
||||||
|
goto line_done;
|
||||||
|
|
||||||
|
++pos;
|
||||||
|
while (*pos == ' ')
|
||||||
|
++pos;
|
||||||
|
|
||||||
|
// allocate the value part and proceed as with m3u
|
||||||
|
pos = strdup(pos);
|
||||||
|
free(line);
|
||||||
|
line = (char *) pos;
|
||||||
|
}
|
||||||
|
|
||||||
if (strncasecmp(line, "http://", strlen("http://")) == 0)
|
if (strncasecmp(line, "http://", strlen("http://")) == 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_DBG, L_HTTP, "Found internet playlist stream (line %d): %s\n", n, line);
|
DPRINTF(E_DBG, L_HTTP, "Found internet playlist stream (line %d): %s\n", n, line);
|
||||||
@ -491,6 +563,7 @@ http_stream_setup(char **stream, const char *url)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
line_done:
|
||||||
free(line);
|
free(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user