:::: MENU ::::

Setting up HLS live streaming server using OBS, NGINX + nginx-rtmp-module on Windows 10 for a local network

My work is currently undergoing some serious renovations. We have lost 6 classrooms, an art room, the music room and the gym/hall to the renovations, and they’ll be out for at least two terms. This means how I’m delivering my lessons has changed, as I no longer have a music room to operate out of. We also need a plan for how to address the entire school for assemblies and other whole school meetings.

Our sister school in China has over 5000 pupils, and each day they are addressed by an internal CCTV network. At the end of last year I decided that something similar to this would be a good thing to setup at our school to help alleviate the pressure of trying to use a PA system to talk to the students each Monday morning, and would also provide opportunities for my extension Digital Tech kids to have some hands on experience running a live web stream.

Get Nginx

To get started, you are going to need nginx with the RTMP module. You can find that here. (The last free version to be compiled with the RTMP module was 1.7.12.1)

I made two quick batch scripts to start and stop the server, and threw them onto my desktop.

@echo off
title Start Stream
cd /d "C:\nginx"
start nginx
exit

and

@echo off
title Stop Stream
cd /d "C:\nginx"
nginx.exe -s stop
exit

Nginx Configuration

rtmp module configuration

The next step is to simply configure nginx to work as an rtmp server.

rtmp {
    server {
        listen 1935;
        allow play all;
        chunk_size 4000;

        application live {
            live on;
            allow publish all;
            allow play all;
        }
    }
}

After the rtmp module is configured, you can point OBS to stream to

rtmp://127.0.0.1/live/

If, for example, you gave it a stream ID of myawesomestream. You can then access the stream from VLC at

rtmp://127.0.0.1/live/myawesomestream

It was here I discovered that a straight up rtmp server wasn’t going to cut it for what I wanted to do.

Enable HLS

HLS is HTTP Live Streaming. It breaks the stream up into small fragments that are then played seamlessly, unlike the rtmp feed.

application live {
    ...
    #enable HLS
    hls on;
    hls_path "c:/nginx/html/hls";
    hls_fragment 3;
    hls_playlist_length 60;
}

http server configuration

Obviously, to access a HTTP Live stream we are going to need a HTTP server.

Still in our nginx.conf, but below our rtmp module we stick this

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

    server {
        listen 80;

        location / {
            root "c:/nginx/html";
        }

        location /hls {
            # Disable cache
            add_header Cache-Control no-cache;

            # CORS setup
            add_header 'Access-Control-Allow-Origin' '*' always;
            add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
            add_header 'Access-Control-Allow-Headers' 'Range';

            # allow CORS preflight requests
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Allow-Headers' 'Range';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Content-Length' 0;
                return 204;
            }

            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }

            root "c:/nginx/html/";
        }
    }   
}

I’m not going to pretend I know what all of that means. I got most of it from other articles, and it works.

DISCLAIMER

I’m fairly sure the CORS stuff allows for some dodgy cross-browser stuff, so just be aware and use at your own risk. I haven’t had time to fiddle and see what the bare minimum is to get this running. I needed it up!

Now when we push our stream from OBS to

http://127.0.0.1/live

and set our stream key (let’s say the stream key is still myawesomestream)

The HLS playlist can be found at

http://127.0.0.1/hls/myawesomestream.m3u8

Viewing the feed in your web browser

Finally, to access the feed, you’ll need a landing page

Pull in the following scripts

<script src="//vjs.zencdn.net/5.8/video.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-hls/5.5.0/videojs-contrib-hls.min.js"></script>

You’ll also need the stylesheet for videojs

<link href="//vjs.zencdn.net/5.8/video-js.min.css" rel="stylesheet">

Then in your body, use a html5 video that points to your m3u8 playlist, and a script to activate the videojs plugin

<video id="player" class="video-js vjs-default-skin height="384" width="680" controls preload="none">
     <source src="http://localhost/hls/stream.m3u8" type="application/x-mpegURL" />
</video>

<script>
    var player = videojs('#player');
</script>

Of course, your video source will need to be the ip address (or host name)  of the nginx server. Any computer on the network should be able to stream to the server.

Final comments

I’m not an expert on this by far, but for all of my searching, I couldn’t find an article or resource for how to do this on Windows. I’m up for any feedback you can give in regards to the efficiency of the setup. This is my first lengthy tutorial, so all feedback would be appreciated! Good luck!

References for this article include (but are not limited to):
https://obsproject.com/forum/resources/how-to-set-up-your-own-private-rtmp-server-using-nginx.50/

and
https://docs.peer5.com/guides/setting-up-hls-live-streaming-server-using-nginx/


2 Comments

  • Opus |

    Hey! I managed to find your site just now, and this is literally exactly what I’ve been looking for. However, I do have an issue that presents when I try to access the m3u8 from an online source. It plays perfectly through VLC (inputting http://[ipaddress]/hls/stream.m3u8 as network stream), however the computer I played it on was on the same network as the hosting computer. The issue comes when I tried to open the same link through https://developer.jwplayer.com/tools/stream-tester/

    When testing through html5, I get the error “Cannot load M3U8: Unable to fetch HTTP resource over HTTPS”

    And when testing through flash, I receive “Cannot load M3U8: Crossdomain access denied (2048)”

    I have no idea why this occurs, but it prevents me from accessing the stream through different connections. Any insight as to why this may be occurring?

    • michaelrtm |

      Sorry, no! I’ve only set this up for a local network, so I haven’t needed to test external access. Hope you come across something though!

So, what do you think ?

You must be logged in to post a comment.