From 35f15cfa35f82bf630da64ee5094767d80f0c6b7 Mon Sep 17 00:00:00 2001 From: Alexander Malaev Date: Thu, 10 Oct 2024 14:00:59 +0300 Subject: [PATCH] Add metadata for videoroom publishers --- src/plugins/janus_videoroom.c | 84 ++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 6 deletions(-) diff --git a/src/plugins/janus_videoroom.c b/src/plugins/janus_videoroom.c index 5ff99541d6..a1be665069 100644 --- a/src/plugins/janus_videoroom.c +++ b/src/plugins/janus_videoroom.c @@ -459,8 +459,10 @@ room-: { { // Participant #1 "id" : , "display" : "", + "metadata" : , "publisher" : "", "talking" : + "metadata" : }, // Other participants ] @@ -494,7 +496,8 @@ room-: { "room" : , "id" : , "display" : "", - "token" : "" + "token" : "", + "metadata" : } \endverbatim * @@ -523,6 +526,7 @@ room-: { { "id" : , "display" : "", + "metadata" : , "dummy" : , "streams" : [ { @@ -546,7 +550,8 @@ room-: { "attendees" : [ // Only present when notify_joining is set to TRUE for rooms { "id" : , - "display" : "" + "display" : "", + "metadata" : , }, // Other attendees ] @@ -576,7 +581,8 @@ room-: { "room" : , "joining" : { "id" : , - "display" : "" + "display" : "", + "metadata" : } } \endverbatim @@ -601,6 +607,7 @@ room-: { "record" : , "filename" : "", "display" : "", + "metadata" : , "audio_level_average" : "", "audio_active_packets" : "", "descriptions" : [ // Optional @@ -668,6 +675,7 @@ room-: { { "id" : , "display" : "", + "metadata" : , "dummy" : , "streams" : [ { @@ -740,6 +748,7 @@ room-: { "record" : , "filename" : "", "display" : "", + "metadata" : , "audio_active_packets" : "", "audio_level_average" : "", "streams" : [ @@ -1648,6 +1657,7 @@ room-: { "id" : , "secret" : "", "display" : "", + "metadata" : , "streams" : [ { // Same syntax as add_remote_publisher: only needs to @@ -2003,7 +2013,7 @@ static struct janus_json_parameter join_parameters[] = { {"bitrate", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE}, {"record", JANUS_JSON_BOOL, 0}, {"filename", JSON_STRING, 0}, - {"token", JSON_STRING, 0} + {"token", JSON_STRING, 0}, }; static struct janus_json_parameter publish_parameters[] = { {"descriptions", JANUS_JSON_ARRAY, 0}, @@ -2014,6 +2024,7 @@ static struct janus_json_parameter publish_parameters[] = { {"record", JANUS_JSON_BOOL, 0}, {"filename", JSON_STRING, 0}, {"display", JSON_STRING, 0}, + {"metadata", JSON_OBJECT, 0}, {"secret", JSON_STRING, 0}, {"audio_level_averge", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE}, {"audio_active_packets", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE}, @@ -2088,7 +2099,8 @@ static struct janus_json_parameter stop_rtp_forward_parameters[] = { {"stream_id", JSON_INTEGER, JANUS_JSON_PARAM_REQUIRED | JANUS_JSON_PARAM_POSITIVE} }; static struct janus_json_parameter publisher_parameters[] = { - {"display", JSON_STRING, 0} + {"display", JSON_STRING, 0}, + {"metadata", JSON_OBJECT, 0} }; static struct janus_json_parameter configure_stream_parameters[] = { {"mid", JANUS_JSON_STRING, 0}, @@ -2196,10 +2208,12 @@ static struct janus_json_parameter remote_publisher_parameters[] = { {"iface", JANUS_JSON_STRING, 0}, {"port", JANUS_JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE}, {"streams", JANUS_JSON_ARRAY, JANUS_JSON_PARAM_REQUIRED}, + {"metadata", JSON_OBJECT, 0} }; static struct janus_json_parameter remote_publisher_update_parameters[] = { {"secret", JSON_STRING, 0}, {"display", JANUS_JSON_STRING, 0}, + {"metadata", JSON_OBJECT, 0}, {"streams", JANUS_JSON_ARRAY, JANUS_JSON_PARAM_REQUIRED} }; static struct janus_json_parameter remote_publisher_stream_parameters[] = { @@ -2432,6 +2446,7 @@ typedef struct janus_videoroom_publisher { gboolean kicked; /* Whether this participant has been kicked */ gboolean e2ee; /* If media from this publisher is end-to-end encrypted */ janus_mutex mutex; /* Mutex to lock this instance */ + json_t *metadata; volatile gint destroyed; janus_refcount ref; } janus_videoroom_publisher; @@ -2760,6 +2775,8 @@ static void janus_videoroom_publisher_free(const janus_refcount *p_ref) { g_free(p->user_id_str); g_free(p->display); g_free(p->recording_base); + if(p->metadata != NULL) + json_decref(p->metadata); /* Get rid of all the streams */ g_list_free_full(p->streams, (GDestroyNotify)(janus_videoroom_publisher_stream_destroy)); g_hash_table_unref(p->streams_byid); @@ -4257,6 +4274,8 @@ static void janus_videoroom_notify_about_publisher(janus_videoroom_publisher *p, json_object_set_new(pl, "id", string_ids ? json_string(p->user_id_str) : json_integer(p->user_id)); if(p->display) json_object_set_new(pl, "display", json_string(p->display)); + if(p->metadata) + json_object_set_new(pl, "metadata", json_deep_copy(p->metadata)); /* Add proper info on all the streams */ gboolean audio_added = FALSE, video_added = FALSE; json_t *media = json_array(); @@ -4332,6 +4351,8 @@ static void janus_videoroom_notify_about_publisher(janus_videoroom_publisher *p, json_object_set_new(info, "id", string_ids ? json_string(p->user_id_str) : json_integer(p->user_id)); if(p->display) json_object_set_new(info, "display", json_string(p->display)); + if(p->metadata) + json_object_set_new(info, "metadata", json_deep_copy(p->metadata)); json_t *media = json_array(); GList *temp = p->streams; while(temp) { @@ -4376,6 +4397,9 @@ static void janus_videoroom_participant_joining(janus_videoroom_publisher *p) { if (p->display) { json_object_set_new(user, "display", json_string(p->display)); } + if (p->metadata) { + json_object_set_new(user, "metadata", json_deep_copy(p->metadata)); + } json_object_set_new(event, "videoroom", json_string("event")); json_object_set_new(event, "room", string_ids ? json_string(p->room_id_str) : json_integer(p->room_id)); json_object_set_new(event, "joining", user); @@ -4424,6 +4448,8 @@ static void janus_videoroom_leave_or_unpublish(janus_videoroom_publisher *partic json_object_set_new(info, "id", string_ids ? json_string(participant->user_id_str) : json_integer(participant->user_id)); if(participant->display) json_object_set_new(info, "display", json_string(participant->display)); + if(participant->metadata) + json_object_set_new(info, "metadata", json_deep_copy(participant->metadata)); gateway->notify_event(&janus_videoroom_plugin, NULL, info); } if(is_leaving) { @@ -4535,6 +4561,8 @@ json_t *janus_videoroom_query_session(janus_plugin_session *handle) { json_object_set_new(info, "private_id", json_integer(participant->pvt_id)); if(participant->display) json_object_set_new(info, "display", json_string(participant->display)); + if(participant->metadata) + json_object_set_new(info, "metadata", json_deep_copy(participant->metadata)); /* TODO Fix the summary of viewers, since everything is stream based now */ //~ if(participant->subscribers) //~ json_object_set_new(info, "viewers", json_integer(g_slist_length(participant->subscribers))); @@ -6848,6 +6876,8 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi json_object_set_new(pl, "id", string_ids ? json_string(p->user_id_str) : json_integer(p->user_id)); if(p->display) json_object_set_new(pl, "display", json_string(p->display)); + if(p->metadata) + json_object_set_new(pl, "metadata", json_deep_copy(p->metadata)); if(p->dummy) json_object_set_new(pl, "dummy", json_true()); if(p->remote) @@ -6931,6 +6961,8 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi json_object_set_new(pl, "publisher_id", string_ids ? json_string(p->user_id_str) : json_integer(p->user_id)); if(p->display) json_object_set_new(pl, "display", json_string(p->display)); + if(p->metadata) + json_object_set_new(pl, "metadata", json_deep_copy(p->metadata)); json_t *flist = json_array(); /* Iterate on all media streams to see what's being forwarded */ janus_videoroom_publisher_stream *ps = NULL; @@ -7576,6 +7608,7 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi char user_id_num[30], *user_id_str = NULL; gboolean user_id_allocated = FALSE; json_t *id = json_object_get(root, "id"); + json_t *metadata = json_object_get(root, "metadata"); if(id) { if(!string_ids) { user_id = json_integer_value(id); @@ -7706,6 +7739,7 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi publisher->remote_ssrc_offset = janus_random_uint32(); publisher->remote_fd = fd; publisher->remote_rtcp_fd = rtcp_fd; + publisher->metadata = metadata ? json_deep_copy(metadata) : NULL; pipe(publisher->pipefd); janus_mutex_init(&publisher->subscribers_mutex); janus_mutex_init(&publisher->own_subscriptions_mutex); @@ -7966,7 +8000,7 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi goto prepare_response; } janus_refcount_increase(&publisher->ref); - /* Check if there's a new display, new streams, or changes to existing ones */ + /* Check if there's a new display, new metadata, new streams, or changes to existing ones */ json_t *display = json_object_get(root, "display"); if(display) { char *old_display = publisher->display; @@ -7974,6 +8008,14 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi publisher->display = new_display; g_free(old_display); } + json_t *metadata = json_object_get(root, "metadata"); + if(metadata) { + json_t *old_metadata = publisher->metadata; + json_t *new_metadata = json_deep_copy(metadata); + publisher->metadata = new_metadata; + if(old_metadata) + json_decref(old_metadata); + } janus_mutex_unlock(&videoroom->mutex); janus_mutex_lock(&publisher->streams_mutex); janus_videoroom_publisher_stream *ps = NULL; @@ -9429,6 +9471,7 @@ static void *janus_videoroom_handler(void *data) { } } json_t *display = json_object_get(root, "display"); + json_t *metadata= json_object_get(root, "metadata"); const char *display_text = display ? json_string_value(display) : NULL; guint64 user_id = 0; char user_id_num[30], *user_id_str = NULL; @@ -9506,6 +9549,7 @@ static void *janus_videoroom_handler(void *data) { publisher->user_id = user_id; publisher->user_id_str = user_id_str ? g_strdup(user_id_str) : NULL; publisher->display = display_text ? g_strdup(display_text) : NULL; + publisher->metadata = NULL; publisher->recording_active = FALSE; publisher->recording_base = NULL; publisher->firefox = FALSE; @@ -9611,6 +9655,11 @@ static void *janus_videoroom_handler(void *data) { JANUS_LOG(LOG_VERB, "Setting user audio_level_average: %d (room %s, user %s)\n", publisher->user_audio_level_average, publisher->room_id_str, publisher->user_id_str); } + if(metadata) { + publisher->metadata = json_deep_copy(metadata); + JANUS_LOG(LOG_VERB, "Setting metadata: (room %s, user %s)\n", + publisher->room_id_str, publisher->user_id_str); + } /* Done */ janus_mutex_lock(&session->mutex); /* Make sure the session has not been destroyed in the meanwhile */ @@ -9658,6 +9707,8 @@ static void *janus_videoroom_handler(void *data) { json_object_set_new(pl, "id", string_ids ? json_string(p->user_id_str) : json_integer(p->user_id)); if(p->display) json_object_set_new(pl, "display", json_string(p->display)); + if(p->metadata) + json_object_set_new(pl, "metadata", json_deep_copy(p->metadata)); if(p->dummy) json_object_set_new(pl, "dummy", json_true()); /* Add proper info on all the streams */ @@ -10509,6 +10560,7 @@ static void *janus_videoroom_handler(void *data) { json_t *record = json_object_get(root, "record"); json_t *recfile = json_object_get(root, "filename"); json_t *display = json_object_get(root, "display"); + json_t *metadata = json_object_get(root, "metadata"); json_t *update = json_object_get(root, "update"); json_t *user_audio_active_packets = json_object_get(root, "audio_active_packets"); json_t *user_audio_level_average = json_object_get(root, "audio_level_average"); @@ -10804,6 +10856,26 @@ static void *janus_videoroom_handler(void *data) { g_free(old_display); janus_mutex_unlock(&participant->room->mutex); } + if(metadata) { + janus_mutex_lock(&participant->room->mutex); + char *old_metadata = participant->metadata; + char *new_metadata = json_deep_copy(metadata); + participant->metadata = new_metadata; + if(old_metadata != NULL) { + /* The metadata changed, notify this */ + json_t *metadata_event = json_object(); + json_object_set_new(metadata_event, "videoroom", json_string("event")); + json_object_set_new(metadata_event, "id", string_ids ? + json_string(participant->user_id_str) : json_integer(participant->user_id)); + json_object_set_new(metadata_event, "metadata", json_deep_copy(participant->metadata)); + if(participant->room && !g_atomic_int_get(&participant->room->destroyed)) { + janus_videoroom_notify_participants(participant, metadata_event, FALSE); + } + json_decref(metadata_event); + json_decref(old_metadata); + } + janus_mutex_unlock(&participant->room->mutex); + } /* Are we updating the description? */ if(descriptions != NULL && json_array_size(descriptions) > 0 && json_string_value(json_object_get(msg->jsep, "sdp")) == NULL) { /* We only do this here if this is an SDP-less configure: in case