How to easily stream to two or more locations?

Streaming to more than one service can be done using an RTMP Server that relays your input to several outputs or using an external service. Services like restream.io offer free and paid options to send your stream to several services at the same time. This can be a viable option if you have not enough upload speed or bandwidth limitations on your internet connection.

Assuming you prefer doing it yourself nginx with the addition of arut’s rtmp module can do the job for us. So let me quickly explain a few things first:

  • your upload bandwidth is “the” limit: (your upload – some free room) / stream bitrate = maximum number of streams
  • nginx-rtmp on windows cannot transcode for you, so input = output BUT
    • the linux version can send different streams from one input
    • for windows you need a workaround (manual ffmpeg setup, or similar)
  • in contrast to xsplit you can save a lot of cpu power if you send the same stream to several locations over nginx 
  • one downside is that you get no info about dropped frames or disconnects as this is all handled by the nginx server
  • as always, there are different ways to reach your perfect solution, but this is a quick and easy one

Now to get started, you can compile nginx yourself (the standard download/binary does not include the rtmp-module). If you are familiar with docker you can also get docker nginx-rtmp containers. And on github you can find a few people rying to keep the nginx-rtmp module alive.

To receive a stream and send it to out different locations we have to change the “nginx.conf”. It is located in the conf folder and should look something like this afterwards:

#user  nobody;
worker_processes  1;

error_log  logs/rtmp_error.log debug;
pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

rtmp {
	server {
		listen 1935;
		chunk_size 8192;

		application stream {
			live on;
			meta copy;
			push rtmp://live-ams.twitch.tv/app/live_XYZ_ZXY;
			push rtmp://live.hitbox.tv/push/username?key=XYZ;
		}
	}
}

You can overwrite the nginx.conf with the above or just copy over the application stream to my included config (if you want to use the http stuff for statistics etc). This very simple config just includes one application called stream which waits for you to send a stream to it.  

The really important part are the two “push” directives I defined. As soon as the application receives your stream it will start sending it to both locations I set after the push. In this example to twitch.tv amsterdam server and to the hitbox.tv master. In OBS, XSplit or whatever program you use you would just setup a stream to a custom location (in xsplit custom rtmp) and choose rtmp://your.ip/stream as your server address and just enter anything for the streamkey/playpath.

This server is not secured in any way, so anyone that finds out your application name and ip address could use your application to stream to the services you setup in the push directive. But luckily you can check out my guide on how to secure your nginx server if you are afraid of something like that happening. So the only downside of this whole setup, remember the big plus of less cpu usage compared to two or more encodings xsplit would do, is that you get less information about the connection to your services.

In OBS or Xsplit you will only see how good your connection to the nginx server is. And especially on a local hosted one, this should be always fine. So you will have to ask your viewers sometimes if everythings fine and regularly check that both or all streams are still online.

Last but not least the nginx error logging capabilities can give you a lot of info of what went wrong, so always check them if you have problems, and see you soon for the next tutorial!

Timothy003 noticed:

I’ve also encountered this issue on Windows Server 2008 R2 (which shares the same code with Windows 7), and I discovered that the send window was too small, bottlenecking FFmpeg. Neither FFmpeg nor nginx-rtmp allow you to adjust their send windows, so I changed Windows’s default send window (no pun intended).

I’ve attached the registration entry for your convenience. It sets the default send window to 64K. Apply the entry and restart your computer. FFmpeg should then be able to stream to Twitch at full speed.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\AFD\Parameters]
"DefaultSendWindow"=dword:00010000

By the way, you probably don’t want ‘-vsync cfr’. This will force FFmpeg to duplicate frames in case of frame drops.

You may also like...