diff --git a/src/plugins/janus_videoroom.c b/src/plugins/janus_videoroom.c index 77c67d876e..c5f246523a 100644 --- a/src/plugins/janus_videoroom.c +++ b/src/plugins/janus_videoroom.c @@ -459,6 +459,7 @@ room-: { { // Participant #1 "id" : , "display" : "", + "metadata" : , "publisher" : "", "talking" : }, @@ -494,7 +495,8 @@ room-: { "room" : , "id" : , "display" : "", - "token" : "" + "token" : "", + "metadata" : } \endverbatim * @@ -523,6 +525,7 @@ room-: { { "id" : , "display" : "", + "metadata" : , "dummy" : , "streams" : [ { @@ -546,7 +549,8 @@ room-: { "attendees" : [ // Only present when notify_joining is set to TRUE for rooms { "id" : , - "display" : "" + "display" : "", + "metadata" : }, // Other attendees ] @@ -576,7 +580,8 @@ room-: { "room" : , "joining" : { "id" : , - "display" : "" + "display" : "", + "metadata" : } } \endverbatim @@ -601,6 +606,7 @@ room-: { "record" : , "filename" : "", "display" : "", + "metadata" : , "audio_level_average" : "", "audio_active_packets" : "", "descriptions" : [ // Optional @@ -668,6 +674,7 @@ room-: { { "id" : , "display" : "", + "metadata" : , "dummy" : , "streams" : [ { @@ -740,6 +747,7 @@ room-: { "record" : , "filename" : "", "display" : "", + "metadata" : , "audio_active_packets" : "", "audio_level_average" : "", "streams" : [ @@ -1648,6 +1656,7 @@ room-: { "id" : , "secret" : "", "display" : "", + "metadata" : , "streams" : [ { // Same syntax as add_remote_publisher: only needs to @@ -2014,6 +2023,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 +2098,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 +2207,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 +2445,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 +2774,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); @@ -4260,6 +4276,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(); @@ -4333,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) { @@ -4377,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); @@ -4414,6 +4437,8 @@ static void janus_videoroom_leave_or_unpublish(janus_videoroom_publisher *partic json_object_set_new(event, "room", string_ids ? json_string(participant->room_id_str) : json_integer(participant->room_id)); if(participant->display) json_object_set_new(event, "display", json_string(participant->display)); + if(participant->metadata) + json_object_set_new(event, "metadata", json_deep_copy(participant->metadata)); json_object_set_new(event, is_leaving ? (kicked ? "kicked" : "leaving") : "unpublished", string_ids ? json_string(participant->user_id_str) : json_integer(participant->user_id)); janus_videoroom_notify_participants(participant, event, FALSE); @@ -4425,6 +4450,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) { @@ -4536,6 +4563,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))); @@ -6850,6 +6879,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) @@ -6933,6 +6964,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; @@ -7579,6 +7612,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); @@ -7709,6 +7743,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); @@ -7973,7 +8008,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; @@ -7981,6 +8016,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_lock(&publisher->streams_mutex); janus_videoroom_publisher_stream *ps = NULL; int changes = FALSE; @@ -9447,6 +9490,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; @@ -9524,6 +9568,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; @@ -9629,6 +9674,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 */ @@ -9676,6 +9726,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 */ @@ -10527,6 +10579,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"); @@ -10822,6 +10875,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