diff --git a/daemon/janus.c b/daemon/janus.c index 6d8108171..5c0bff782 100644 --- a/daemon/janus.c +++ b/daemon/janus.c @@ -1096,6 +1096,68 @@ void janus_rtc_up(struct call_monologue *ml) { } +// call is locked in some way +void janus_media_up(struct call_media *media) { + struct call_monologue *ml = media->monologue; + if (!ml) + return; + + struct janus_session *session = ml->janus_session; + if (!session) + return; + + // the monologue tag is the handle ID + uint64_t handle = str_to_ui(&ml->tag, 0); + if (!handle) + return; + + // build json + + JsonBuilder *builder = json_builder_new(); + json_builder_begin_object(builder); // { + json_builder_set_member_name(builder, "janus"); + json_builder_add_string_value(builder, "media"); + json_builder_set_member_name(builder, "session_id"); + json_builder_add_int_value(builder, session->id); + json_builder_set_member_name(builder, "sender"); + json_builder_add_int_value(builder, handle); + json_builder_set_member_name(builder, "mid"); + if (media->media_id.s) + json_builder_add_string_value(builder, media->media_id.s); + else + json_builder_add_null_value(builder); + json_builder_set_member_name(builder, "type"); + json_builder_add_string_value(builder, media->type.s); + json_builder_set_member_name(builder, "receiving"); + json_builder_add_boolean_value(builder, true); + json_builder_end_object(builder); // } + + JsonGenerator *gen = json_generator_new(); + JsonNode *root = json_builder_get_root(builder); + json_generator_set_root(gen, root); + char *result = json_generator_to_data(gen, NULL); + + json_node_free(root); + g_object_unref(gen); + g_object_unref(builder); + + // lock order constraint: janus_session lock first, websocket_conn lock second + + LOCK(&session->lock); + + GHashTableIter iter; + gpointer value; + g_hash_table_iter_init(&iter, session->websockets); + + while (g_hash_table_iter_next(&iter, NULL, &value)) { + struct websocket_conn *wc = value; + websocket_write_text(wc, result, true); + } + + g_free(result); +} + + const char *janus_attach(JsonReader *reader, JsonBuilder *builder, struct janus_session *session, int *retcode) { *retcode = 458; if (!session) diff --git a/daemon/media_socket.c b/daemon/media_socket.c index a8527f260..56594951b 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -2475,8 +2475,11 @@ static int stream_packet(struct packet_handler_ctx *phc) { // XXX separate stats for received/sent if (atomic64_inc(&phc->mp.stream->stats_in.packets) == 0) { - if (phc->mp.stream->component == 1 && phc->mp.media->index == 1) - janus_rtc_up(phc->mp.media->monologue); + if (phc->mp.stream->component == 1) { + if (phc->mp.media->index == 1) + janus_rtc_up(phc->mp.media->monologue); + janus_media_up(phc->mp.media); + } } atomic64_add(&phc->mp.stream->stats_in.bytes, phc->s.len); atomic64_set(&phc->mp.stream->last_packet, rtpe_now.tv_sec); diff --git a/include/janus.h b/include/janus.h index e88608721..b261bbc44 100644 --- a/include/janus.h +++ b/include/janus.h @@ -5,6 +5,7 @@ struct websocket_conn; struct websocket_message; struct janus_session; struct call_monologue; +struct call_media; void janus_init(void); @@ -15,6 +16,7 @@ const char *websocket_janus_get(struct websocket_message *wm); const char *websocket_janus_post(struct websocket_message *wm); void janus_detach_websocket(struct janus_session *session, struct websocket_conn *wc); void janus_rtc_up(struct call_monologue *); +void janus_media_up(struct call_media *); #endif diff --git a/t/auto-daemon-tests-websocket.py b/t/auto-daemon-tests-websocket.py index d32311481..e2e1fd31a 100644 --- a/t/auto-daemon-tests-websocket.py +++ b/t/auto-daemon-tests-websocket.py @@ -1341,6 +1341,13 @@ class TestVideoroom(unittest.TestCase): {"janus": "webrtcup", "session_id": session, "sender": pub_handle}, ) + # wait for media event + eventloop.run_until_complete(testIJson(self)) + self.assertEqual( + self._res, + {"janus": "media", "session_id": session, "sender": pub_handle, "type": "audio", "mid": "audio", "receiving": True}, + ) + self.destroyVideoroom(token, session, control_handle, room) pub_sock.close()