Setup RTMP Server with nginx & bandwidth throttle

 

What’s this for?

Many people have bandwidth limitations and want to stream, or want to stream at a higher bitrate, but their bandwidth from their ISP prevents it, this allows for the facilitation of that!

Pre-configure warnings

Be aware the guide I write here is utilizing Raspbian Buster, however most of the configuration in question here can be done on other Debian or Ubuntu based distributions. Also note that nginx can be installed on Windows, Linux, or Mac, but configuration may be slightly or very different!

Hardware Prerequisites

  • Spare computer (with networking capabilities, wired preferred)
  • Working and configured operating system (this guide assumes Raspbian Buster)
  • Any necessary updates

Build nginx with rtmp

The nginx that comes with the apt database does not include RTMP, so we have to get Nginx and the RTMP module from source, but first, we need to install some prerequisites. So from your terminal/command line run these

sudo apt-get install build-essential libpcre3 libpcre3-dev libssl-dev

Just to keep things clean, lets make a new folder named nginx and go into it

mkdir ~/nginx
cd ~/nginx

Next, we need to download nginx source and rtmp module source

wget https://nginx.org/download/nginx-1.17.10.tar.gz
wget https://github.com/arut/nginx-rtmp-module/archive/master.zip

If the above fails you likely don’t have wget installed just run sudo apt-get install wget -y and it will go through the process for you.

You may want to make sure you also have unzip installed, sudo apt-get install unzip -y.

Once done, run the following 2 commands

tar -xvzf nginx-1.17.10.tar.gz
unzip master.zip

Now you should have 2 new directories

  • nginx-1.17.10
  • nginx-rtmp-module-master

Lets move into the nginx-1.17.10 directory

cd nginx-1.17.10

From here we can start the configuration portion of the build, it’s just one command line command

./configure --with-http_ssl_module --add-module=../nginx-rtmp-module-master --with-cc-opt="-Wimplicit-fallthrough=0"

This will configure your nginx and where it is going to expect to be installed (you’ll see a preview of the directories at the end of the prompts.)

Next, we “make” the software (this is the actual compile and installation process.) So run these 2 commands

make
sudo make install

At this point many people would actually have you install FFMpeg, but seeing as we’re only utilizing this as a relay, this is unnecessary.

Testing & configuring nginx

First up, lets see if nginx runs!
Run this to start

sudo /usr/local/nginx/sbin/nginx

If you now visit the IP address of your device on your network (or if it’s your own computer) you’ll see a “Welcome to nginx” page! Nginx works!

Alright, moving on to configuring nginx to accept the rtmp input
Open /usr/local/nginx/conf/nginx.conf with your favorite text editor, remember sudo is required here.
This .conf lets us define protocols that nginx supports, so we’re going to add rtmp to it

rtmp {
        server {
                listen 1935;
                chunk_size 4096;

                application live {
                        live on;
                        record off;
                }
        }
}

You can replace live with anything. You can technically replace 1935 as well, but this is the default port for RTMP services, so it requires more client configuration when you’re ready to do that, so it is not recommended to do so.

Now, in OBS (Or your RTMP Supported Streaming Software) you can add in a custom server

Streaming service: Custom/RTMP
Server: rtmp://live
Play Path/Stream Key: test

Why is your stream key test? Because this is actually the connection path. You can start your stream to this RTMP and use software like VLC to connect to a live broadcast using the address rtmp:///live/test and you will see your broadcast!

Note you may experience some delays with this.

Cool, an RTMP broadcast to only people who know my IP inside my network, how is this useful?

It’s not, but what it does now do is facilitate another very cool feature, push.

This will actually accept your RTMP ingest, and push it out to your stream-platform of choice.

Lets say you wanted to do twitch. You can edit the nginx.conf underneath record off to include a line that looks like this
push rtmp://live-ord02.twitch.tv/app/{stream_key}

So the end result will be something like

rtmp {
        server {
                listen 1935;
                chunk_size 4096;

                application live {
                        live on;
                        record off;
                        push rtmp://live-ord02.twitch.tv/app/{stream_key};
                }
        }
}

The coolest part about this feature is you can have it push to multiple locations so Twitch, Mixer, YouTube, and so on, as long as they support RTMP so this is your own personal restream! Cool, right?

If Twitch is your forte here’s a link to recommended ingest servers for you.
https://stream.twitch.tv/ingests/

If you’re not sure of your Twitch Stream Key it should be here (do not share it):
https://dashboard.twitch.tv/settings/channel

How does it help my bandwidth?

It doesn’t, yet, kind of.
You can configure your router to throttle bandwidth from individual devices if you have QoS features, so you could throttle the device (in my case raspberry pi) this way. But many modern routers have “adaptive QoS” which will prioritize what it thinks should be priority, which in many cases is actually better. So we want to look at a software solution.

But before we do, I do want to point out that in its current state, this rtmp restream system actually allows you to support a higher bitrate, as this is happening inside of your network, most networks today are gigabit, so you can probably push that bitrate threshold assuming your computer can process your encoding that quickly. The reason we can do this is that once it starts heading “out” from your RTMP server it’s going to process at whatever data speed you’ve throttled it to.

Wondershaper

Wondershaper is quite possibly the easiest possible thing to do of all of this.
It lets you explicitly state your bandwidth limit based on your network interface.
Let’s install it

sudp apt-get install wondershaper -y

Next, you should know what your upload and download speeds are, so from a computer or device head to https://testmy.net or https://speedtest.net and run a speed test.

I actually know what I pay for so I know what I should be receiving up and down most of the time, my download is 300 mbps, and my upload is 50 mbps.

I know that if I run a “test” of OBS or Streamlabs OBS it’ll put my bitrate at 6000 (about 6 mbps) but that’s a bit too much for my liking, and it’s a bit overkill. It’s great for speed, but not ideal. I usually half it then go a little lower, so my personal safe bitrate, I think, is 2500. But I don’t need to set it to that on OBS or SLOBS, I can enforce the 2.5 mbps upload with wondershaper!

Alright, so next, Wondershaper needs to know what network interface to shape, so run this command

ifconfig

It will provide you an output that has lines that start with colons at the end of the first section, most common are

eth0: <-- ethernet
lo: <-- local [not relevant to outside of the device]
wlan0: <-- wifi

Yours may display differently and this is normal! But be aware of them. In my case eth0 is ethernet, and wlan0 is wifi.
I want to make sure I never allow either to use upload speeds are more than 2.5 mbps. So I run commands based on the following format
wondershaper networkinterface download upload

So because I have 2 network interface cards (ethernet and wifi) I run these 2 commands

sudo wondershaper eth0 307200 2560
sudo wondershaper wlan0 307200 2560

You may be wondering where I get these numbers, wondershaper takes input in kilobits per second (kbps), and my ISP operates in megabits, the increase in these items is always by 1024 bits. So if you’re at 100 mbps, you would multiply 100 by 1024, which would be 102,400. SO in my case, 2.5 mbps upload is 2560, and 300 mbps download is 307200

Conclusion

In this instructional you have learned how to download, and compile nginx with RTMP, connect a streaming software to that RTMP, push that RTMP to another RTMP server, and set up bandwidth throttling.

Be aware that these configurations are not automated and nginx, and wondershaper settings will need to be re-applied or re-loaded every time you reboot the device you configured for this. There are plans to add automation instruction to this later.

Lastly, be aware that with this configuration it’s best to only use this device (in my case a Raspberry Pi 4) as this kind of stream ingestion, as you are throttling the whole network device or network devices. It would be a waste to try to operate anything more as those other services would rely on those network devices.

Pros

Higher bitrate from source

Less bandwidth usage

You can use this to isolate problems, if your streaming software reports frame drops that’s inside your network. If your stream destination reports frame drops that’s on your ISP or the stream destination.

Cons

This requires using separate tools for monitoring your push-destination and your local frame drops (luckily most providers like Twitch & Mixer have dashboards for this on their end.)

You are bandwidth limiting your entire network device, so utilizing this device for anything else will be impeded by this bandwidth limit as well.