How to set up your own private RTMP server using nginx

All Versions How to set up your own private RTMP server using nginx

mclovinbam

New Member
Hey Does anyone have a nginx.conf that i can use that will allow me to stream to it from another location and i can have it show up on my obs like my friend playing a split screen game, showing both povs.
 

Tarumes

Member
Hey Does anyone have a nginx.conf that i can use that will allow me to stream to it from another location and i can have it show up on my obs like my friend playing a split screen game, showing both povs.
you have to set the split screen in obs. nginx can't do this for you on its own.

The only "standalone" way i know is
Code:
             Twitch
               ^
               |
               +
         +---Server---+
         |   FFMPEG   |
         |     ^      |
         |     |      |
You+-----> NGINX-RTMP <------+Friend
         +------------+
 
Last edited:

mclovinbam

New Member
I thought what i can do is have him stream to the NGINX-RTMP server and i pull the RTMP server to my obs so on my obs i have my stuff then i can pull his camera (or his screen), and then I'm the one streaming to twitch or YouTube, but I'm not sure what nginx.conf to use or what to put in the nginx.conf so it would all work, basically he would be the only one streaming to it and I'm pulling from the NGINX-RTMP server using the OBS, VLC plugin right here
Capture2.JPG

Capture.JPG


you have to set the split screen in obs. nginx can't do this for you on its own.

The only "standalone" way i know is
Code:
             Twitch
               ^
               |
               +
         +---Server---+
         |   FFMPEG   |
         |     ^      |
         |     |      |
You+-----> NGINX-RTMP <------+Friend
         +------------+
 

Mark Weiss

Member
Hi at first
Note to Windows users:
http://nginx-win.ecsds.eu/download/

- rtmp, 1.7.12.1 is the last free version with rtmp, we do have a rtmp
special offer for the 1.9 branch (which without rtmp you could use
to tcp load balance 1.7.12.1 with rtmp)

Commercial subscription only modules:
...
= Streaming with nginx-rtmp-module
...


nginx.exe


webserver


Use HLS output in NGINX-rtmp config


multicast? i belive its only possible in your local network
i think you should use someting like p2p
a plugin for video.js is aviable


It seems there should be a way to just broadcast a stream that any number of people can connect to without multiplying the bandwidth requirement.

At the moment, I still haven't figured out how to get a player window on my page with the video stream from OBS. I'm also somewhat confused as to why I need a second server software running in parallel with IIS7 to do this.

Missing is the code to put in the web page to display the stream, a player of sorts.

I'm growing annoyed with Twitch because of the lengthy adverts that they display now when someone attempts to watch a stream.

This underscores the need to stream directly from my own server without involving outside corporations. But the building blocks between OBS and my server are missing.
 

Tarumes

Member
It seems there should be a way to just broadcast a stream that any number of people can connect to without multiplying the bandwidth requirement.

At the moment, I still haven't figured out how to get a player window on my page with the video stream from OBS. I'm also somewhat confused as to why I need a second server software running in parallel with IIS7 to do this.

Missing is the code to put in the web page to display the stream, a player of sorts.

I'm growing annoyed with Twitch because of the lengthy adverts that they display now when someone attempts to watch a stream.

This underscores the need to stream directly from my own server without involving outside corporations. But the building blocks between OBS and my server are missing.

Yes it is possible to save bandwidth but it is not really practical or easy to set up.

The IIS7 doesn't speak RTMP, you just need a receiver in this case nginx which converts it to hls
browsers can not play rtmp without flash plugin
so you need to provide this as hls.

for this you also need javascript
https://github.com/video-dev/hls.js

i would recommend you to use youtube there you can turn off the advertising
 

Mark Weiss

Member

I'm trying to avoid Flash now. It's obsolete, unsupported and a security risk and using it will limit my audience to outdated legacy browsers. What are sites like Youtube using? HTML5? I don't have Flash on any of my machines, but can play Youtube videos. One of my websites requires flash (it hasn't been updated in years) and it won't display in my current browser.

Saving bandwidth... I should be able to have 1 or 1000 viewers watch my stream without increasing bandwidth. I'm on cable, so the backhaul is only enough for user responses and sending e-mail. I have had good success with 2.5mb/s streaming. There HAS to be a way to have people tap into the stream without doubling the bandwidth each time the number of viewers increases. The data is already flowing out the port... the trick is to make it so it's not locked to one viewer (one stream, one viewer), but make it so it's one stream any number of viewers, like a radio broadcast.

Back to the player problem, so I DO need a second server to handle the stream video... the next question becomes how to display the stream without requiring viewers to download software first. I want it to play just like Youtube. There must be a way.
 

Tarumes

Member
I'm trying to avoid Flash now. It's obsolete, unsupported and a security risk and using it will limit my audience to outdated legacy browsers. What are sites like Youtube using? HTML5? I don't have Flash on any of my machines, but can play Youtube videos. One of my websites requires flash (it hasn't been updated in years) and it won't display in my current browser.

Saving bandwidth... I should be able to have 1 or 1000 viewers watch my stream without increasing bandwidth. I'm on cable, so the backhaul is only enough for user responses and sending e-mail. I have had good success with 2.5mb/s streaming. There HAS to be a way to have people tap into the stream without doubling the bandwidth each time the number of viewers increases. The data is already flowing out the port... the trick is to make it so it's not locked to one viewer (one stream, one viewer), but make it so it's one stream any number of viewers, like a radio broadcast.

Back to the player problem, so I DO need a second server to handle the stream video... the next question becomes how to display the stream without requiring viewers to download software first. I want it to play just like Youtube. There must be a way.

as i said before, the nginx accepts the stream and makes it available as rtmp and as hls

rtmp can only be viewed from flashplayer

hls with html5
all you need is some code in your html

Code:
worker_processes  1;

error_log  logs/error.log info;

events {
    worker_connections  1024;
}

rtmp {
    server {
        listen 1935;

        application live {
            live on;
            push rtmp://127.0.0.1/hls/stream;
        }
      
        application hls {
            live on;
            hls on;
            hls_path temp/hls;
            hls_fragment 8s;
        }
    }
}

http {
    server {
        listen      8080;
      
        location / {
            root html;
        }
      
        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl {
            root html;
        }
      
        location /hls {
            #server hls fragments
            types{
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            alias temp/hls;
            expires -1;
        }
    }
}

here for hls in html5
https://github.com/video-dev/hls.js

HTML:
<html>

  <head>
    <title>Hls.js demo - basic usage</title>
  </head>

  <body>
      <script src="hls.js"></script>

      <center>
          <h1>Hls.js demo - basic usage</h1>
          <video height="600" id="video" controls></video>
      </center>

      <script>
        if(Hls.isSupported()) {
          var video = document.getElementById('video');
          var hls = new Hls();
          hls.loadSource('hls/stream.m3u8');
          hls.attachMedia(video);
          hls.on(Hls.Events.MANIFEST_PARSED,function() {
            video.play();
        });
       }
       // hls.js is not supported on platforms that do not have Media Source Extensions (MSE) enabled.
       // When the browser has built-in HLS support (check using `canPlayType`), we can provide an HLS manifest (i.e. .m3u8 URL) directly to the video element throught the `src` property.
       // This is using the built-in support of the plain video element, without using hls.js.
        else if (video.canPlayType('application/vnd.apple.mpegurl')) {
          video.src = 'hls/stream.m3u8';
          video.addEventListener('canplay',function() {
            video.play();
          });
        }
      </script>

  </body>
</html>

the saving of bandwidth even over p2p is very small and is decided by the viewer whether this is possible or not (mostly not)

for your own streaming service you will not get around a server on the internet with a strong connection, no matter if you like it or not
 
Last edited:

MamadoTV

New Member
Hi guys, I'm new and sorry if this was already discussed but didn't find nothing about it, but like, I'm IRL streamer and I have LiveU sendind video to Nginx server running on my computer sending data do OBS and then twitch, do you know how can I do something that detect's when Nginx is receiving low Bitrate/failing to switch to a Be Right Back scene on obs ? Thanks :D
 

Mark Weiss

Member
Thanks for that sample code, especially how to stream html5.

I've managed to play stored video files from one of my test sites with html5 with good success, but have not streamed live video via html5. The video just plays right inside the page without any extra software downloads or external players. If I could get my stream to play like that, fantastic.

I'm unclear about the following piece of code:
<script src="hls.js"></script>

Where is the Javascript file found (I assume it has to be placed on the server in order to make the player work?)

I know that currently there is no published way to tap into a video stream by thousands of viewers without invoking thousands of streams and the requisite bandwidth. (I think the person that solves this will put Youtube and Twitch out of business.) Logic tells me that there HAS to be a way to allow one stream, unlimited connections, with only the bandwidth required for the one stream. It may require thinking 'out of the box' to solve it.
 

Mark Weiss

Member
I'm thrashing away here, little by little.. so far, I've dropped in the code on a test site and the player appears along with player controls.

I've got nginx running on port 8080 to avoid conflict with IIS7, and firewall pinholes for it. I can see the server from elsewhere on the LAN.

I have OBS set to stream to rtsp:192.168.0.109:8080 (but I get server timeouts when I start stream).

I have this code embedded in the test website:

<center>
<h1>Hls.js demo - basic usage</h1>
<video height="480" id="video" controls></video>
</center>

<script>
if(Hls.isSupported()) {
var video = document.getElementById('video');
var hls = new Hls();
hls.loadSource('rtmp://192.168.0.109:8080/live');
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED,function() {
video.play();
});
}
// hls.js is not supported on platforms that do not have Media Source Extensions (MSE) enabled.
// When the browser has built-in HLS support (check using `canPlayType`), we can provide an HLS manifest (i.e. .m3u8 URL) directly to the video element throught the `src` property.
// This is using the built-in support of the plain video element, without using hls.js.
else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = 'rtmp://192.168.0.109:8080/live';
video.addEventListener('canplay',function() {
video.play();
});
}
</script>&nbsp;
 

Tarumes

Member
Thanks for that sample code, especially how to stream html5.
I'm unclear about the following piece of code:
<script src="hls.js"></script>

Where is the Javascript file found (I assume it has to be placed on the server in order to make the player work?)

<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>

Code:
<center>
<h1>Hls.js demo - basic usage</h1>
<video height="480" id="video" controls></video>
</center>

<script>
if(Hls.isSupported()) {
var video = document.getElementById('video');
var hls = new Hls();



hls.loadSource('rtmp://192.168.0.109:8080/live'); //<-------- here is something wrong
//url should be like http://192.168.0.109:8080/live
//or the path were these hls files stored by nginx



hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED,function() {
video.play();
});
}
// hls.js is not supported on platforms that do not have Media Source Extensions (MSE) enabled.
// When the browser has built-in HLS support (check using `canPlayType`), we can provide an HLS manifest (i.e. .m3u8 URL) directly to the video element throught the `src` property.
// This is using the built-in support of the plain video element, without using hls.js.
else if (video.canPlayType('application/vnd.apple.mpegurl')) {




video.src = 'rtmp://192.168.0.109:8080/live';//<-------- here is something wrong
//url should be like http://192.168.0.109:8080/live
//or the path were these hls files stored by nginx


video.addEventListener('canplay',function() {
video.play();
});
}
</script>&nbsp;
 

Tarumes

Member
I'm thrashing away here, little by little.. so far, I've dropped in the code on a test site and the player appears along with player controls.

I've got nginx running on port 8080 to avoid conflict with IIS7, and firewall pinholes for it. I can see the server from elsewhere on the LAN.

I have OBS set to stream to rtsp:192.168.0.109:8080 (but I get server timeouts when I start stream).

I have this code embedded in the test website:

<center>
<h1>Hls.js demo - basic usage</h1>
<video height="480" id="video" controls></video>
</center>


<script>
if(Hls.isSupported()) {
var video = document.getElementById('video');
var hls = new Hls();
hls.loadSource('rtmp://192.168.0.109:8080/live');
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED,function() {
video.play();
});
}
// hls.js is not supported on platforms that do not have Media Source Extensions (MSE) enabled.
// When the browser has built-in HLS support (check using `canPlayType`), we can provide an HLS manifest (i.e. .m3u8 URL) directly to the video element throught the `src` property.
// This is using the built-in support of the plain video element, without using hls.js.
else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = 'rtmp://192.168.0.109:8080/live';
video.addEventListener('canplay',function() {
video.play();
});
}
</script>&nbsp;
dam sorry i missed something
here it is

HTML:
<html>

  <head>
    <title>Hls.js demo - basic usage</title>
  </head>

  <body>
      <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>


      <center>
          <h1>Hls.js demo - basic usage</h1>
          <video height="600" id="video" autoplay controls preload="metadata"></video>
      </center>

      <script>
        if(Hls.isSupported()) {
          var video = document.getElementById('video');
          var hls = new Hls();
        
        
          hls.loadSource('http://192.168.0.109:8080/hls/stream.m3u8'); //<--------- here the server path to the hls playlist file
        
        
        
          hls.attachMedia(video);
          hls.on(Hls.Events.MANIFEST_PARSED,function() {
            video.play();
        });
       }
        else if (video.canPlayType('application/vnd.apple.mpegurl')) {
      
      
          video.src = 'http://192.168.0.109:8080/hls/stream.m3u8'; //<--------- here the server path to the hls playlist file
        
        
          video.addEventListener('canplay',function() {
            video.play();
          });
        }
      </script>

  </body>
</html>
 

Mark Weiss

Member
When I try to follow the tutorial, I always get an error in the ngix log (using the linked to Windows builds):
[emerg] 8572#3080: unknown directive "rtmp" in C:\nginx/conf/nginx.conf:182
This has happened across 2 different systems. If I delete the RTMP reference from nginx.conf I get no error. Am I somehow missing the RTMP module?
I appreciate any insight the forum can provide...
Yes, you are missing the RTMP module. Which version did you download from the linked site?


I am getting the same error. So the nginx.exe is not the full package?
Where do I get the full Windows package?
 

Mark Weiss

Member
I downloaded a newer nginx package and set up OBS as follows: rtmp://192.168.0.109:1935/live
OBS now shows all indications that it's streaming to a valid server.

I updated the code in my test website to your new version. I'm inching closer... the player window is showing a rotating animated circle, like it's buffering. But that's as far as I've gotten.

Should I change :8080 to :1935 and open a pinhole in the router, or is :8080 correct and the m3u8 string is doing the reference to the stream?

Also, what is /hls/ in the stream path? How do I know that path exists on the server?

And it looks like the player is dependent on another website to load:
src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>

Is there a way to do this internally, like I can with html5 video?
My html5 code to play video totally self contained is this:

<video width="640" height="360" controls>
<source src="A008C013_150615BZ.mp4" type="video/mp4; codecs=avc1.42E01E,mp4a.40.2">
</video>


-MORE INFO-
I tried testing with VLC by opening this as a network stream. The following error results:


Your input can't be opened:

VLC is unable to open the MRL 'http://192.168.0.109:8080/hls/stream.m3u8'. Check the log for details.


I have a hunch it has to do with OBS streaming RTMP and HLS expecting m3u8, but I'm not sure if that happens automagically somewhere?
 
Last edited:

Mark Weiss

Member
Here is the nginx.conf file:

Code:
worker_processes  1;

error_log  logs/error.log debug;

events {
    worker_connections  1024;
}

rtmp {
    server {
        listen 1935;

        application live {
            live on;
        }
        
        application hls {
            live on;
            hls on; 
            hls_path temp/hls; 
            hls_fragment 8s; 
        }
    }
}

http {
    server {
        listen      8080;
        
        location / {
            root www;
        }
        
        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl {
            root www;
        }
        
        location /hls { 
           #server hls fragments 
            types{ 
                application/vnd.apple.mpegurl m3u8; 
                video/mp2t ts; 
            } 
            alias temp/hls; 
            expires -1; 
        } 

    }
}


    }
}

This line seems to indicate where the html files should be:
hls_path temp/hls

However, when I look at the contents of the \TEMP folder in the nginx folder, there are no files, even when streaming is happening. Perhaps this is why I'm not getting a stream in the video player?
 

goky

New Member
Anyone had a problem when nginx randomly stops working? I,'m on raspberry pi 3,tried multiple distributions (currently on raspbian ) checked error logs (nothing). Server is working and I can stream to it over lan or internet just fine but after some time it refuses to connect to it an I need to restart the nginx.Googled the problem but still did not found any solution.
 

Tarumes

Member
Anyone had a problem when nginx randomly stops working? I,'m on raspberry pi 3,tried multiple distributions (currently on raspbian ) checked error logs (nothing). Server is working and I can stream to it over lan or internet just fine but after some time it refuses to connect to it an I need to restart the nginx.Googled the problem but still did not found any solution.

error_log logs/error.log debug;

should give you more information about what is happen
please keep in mind logfile size can be huge :P

The second parameter determines the level of logging, and can be one of the following: debug, info, notice,warn, error, crit, alert, or emerg. Log levels above are listed in the order of increasing severity. Setting a certain log level will cause all messages of the specified and more severe log levels to be logged. For example, the default level error will cause error, crit, alert, and emerg messages to be logged. If this parameter is omitted then error is used.
 

snblg

New Member
Hello,

I cannot receive the stream in the html page.
Vlc does receive the rtmp data (audio and video)
Files are created in the hls subfolder, they disappear automatically after a while,
the stream.m3u8 file is created and updated.

Nothing valuable in the error.log file that is filled.

When opening the firefox console (Ctrl Shift J ) I can see :
SyntaxError: import declarations may only appear at top level of a module hls.js:1

ReferenceError: Hls is not defined 192.168.2.52:55:9
<anonyme> http://192.168.2.52/:55:9


192.168.2.52 is my computer local address, of course I run the page locally.

Oh, oh, your above code mentions Hls and I'm using hls in the nginx.conf file.
I'll modify the source code of my web page and check again ...
 
Top