1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-09-29 04:25:55 -04:00

add intro file handling

svn path=/icecast/branches/kh/icecast/; revision=8189
This commit is contained in:
Karl Heyes 2004-11-10 20:14:31 +00:00
parent f2f292cfaa
commit 0d0a87ea84
12 changed files with 108 additions and 10 deletions

View File

@ -100,6 +100,7 @@
<fallback-override>1</fallback-override>
<fallback-when-full>1</fallback-when-full>
<hidden>1</hidden>
<intro>/path/to/stream-intro.ogg</intro>
<no-yp>1</no-yp>
<authentication type="htpasswd">
<option name="filename" value="myauth"/>

View File

@ -330,6 +330,7 @@ An on-demand relay will only retrieve the stream if there are listeners connecte
&lt;password&gt;hackmemore&lt;/password&gt;
&lt;max-listeners&gt;1&lt;/max-listeners&gt;
&lt;dump-file&gt;/tmp/dump-example1.ogg&lt;/dump-file&gt;
&lt;intro&gt;/path/to/intro.ogg&lt;/intro&gt;
&lt;fallback-mount&gt;/example2.ogg&lt;/fallback-mount&gt;
&lt;fallback-override&gt;1&lt;/fallback-override&gt;
&lt;burst-size&gt;65536&lt;/burst-size&gt;
@ -363,6 +364,12 @@ An optional value which will set the maximum number of listeners that can be att
<div class="indentedbox">
An optional value which will set the filename which will be a dump of the stream coming through on this mountpoint.
</div>
<h4>intro</h4>
<div class="indentedbox">
An optional value which will specify the file those contents will be sent to new listeners when they
connect but before the normal stream is sent. Make sure the format of the file specified matches the
streaming format.
</div>
<h4>fallback-mount</h4>
<div class="indentedbox">
This optional value specifies a mountpoint that clients are automatically moved to if the source

View File

@ -183,6 +183,7 @@ void config_clear(ice_config_t *c)
xmlFree(mount->username);
xmlFree(mount->password);
xmlFree(mount->dumpfile);
xmlFree(mount->intro_filename);
xmlFree(mount->on_connect);
xmlFree(mount->on_disconnect);
xmlFree(mount->fallback_mount);
@ -551,6 +552,10 @@ static void _parse_mount(xmlDocPtr doc, xmlNodePtr node,
mount->dumpfile = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
}
else if (strcmp(node->name, "intro") == 0) {
mount->intro_filename = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
}
else if (strcmp(node->name, "fallback-mount") == 0) {
mount->fallback_mount = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);

View File

@ -47,6 +47,7 @@ typedef struct _mount_proxy {
char *dumpfile; /* Filename to dump this stream to (will be appended). NULL
to not dump. */
char *intro_filename; /* Send contents of file to client before the stream */
int fallback_when_full; /* switch new listener to fallback source
when max listeners reached */
int max_listeners; /* Max listeners for this mountpoint only. -1 to not

View File

@ -40,6 +40,9 @@ typedef struct _client_tag
/* auth completed, 0 not yet, 1 passed, 2 failed */
int authenticated;
/* is client getting intro data */
long intro_offset;
/* where in the queue the client is */
refbuf_t *refbuf;

View File

@ -98,6 +98,48 @@ int format_get_plugin(format_type_t type, source_t *source)
return ret;
}
static int get_intro_data (FILE *intro, client_t *client)
{
refbuf_t *refbuf = client->refbuf;
int bytes;
if (intro == NULL || fseek (intro, client->intro_offset, SEEK_SET) < 0)
return 0;
bytes = fread (refbuf->data, 1, 4096, intro);
if (bytes == 0)
{
client->intro_offset = 0;
return 0;
}
refbuf->len = bytes;
return 1;
}
/* wrapper for the per-format write to client routine. Here we populate
* the refbuf before calling it
*/
static int format_intro_write_to_client (source_t *source, client_t *client)
{
refbuf_t *refbuf = client->refbuf;
if (client->pos == refbuf->len)
{
if (get_intro_data (source->intro_file, client) == 0)
{
client_set_queue (client, source->stream_data_tail);
client->write_to_client = source->format->write_buf_to_client;
return 0;
}
client->pos = 0;
client->intro_offset += refbuf->len;
}
return source->format->write_buf_to_client (source, client);
}
int format_http_write_to_client (source_t *source, client_t *client)
{
refbuf_t *refbuf = client->refbuf;
@ -131,8 +173,19 @@ int format_http_write_to_client (source_t *source, client_t *client)
if (ret > 0)
client->pos += ret;
if (client->pos == refbuf->len)
{
if (source->intro_file)
{
/* client should be sent an intro file */
client->write_to_client = format_intro_write_to_client;
client->intro_offset = 0;
}
else
{
client_set_queue (client, NULL);
}
}
return ret;
}

View File

@ -43,7 +43,7 @@ typedef struct _format_plugin_tag
char *format_description;
refbuf_t *(*get_buffer)(struct source_tag *);
int (*write_buf_to_client)(struct source_tag *format, client_t *client);
int (*write_buf_to_client)(struct source_tag *source, client_t *client);
void (*write_buf_to_file)(struct source_tag *source, refbuf_t *refbuf);
int (*create_client_data)(struct source_tag *source, client_t *client);
void (*set_tag)(struct _format_plugin_tag *plugin, char *tag, char *value);

View File

@ -59,7 +59,7 @@ static refbuf_t *mp3_get_no_meta (source_t *source);
static int format_mp3_create_client_data (source_t *source, client_t *client);
static void free_mp3_client_data (client_t *client);
static int format_mp3_write_buf_to_client(source_t *self, client_t *client);
static int format_mp3_write_buf_to_client(source_t *source, client_t *client);
static void write_mp3_to_file (struct source_tag *source, refbuf_t *refbuf);
static void mp3_set_tag (format_plugin_t *plugin, char *tag, char *value);
static void format_mp3_apply_settings(struct source_tag *source, struct _mount_proxy *mount);
@ -296,7 +296,7 @@ static int send_mp3_metadata (client_t *client, refbuf_t *associated)
/* Handler for writing mp3 data to a client, taking into account whether
* client has requested shoutcast style metadata updates
*/
static int format_mp3_write_buf_to_client (source_t *self, client_t *client)
static int format_mp3_write_buf_to_client (source_t *source, client_t *client)
{
int ret, written = 0;
mp3_client_data *client_mp3 = client->format_data;

View File

@ -509,7 +509,7 @@ static void free_ogg_client_data (client_t *client);
static void write_ogg_to_file (struct source_tag *source, refbuf_t *refbuf);
static refbuf_t *ogg_get_buffer (source_t *source);
static int write_buf_to_client (source_t *self, client_t *client);
static int write_buf_to_client (source_t *source, client_t *client);
static void free_ogg_codecs (ogg_state_t *ogg_info)
@ -802,7 +802,7 @@ static int send_ogg_headers (client_t *client, refbuf_t *headers)
}
static int write_buf_to_client (source_t *self, client_t *client)
static int write_buf_to_client (source_t *source, client_t *client)
{
refbuf_t *refbuf = client->refbuf;
char *buf;

View File

@ -98,7 +98,7 @@ static void free_vorbis_client_data (client_t *client);
static void write_vorbis_to_file (struct source_tag *source, refbuf_t *refbuf);
static refbuf_t *vorbis_get_buffer (source_t *source);
static int vorbis_write_buf_to_client (source_t *self, client_t *client);
static int vorbis_write_buf_to_client (source_t *source, client_t *client);
static void vorbis_set_tag (format_plugin_t *plugin, char *tag, char *value);
@ -751,7 +751,7 @@ static int send_vorbis_headers (client_t *client, refbuf_t *headers)
}
static int vorbis_write_buf_to_client (source_t *self, client_t *client)
static int vorbis_write_buf_to_client (source_t *source, client_t *client)
{
refbuf_t *refbuf = client->refbuf;
char *buf;

View File

@ -264,6 +264,12 @@ void source_clear_source (source_t *source)
free(source->dumpfilename);
source->dumpfilename = NULL;
if (source->intro_file)
{
fclose (source->intro_file);
source->intro_file = NULL;
}
free (source->on_connect);
source->on_connect = NULL;
@ -562,6 +568,7 @@ static void process_listeners (source_t *source, int fast_clients_only, int dele
static void get_next_buffer (source_t *source)
{
refbuf_t *refbuf = NULL;
int no_delay_count = 0;
while (global.running == ICE_RUNNING && source->running)
{
@ -569,8 +576,18 @@ static void get_next_buffer (source_t *source)
time_t current = time(NULL);
int delay = 200;
/* service fast clients but jump out once in a while to check on
* normal clients */
if (no_delay_count < 10)
{
if (source->active_clients != source->first_normal_client)
{
delay = 0;
no_delay_count++;
}
}
else
return;
thread_mutex_unlock (&source->lock);
@ -1175,6 +1192,15 @@ static void source_apply_mount (source_t *source, mount_proxy *mountinfo)
free (source->dumpfilename);
source->dumpfilename = strdup (mountinfo->dumpfile);
}
if (source->intro_file)
fclose (source->intro_file);
if (mountinfo->intro_filename)
{
source->intro_file = fopen (mountinfo->intro_filename, "rb");
if (source->intro_file == NULL)
WARN2 ("Cannot open intro file \"%s\": %s",
mountinfo->intro_filename, strerror(errno));
}
if (mountinfo->queue_size_limit)
source->queue_size_limit = mountinfo->queue_size_limit;

View File

@ -85,6 +85,8 @@ typedef struct source_tag
refbuf_t *stream_data;
refbuf_t *stream_data_tail;
FILE *intro_file;
} source_t;
source_t *source_reserve (const char *mount);