mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Feature: Added support to send vorbis comments
This commit is contained in:
parent
7965610b26
commit
dbffcb6dc0
@ -19,6 +19,7 @@
|
||||
#include <igloo/error.h>
|
||||
#include <igloo/ro.h>
|
||||
#include <igloo/sp.h>
|
||||
#include <igloo/cs.h>
|
||||
#include <igloo/uuid.h>
|
||||
|
||||
#include "common/thread/thread.h"
|
||||
@ -33,7 +34,9 @@
|
||||
#include "event.h"
|
||||
#include "client.h"
|
||||
#include "connection.h"
|
||||
#include "source.h"
|
||||
#include "errors.h"
|
||||
#include "format_mp3.h"
|
||||
#include "logging.h"
|
||||
#define CATMODULE "event-stream"
|
||||
|
||||
@ -44,10 +47,12 @@ struct event_stream_event_tag {
|
||||
|
||||
const char * uuid;
|
||||
const char * mount;
|
||||
const char * source_instance_uuid;
|
||||
const char * rendered;
|
||||
size_t rendered_length;
|
||||
|
||||
event_t *event;
|
||||
vorbis_comment *vc;
|
||||
|
||||
event_stream_event_t *next;
|
||||
};
|
||||
@ -95,6 +100,8 @@ static void event_stream_event_free(igloo_ro_t self)
|
||||
{
|
||||
event_stream_event_t *event = igloo_ro_to_type(self, event_stream_event_t);
|
||||
igloo_sp_unref(&(event->uuid), igloo_instance);
|
||||
igloo_sp_unref(&(event->mount), igloo_instance);
|
||||
igloo_sp_unref(&(event->source_instance_uuid), igloo_instance);
|
||||
igloo_sp_unref(&(event->rendered), igloo_instance);
|
||||
igloo_ro_unref(&(event->event));
|
||||
igloo_ro_unref(&(event->next));
|
||||
@ -255,6 +262,12 @@ void event_stream_add_client(client_t *client)
|
||||
fserve_add_client_callback(client, event_stream_add_client_inner, NULL);
|
||||
}
|
||||
|
||||
static void event_stream_set_source(event_stream_event_t *event, source_t *source)
|
||||
{
|
||||
igloo_sp_replace(source->mount, &(event->mount), igloo_instance);
|
||||
igloo_sp_replace(source->instance_uuid, &(event->source_instance_uuid), igloo_instance);
|
||||
}
|
||||
|
||||
void event_stream_emit_event(event_t *event)
|
||||
{
|
||||
event_stream_event_t *el = event_stream_event_new();
|
||||
@ -267,6 +280,22 @@ void event_stream_emit_event(event_t *event)
|
||||
event_stream_queue(el);
|
||||
}
|
||||
|
||||
void event_stream_emit_vc(source_t *source, vorbis_comment *vc)
|
||||
{
|
||||
event_stream_event_t *el = event_stream_event_new();
|
||||
if (!el)
|
||||
return;
|
||||
|
||||
event_stream_set_source(el, source);
|
||||
|
||||
/* we only have a temp reference to vc, so we set it, render, and then unset before we queue. */
|
||||
el->vc = vc;
|
||||
event_stream_event_render(el);
|
||||
el->vc = NULL;
|
||||
|
||||
event_stream_queue(el);
|
||||
}
|
||||
|
||||
static void event_stream_send_to_client(client_t *client)
|
||||
{
|
||||
event_stream_clientstate_t *state = client->format_data;
|
||||
@ -393,6 +422,8 @@ static void event_stream_event_render(event_stream_event_t *event)
|
||||
string_renderer_t * renderer;
|
||||
json_renderer_t *json;
|
||||
char *body;
|
||||
bool has_type = false;
|
||||
bool has_crude = false;
|
||||
|
||||
if (event->rendered)
|
||||
return;
|
||||
@ -409,6 +440,9 @@ static void event_stream_event_render(event_stream_event_t *event)
|
||||
if (event->event) {
|
||||
event_t *uevent = event->event;
|
||||
|
||||
has_type = true;
|
||||
has_crude = true;
|
||||
|
||||
json_renderer_write_key(json, "type", JSON_RENDERER_FLAGS_NONE);
|
||||
json_renderer_write_string(json, "event", JSON_RENDERER_FLAGS_NONE);
|
||||
|
||||
@ -450,6 +484,111 @@ static void event_stream_event_render(event_stream_event_t *event)
|
||||
json_renderer_write_key(json, "mount", JSON_RENDERER_FLAGS_NONE);
|
||||
json_renderer_write_string(json, event->mount, JSON_RENDERER_FLAGS_NONE);
|
||||
}
|
||||
|
||||
if (event->vc) {
|
||||
if (!has_type) {
|
||||
json_renderer_write_key(json, "type", JSON_RENDERER_FLAGS_NONE);
|
||||
json_renderer_write_string(json, "vc", JSON_RENDERER_FLAGS_NONE);
|
||||
has_type = true;
|
||||
}
|
||||
|
||||
json_renderer_write_key(json, "vc", JSON_RENDERER_FLAGS_NONE);
|
||||
json_renderer_begin(json, JSON_ELEMENT_TYPE_OBJECT);
|
||||
{
|
||||
/* ok, this part is tricky, we first need to figure out all the keys.
|
||||
* we however cheat here by assuming a few things.
|
||||
* TODO: Fix this.
|
||||
*/
|
||||
struct {
|
||||
char name[64];
|
||||
size_t count;
|
||||
} keys[64];
|
||||
memset(keys, 0, sizeof(keys));
|
||||
|
||||
/* it is an int in libvorbis, not a size_t */
|
||||
for (int i = 0; i < event->vc->comments; i++) {
|
||||
const char *comment = event->vc->user_comments[i];
|
||||
const char *keyend = strchr(comment, '=');
|
||||
bool found = false;
|
||||
size_t keylen;
|
||||
|
||||
if (!keyend)
|
||||
continue;
|
||||
keylen = keyend - comment;
|
||||
if (keylen >= sizeof(keys->name))
|
||||
continue;
|
||||
|
||||
for (size_t j = 0; j < (sizeof(keys)/sizeof(*keys)); j++) {
|
||||
char *name = keys[j].name;
|
||||
|
||||
if (*name) {
|
||||
if (strncasecmp(comment, name, keylen) == 0) {
|
||||
found = true;
|
||||
keys[j].count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
break;
|
||||
|
||||
for (size_t j = 0; j < (sizeof(keys)/sizeof(*keys)); j++) {
|
||||
char *name = keys[j].name;
|
||||
|
||||
if (!*name) {
|
||||
memcpy(name, comment, keylen);
|
||||
name[keylen] = 0;
|
||||
keys[j].count = 1;
|
||||
igloo_cs_to_upper(name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we have a list of all keys... */
|
||||
for (size_t j = 0; j < (sizeof(keys)/sizeof(*keys)); j++) {
|
||||
const char *name = keys[j].name;
|
||||
if (!*name)
|
||||
continue;
|
||||
|
||||
json_renderer_write_key(json, name, JSON_RENDERER_FLAGS_NONE);
|
||||
json_renderer_begin(json, JSON_ELEMENT_TYPE_ARRAY);
|
||||
for (size_t i = 0; i < keys[j].count; i++) {
|
||||
const char *value = vorbis_comment_query(event->vc, name, i);
|
||||
json_renderer_write_string(json, value, JSON_RENDERER_FLAGS_NONE);
|
||||
}
|
||||
json_renderer_end(json);
|
||||
}
|
||||
}
|
||||
json_renderer_end(json);
|
||||
|
||||
if (!has_crude) {
|
||||
has_crude = true;
|
||||
json_renderer_write_key(json, "crude", JSON_RENDERER_FLAGS_NONE);
|
||||
json_renderer_begin(json, JSON_ELEMENT_TYPE_OBJECT);
|
||||
{
|
||||
static const char * display_title_keys[] = {"TITLE", MP3_METADATA_TITLE};
|
||||
const char *display_title = NULL;
|
||||
for (size_t i = 0; i < (sizeof(display_title_keys)/sizeof(*display_title_keys)); i++) {
|
||||
display_title = vorbis_comment_query(event->vc, display_title_keys[i], 0);
|
||||
if (display_title)
|
||||
break;
|
||||
}
|
||||
json_renderer_write_key(json, "display-title", JSON_RENDERER_FLAGS_NONE);
|
||||
if (display_title) {
|
||||
json_renderer_write_string(json, display_title, JSON_RENDERER_FLAGS_NONE);
|
||||
} else {
|
||||
json_renderer_write_null(json);
|
||||
}
|
||||
if (event->source_instance_uuid) {
|
||||
json_renderer_write_key(json, "source-instance", JSON_RENDERER_FLAGS_NONE);
|
||||
json_renderer_write_string(json, event->source_instance_uuid, JSON_RENDERER_FLAGS_NONE);
|
||||
}
|
||||
}
|
||||
json_renderer_end(json);
|
||||
}
|
||||
}
|
||||
|
||||
json_renderer_end(json);
|
||||
|
||||
body = json_renderer_finish(&json);
|
||||
|
@ -9,6 +9,8 @@
|
||||
#ifndef __EVENT_STREAM_H__
|
||||
#define __EVENT_STREAM_H__
|
||||
|
||||
#include <vorbis/codec.h>
|
||||
|
||||
#include "icecasttypes.h"
|
||||
|
||||
igloo_RO_FORWARD_TYPE(event_stream_event_t);
|
||||
@ -18,5 +20,6 @@ void event_stream_shutdown(void);
|
||||
|
||||
void event_stream_add_client(client_t *client);
|
||||
void event_stream_emit_event(event_t *event);
|
||||
void event_stream_emit_vc(source_t *source, vorbis_comment *vc);
|
||||
|
||||
#endif
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "source.h"
|
||||
#include "client.h"
|
||||
#include "connection.h"
|
||||
#include "event_stream.h"
|
||||
|
||||
#include "stats.h"
|
||||
#include "format.h"
|
||||
@ -206,6 +207,7 @@ static void filter_shoutcast_metadata (source_t *source, char *metadata, unsigne
|
||||
yp_touch (source->mount);
|
||||
free (p);
|
||||
playlist_push_track(source->history, &source->format->vc);
|
||||
event_stream_emit_vc(source, &source->format->vc);
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
#include "stats.h"
|
||||
#include "playlist.h"
|
||||
#include "event_stream.h"
|
||||
#include "event.h"
|
||||
#include "format.h"
|
||||
#include "format_ogg.h"
|
||||
@ -332,6 +333,7 @@ static void update_comments(source_t *source)
|
||||
stats_event (source->mount, "display-title", title);
|
||||
|
||||
playlist_push_track(source->history, &source->format->vc);
|
||||
event_stream_emit_vc(source, &source->format->vc);
|
||||
|
||||
codec = ogg_info->codecs;
|
||||
while (codec)
|
||||
|
Loading…
Reference in New Issue
Block a user