diff --git a/.github/workflows/janus-ci.yml b/.github/workflows/janus-ci.yml index 35b8a9561f..b54cddf66b 100644 --- a/.github/workflows/janus-ci.yml +++ b/.github/workflows/janus-ci.yml @@ -14,7 +14,7 @@ jobs: datachannels: ["yes", "no"] libcurl: ["yes", "no"] include: - - datachannel: "yes" + - datachannels: "yes" libcurl: "yes" deps_from_src: "yes" janus_config_opts: "" diff --git a/Makefile.am b/Makefile.am index 67b3b78035..576c2c17f4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -585,6 +585,8 @@ janus_pp_rec_SOURCES = \ postprocessing/pp-h264.h \ postprocessing/pp-av1.c \ postprocessing/pp-av1.h \ + postprocessing/pp-avformat.c \ + postprocessing/pp-avformat.h \ postprocessing/pp-h265.c \ postprocessing/pp-h265.h \ postprocessing/pp-opus.c \ diff --git a/README.md b/README.md index 3c86cac1a6..f2bfd40ff6 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ To install it, you'll need to satisfy the following dependencies: * [Jansson](http://www.digip.org/jansson/) * [libconfig](https://hyperrealm.github.io/libconfig/) -* [libnice](https://libnice.freedesktop.org/) (at least v0.1.16 suggested, master recommended) +* [libnice](https://libnice.freedesktop.org/) (at least v0.1.16 suggested, v0.1.18 recommended) * [OpenSSL](http://www.openssl.org/) (at least v1.0.1e) * [libsrtp](https://github.com/cisco/libsrtp) (at least v2.x suggested) * [usrsctp](https://github.com/sctplab/usrsctp) (only needed if you are interested in Data Channels) diff --git a/conf/janus.eventhandler.rabbitmqevh.jcfg.sample b/conf/janus.eventhandler.rabbitmqevh.jcfg.sample index a29ec4e3cb..c8635e2453 100644 --- a/conf/janus.eventhandler.rabbitmqevh.jcfg.sample +++ b/conf/janus.eventhandler.rabbitmqevh.jcfg.sample @@ -20,7 +20,7 @@ general: { #exchange = "janus-exchange" route_key = "janus-events" # Routing key to use when publishing messages #exchange_type = "fanout" # Rabbitmq exchange_type can be one of the available types: direct, topic, headers and fanout (fanout by defualt). - #heartbeat = 60 # Defines the seconds without communication that should pass before considering the TCP connection has unreachable. + #heartbeat = 60 # Defines the seconds without communication that should pass before considering the TCP connection unreachable. #declare_outgoing_queue = true # By default (for backwards compatibility), we declare an outgoing queue. Set this to false to disable that behavior #ssl_enable = false # Whether ssl support must be enabled diff --git a/conf/janus.plugin.audiobridge.jcfg.sample b/conf/janus.plugin.audiobridge.jcfg.sample index b4a7929187..e57a20f109 100644 --- a/conf/janus.plugin.audiobridge.jcfg.sample +++ b/conf/janus.plugin.audiobridge.jcfg.sample @@ -4,6 +4,7 @@ # secret = "" # pin = "" # sampling_rate = (e.g., 16000 for wideband mixing) +# spatial_audio = true|false (if true, the mix will be stereo to spatially place users, default=false) # audiolevel_ext = true|false (whether the ssrc-audio-level RTP extension must # be negotiated/used or not for new joins, default=true) # audiolevel_event = true|false (whether to emit event to other users or not, default=false) diff --git a/conf/janus.transport.rabbitmq.jcfg.sample b/conf/janus.transport.rabbitmq.jcfg.sample index 9aae80ef0a..27cfebd0a0 100644 --- a/conf/janus.transport.rabbitmq.jcfg.sample +++ b/conf/janus.transport.rabbitmq.jcfg.sample @@ -34,6 +34,7 @@ general: { #queue_durable = false # Whether or not incoming queue should remain after a RabbitMQ reboot #queue_autodelete = false # Whether or not incoming queue should autodelete after janus disconnects from RabbitMQ #queue_exclusive = false # Whether or not incoming queue should only allow one subscriber + #heartbeat = 60 # Defines the seconds without communication that should pass before considering the TCP connection unreachable. #ssl_enabled = false # Whether ssl support must be enabled #ssl_verify_peer = true # Whether peer verification must be enabled diff --git a/configure.ac b/configure.ac index 8315f2b6b8..69827ed9eb 100644 --- a/configure.ac +++ b/configure.ac @@ -605,6 +605,7 @@ AC_CHECK_LIB([rabbitmq], AC_DEFINE(HAVE_RABBITMQEVH) enable_rabbitmq_event_handler=yes ]) + AC_CHECK_HEADERS([rabbitmq-c/amqp.h]) ], [ AS_IF([test "x$enable_rabbitmq" = "xyes"], diff --git a/events/janus_rabbitmqevh.c b/events/janus_rabbitmqevh.c index 9fda6ddced..003ddf22be 100644 --- a/events/janus_rabbitmqevh.c +++ b/events/janus_rabbitmqevh.c @@ -12,10 +12,18 @@ #include +/* Latest RabbitMQ-C library changes the library paths from 0.12.0.0 onwards */ +#ifdef HAVE_RABBITMQ_C_AMQP_H +#include +#include +#include +#include +#else #include #include #include #include +#endif #include "../debug.h" #include "../config.h" @@ -177,7 +185,7 @@ int janus_rabbitmqevh_init(const char *config_path) { /* Compact, so no spaces between separators */ json_format = JSON_COMPACT | JSON_PRESERVE_ORDER; } else { - JANUS_LOG(LOG_WARN, "Unsupported JSON format option '%s', using default (indented)\n", item->value); + JANUS_LOG(LOG_WARN, "RabbitMQEventHandler: Unsupported JSON format option '%s', using default (indented)\n", item->value); json_format = JSON_INDENT(3) | JSON_PRESERVE_ORDER; } } @@ -224,7 +232,7 @@ int janus_rabbitmqevh_init(const char *config_path) { item = janus_config_get(config, config_general, janus_config_type_item, "heartbeat"); if(item && item->value && janus_string_to_uint16(item->value, &heartbeat) < 0) { - JANUS_LOG(LOG_ERR, "Invalid heartbeat timeout (%s), falling back to default\n", item->value); + JANUS_LOG(LOG_ERR, "RabbitMQEventHandler: Invalid heartbeat timeout (%s), falling back to default (0, disabling heartbeat)\n", item->value); heartbeat = 0; } @@ -279,9 +287,9 @@ int janus_rabbitmqevh_init(const char *config_path) { exchange = g_strdup(item->value); } if (exchange == NULL) { - JANUS_LOG(LOG_INFO, "RabbitMQ event handler enabled, %s:%d (%s) exchange_type:%s\n", rmqhost, rmqport, route_key,exchange_type); + JANUS_LOG(LOG_INFO, "RabbitMQEventHandler: enabled, %s:%d (%s) exchange_type:%s\n", rmqhost, rmqport, route_key,exchange_type); } else { - JANUS_LOG(LOG_INFO, "RabbitMQ event handler enabled, %s:%d (%s) exch: (%s) exchange_type:%s\n", rmqhost, rmqport, route_key, exchange,exchange_type); + JANUS_LOG(LOG_INFO, "RabbitMQEventHandler: enabled, %s:%d (%s) exch: (%s) exchange_type:%s\n", rmqhost, rmqport, route_key, exchange,exchange_type); } /* Connect */ @@ -300,7 +308,7 @@ int janus_rabbitmqevh_init(const char *config_path) { handler_thread = g_thread_try_new("janus rabbitmqevh handler", jns_rmqevh_hdlr, NULL, &error); if(error != NULL) { g_atomic_int_set(&initialized, 0); - JANUS_LOG(LOG_FATAL, "Got error %d (%s) trying to launch the RabbitMQEventHandler handler thread...\n", + JANUS_LOG(LOG_FATAL, "RabbitMQEventHandler: Got error %d (%s) trying to launch the RabbitMQEventHandler handler thread...\n", error->code, error->message ? error->message : "??"); g_error_free(error); goto error; @@ -309,7 +317,7 @@ int janus_rabbitmqevh_init(const char *config_path) { in_thread = g_thread_try_new("janus rabbitmqevh heartbeat handler", jns_rmqevh_hrtbt, NULL, &error); if(error != NULL) { g_atomic_int_set(&initialized, 0); - JANUS_LOG(LOG_FATAL, "Got error %d (%s) trying to launch the RabbitMQEventHandler heartbeat thread...\n", + JANUS_LOG(LOG_FATAL, "RabbitMQEventHandler: Got error %d (%s) trying to launch the RabbitMQEventHandler heartbeat thread...\n", error->code, error->message ? error->message : "??"); g_error_free(error); goto error; @@ -350,16 +358,10 @@ int janus_rabbitmqevh_connect(void) { JANUS_LOG(LOG_FATAL, "RabbitMQEventHandler: Can't connect to RabbitMQ server: error creating socket...\n"); return -1; } - if(ssl_verify_peer) { - amqp_ssl_socket_set_verify_peer(socket, 1); - } else { - amqp_ssl_socket_set_verify_peer(socket, 0); - } - if(ssl_verify_hostname) { - amqp_ssl_socket_set_verify_hostname(socket, 1); - } else { - amqp_ssl_socket_set_verify_hostname(socket, 0); - } + + amqp_ssl_socket_set_verify_peer(socket, ssl_verify_peer); + amqp_ssl_socket_set_verify_hostname(socket, ssl_verify_hostname); + if(ssl_cacert_file) { status = amqp_ssl_socket_set_cacert(socket, ssl_cacert_file); if(status != AMQP_STATUS_OK) { @@ -385,7 +387,7 @@ int janus_rabbitmqevh_connect(void) { JANUS_LOG(LOG_VERB, "RabbitMQEventHandler: Connecting to RabbitMQ server...\n"); status = amqp_socket_open(socket, rmqhost, rmqport); if(status != AMQP_STATUS_OK) { - JANUS_LOG(LOG_FATAL, "Can't connect to RabbitMQ server: error opening socket... (%s)\n", amqp_error_string2(status)); + JANUS_LOG(LOG_FATAL, "RabbitMQEventHandler: Can't connect to RabbitMQ server: error opening socket... (%s)\n", amqp_error_string2(status)); return -1; } JANUS_LOG(LOG_VERB, "RabbitMQEventHandler: Logging in...\n"); @@ -410,13 +412,13 @@ int janus_rabbitmqevh_connect(void) { amqp_exchange_declare(rmq_conn, rmq_channel, rmq_exchange, amqp_cstring_bytes(exchange_type), 0, 0, 0, 0, amqp_empty_table); result = amqp_get_rpc_reply(rmq_conn); if(result.reply_type != AMQP_RESPONSE_NORMAL) { - JANUS_LOG(LOG_FATAL, "RabbitMQEventHandler: Can't connect to RabbitMQ server: error diclaring exchange... %s, %s\n", amqp_error_string2(result.library_error), amqp_method_name(result.reply.id)); + JANUS_LOG(LOG_FATAL, "RabbitMQEventHandler: Can't connect to RabbitMQ server: error declaring exchange... %s, %s\n", amqp_error_string2(result.library_error), amqp_method_name(result.reply.id)); return -1; } } if (declare_outgoing_queue) { - JANUS_LOG(LOG_VERB, "Declaring outgoing queue... (%s)\n", route_key); + JANUS_LOG(LOG_VERB, "RabbitMQEventHandler: Declaring outgoing queue... (%s)\n", route_key); amqp_queue_declare(rmq_conn, rmq_channel, amqp_cstring_bytes(route_key), 0, 0, 0, 0, amqp_empty_table); result = amqp_get_rpc_reply(rmq_conn); if(result.reply_type != AMQP_RESPONSE_NORMAL) { @@ -425,6 +427,8 @@ int janus_rabbitmqevh_connect(void) { } } + JANUS_LOG(LOG_INFO, "RabbitMQEventHandler: Connected successfully"); + return 0; } @@ -446,9 +450,7 @@ void janus_rabbitmqevh_destroy(void) { g_async_queue_unref(events); events = NULL; - if(rmq_conn && rmq_channel) { - amqp_channel_close(rmq_conn, rmq_channel, AMQP_REPLY_SUCCESS); - amqp_connection_close(rmq_conn, AMQP_REPLY_SUCCESS); + if(rmq_conn) { amqp_destroy_connection(rmq_conn); } if(rmq_exchange.bytes) @@ -548,7 +550,7 @@ json_t *janus_rabbitmqevh_handle_request(json_t *request) { if(json_object_get(request, "grouping")) group_events = json_is_true(json_object_get(request, "grouping")); } else { - JANUS_LOG(LOG_VERB, "Unknown request '%s'\n", request_text); + JANUS_LOG(LOG_VERB, "RabbitMQEventHandler: Unknown request '%s'\n", request_text); error_code = JANUS_RABBITMQEVH_ERROR_INVALID_REQUEST; g_snprintf(error_cause, 512, "Unknown request '%s'", request_text); } @@ -570,7 +572,7 @@ json_t *janus_rabbitmqevh_handle_request(json_t *request) { /* Thread to handle incoming events */ static void *jns_rmqevh_hdlr(void *data) { - JANUS_LOG(LOG_VERB, "Joining RabbitMQEventHandler handler thread\n"); + JANUS_LOG(LOG_VERB, "RabbitMQEventHandler: joining handler thread\n"); json_t *event = NULL, *output = NULL; char *event_text = NULL; int count = 0, max = group_events ? 100 : 1; @@ -589,7 +591,7 @@ static void *jns_rmqevh_hdlr(void *data) { if(created && json_is_integer(created)) { gint64 then = json_integer_value(created); gint64 now = janus_get_monotonic_time(); - JANUS_LOG(LOG_DBG, "Handled event after %"SCNu64" us\n", now-then); + JANUS_LOG(LOG_DBG, "RabbitMQEventHandler: Handled event after %"SCNu64" us\n", now-then); } if(!group_events) { /* We're done here, we just need a single event */ @@ -613,7 +615,7 @@ static void *jns_rmqevh_hdlr(void *data) { /* Since this a simple plugin, it does the same for all events: so just convert to string... */ event_text = json_dumps(output, json_format); if(event_text == NULL) { - JANUS_LOG(LOG_WARN, "Failed to stringify event, event lost...\n"); + JANUS_LOG(LOG_WARN, "RabbitMQEventHandler: Failed to stringify event, event lost...\n"); /* Nothing we can do... get rid of the event */ json_decref(output); output = NULL; @@ -638,14 +640,14 @@ static void *jns_rmqevh_hdlr(void *data) { json_decref(output); output = NULL; } - JANUS_LOG(LOG_VERB, "Leaving RabbitMQEventHandler handler thread\n"); + JANUS_LOG(LOG_VERB, "RabbitMQEventHandler: leaving handler thread\n"); return NULL; } /* Thread to handle heartbeats */ static void *jns_rmqevh_hrtbt(void *data) { - JANUS_LOG(LOG_VERB, "Monitoring RabbitMQ HeartBeat\n"); + JANUS_LOG(LOG_VERB, "RabbitMQEventHandler: Monitoring RabbitMQ Heartbeat\n"); int waiting_usec = (heartbeat/2) * 1000000; struct timeval timeout; timeout.tv_sec = 0; @@ -666,15 +668,13 @@ static void *jns_rmqevh_hrtbt(void *data) { continue; } - JANUS_LOG(LOG_VERB, "Error on amqp_simple_wait_frame_noblock: %d (%s)\n", res, amqp_error_string2(res)); + JANUS_LOG(LOG_VERB, "RabbitMQEventHandler: Error on amqp_simple_wait_frame_noblock: %d (%s)\n", res, amqp_error_string2(res)); - if(rmq_conn && rmq_channel) { - amqp_channel_close(rmq_conn, rmq_channel, AMQP_REPLY_SUCCESS); - amqp_connection_close(rmq_conn, AMQP_REPLY_SUCCESS); + if(rmq_conn) { amqp_destroy_connection(rmq_conn); } if(!g_atomic_int_get(&stopping)) { - JANUS_LOG(LOG_VERB, "Trying to reconnect with RabbitMQ Server\n"); + JANUS_LOG(LOG_VERB, "RabbitMQEventHandler: Trying to reconnect\n"); int result = janus_rabbitmqevh_connect(); if(result < 0) { g_usleep(5000000); @@ -688,6 +688,6 @@ static void *jns_rmqevh_hrtbt(void *data) { } } - JANUS_LOG(LOG_VERB, "Leaving RabbitMQEventHandler HeartBeat thread\n"); + JANUS_LOG(LOG_VERB, "RabbitMQEventHandler: Leaving HeartBeat thread\n"); return NULL; } diff --git a/fuzzers/config.sh b/fuzzers/config.sh index de548eb78f..a362261956 100755 --- a/fuzzers/config.sh +++ b/fuzzers/config.sh @@ -16,7 +16,7 @@ DEFAULT_CC="clang" DEFAULT_CCLD=$DEFAULT_CC DEFAULT_CFLAGS="-O1 -fno-omit-frame-pointer -g -ggdb3 -fsanitize=address,undefined -fsanitize-address-use-after-scope -fno-sanitize-recover=undefined -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" DEFAULT_LDFLAGS="-O1 -fno-omit-frame-pointer -g -ggdb3 -fsanitize=address,undefined -fno-sanitize-recover=undefined -fsanitize-address-use-after-scope" -COVERAGE_CFLAGS="-O1 -fno-omit-frame-pointer -g -ggdb3 -fprofile-instr-generate -fcoverage-mapping -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" +COVERAGE_CFLAGS="-O1 -fno-omit-frame-pointer -g -ggdb3 -fprofile-instr-generate -fcoverage-mapping -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" COVERAGE_LDFLAGS="-O1 -fno-omit-frame-pointer -g -ggdb3 -fprofile-instr-generate -fcoverage-mapping -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" # Janus configure flags diff --git a/html/audiobridgetest.html b/html/audiobridgetest.html index 6621aca885..c30994b1c8 100644 --- a/html/audiobridgetest.html +++ b/html/audiobridgetest.html @@ -11,6 +11,7 @@ +