NGINX with RTMP on Raspberry Pi as a streaming server for OBS

Published by Tobias Hofmann on

3 min read

Some time passed since I last wrote about OBS. In 2014, I started using OBS as a streaming solution for an event in Sao Paulo. I had quite some time to convince the co-organizers that streaming to an app and YouTube at the same time is a good idea, and that OBS is a good software for achieving this. In the end, my idea was accepted and SITSP video was captured with OBS and streamed through NGINX to YouTube. I even managed to provide live streaming to iPhone devices via an event app I wrote! OBS was not a very well-known software in 2014, and today it is like the de-facto standard for YouTubers when it comes to streaming game videos. 5+ years later and my architecture is still valid and an example of good solution architecture (and another proof of my visionary skills).

End of 2019 I decided to record videos: capture content of a computer with OBS and stream it to NGINX and recapture it with OBS or watch it with VLC. As my 2014 architecture is still valid, I decided to use my old solution architecture, review it and update it where necessary.

NGINX installation

Debian has a package for NGINX and RTMP. My Raspberry Pi is using the armv7l architecture (uname -m), and for that architecture, the RTMP module is available for Debian buster. If you are not on buster, consider upgrading Raspbian. It’s easier to install software via apt than having to compile it manually.

sudo apt-get update
sudo apt-get install libnginx-mod-rtmp

NGINX configuration

During the installation, NGINX will be started. This fails in my case, as I already have a web server (Apache) running. The port 80 is already used and NGINX startup fails. This is OK, as I do not want NGINX as a web server, just for RTMP and OBS.

To solve this “problem”, I’ll change NGINX configuration and deactivate the HTTP server listening on port 80. The NGINX configuration is located in directory /etc/nginx/.

  • The master configuration file is nginx.conf, where the http connector is configured.
  • The actual server is located in /etc/nginx/sites-enabled/default. Here the local server is configured to listen on port 80.

Deleting this symlink in sites-enabled will deactivate the localhost server and NGINX will start, as it now no longer tries to start a server on port 80 (that is already in use by Apache).

sudo rm sites-enabled/default
sudo systemctl start nginx.service
sudo systemctl status nginx.service

Status so far: NGINX is installed and running. Next task is to enable RTMP.

Enable RTMP

Create file rtmp.conf in /etc/nginx/. In this file will contain the RTMP server configuration. The configuration will make RTMP listen on port 1935 and expose a RTMP URL named live. This is the URL RTMP clients will connect to.

sudo vim rtmp.conf

Add content.

rtmp {
  server {
    listen 1935;
    chunk_size 4096;
    application live {
      live on;
      record off;
    }
  }
}

Enable RTMP configuration in NGINX. Change nginx.conf to load the above created rtmp.conf file. Add the following line at the top of the file to load the above created rtmp.conf file.

include /etc/nginx/rtmp.conf;

Start NGINX with RTMP

sudo systemctl stop nginx.service
sudo systemctl start nginx.service
sudo systemctl status nginx.service

This should restart NGINX and show no errors. To see if NGINX is now listening on port 1935 for RTMP, you can use netstat.

netstat -an | grep 1935

OBS configuration

After performing all the above tasks, NGINX with RTMP is up and running. Now you can connect OBS to it.

Server: rtmp://192.168.0.164:1935/live
Key: test

Start streaming in OBS. To see if it works, start VLC and connect to rtmp://192.168.0.164:1935/live/test The content OBS captures and streams should now be shown in VLC. There is a lag of a few seconds. This is normal, as the content is buffered.

Let the world know

Tobias Hofmann

Doing stuff with SAP since 1998. Open, web, UX, cloud. I am not a Basis guy, but very knowledgeable about Basis stuff, as it's the foundation of everything I do (DevOps). Performance is king, and unit tests is something I actually do. Developing HTML5 apps when HTML5 wasn't around. HCP/SCP user since 2012, NetWeaver since 2002, ABAP since 1998.

40 Comments

Donald Reynolds · April 1, 2020 at 04:42

I’m having troubles getting NGINX running with RTMP… In the process above do I need to install NGINX separately in advance? I didn’t and I expect that the steps above install a complete version of NGINX that is RTMP enabled. Is that correct?

    Tobias Hofmann · April 1, 2020 at 12:49

    The command “apt-get install libnginx-mod-rtmp” installs nginx with rtmp enabled. The output shows the additionals files selected (e.g. nginx-common, nginx-full).

Matthew · April 4, 2020 at 15:27

Tobias, thankful I came across your site. I’ve followed your install instructions for RPi 4 (Linux raspberrypi 4.19.97-v7l+ #1294 SMP Thu Jan 30 13:21:14 GMT 2020 armv7l GNU/Linux) but NGINX won’t get beyond the initial load …any help would be most appreciated!

The systemctl status shows this:

pi@raspberrypi:~ $ systemctl status nginx.service
● nginx.service – A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Sun 2020-04-05 00:07:50 AEDT; 13s ago
Docs: man:nginx(8)
Process: 1702 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=203/EXEC)

Apr 05 00:07:50 raspberrypi systemd[1]: Starting A high performance web server and a reverse proxy server…
Apr 05 00:07:50 raspberrypi systemd[1702]: nginx.service: Failed to execute command: No such file or directory
Apr 05 00:07:50 raspberrypi systemd[1702]: nginx.service: Failed at step EXEC spawning /usr/sbin/nginx: No such file or directory
Apr 05 00:07:50 raspberrypi systemd[1]: nginx.service: Control process exited, code=exited, status=203/EXEC
Apr 05 00:07:50 raspberrypi systemd[1]: nginx.service: Failed with result ‘exit-code’.
Apr 05 00:07:50 raspberrypi systemd[1]: Failed to start A high performance web server and a reverse proxy server.

    Tobias Hofmann · April 8, 2020 at 09:41

    Hi Matthew,

    it seems that the start script cannot find the nginx binary at /usr/sbin/nginx. Is the file available?Try to install nginx via apt again.

      prichardsondev · October 31, 2020 at 19:32

      see his image to see were this line should go.
      include /etc/nginx/rtmp.conf;
      if you put it at the top of nginx.conf that err will occur

Warren · April 7, 2020 at 18:56

Thanks Tobias. That looks like a solution for my attempts, too. But I do encounter similar problems like Matthew.
No errors when installing nginx on latest Raspian Buster lite. But it won’t start then automatically.Only get from

sudo systemctl start nginx.service
Job for nginx.service failed because the control process exited with error code.
See “systemctl status nginx.service” and “journalctl -xe” for details.
pi@raspberrypi:~ $ systemctl status nginx.service
● nginx.service – A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Tue 2020-04-07 16:06:40 BST; 37s ago
Docs: man:nginx(8)
Process: 987 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=

Apr 07 16:06:40 raspberrypi systemd[1]: Starting A high performance web server and a reverse proxy serve
Apr 07 16:06:40 raspberrypi systemd[987]: nginx.service: Failed at step EXEC spawning /usr/sbin/nginx: N
Apr 07 16:06:40 raspberrypi systemd[1]: nginx.service: Control process exited, code=exited, status=203/E
Apr 07 16:06:40 raspberrypi systemd[1]: nginx.service: Failed with result ‘exit-code’.
Apr 07 16:06:40 raspberrypi systemd[1]: Failed to start A high performance web server and a reverse prox

    Tobias Hofmann · April 8, 2020 at 09:46

    Hi Warren,

    what happens when you run “sudo nginx -t”? Nginx should check the configuration and also show you which config files are used. For further information, running just sudo nginx should start the server and show additional errors that may not be visible using systemctl

warren · April 8, 2020 at 14:01

Thanks Tobias. Did a complete fresh install and ran through it again…..still the same. “sudo nguni -t” resolves in “command not found”. the nginx folder gets installed in /etc though. I suppose the crucial part happens after installation of nginx. Unlike in your description, it won’t start.
“systemctl status nginx.service” and journalctl -xe show

nginx.service: Failed at step EXEC spawning /usr/sbin/nginx: No such file or directory

which makes me wonder….

Warren · April 8, 2020 at 21:03

Got it solved
There’s, of course, no Apache running on a mint Raspbian Buster Lite – so there’ no interference as you described.
First, I installed the regular nginx for RPi according to this https://www.raspberrypi.org/documentation/remote-access/web-server/nginx.md and tested it successfully.
Then followed your instruction, but used just “sudo apt install libnginx-mod-rtmp” and all the rest of it.
Done. Up and running now 🙂

Thanks for the inspiration.
Stay healthy
w

    Tobias Hofmann · April 9, 2020 at 11:21

    Great to hear that it works now for you. Just wondering why apt did not select nginx for automatic installation in your case when you installed the rtmp mod.

Warren (again) · April 8, 2020 at 21:04

Got it solved
There’s, of course, no Apache running on a mint Raspbian Buster Lite – so there’ no interference as you described.
First, I installed the regular nginx for RPi according to this https://www.raspberrypi.org/documentation/remote-access/web-server/nginx.md and tested it successfully.
Then followed your instruction, but used just “sudo apt install libnginx-mod-rtmp” and all the rest of it.
Done. Up and running now 🙂

Thanks for the inspiration.
Stay healthy
w

Lee · May 24, 2020 at 09:37

Have you been able to get rtmp into html5 web page?

    David · August 3, 2020 at 23:09

    You will need to reencode in hls for html5 . Apparently there is an ffmpeg variant for that but it doesn’t appear to have been packaged.

Xavier · May 30, 2020 at 17:59

Had the same problems with the installation on a fresh Raspi Buster. It’s actually necessary to install nginx first and then rtmp.
After that, all works very well

Marc · June 6, 2020 at 22:13

I didn’t think this would be so easy.

Thanks for showing us how it works.

Is there any way to change the key from “test” to something else?

    Tobias Hofmann · June 7, 2020 at 09:37

    Hi Marc,

    just change the key name to something else. The rtmp module will take the passed on key and add it to the /live/ URL.

Mowgli · June 15, 2020 at 13:19

I’ve got as far as having nginx running on my Pi and OBS sending video to it from a different computer on the same network. Now, the video I’m getting on the Pi viewed using VLC is unusable. There is a considerable lag which in itself is not the end of the world but I’m getting about one frame every 30 secs, I don’t think this qualifies as video! I really don’t know where the problem might be or what to do about it. The thing is that this is not even the set-up that I’m trying to get going. I want to be able to stream to the Pi from outside my network but after seeing the current performance I’m questioning whether this is a worthwhile pursuit!

    Christer Johansson · October 4, 2020 at 15:21

    Hey! As an alternative you can actually just set up a Docker Container as a RTMP-server as well. I managed to stream 2K @60fps from my gaming rig without issues. Works the same way with Nginx, but uses cloud instead. Stream was very smooth on mobile and remote computer screens.

    But don’t stream from your home IP though…route traffic to a remote end point instead.

Amar · September 16, 2020 at 08:19

Hi Tobias, thanks for the article its great. Can you tell me what are the additional lines of code i need to add to allow the Pi to restream to multiple rtmp addresses ? where do i add these ? thanks

    Zoltán · October 25, 2020 at 08:18

    Hi Amar, in your /etc/nginx/rtmp.conf file you have to add
    push rtmp://[your service]/[service_key]
    i.e. youtube = push rtmp://a.rtmp.youtube.com/live2/[and now your streaming key you got from YT]

    hope it helps

Hugo · November 7, 2020 at 19:43

Hi, I have a question, is it possible to force the play the rtmp feed through the HDMI port ? what kind of command line should I use ? and what could be the best player?

Daniel · March 27, 2021 at 03:33

Hi Tobias! Your guide is wonderful and seems to have gotten me very close to what I need, but I’m having trouble with the last step. The terminal shows that the server is up and running, my port 1935 is forwarded on my router, and my laptop seems to be successfully streaming to the server. But now I haven’t figured out how to view it in VLC or better yet, mix in the different A/V streams with another instance of OBS or similar software. My goal is to combine OBS streams from different locations into a seamless stream I can send out to youtube/twitch/etc. from the server on my Pi. I’m so close! What am I missing?

    Tobias Hofmann · March 27, 2021 at 15:40

    HI Daniel,
    to get the stream from nginx, you have to connect your VLC to it. This is the step in the last paragraph: rtmp://192.168.0.164:1935/live/test
    x.x.x.164 is your NGINX, and live/test the stream. If it is working, you should see the video in VLC.

Charles Harris · April 13, 2021 at 23:14

I have NGINX up and running as per your directions and the recommendation to install the full NGINX platform. The rtmp config is very simple and my next step is to get server-side recording of livestream for archive/vod. I have seen many recording ideas for recording, however none apparently work without error. I’m going to keep trying, but if anyone has this working and would share their code would be greatly appreciated.

    GetchLives · April 19, 2021 at 23:51

    I would love to know how to do this too!
    ALSO:
    Can you set up so that multiple streams coming in are viewable in the output?

    Tobias Hofmann · April 20, 2021 at 13:17

    What you get nginx in the end is a live stream. To record this stream, you need to connect to the live stream and write it to a local file. Any program that can read a live stream and output it should do. Have you tried ffmpeg? Start ffmpeg, connect to live stream, set as output a local file like stream.mp4. You’ll have to do this manually for each stream you start.

n0braist · May 4, 2021 at 16:34

thnaks a lot for the documentation. Unfortunately I have no audio on hdmi with omxplayer (other applications working) and yes I use -o hdmi. Any ideas about that?

Anil · May 19, 2021 at 17:03

hello Tobias, we tried to set up the RTMP as above. But we could see only a black screen from OBS studio end when we start streaming. I was just wondering; shouldn’t we specify the camera device(/dev/video0) anywhere in the configuration. Or is it am missing something. Additionally, I tried to set up the OBS studio in another network and then tried to start streaming from the raspberry pi ip. Should the OBS studio be in the same network where the raspberry pi is connected to ? Anything like that.

    Tobias Hofmann · May 21, 2021 at 14:11

    The above is to set up NGINX as a streaming server. You still have to set up your OBS to capture what you want: Video, Audio, Screen, etc. OBS is streaming to NGINX and from there you can watch the stream, e.g. via VLC.

SSY · May 20, 2021 at 07:24

Hi Tobias,
We were following your article for viewing data on my PC which is connected to raspberry pi. A webcam is connected to this raspberry on HDMI port . I could stream data using RTSP protocol but when I am trying RTMP I could see only a black screen on OBS and VLC on my PC. nginx -t, netstat for port 1935 is all working fine. I wonder where to mention the /dev/device0 for camera. Your help will be much appreciated.

    Tobias Hofmann · May 21, 2021 at 14:14

    With your camera connected on the RP, you need to set up your OBS to use that camera as input and send the stream to NGINX. NGINX is receiving a stream, not creating it.

Andreea · August 5, 2021 at 16:07

And how could we embed such stream into a website? Any HTML(5) code? Any suggestion would be much appreciated. Thank you!

    Tobias Hofmann · August 6, 2021 at 15:11

    Hi Andreea,

    to be able to embed the stream into a web page you should convert the stream to HLS or DASH. For RMTP to work you’d need a flash player and the HTML5 video libraries are not supporting RMTP.

Joachim · June 4, 2022 at 16:52

How can I make the stat-page available? (localhost/stat) It is super useful to quickly check what streams are connected and their streamkey/name.

VAN · August 26, 2022 at 13:14

thanks Tobias. My Raspberry Pi 4 with 4 Gb RAM runs OBS and Nginx Rtmp server. However OBS takes too much CPU 300%. I use the LARIX app on my iPhone to take video.
OBS sends to YouTube livestream. I will check again to see it is working 100%. It could be broken if I increase the resolution or frame rate on OBS configuration.
Do you know how to forward the Rtmp stream from Rtmp server to YouTube livestream ?

Anton · November 6, 2022 at 23:27

nov 06 23:03:03 raspberrypi systemd[1]: Starting A high performance web server >
nov 06 23:03:03 raspberrypi systemd[1]: Started A high performance web server a>
anton@raspberrypi:/etc/nginx $ netstat -an | grep 1935
tcp 0 0 0.0.0.0:1935 0.0.0.0:* LISTEN
anton@raspberrypi:/etc/nginx $ Server: rtmp://192.168.0.164:1935/live
Key: test
bash: Server:: opdracht niet gevonden

how to proceed to gat obs-studio running ?

Anton Houweling · November 7, 2022 at 23:04

finally the Nginx Rtmp server is runnig on my raspbery and OBS on my windows PC. OBS now steams a video to the raspberry, but the intention was that de raspberry would sent the movie to youtube, it is fun to see the movie from OBS on my windows pc in the vlc media player but how can i get it on youtube ?

regards
Anton

adrian · December 27, 2022 at 07:46

runs ok for me with a 500ms buffer in OBS, but it does not load every time..its hit and miss mostly, having to restart this and that ntil it finally works. I’m using a DJI Fly app and video setttings are the lowest seting of 720 @ 1 MB/sec and it still freezes up.

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.