[MPlayer-dev-eng] [PATCH] Displaying SHOUTcast title
Reimar Döffinger
Reimar.Doeffinger at stud.uni-karlsruhe.de
Thu Jun 16 20:58:37 CEST 2005
Hi,
the attached patch is a very first, hackish version of support for
Metadata in SHOUTcast streams.
I lost interest and probably won't improve it to a point where it can go
into CVS.
I post it here anyway, maybe someone else wants to work on it.
Greetings,
Reimar Döffinger
-------------- next part --------------
--- libmpdemux/network.c 2005-05-29 19:17:13.000000000 +0200
+++ libmpdemux/network.c 2005-06-15 17:23:23.000000000 +0200
@@ -400,6 +400,8 @@
else
http_set_field( http_hdr, "User-Agent: MPlayer/"VERSION);
+ http_set_field(http_hdr, "Icy-MetaData: 1");
+
if(pos>0) {
// Extend http_send_request with possibility to do partial content retrieval
snprintf(str, 256, "Range: bytes=%d-", pos);
--- libmpdemux/http.c 2005-06-03 21:33:16.000000000 +0200
+++ libmpdemux/http.c 2005-06-15 20:58:46.000000000 +0200
@@ -34,6 +34,104 @@
extern int http_seek(stream_t *stream, off_t pos);
+static unsigned my_recv(int fd, char *buffer, int len) {
+ unsigned pos = 0;
+ while (pos < len) {
+ int ret = read(fd, &buffer[pos], len - pos);
+ if (ret <= 0)
+ break;
+ pos += ret;
+ }
+ return pos;
+}
+
+static int scast_recv(int fd, char *buffer, int metaint) {
+ unsigned char tmp = 0;
+ unsigned metalen;
+ unsigned ret = my_recv(fd, buffer, metaint);
+ read(fd, &tmp, 1);
+ metalen = tmp * 16;
+ if (metalen > 0) {
+ char *info = (char *)malloc(metalen + 1);
+ unsigned nlen = my_recv(fd, info, metalen);
+ info[nlen] = 0;
+ mp_msg(MSGT_DEMUXER, MSGL_INFO, "\nICY Info: %s\n", info);
+ free(info);
+ }
+ return ret;
+}
+
+static int scast_streaming_read(int fd, char *buffer, int size,
+ streaming_ctrl_t *stream_ctrl) {
+ unsigned metaint = stream_ctrl->buffer_size;
+ unsigned block;
+ unsigned done = 0;
+
+ // first read data from buffer
+ block = metaint - stream_ctrl->buffer_pos;
+ if (block > size)
+ block = size;
+ memcpy(buffer, &stream_ctrl->buffer[stream_ctrl->buffer_pos], block);
+ stream_ctrl->buffer_pos += block;
+ done += block;
+
+ if (done < size) { // buffer is empty now
+ // read big blocks directly from stream
+ while (size - done > metaint) {
+ unsigned ret = scast_recv(fd, &buffer[done], metaint);
+ done += ret;
+ if (ret != metaint) // read problems or eof
+ size = done;
+ }
+
+ if (done < size) {
+ int len = scast_recv(fd, stream_ctrl->buffer, metaint);
+ block = size - done;
+ if (len < block) // read problems or eof
+ block = len;
+ memcpy(&buffer[done], stream_ctrl->buffer, block);
+ stream_ctrl->buffer_pos = block;
+ if (len < metaint) {
+ memmove(&stream_ctrl->buffer[block + metaint - len],
+ &stream_ctrl->buffer[block], len - block);
+ stream_ctrl->buffer_pos = block + metaint - len;
+ }
+ done += block;
+ }
+ }
+ return done;
+}
+
+static int scast_streaming_start(stream_t *stream) {
+ int metaint;
+ int fromhdr;
+ HTTP_header_t *http_hdr = stream->streaming_ctrl->data;
+ if (!stream || stream->fd < 0 || !http_hdr)
+ return -1;
+ metaint = atoi(http_get_field(http_hdr, "Icy-MetaInt"));
+ if (metaint <= 0)
+ return -1;
+ fromhdr = http_hdr->buffer_size - http_hdr->body_size;
+ if (http_hdr->body_size > metaint) {
+ mp_msg(MSGT_DEMUXER, MSGL_ERR, "http_hdr->body_size too big\n");
+ return -1;
+ }
+ stream->streaming_ctrl->buffer = malloc(metaint);
+ stream->streaming_ctrl->buffer_size = metaint;
+ stream->streaming_ctrl->buffer_pos = 0;
+ memcpy(stream->streaming_ctrl->buffer, http_hdr->body, http_hdr->body_size);
+ scast_recv(stream->fd, &stream->streaming_ctrl->buffer[http_hdr->body_size],
+ metaint - http_hdr->body_size);
+ http_free(http_hdr);
+ stream->streaming_ctrl->data = NULL;
+ stream->streaming_ctrl->streaming_read = scast_streaming_read;
+ stream->streaming_ctrl->streaming_seek = NULL;
+ stream->streaming_ctrl->prebuffer_size = 64*1024; // 64 KBytes
+ stream->streaming_ctrl->buffering = 1;
+ stream->streaming_ctrl->status = streaming_playing_e;
+ return 0;
+}
+
static int nop_streaming_start( stream_t *stream ) {
HTTP_header_t *http_hdr = NULL;
char *next_url=NULL;
@@ -677,14 +775,17 @@
}
static int fixup_open(stream_t *stream,int seekable) {
+ HTTP_header_t *http_hdr = stream->streaming_ctrl->data;
+ int is_icy = http_hdr && strcasecmp(http_hdr->protocol, "ICY") == 0;
stream->type = STREAMTYPE_STREAM;
- if(seekable)
+ if(is_icy && seekable)
{
stream->flags |= STREAM_SEEK;
stream->seek = http_seek;
}
stream->streaming_ctrl->bandwidth = network_bandwidth;
+ if (!is_icy || scast_streaming_start(stream))
if(nop_streaming_start( stream )) {
mp_msg(MSGT_NETWORK,MSGL_ERR,"nop_streaming_start failed\n");
streaming_ctrl_free(stream->streaming_ctrl);
More information about the MPlayer-dev-eng
mailing list