How to set up your own private RTMP server using nginx

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

Mark Weiss

Member
I'm looking into this for the Windows platform. I run a IIS7 server with all my web sites on it.
I'm looking at adding live streaming webcasting, but I don't have a big upstream pipe and thus need multicast, else I'm limited to one viewer at a time.
I found the Windows-based components for nginx. Are those .exe files archives or the actual server program? There's a nginx.exe and nginx_basic.exe.
Should nginx be run on the capture machine or the web server?
I'm on a business cable connection and we have Linksys WRT 3200ACM routers, which work fine with our server.
What I would like to do is capture the video (machine equipped with BMD Intensity Pro 4K) off our camera, using a dedicated video PC and then pipe that stream to our server PC, where it would (ideally) be embedded in an HTML5 page.
Our setup is OBS right now and we've tested it with Youtube and Facebook. It works well. But we want control over our streams and content, so wish to host everything on our own server. My understanding of Multicast is that the number of viewers is not dependent on the size of our upstream pipe.
If someone could advise on the proposed configuration and make suggestions (remember, we're on Windows, not Linux), that would be appreciated.
 

Tarumes

Member
I'm looking into this for the Windows platform. I run a IIS7 server with all my web sites on it.----.
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
...

I found the Windows-based components for nginx. Are those .exe files archives or the actual server program? There's a nginx.exe and nginx_basic.exe.
nginx.exe

Should nginx be run on the capture machine or the web server?
webserver

I'm on a business cable connection and we have Linksys WRT 3200ACM routers, which work fine with our server.
What I would like to do is capture the video (machine equipped with BMD Intensity Pro 4K) off our camera, using a dedicated video PC and then pipe that stream to our server PC, where it would (ideally) be embedded in an HTML5 page.
Use HLS output in NGINX-rtmp config

Our setup is OBS right now and we've tested it with Youtube and Facebook. It works well. But we want control over our streams and content, so wish to host everything on our own server. My understanding of Multicast is that the number of viewers is not dependent on the size of our upstream pipe.
If someone could advise on the proposed configuration and make suggestions (remember, we're on Windows, not Linux), that would be appreciated.
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
 
Last edited:

FruiTee

New Member
Hi Dodge Pong how would i set this up so if my friend streams to my RMTP server it will push his stream to his channel instead of mine?
 

Tarumes

Member
Hi Dodge Pong how would i set this up so if my friend streams to my RMTP server it will push his stream to his channel instead of mine?
it is very simple add a new application{} to your config
Code:
application yourfriend {
    live on;
    push rtmp://live-fra.twitch.tv/app/live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx;
}

replace xxxxxxxxxxxxx with your friends streamkey

open port 1935 TCP for incoming connections
your friend have to set in OBS RTMP server rtmp://<your ip or dyndnsurl>/yourfriend
and streamkey stream or any random word ^^
 

MaLund13

New Member
Hi!
First off, thanks for an excellent guide!
I managed to get the server up and running on a Raspberry Pi B+ v1.2 fairly easily, and using it for streaming on with a local device works great.
But when I'm trying to recieve the stream from an external source, the output from the server is very delayed, choppy and with lots of skipped frames. In both cases I'm using the StreamLabs Android app to stream from. Port 1935 is forwarded in router (TCP), the server as well as the recieving computer has a wired connection. I have gigabit internet connection, so that shouldn't be a problem. I also tried running the same server on a much more powerful Windows machine with the same result.

I feel like the bottleneck must be in my network setup since it works fine locally, but I can't figure out what it is. Would appreciate any help with fixing this.
 

dfctr

New Member
Hi.

I have set up a livestreaming platform with two Windows 7 machines but getting an issue. Client (videojs with HLS) stutters after about 14/15 minutes of streaming. I don't really know what can it be...what are your thoughs?

Below you'll find my config (and maybe is useful for someone else).

Machine 1: Encoder, with OBS
Custom Streaming to Machine 2 via RTMP to rtmp://<ip>:1935/transcode/test
Output: x264, CBR @ 6000kbps, Keyframe 3, veryfast, profile main, tune zerolatency, audio @ 160kpbs.
1280x720@30fps

Machine 2: Distributor via NGINX w/RTMP (v1.13.12) with transcoding for HLS.
FFMPEG runs as a batch process (no exec in Windows).
Code:
ffmpeg.exe -i rtmp://localhost/transcode/test -async 1 -vsync -1 -c:v libx264 -x264opts keyint=90 -c:a aac -b:v 256k -b:a 32k -vf "scale=480:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost/live/test_low -c:v libx264 -x264opts keyint=90 -c:a aac -b:v 768k -b:a 96k -vf "scale=720:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost/live/test_mid -c:v libx264 -x264opts keyint=90 -c:a aac -b:v 1024k -b:a 128k -vf "scale=960:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost/live/test_high -c:v libx264 -x264opts keyint=90  -c:a aac -b:v 1920k -b:a 128k -vf "scale=1280:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost/live/test_hd720 -c copy -f flv rtmp://localhost/live/test_src

NGINX config:
Code:
# *******************************************************************
# important notes for OBS studio on RTMP
# OBSstudio url
# rtmp://localhost:1935/live

# OBSstudio StreamKey
# test

# HTTP access
# http://localhost:8080/live/test/index.m3u8
# http://localhost:8080/        Welcome Nginx
# *******************************************************************
# Folders
# C:\nginx\nginx.exe
# C:\nginx\hls\live
# C:\nginx\hls\mobile
# C:\nginx\dash
# C:\nginx\html
# C:\nginx\conf
# C:\nginx\temp
# C:\nginx\logs
# C:\nginx\stats
# C:\nginx\videos
# *******************************************************************

worker_processes  1;
error_log  logs/error.log debug;
events {
worker_connections  1024;
}
rtmp {
server {
listen 1935;
chunk_size 4000;
allow play all;

#creates our "live" full-resolution HLS videostream from our incoming encoder stream and tells where to put the HLS video manifest and video fragments
application transcode {
    live on;
    
}


application live {
allow play all;
live on;
record off;
record_path /videos;
record_unique on;
hls on;
hls_nested on;
hls_path D:/nginx/HLS/live;
#hls_fragment 8s;
hls_fragment    6s;
hls_playlist_length 60s;



hls_fragment_naming timestamp;
            hls_variant _low BANDWIDTH=288000; # Low bitrate, sub-SD resolution
            hls_variant _mid BANDWIDTH=448000; # Medium bitrate, SD resolution
            hls_variant _high BANDWIDTH=1152000; # High bitrate, higher-than-SD resolution
            hls_variant _hd720 BANDWIDTH=2048000; # High bitrate, HD 720p resolution
#            hls_variant _src BANDWIDTH=4096000; # Source bitrate, source resolution

}
}
}

http {
include       mime.types;
default_type  application/octet-stream;
    sendfile off;
    tcp_nopush on;
  #  aio on;
    directio 512;

    server {
listen 80;
server_name home;

#creates the http-location for our full-resolution (desktop) HLS stream - "http://localhost:8080/live/test/index.m3u8"     
location /live {
types {
application/vnd.apple.mpegurl m3u8;
}
alias HLS/live;
add_header Cache-Control no-cache;
}
#allows us to see how stats on viewers on our Nginx site using a URL like: "http://my-ip/stats"     
location /stats {
stub_status;
}
#allows us to host some webpages which can show our videos: "http://localhost:8080/index.html"   
location / {
root   D:/nginx/html;
index  index.html index.htm;
} 
}
}

VideoJS embedding HTML.
Code:
<!DOCTYPE html>
<html lang="en">
<head>

    <title>Video.js | HTML5 Video Player</title>
    <link href="http://vjs.zencdn.net/7.0/video-js.min.css" rel="stylesheet">
    <script src="videojs/video.min.js"></script>
    
</head>
<body>
  <video id="video" preload="auto" class="video-js vjs-default-skin" controls >
<!--    <source src="http://cdd2180/live/test.m3u8" type="application/vnd.apple.mpegurl"> -->
</video>
<script src="videojs/hls.js"></script>
<script src="videojs/video.min.js"></script>


<!-- <script>
    var player = videojs('video', {
        // hlsjs tech should come before html5, if you want to give precedence to native HLS playback
        // use the favorNativeHLS option.
        techOrder: ["hlsjs", "html5"]
    });
    player.play();
</script> -->
<script>
var video = document.getElementById('video');
  if(Hls.isSupported()) {
    var hls = new Hls();
    hls.loadSource('http://cdd2180/live/test.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.
 // Note: it would be more normal to wait on the 'canplay' event below however on Safari (where you are most likely to find built-in HLS support) the video.src URL must be on the user-driven
 // white-list before a 'canplay' event will be emitted; the last video event that can be reliably listened-for when the URL is not on the white-list is 'loadedmetadata'.
  else if (video.canPlayType('application/vnd.apple.mpegurl')) {
    video.src = 'http://cdd2180/live/test.m3u8';
    video.addEventListener('loadedmetadata',function() {
      video.play();
    });
  }
 </script>
</body>

</html>
 

lancetv

New Member
Hi All,
Am seeking some assistance with setting up my re-stream server, as per the OBS guide. I have followed all instructions to the letter, but when it comes time to open the config file I get the following message -bash: /usr/local/nginx/conf/nginx.conf: Permission denied

I am able to start and stop my server, but it is frustrating to come this far and not be able to finish the job properly.
I am super new (3 days) to the Linux system. so not up with the necessary Linux based jargon.

I am running Ubuntu 18.04 and utilising Digital Ocean for my Debian droplet.

My ls -la command returns the following info:

drwxr-xr-x 9 1001 1001 4096 Apr 17 15:22 .
drwx------ 5 root root 4096 Jul 5 03:12 ..
drwxr-xr-x 6 1001 1001 4096 Jul 5 03:14 auto
-rw-r--r-- 1 1001 1001 286953 Apr 17 15:22 CHANGES
-rw-r--r-- 1 1001 1001 437286 Apr 17 15:22 CHANGES.ru
drwxr-xr-x 2 1001 1001 4096 Jul 5 03:14 conf
-rwxr-xr-x 1 1001 1001 2502 Apr 17 15:22 configure
drwxr-xr-x 4 1001 1001 4096 Jul 5 03:14 contrib
drwxr-xr-x 2 1001 1001 4096 Jul 5 03:14 html
-rw-r--r-- 1 1001 1001 1397 Apr 17 15:22 LICENSE
-rw-r--r-- 1 root root 376 Jul 5 03:22 Makefile
drwxr-xr-x 2 1001 1001 4096 Jul 5 03:14 man
drwxr-xr-x 4 root root 4096 Jul 5 03:23 objs
-rw-r--r-- 1 1001 1001 49 Apr 17 15:22 README
drwxr-xr-x 9 1001 1001 4096 Apr 17 15:22 src

Any assistance would be greatly appreciated
Cheers!
 

vax-unlimited

New Member
Hi All,
Am seeking some assistance with setting up my re-stream server, as per the OBS guide. I have followed all instructions to the letter, but when it comes time to open the config file I get the following message -bash: /usr/local/nginx/conf/nginx.conf: Permission denied

I am able to start and stop my server, but it is frustrating to come this far and not be able to finish the job properly.
I am super new (3 days) to the Linux system. so not up with the necessary Linux based jargon.

I am running Ubuntu 18.04 and utilising Digital Ocean for my Debian droplet.

My ls -la command returns the following info:

drwxr-xr-x 9 1001 1001 4096 Apr 17 15:22 .
drwx------ 5 root root 4096 Jul 5 03:12 ..
drwxr-xr-x 6 1001 1001 4096 Jul 5 03:14 auto
-rw-r--r-- 1 1001 1001 286953 Apr 17 15:22 CHANGES
-rw-r--r-- 1 1001 1001 437286 Apr 17 15:22 CHANGES.ru
drwxr-xr-x 2 1001 1001 4096 Jul 5 03:14 conf
-rwxr-xr-x 1 1001 1001 2502 Apr 17 15:22 configure
drwxr-xr-x 4 1001 1001 4096 Jul 5 03:14 contrib
drwxr-xr-x 2 1001 1001 4096 Jul 5 03:14 html
-rw-r--r-- 1 1001 1001 1397 Apr 17 15:22 LICENSE
-rw-r--r-- 1 root root 376 Jul 5 03:22 Makefile
drwxr-xr-x 2 1001 1001 4096 Jul 5 03:14 man
drwxr-xr-x 4 root root 4096 Jul 5 03:23 objs
-rw-r--r-- 1 1001 1001 49 Apr 17 15:22 README
drwxr-xr-x 9 1001 1001 4096 Apr 17 15:22 src

Any assistance would be greatly appreciated
Cheers!

Para poder editar nginx.conf debes ejecutar desde consola

sudo nano /usr/local/nginx/conf/nginx.conf

Te pedirá contraseña de usuario,

ingresas la contraseña y luego presionas ENTER, listo. (Deberías poder editar el archivo .conf)
 

lancetv

New Member
Hi vax-unlimited,

Many thanks for you reply. I was able to progress because of your suggestion. But now I have been faced with a new problem. Any further assistance would be most helpful. Please see attached.
 

Attachments

  • Nano Capture.JPG
    Nano Capture.JPG
    51.7 KB · Views: 204

CarnageHeart

New Member
I tried looking through the thread here, and couldn't find it. So sorry if I missed this and am asking a repeat question. But I'm getting an error when trying to make.

Code:
adding module in ../nginx-rtmp-module-master
./configure: error: no ../nginx-rtmp-module-master/config was found

Any help with this? It would be appreciated.
 

jembo

New Member
I'm relieved to see so many new (and answered) comments here. I signed up to twitch 2 days ago, downloaded OBS yesterday and impulsively just bought a raspberry pi after reading these instructions 10 minutes ago without stopping to think about the fact that this is all entirely new to me and I'm likely to have no clue what I'm doing. My raspberry pi arrives on Friday so I'll probably start trying to set this up on the weekend. apologies in advance if my questions are silly or have obvious answers to anyone who has progressed beyond absolute beginner level.
 

centrespot

New Member
Hi dodgepong and all
Just found this thread while trying to find the best way of streaming a CCTV IP camera for users to check on the weather at a local golf club, is it still relevant and will it still work with a raspberry pi or is there a better way nowerdays that is still free of any subscriptions.
Thanks
 

Archmage

New Member
Anyone know any module or this RTMP module have supported stream saving?
I mean local file saving on the server, any guide for that? I want to save it locally on my hard drive so I can edit some stream highlight later without losing any quality and that also the point of use RTMP to reduce compute load for another stream (I'm simulcasting 3 stream at the same time, my network bandwidth allowed this while my PC compute power don't)
 

Tarumes

Member
Anyone know any module or this RTMP module have supported stream saving?
I mean local file saving on the server, any guide for that? I want to save it locally on my hard drive so I can edit some stream highlight later without losing any quality and that also the point of use RTMP to reduce compute load for another stream (I'm simulcasting 3 stream at the same time, my network bandwidth allowed this while my PC compute power don't)

Recording is possible

Code:
rtmp {
    server {
        listen 1935;

        application tarumes {
            live on;
            push rtmp://127.0.0.1/view/stream;
            push rtmp://live-fra.twitch.tv/app/live_12345678_xxxxxxxxxx;
            recorder all {
                record all;
                record_path html/record/stream/tarumes;
                #record_interval 15s;
                record_lock on;
                record_unique on;
            }
        }

        application view {
            live on;
        }
    }
}
 
Top