Kurento is an Open Source Software WebRTC media server

Kurento 6.15.0 (November 2020)


To install Kurento Media Server: Installation Guide.

These Release Notes were originally published here.



SDP generateOffer(): offerToReceiveAudio, offerToReceiveVideo

Albeit the way applications are typically written have the SDP Offer/Answer being started from the client (i.e. a client browser sends an SDP Offer to KMS), it has always been possible to do the opposite, and start the WebRTC negotiation from KMS, with the client method generateOffer() (i.e. KMS generates an SDP Offer that is sent to the client browser).

However, SDP Offers generated by KMS would always contain one audio and one video media-level sections (those lines starting with m= in the SDP). This would make it impossible to send an audio-only or video-only offer to the clients.

The WebRTC implementation in Kurento strives to be familiar to JavaScript developers who know about the RTCPeerConnection browser API, and in this case we are introducing the offerToReceiveAudio / offerToReceiveVideo options that are well known from the RTCPeerConnection.createOffer() method. These options can be used to change the SDP Offer generation in KMS, so it is now possible to control whether the offer includes audio or video, separately.

Example Java code, for an audio-only offer:

import org.kurento.client.OfferOptions;
OfferOptions options = new OfferOptions();
String sdpOffer = webRtcEp.generateOffer(options);


WebRTC: externalIPv4 & externalIPv6 instead of externalAddress

The externalAddress parameter, introduced in Kurento 6.13.0, offered a way to tell the media server about its own public IP, without the need to use an additional STUN server. This is a nice feature because then the WebRTC connectivity checks could save some time trying to find out about the public IP in the first place. However, externalAddress would replace all of IPv4 and IPv6 addresses in the ICE candidate gathering phase, which is problematic because the actual type of address wasn't being taken into account for the substitution.

With the new parameters, externalIPv4 and externalIPv6, it is now possible to define either of static public IPv4 and/or IPv6 addresses. It is now possible to specify any of those, or both at the same time. As usual, this can be done upon installation, by editing the Kurento configuration files, or otherwise it can be set dynamically by the Client Application, via an API call offered by the Java or JavaScript client SDKs.

These parameters supersede the externalAddress, which now is deprecated and scheduled for removal in the next major release of Kurento.

Thanks to @prlanzarin (Paulo Lanzarin) for contributing these new parameters in Kurento/kms-elements#27 (Add externalIPv4/externalIPv6 configs and API methods for them).


Missing modules now available again

Some of the Kurento example modules had been broken for a while (since around version 6.10). This was caused by incompatibilities with newer versions of system libraries in Ubuntu 18.04, so we had to disable the build system for these modules due to a lack of maintainers that could get them up to date.

This situation has now been corrected and all of the additional modules can be installed with apt and are also included by default in Docker images: kms-chroma, kms-crowddetector, kms-markerdetector, kms-platedetector, kms-pointerdetector.

All plugins using HTTP are working again, too. This includes the HTTP recording capabilities of the RecorderEndpoint, and some plugins such as the ImageOverlayFilter which in turn is used by FaceOverlayFilter (both available from kms-filters); a demo of the FaceOverlayFilter can be seen with the WebRTC Magic Mirror tutorial.

Remember that these example modules are provided exclusively for demonstration purposes.



TURN port configuration in Coturn and Kurento.

Previous versions of the Kurento FAQ contained this sentence:

> Port ranges must match between Coturn and Kurento Media Server.
> Check the files /etc/turnserver.conf and /etc/kurento/modules/kurento/BaseRtpEndpoint.conf.ini, to verify that both will be using the same set of ports.

This was wrong. Normally, when a TURN server is in use it will be deployed in a network segment that is different from both the one where KMS is, and where the WebRTC peers are. The TURN server acts as a relay which allows connecting both of those networks when a direct connection cannot be achieved between them. As such, there is no reason why the TURN server should be using the same port range than the WebRTC peers, of which KMS is one.


Service stop script now waits until actually exiting.

The scripts that run when Kurento is started as a system service (either with systemctl or the traditional service kurento-media-server (start|stop|restart)) would not wait until the KMS process released all its resources and exited, when issuing a stop request. Instead, stopping the service would return immediately, regardless of the time KMS took to stop. This meant that the restart operation was broken: the current KMS instance would be told to stop, and a new one would be launched immediately, causing conflicts between both instances if the old one took some time to exit.

This has now been changed so the stop and restart actions wait a maximum of 25 seconds for the KMS process to stop; after that time, if the process didn't exit yet, it will be forcefully killed.

Remember this only applies to KMS instances that are initiated using the system service tools; other kinds of deployments (such as Docker containers) have their own way to manage the lifetime of the media server processes.


Updated OpenH264 to v1.5.0.

OpenH264 is the H.264 codec implementation offered by Cisco. The maximum version of OpenH264 that we can build is 1.5.0. Cisco introduced a breaking change starting from 1.6.0, which means our fork of gst-plugins-bad won't build with that version. In order to update OpenH264 further than 1.5.0, we need to drop our old GStreamer forks and move to more up to date versions.



  • externalAddress should be replaced by externalIPv4 and/or externalIPv6.



SDP generateOffer() H.264 profile-level-id.

When a WebRTC implementation creates a new SDP Offer in order to negotiate usage of the H.264 video codec, this must include some attributes that Kurento wasn't including in its own offers. This has now been fixed, and SDP Offers created by Kurento will include the required attributes for H.264: level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f.


RecorderEndpoint HTTP docs.

Client docs (Java, JavaScript) wrongly stated that the HTTP recording mode requires an HTTP server with support for the PUT method. This was wrong, and now it correctly explains that the HTTP method is POST in chunked mode (using the HTTP header Transfer-Encoding: chunked).


GStreamer Merge Request 38.

All commits from this change (https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_reques...) have been backported from the upstream repository, fixing a memory leak related to incorrect handling of RTCP packets, as described in issue 522 (https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/issues/522).


Fixed libnice DDoS

Some users reported a worrying bug that could end up used to force DDoS attacks to machines running Kurento Media Server. The summary of it is that simply sending any bit of data to one of the TCP-Passive ports where the WebRTC engine was listening for connections, would cause a thread to spin-lock and use 100% of a CPU core.

The issue was studied and located to be in libnice, a 3rd-party library that Kurento uses to implement the ICE protocol which is part of WebRTC. libnice developers had a great reaction time and this issue got fixed in a matter of days!

Kurento now comes with libnice 0.1.18, the newest version of this library, meaning that our favorite media server is now safer and more robust.

Thanks to @darrenhp for reporting this issue in Kurento/bugtracker#486 (libnice cause cpu 100% and don't restore after 'attacked' by a spider or security-scaner).


Fixed Recorder synchronization on streaming gaps

The RecorderEndpoint suffered from an audio/video synchronization issue that multiple users have noticed over time. The root cause of this issue was packet loss in the network: any missing packet would cause a gap in the sequence of audio timestamps that got stored to file. These gaps would make the audio and video tracks to drift over time, ending up with a noticeable difference and with a broken lipsync.

A new method to avoid timestamp gaps has been added to the recorder: now, whenever a gap is detected, the recorder will overwrite the timestamps in order to take into account the missing data. This way, both audio and video will still match and be synchronized during playback.


Other changes

This list includes other changes and fixes contributed by users and/or fellow developers, who merit our sincere appreciation and thanks for sharing their work with the Kurento project: