[Blog] MistServer and Secure Reliable Transport (SRT)
Hello everyone, this article is about using Haivison SRT together with MistServer.
What is Secure Reliable Transport (SRT)?
Secure Reliable Transport, or SRT for short, is a method to send stream data over unreliable network connections. Do note that it is meant for server traffic, there are no SRT players. The main advantage of SRT is that it allows you to push a playable stream over networks that otherwise would not work properly. However, keep in mind that for "perfect connections" it would just add unnecessary latency. So it is mostly something to use when you have to rely on public internet connections.
How to use SRT in MistServer
SRT is implemented to behave like srt-live-transmit, so using SRT under MistServer should feel familiar if you’re familiar with the usage of srt-live-transmit. Filling in a host on one side implies caller mode while leaving the host out implies listener mode.
The only difference is that you do not set up the input or output side depending on how you’re using SRT. You will only need to set up one side of the connection as the other side will be implied by the usage. If you can also overwrite any “default” setting by using
Not setting a host will imply Listener mode for the input/output
Setting a host will imply Caller mode for the input/output
You can always overwrite a mode by using
?mode=caller/listener as a parameter
Not setting a host will default the bind to: 0.0.0.0
Both caller/listener inputs are set up through setting up a new stream through the stream panel.
SRT LISTENER INPUT
This input is set up by creating/editing a new stream and setting the following source:
By leaving out the host you will imply Listener mode, thus instructing MistServer to look at all available addresses on the given port for SRT stream data. Another method would be:
This will force MistServer to open the given address/port as listener mode (host is optional, if left out 0.0.0.0 will be used).
If no SRT data is given it will behave like other MistServer inputs, if set to “always on” it will keep on trying and trying. If set to “default” it will try for about 20 seconds, then retry once a new viewer tries to open the stream.
SRT CALLER INPUT
This input is set up by creating/editing a new stream and setting the following source:
By setting the host you will put the SRT input in caller mode, thus instructing it to connect to the given address/port and look for SRT data to receive.
Another method would be:
Though not recommended you could use this to set up caller mode. The reason why it’s unrecommended is that giving a host already implies caller mode and leaving host out will default to 0.0.0.0 which is nonsensical for a caller mode.
Both Styles are available through the push panel, Listener output is available through the protocol panel as well.
SRT LISTENER OUTPUT
Two methods to set this up, a “sort of” temporarily through the push panel and a more permanent one through the protocol panel.
Push panel style
Setting up SRT LISTENER output through the push panel is done through the Push panel and setting up a push stream with target:
This will set up MistServer to push out the stream and accept incoming connections. Those that connect will jump to the current live point of the stream, whether it’s Live or VoD. There is no starting from the beginning here. The push will stop once it reaches the stream end or the source input disappears.
Protocol Panel Style
Setting up SRT Listener output through the protocol panel is done by selecting TS over SRT and setting up the following:
- Set up the source input by filling in the stream name.
- Choose a port (optional: Host too)
This will start the input and make the stream available for viewers. VoD files will always start at the beginning of the VoD file, while Live streams will go to the most live point.
SRT CALLER OUTPUT
This is only done through the push panel, set up a new push and use the following target:
Again, the alternative mode is not recommended as it does not make much sense. Setting an SRT output in caller mode will connect to an SRT listener and start pushing if it makes a connection. VoD will always start at the beginning and live will start at the most live point. If there is no connection made within ~10 seconds it will close down and only start up if it is an automatic push with retry enabled.
All SRT over a single Port
SRT can also be set up to work through a single port using the ?streamid parameters. Within the MistServer Protocol panel you can set up SRT (default 8889) to accept connections coming in, out or both.
If set to incoming connections, this port can only be used for SRT connections going into the server. If set to outgoing the port will only be available for SRT connections going out of the server. If set to both, SRT will try to listen first and if nothing happens in 3 seconds it will start trying to send out a connection when contact has been made. Do note that we have found this functionality to be buggy in some implementations of Unix (Ubuntu 18.04) or highly unstable connections.
Once set up you can use SRT in a similar fashion as RTMP or RTSP. You can pull any available stream within MIstServer using SRT and push towards any stream that’s setup to receive incoming pushes. It makes the overall usage of SRT a lot easier as you do not need to set up a port per stream.
Pushing towards SRT using a single port
You can push towards a MistServers incoming SRT connection port using:
Do note that the stream has to be set up to accept incoming pushes.
Pulling SRT from MistServer using a single port
You can pull from a MistServer using it’s outgoing SRT connection port:
Known issue in some of the Linux OSs (like Ubuntu 18.04)
The SRT library we use for the native implementation has one issue in some Linux distros. Our default usage for SRT is to accept both incoming and outgoing connections. Some Linux distro have a bug in the logic there and could get stuck on waiting for data while they should be pushing out when you're trying to pull an SRT stream from the server. If you notice this you can avoid the issue by setting a port for outgoing SRT connections and another port for incoming SRT connections. This setup will also win you ~3seconds of latency when used. The only difference is that the port changes depending on whether the stream data comes into the server or leaves the server.
Recommendations and best practices
The most flexible method of working with SRT is using SRT over a single port. Truly using a single port brings some downsides in terms of latency and stability however. Therefore we recommend setting up 2 ports, one for input and one for output and then using these together with ?streamid parameters.
Getting SRT to work better
There are several parameters (options) you can give to any SRT url to set up the SRT connection better, anything using the SRT library should be able to handle these parameters. These are often overlooked and forgotten as most first users tend to just fill in the urls and see it does not work how they would like it to and stop trying there and then. Now understand that the default settings of any SRT connection cannot be optimized for your connection from the get go. The defaults will work under good network conditions, but are not meant to be used as is in unreliable connections.
A full list of options you can use can be found in the SRT documentation.
Using these options is as simple as setting a parameter within the url, making them lowercase and stripping the SRTO_ part. For example
&streamid= depending on if it’s the first or following parameter.
We highly recommend starting out with the parameters below as these make all the difference in the world for stream quality especially with bad connections where SRT should be used.
This is what we consider the most important parameter to set for unstable connections. Simply put, it is the time SRT will wait for other packets coming in before sending it on. As you might understand if the connection is bad you will want to give the process some time. It’ll be unrealistic to just assume everything got sent over correctly at once as you wouldn’t be using SRT otherwise! Haivision themselves recommend setting this as:
RTT_Multiplier * RTT
RTT = Round Time Trip, basically the time it takes for the servers to reach each other back and forth. If you’re using ping or iperf remember you will need to double the ms you get.
RTT_Multiplier = A multiplier that indicates how often a packet can be sent again before SRT gives up on it. The values are between 3 and 20, where 3 means perfect connection and 20 means 100% packet loss.
Now what Haivision recommends is using their table depending on your network constraints, however if you are anything like me and do not want to spend time on such calculations I would recommend using the following and going up a step whenever you see it is still not working properly:
1: 4 x RTT 2: 8 x RTT 3: 12 x RTT 4: 16 x RTT 5: 20 x RTT
While it is not the best setting, it does get the job done. You might lose out on latency, but our priority with SRT is ensuring stream stability, not latency.
This option enables forward error correction, which in turn can help stream stability. A very good explanation on how to tackle this is available here. Important to note here is that it is recommended that one side has no settings and the other sets all of them. In order to do this the best you should have MistServer set no settings and any incoming push towards MistServer set the forward error correction filter.
Our personal default setting is:
We start with this and have not had to switch it yet if mixed together with a good latency filter. Now optimizing this is obviously the best choice, but using “something” is already better than nothing in this case.
Combining multiple parameters
To avoid confusion, these parameters work like any other parameters for urls. So the first one always starts with a
? while every other starts with an
Hopefully this should've given you enough to get started with SRT on your own. Of course if there's any questions left or you run into any issues feel free to contact us and we'll happily help you!