--- libshout-2.2.2/include/shout/shout.h.in 2005-06-27 17:33:21.000000000 -0400 +++ libshout-2.2.2-fs/include/shout/shout.h.in 2010-05-25 11:21:31.000000000 -0400 @@ -39,11 +39,28 @@ #define SHOUTERR_BUSY (-10) +/* Main ogg format, sets mime type to + * SHOUT_OGG_MIME by default */ #define SHOUT_FORMAT_OGG (0) #define SHOUT_FORMAT_MP3 (1) +/* Specific sub-formats for ogg */ +/* Ogg stream with audio data. + * Sets mime type to SHOUT_OGG_AUDIO_MIME + * by default */ +#define SHOUT_FORMAT_OGG_AUDIO (2) +/* Ogg stream with video and possibly + * audio */ +#define SHOUT_FORMAT_OGG_VIDEO (3) /* backward-compatibility alias */ #define SHOUT_FORMAT_VORBIS SHOUT_FORMAT_OGG +/* Default mime types */ +#define SHOUT_OGG_MIME "application/ogg" +#define SHOUT_MP3_MIME "audio/mpeg" +/* Ogg specific mime types */ +#define SHOUT_OGG_AUDIO_MIME "audio/ogg" +#define SHOUT_OGG_VIDEO_MIME "video/ogg" + #define SHOUT_PROTOCOL_HTTP (0) #define SHOUT_PROTOCOL_XAUDIOCAST (1) #define SHOUT_PROTOCOL_ICY (2) @@ -135,6 +152,14 @@ unsigned int shout_get_public(shout_t *s int shout_set_format(shout_t *self, unsigned int format); unsigned int shout_get_format(shout_t *self); +/* Set the data's mime type. + * This value is set to a decent value by + * shout_set_format. Using this function + * is optional and should be done after + * calling shout_set_format. */ +int shout_set_mime(shout_t *self, const char *mime); +const char *shout_get_mime(shout_t *self); + /* takes a SHOUT_PROTOCOL_xxxxx argument */ int shout_set_protocol(shout_t *self, unsigned int protocol); unsigned int shout_get_protocol(shout_t *self); --- libshout-2.2.2/src/shout.c 2006-06-09 19:09:46.000000000 -0400 +++ libshout-2.2.2-fs/src/shout.c 2010-05-28 07:53:06.000000000 -0400 @@ -113,8 +113,13 @@ shout_t *shout_new(void) return NULL; } + if (shout_set_format(self, LIBSHOUT_DEFAULT_FORMAT) != SHOUTERR_SUCCESS) { + shout_free(self); + + return NULL; + } + self->port = LIBSHOUT_DEFAULT_PORT; - self->format = LIBSHOUT_DEFAULT_FORMAT; self->protocol = LIBSHOUT_DEFAULT_PROTOCOL; return self; @@ -134,6 +139,7 @@ void shout_free(shout_t *self) if (self->user) free(self->user); if (self->useragent) free(self->useragent); if (self->audio_info) _shout_util_dict_free (self->audio_info); + if (self->mime) free(self->mime); free(self); } @@ -147,7 +153,7 @@ int shout_open(shout_t *self) return SHOUTERR_CONNECTED; if (!self->host || !self->password || !self->port) return self->error = SHOUTERR_INSANE; - if (self->format == SHOUT_FORMAT_OGG && self->protocol != SHOUT_PROTOCOL_HTTP) + if (self->format != SHOUT_FORMAT_MP3 && self->protocol != SHOUT_PROTOCOL_HTTP) return self->error = SHOUTERR_UNSUPPORTED; return self->error = try_connect(self); @@ -710,6 +716,31 @@ unsigned int shout_get_public(shout_t *s return self->public; } +int shout_set_mime(shout_t *self, const char *mime) +{ + if (!self) + return SHOUTERR_INSANE; + + if (self->state != SHOUT_STATE_UNCONNECTED) + return SHOUTERR_CONNECTED; + + if (self->mime) + free(self->mime); + + if (! (self->mime = _shout_util_strdup (mime))) + return self->error = SHOUTERR_MALLOC; + + return self->error = SHOUTERR_SUCCESS; +} + +const char *shout_get_mime(shout_t *self) +{ + if (!self) + return NULL; + + return self->mime; +} + int shout_set_format(shout_t *self, unsigned int format) { if (!self) @@ -718,12 +749,27 @@ int shout_set_format(shout_t *self, unsi if (self->state != SHOUT_STATE_UNCONNECTED) return self->error = SHOUTERR_CONNECTED; - if (format != SHOUT_FORMAT_OGG && format != SHOUT_FORMAT_MP3) + if (format != SHOUT_FORMAT_OGG && + format != SHOUT_FORMAT_OGG_AUDIO && + format != SHOUT_FORMAT_OGG_VIDEO && + format != SHOUT_FORMAT_MP3) return self->error = SHOUTERR_UNSUPPORTED; self->format = format; - return self->error = SHOUTERR_SUCCESS; + /* Set decent value for mime. */ + switch (format) { + case SHOUT_FORMAT_OGG: + return shout_set_mime(self,SHOUT_OGG_MIME); + case SHOUT_FORMAT_OGG_AUDIO: + return shout_set_mime(self,SHOUT_OGG_AUDIO_MIME); + case SHOUT_FORMAT_OGG_VIDEO: + return shout_set_mime(self,SHOUT_OGG_VIDEO_MIME); + case SHOUT_FORMAT_MP3: + return shout_set_mime(self,SHOUT_MP3_MIME); + } + + return self->error = SHOUTERR_INSANE; } unsigned int shout_get_format(shout_t* self) @@ -984,7 +1030,10 @@ static int try_connect (shout_t *self) if ((rc = parse_response(self)) != SHOUTERR_SUCCESS) goto failure; - if (self->format == SHOUT_FORMAT_OGG) { + if (self->format == SHOUT_FORMAT_OGG || + self->format == SHOUT_FORMAT_OGG_AUDIO || + self->format == SHOUT_FORMAT_OGG_VIDEO ) + { if ((rc = self->error = shout_open_ogg(self)) != SHOUTERR_SUCCESS) goto failure; } else if (self->format == SHOUT_FORMAT_MP3) { @@ -1116,9 +1165,7 @@ static int create_http_request(shout_t * } if (self->useragent && queue_printf(self, "User-Agent: %s\r\n", self->useragent)) break; - if (self->format == SHOUT_FORMAT_OGG && queue_printf(self, "Content-Type: application/ogg\r\n")) - break; - if (self->format == SHOUT_FORMAT_MP3 && queue_printf(self, "Content-Type: audio/mpeg\r\n")) + if (self->mime && queue_printf(self, "Content-Type: %s\r\n", self->mime)) break; if (queue_printf(self, "ice-name: %s\r\n", self->name ? self->name : "no name")) break; @@ -1294,9 +1341,11 @@ static int create_icy_request(shout_t *s break; if (queue_printf(self, "icy-genre:%s\n", self->genre ? self->genre : "icecast")) break; - if (queue_printf(self, "icy-br:%s\n\n", bitrate)) + if (queue_printf(self, "icy-br:%s\n", bitrate)) break; - + if (self->mime && queue_printf(self, "content-type:%s\n\n", self->mime)) + break; + ret = SHOUTERR_SUCCESS; } while (0); --- libshout-2.2.2/src/shout_private.h 2005-06-27 17:33:25.000000000 -0400 +++ libshout-2.2.2-fs/src/shout_private.h 2010-05-25 11:21:31.000000000 -0400 @@ -65,6 +65,8 @@ struct shout { unsigned int protocol; /* type of data being sent */ unsigned int format; + /* Mime type for data */ + char *mime; /* audio encoding parameters */ util_dict *audio_info;