Build a live-stream server

This guide will show you step by step how to install Nginx webserver & Certbot SSL certificates, the RTMP module, Ffmpeg on a Ubuntu 18.04 VPS server. It will then will also explain how to setup HLS live-streaming and create a webpage with Video.JS to show the live-stream.
I decided to write this guide after receiving a lot of questions and responses on a video or two that I made a while ago. HLS and SSL related mostly. So hopefully this guide will clear up all of those questions for you all. If not, please leave any questions at the bottom of this page or as comment on the Youtube page.

This guide contains 7 steps. I strongly advice to read through them all beforehand so you’ll know what you’re doing in stead of just blindly start copy/pasting everything, because that rarely works out like it should, in my experience. This looks like a long-ass guide, and it is in a way, but you could do this all in under 25 minutes. Anyways, it’s too long for this blog’s layout so click on the continue reading link below to read the full article and to see the video.

EDIT 24-07-2020 – Take a look at the git repo for easy hls site instal by Quinn Ebert. He has created it based on my guide and video. Thanks Quinn! Good work πŸ™‚

TIP! Please use a fresh install for Ubuntu 18.04 so you won’t run in to any conflicts or other issues.

Let’s get started! So you’ve installed your server or VPS with Ubuntu 18.04, and you’re now logged in to the local console or through SSH from a remote location. Let’s start of by making sure the system is up to date.

sudo apt update && sudo apt upgrade

1: Install Nginx + RTMP module.

sudo apt install -y nginx
sudo apt install -y libnginx-mod-rtmp

When you enter the IP address of your server in your web-browser you should now see a default Nginx webpage.

2: Installing required & additional software.

Add Certbot repository to our server so it will install the version we want later on.

sudo apt install -y software-properties-common
sudo add-apt-repository ppa:certbot/certbot

Add architecture for i386 because we will need it later on when we’re going to install additional codecs.

sudo dpkg --add-architecture i386
sudo apt update

We’re ready to start installing a bunch of additional, required software, and please be aware that it might take several moments to complete.

sudo apt install wget nano python-certbot-nginx ufw unzip software-properties-common dpkg-dev git make gcc automake build-essential joe ntpdate zlib1g-dev libpcre3 libpcre3-dev libssl-dev libxslt1-dev libxml2-dev libgd-dev libgeoip-dev libgoogle-perftools-dev libperl-dev pkg-config autotools-dev gpac ffmpeg sysstat nasm yasm mediainfo mencoder lame libvorbisenc2 libvorbisfile3 libx264-dev libvo-aacenc-dev libmp3lame-dev libopus-dev libfdk-aac-dev libavcodec-dev libavformat-dev libavutil-dev g++ libc6:i386 freeglut3-dev libx11-dev libxmu-dev libxi-dev libglu1-mesa libglu1-mesa-dev

The following two steps are totally optional!! It includes PHP, MySQL or MariaDB, PhpMyAdmin. Please refer to my Youtube video to see more information on this.

sudo apt install mariadb-server mariadb-client phpmyadmin php php-cgi php-common php-pear php-mbstring php-fpm

3: Setup a firewall and perform other required steps.

Next we’ll be performing various required steps and setup our UFW firewall. We’re going to start with downloading the RTMP module source files because we need a certain file from it that we need to copy to /var/www/html.

cd /usr/src
git clone https://github.com/arut/nginx-rtmp-module
cp /usr/src/nginx-rtmp-module/stat.xsl /var/www/html/stat.xsl

Create the file ‘crossdomain.xml’ in /var/www/html folder, and paste in it what you see below.

sudo nano /var/www/html/crossdomain.xml
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*"/>
</cross-domain-policy>

Create the file ‘info.php’ in /var/www/html folder, and paste in it what you see below.

sudo nano /var/www/html/info.php
<?php
phpinfo();
?>

If you want to display an image whenever people open your web page while you are not streaming, make sure it’s a jpg file with resolution 1280×720 or 1920×1080, placed in /var/www/html and named “poster.jpg”
For testing purposes you can always use a random publicly available poster from the web like the one I used for this guide:

wget -O /var/www/html/poster.jpg https://i.imgur.com/gTeWLDO.jpg

Create these folders. You can choose a different location but remember to also change the locations in the Nginx config files.

sudo mkdir /var/livestream
sudo mkdir /var/livestream/hls
sudo chown -R www-data: /var/livestream

Now it’s about time to install our firewall. UFW is commonly used and should already be installed. If this is not the case do “sudo apt install ufw” first.

ufw status
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 10000/tcp
sudo ufw allow 1935

Port 1935 is the one that RTMP uses so we need to open that on the firewall and perhaps in some cases you will also need to forward the port on your router.
To make things easy for yourself if you are setting up your server from a remote location is to add the external IP address of your remote location to the allow list. Before enabling the firewall make VERY SURE that you’ve allowed yourself access to the server on your SSH port or else you’re going to lock yourself out of the server.

sudo ufw allow from XX.XX.XX.XX
sudo ufw enable
sudo ufw status verbose

4: Edit Nginx configuration.

sudo nano /etc/nginx/nginx.conf

On line 2 change the worker_processes option from auto to 1, so it says: worker_processes 1;

Scroll all the way down and add the following at the end of the file, or something similar if you’re situation requires other variables (use your brain πŸ™‚

rtmp {
        server {
                listen 1935;
                chunk_size 8192;

	application live {
		live on;
		interleave off;
		meta on;
		wait_key on;
		wait_video on;
		idle_streams off;
		sync 300ms;
		session_relay on;
		allow publish all;
		allow play all;
		max_connections 1000;

		## == FORWARD STREAM (OPTIONAL) == ##
		# == == TWITCH RE-STREAM == == #
		# push rtmp://live-ams.twitch.tv/app/LIVESTREAM_KEY;
		# == == YOUTUBE RE-STREAM == == #
		# push rtmp://a.rtmp.youtube.com/live2/LIVESTREAM_KEY;
		# == == MIXER.com RE-STREAM == == #
		# push rtmp://ingest-ams.mixer.com:1935/beam/LIVESTREAM_KEY;

		publish_notify off;
		# play_restart off;
		# on_publish http://your-website/on_publish.php;
		# on_play http://your-website/on_play.php;
		# on_record_done http://your-website/on_record_done.php;
			
		## == HLS == ##
		hls off;
		# hls_nested on;
		# hls_path /var/livestream/hls/live;
		# hls_base_url http://;
		# hls_playlist_length 60s;
		# hls_fragment 10s;
		# hls_sync 100ms;
		# hls_cleanup on;

		## == DASH == ##
		dash off;
		# dash_nested on;
		# dash_path /var/livestream/dash;
		# dash_fragment 10s;
		# dash_playlist_length 60s;
		# dash_cleanup on;

		push rtmp://localhost/hls;
		}
		
	application hls {
		live on;
		allow play all;
		hls on;
		hls_type live;
		hls_nested on;
		hls_path /var/livestream/hls;
		hls_cleanup on;
		hls_sync 100ms;
		hls_fragment 10s;
		hls_playlist_length 60s;
		hls_fragment_naming system;
		}
	}
}
nginx -t
sudo systemctl restart nginx
sudo nano /etc/nginx/sites-available/default
server {
	listen 80 default_server;
	listen [::]:80 default_server;
	# listen 443 ssl http2 default_server;
	# listen [::]:443 ssl default_server;
	# include snippets/snakeoil.conf;
	keepalive_timeout 70;
	gzip off;

	root /var/www/html;

	# Add index.php to the list if you are using PHP
	index index.php index.nginx-debian.html index.html index.htm;

	server_name _;

	# add_header Strict-Transport-Security "max-age=63072000;";
	# add_header X-Frame-Options "DENY";

	location / {
		location ~* \.m3u8$ {
		add_header Cache-Control no-cache;
		}
		add_header Access-Control-Allow-Origin *;

		# First attempt to serve request as file, then as directory, then fall back to displaying a 404.
		try_files $uri $uri/ =404;
	}

	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
	#	# With php-fpm (or other unix sockets):
		fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
	#	# With php-cgi (or other tcp sockets):
	#	fastcgi_pass 127.0.0.1:9000;
	}

	## deny access to .htaccess files, if Apache's document root concurs with nginx's one
	#location ~ /\.ht {
	#	deny all;
	#}

## This provides RTMP statistics in XML at 
location /stat {
	rtmp_stat all;
	rtmp_stat_stylesheet stat.xsl;
	# auth_basic "Restricted Content";
        # auth_basic_user_file /etc/nginx/.htpasswd;
	}

## XML stylesheet to view RTMP stats. Copy stat.xsl wherever you want and put the full directory path here
location /stat.xsl {
	root /var/www/html/;
	}
}
nginx -t
sudo systemctl restart nginx

Obviously you need to change the DOMAIN part in the next lines to whatever your domain name is.

sudo nano /etc/nginx/sites-available/DOMAIN.net.conf

Add the following to this new file, but don’t forget to change DOMAIN first!

server {
    listen 80;
    listen [::]:80;
    root /var/www/html;
    server_name DOMAIN.net www.DOMAIN.net;
}
nginx -t

If everything is good and we don’t see any error messages we can create the symlink to the config file so it will be activated for Nginx. Use your brain and edit the DOMAIN parts.

ln -s /etc/nginx/sites-available/DOMAIN.net.conf /etc/nginx/sites-enabled/DOMAIN.net.conf
nginx -t
sudo systemctl restart nginx

5: Confirm that the RTMP stream works.

At this point you could try to test if you can livestream to your server using OBS or any other live-stream app. In your config use something similar as shown below.

You can check the status bar in OBS to check if you are able to connect and stream to the server. When it shows something similar to this, you’re good.

Our stat page at should now show one live RTMP source. Now you should already be able to watch the livestream using VLC Player or PodPlayer or any other media player that can play media from URL’s. Open it in your player like this: rtmp://DOMAIN.net/live/stream

It might take a couple of seconds but it should start loading the livestream video. If all works fine, we can continue to the next chapter. You’re doing great so far by the way! πŸ™‚

6: Create SSL certificates for Nginx

This first step is not required, but I advise you to go through it anyway because if you want to get tripple A++ rated certificates for your website, this will be required (see www.ssllabs.com/ssltest for info). The next command might take five minutes and probably even more (depending on your processing power ofc).

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096

Now for the creation of the actual certificates for your domain. Use brain here!

sudo certbot --nginx -d DOMAIN.net -d www.DOMAIN.net

You will be asked to enter your e-mail address and two or three other questions. Don’t choose to enable the auto forward for http to https. You can always set this up later.
If everything went fine, you should see the location of the newly created certificates. Keep these in mind. Don’t forget to add a crontab so the certificates get renewed automatically in time.

sudo crontab -e
0 12 * * * /usr/bin/certbot renew --quiet

We’re going to edit the /etc/nginx/sites-available/DOMAIN.net.conf file that we’ve created earlier on.

sudo nano /etc/nginx/sites-available/DOMAIN.net.conf

Remove everything in this file, and afterwards paste the following:

server {
	listen 80;
	listen [::]:80;
	listen 443 ssl http2;
	listen [::]:443 ssl;
	# include snippets/snakeoil.conf;
	keepalive_timeout 70;
	gzip off;

	root /var/www/html;

	# Add index.php to the list if you are using PHP
	index index.php index.nginx-debian.html index.html index.htm;

	server_name DOMAIN.COM;

	ssl_certificate /etc/letsencrypt/live/DOMAIN.COM/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/DOMAIN.COM/privkey.pem;
	ssl_trusted_certificate /etc/letsencrypt/live/DOMAIN.COM/chain.pem;
	ssl_dhparam /etc/ssl/certs/dhparam.pem;

	ssl_protocols TLSv1.2 TLSv1.3;
	ssl_session_cache shared:le_nginx_SSL:1m;
	ssl_session_timeout 1440m;
	ssl_prefer_server_ciphers on;
	ssl_session_tickets off;
	ssl_stapling off;
	ssl_stapling_verify on;
	resolver 8.8.8.8 8.8.4.4 valid=300s;
	resolver_timeout 5s;
	ssl_ecdh_curve secp384r1;

	ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

	add_header Strict-Transport-Security "max-age=63072000;";
	add_header X-Frame-Options "DENY";

 	# Redirect non-https traffic to https
		# if ($scheme != "https") {
		# return 301 https://$host$request_uri;
		# }

	location / {
		location ~* \.m3u8$ {
		add_header Cache-Control no-cache;
		}
		add_header Access-Control-Allow-Origin *;

	# First attempt to serve file, then as directory, then a 404.
		try_files $uri $uri/ =404;
	}

	# pass PHP scripts to FastCGI server

	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
	#	# With php-fpm (or other unix sockets):
		fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
	#	# With php-cgi (or other tcp sockets):
	#	fastcgi_pass 127.0.0.1:9000;
	}

	# deny access to .htaccess files, if Apache's document root concurs with nginx's one
	
	#location ~ /\.ht {
	#	deny all;
	#}

# This provides RTMP statistics in XML at http://your-server-address/stat
location /stat {
	rtmp_stat all;
	rtmp_stat_stylesheet stat.xsl;
	# auth_basic "Restricted Content";
        # auth_basic_user_file /etc/nginx/.htpasswd;
	}

# XML stylesheet to view RTMP stats. Copy stat.xsl wherever you want and put the full directory path here
location /stat.xsl {
	root /var/www/html/;
	}

# Control interface (extremely useful, but can also boot people from streams so we put basic auth in front of it - see https://github.com/arut/nginx-rtmp-module/wiki/Control-module for more info

#location /control {
	# you'll need a htpasswd auth file, that's outside the scope of this doc but any apache one will work
	# auth_basic "Restricted Content";
	# auth_basic_user_file /etc/nginx/.htpasswd;
	#rtmp_control all;
	#}

#creates the http-location for our full-res desktop HLS stream "http://my-ip/live/my-stream-key/index.m3u8"
location /live {
	# root /var/livestream/hls;
	alias /var/livestream/hls;
	expires -1;
	autoindex on;
	autoindex_localtime on;
	# CORS setup #
		set $sent_http_accept_ranges bytes;
		add_header 'Cache-Control' 'no-cache';
		add_header Cache-Control no-cache;
		add_header 'Access-Control-Allow-Origin' '*' always;
		add_header 'Access-Control-Expose-Headers' 'Content-Length';
	# allow CORS preflight requests #
		if ($request_method = 'OPTIONS') {
		add_header 'Access-Control-Allow-Origin' '*';
		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;
		application/dash+xml mpd;
		video/mp2t ts;
		}
	}
}
nginx -t
sudo systemctl restart nginx

6: Video.js installation & and example index.html

Video.js can do a lot of extra things that I won’t go in to right now, so you should investigate yourself at https://github.com/videojs.
Create a new sub-folder in /var/www/html called videojs and enter this folder.

sudo mkdir /var/www/html/videojs
cd /var/www/html/videojs
wget https://github.com/videojs/video.js/releases/download/v7.7.6/video-js-7.7.6.zip

wget https://github.com/videojs/http-streaming/releases/download/v1.13.1/videojs-http-streaming.js

Optional! wget https://github.com/videojs/videojs-contrib-dash/releases/download/v2.11.0/videojs-dash.js

unzip /var/www/html/videojs/video-js-7.7.6.zip
chown -R www-data: /var/www/html
ls -la /var/www/html/videojs

The previous command should show something like what is shown below.

Now we’re going to create a file that will show the video.js player. You can name it whatever you want but here I’ll be naming it “index.html”

sudo nano /var/www/html/index.html
<!DOCTYPE html>
<html>
<head>
<script src='https://DOMAIN.net/videojs/video.js'></script>
<script src="https://DOMAIN.net/videojs/videojs-http-streaming.js"></script>
<meta charset=utf-8 />
<title>LiveStream</title>
<link href="https://DOMAIN.net/videojs/video-js.min.css" rel="stylesheet">
<!-- <link href="https://DOMAIN.net/videojs/videojs-sublime-skin.min.css" rel="stylesheet"> -->
<!-- <link href="https://DOMAIN.net/videojs/videojs-sublime-skin.css" rel="stylesheet"> -->
<!-- <link href="https://DOMAIN.net/videojs/video-js.css" rel="stylesheet"> -->
<!-- <link href="https://DOMAIN.net/videojs/videojs-skin-twitchy.css" rel="stylesheet" type="text/css">  -->
</head>
<body>
<center>

<video-js id="live_stream" class="video-js vjs-fluid vjs-default-skin vjs-big-play-centered" controls preload="auto" autoplay="true" width="auto" height="auto" poster="https://DOMAIN.net/poster.jpg">

<source src="https://DOMAIN.net/live/stream/index.m3u8" type="application/x-mpegURL">

    <p class='vjs-no-js'>
      To view this video please enable JavaScript, and consider upgrading to a web browser that
      <a href='https://videojs.com/html5-video-support/' target='_blank'>supports HTML5 video</a>
    </p>
</video-js>
  
  <script>
    var player = videojs('live_stream');
	player.play();
  </script>

</center>
</body>
</html>
chown -R www-data: /var/www/html

We’re basically done! Now it’s time to see if it all works. Streaming to your server and open your website or the file we’ve just created at: https://DOMAIN.net/index.html

Thanks for following my guide. Please report any issues and you can leave questions or other remarks on this page or the Youtube page of the video.

I posted all the commands in a pastebin right here. https://pastebin.com/qMCpKYC8

43 thoughts on “Build a live-stream server

  1. FunDeckHermit 5 April 2020 / 18:21

    Thank you very much!

    This was exactly what I was looking for!

    The only thing I changed was the authentication. I’m using Nginx auth_request module + Vouch + Gitea to restrict access to the stream.

    Do you have some ideas on how to add subtitles, different audio-tracks or improve latency?

    • beheerder 5 April 2020 / 20:16

      Subtitles? Oh that’s a good one! I know that ffmpeg can do subtitles. I’m not sure if there’s a already existing solution to what your wishes are, I should google that. But I dΓ³ know that somehow it must be possible. Good luck with that! If I learn anything on the subject I’ll share it.
      Latency is indeed a thing… The RTMP stream is pretty good and acceptable with the latency but the HLS stream not really. In all honesty I have no idea, yet, on how to improve this. My clueless first guess would be, upgrade the live-stream server’s processing power. Although I don’t think that will be the solution. I’m gonna look into this because it is something I am actually also interested to learn more on. Keep an eye out for any new posts on the subject!

    • beheerder 5 April 2020 / 20:17

      Oh je bent gewoon een Nederlander zie ik nu. Hahah had ik dat maar geweten voor ik de vorige reactie plaatste.

  2. Pascal Wiersma 21 April 2020 / 10:34

    Hey, Welke porten moeten allemaal open om te kunnen uitzenden vanaf buitenhuis?

    • andre 5 May 2020 / 17:34

      80 en / of 443. En 1935 voor RTMP

  3. Felipe 27 April 2020 / 21:15

    Hello Thanks for this !! Regards from Chile

    i have a Problem with

    ln -s /etc/nginx/sites-available/mydomain.com.conf /etc/nginx/sites-enabled/mydomain.com.conf

    No such file or directory

    Thanks for your time ! πŸ˜‰

    • Felipe 27 April 2020 / 23:42

      I reset after updating ubuntu and fix

      πŸ™‚ Thanks!!

  4. Felipe 28 April 2020 / 21:13

    Hello Andre! me again πŸ™‚ , how add application in nginx additional to live?Example:

    application a {}
    application b {}

    could you teach me please πŸ™‚

    • andre 5 May 2020 / 17:47

      Yes this is possible. And it’s exactly as you already pointed out yourself.

      application live {
      live on;
      interleave off;
      meta on;
      sync 300ms;
      session_relay on;
      max_connections 200;
      allow publish all;
      allow play all;
      }

      application yourapp {
      live on;
      }

      • Felipe 9 May 2020 / 04:44

        Thanks Andre, Doesn’t the code need anything else? nginx additional to live?

        Thanks for you time
        Amigo

  5. Flo 1 May 2020 / 15:18

    Why i have this error?

    “The media could not be loaded, either because the server or network failed or because the format is not supported.”

    • andre 5 May 2020 / 17:33

      To be honest… I have no idea. I need more information if I want to be able to pinpoint the problem.

    • Chris 20 May 2020 / 17:04

      Unfortunately having the same error. What additional details do you need, so as to avoid a core dump. =)

      • andre 24 May 2020 / 22:52

        Like when and where do you see this error? What do your config files look like. Stuff like that.

  6. FunDeckHermit 3 May 2020 / 10:35

    Could you make a guide on how to restream or relay an incoming RTMP stream to multiple providers?

    I’m thinking about buying the Panasonic AG-CX10 for my church but it only supports a single RTMP endpoint. Having the options to relay it to multiple providers would be very nice.

    • andre 5 May 2020 / 16:49

      I actually already made a video on that exact subject. It’s about 1,5 years ago that I uploaded it: https://www.youtube.com/watch?v=FANQptVSo3A
      ik kan het trouwens net zo goed in Nederlands zeggen zie ik nu, aan je domainnaam.
      Maar goed, ik had zelf ook de intentie om daar een video over te maken nu dat we anderhalf jaar verder zijn ik in de tijd veel wijzer ben geworden. Dus houd mijn youtube kanaal en/of deze blog goed in de gaten!

  7. liam 12 May 2020 / 22:07

    Hey, thank for the nice guide.

    I’m up and running with my private twitch.

    One or two things though,

    How can set the lag to less than 5 seconds?

    • andre 24 May 2020 / 22:51

      I don’t think it’s possible. 5 seconds is actually pretty good for an RTMP delay. There will always be some sort of delay.

      • LIAM 29 May 2020 / 04:28

        5 Seconds is the goal right now its close to 60 seconds.

        What step can i take to reduce this delay. What will affect the delay being so long.

        thanks

  8. Lukas 26 May 2020 / 00:03

    I did not do the domain part just wanted to test out via the IP version. So I can stream from OBS and view from VLC but when I try to access the website via index.html there is no video.js player. just shows the message to view this video please enable javascript. Tried on an iphone,android, pc with different browsers same message. And I can only reach the server via HTTP Im guessing since I skipped the domain ant certificate portions. Where can Troubleshoot this problem? Because I tried hosting this on digital ocean.

    • andre 26 May 2020 / 22:31

      Yes is hosting it on IP only is possible, but without the certificates then of course. So make sure you change all the HTTPS entries to HTTP in your config files and index.html and such. You could, if you want, send me your nginx.conf and such so I can investigate, correct it. Mail: ustoopia over at gmail.com

  9. Tony 21 June 2020 / 13:15

    This is awesome, exactly what I was looking for, thank you so much!!!

  10. F Clark 21 June 2020 / 15:08

    Thank you so much for the tutorial. I have completed all steps successfully as far as I can tell, and I can view on http site, but if I change to https it will not load – and I need https so I can embed the stream on our website (it will not allow embedding insecure site).

    • F Clark 22 June 2020 / 22:45

      Solved. πŸ™‚

      • James 27 June 2020 / 21:45

        can you detail what you did to solve that? I noticed that it wouldnt load my index.html automatically after the ssl stuff, is there a change on the ssl redirect somewhere.?

        thanks in advance

  11. Tracer Bite 21 June 2020 / 22:56

    Hello, thanks you so much for post. I success follow setup stream with you, I can ask how to CORS multiple domain because I tried in the Crossdomain. xml file But it doesn’t work

    • Ativi.net 27 June 2020 / 23:02

      Help me remove comment, Thanks so much

  12. James 27 June 2020 / 21:43

    I worked through your very detailed instructions and I now have the server running very smoothly with live streams through my network. For whatever reason it doesn’t pick up the default index.html but loads it when I put it ion the URL, I know I got confused with apache and Nginx etc.

    Anyway thanks for your hard work, my young boy is super pleased I got him a streaming platform for his OBS and his games, all his friends commented on the quality.

    Q. If I wanted to stream a second channel, do I have to install another instance do I just modify/copy the index.html into another like stream2.html and what would need to be changed?

    Thank you for publishing this it is greatly appreciated.

  13. Antonio 4 July 2020 / 15:47

    Hi,
    tnx for the tutorial.
    I’m using an AWS (amazon) server and I’m getting some error:
    – the procedure to obtain an SSL certificate, when I put in terminal the command “sudo certbot –nginx -d ec2-3-21-241-87.us-east-2.compute.amazonaws.com”
    the terminal say:
    An unexpected error occurred:
    Error creating new order :: Cannot issue for “ec2-3-21-241-87.us-east-2.compute.amazonaws.com”: The ACME server refuses to issue a certificate for this domain name, because it is forbidden by policy

    and so I cannot configure the default with SSL.

    Also if I try to see the stat I obtain ever 404error.

    at the same time trying to see the js player I have, on all browser I tested on more than 1 pc or Mac, that “To view this video please enable JavaScript, and consider upgrading to a web browser that supports HTML5 video”.

    May you help me? I’m newbie to linux…

    Tnx again.

  14. Salvatore Martinico 15 July 2020 / 17:12

    I am trying to stream video using nginx.
    I’ have compiled NGINX on UBUNTU 20 with rtmp module. This the ffmpeg command i use to start streaming:

    ffmpeg -re -i “myvideo.mp4” -vcodec h264 -acodec aac -b:a 300k -bufsize 10M -ar 48000 -strict -2 -f flv rtmp://localhost/hls/stream

    In VLC i open this url: http://MY_IP:8080/tv/stream.m3u8, but doesn’t work. What am I doing wrong?

    The configuration of my nginx.cof is this:

    user www-data;
    worker_processes 1;

    #error_log logs/error.log;
    #error_log logs/error.log notice;
    #error_log logs/error.log info;

    #pid logs/nginx.pid;

    events {
    worker_connections 1024;
    }

    rtmp {
    server {
    listen 1935;
    chunk_size 8192;
    application hls {
    live on;
    allow play all;
    hls on;
    hls_type live;
    hls_nested on;
    hls_path /mnt/hls;
    hls_cleanup on;
    hls_sync 100ms;
    hls_fragment 10s;
    hls_playlist_length 60s;
    hls_fragment_naming system;
    }
    }
    }

    http{

    include mime.types;
    default_type application/octet-stream;
    log_format main ‘$remote_addr – $remote_user [$time_local] “$request” ‘
    ‘$status $body_bytes_sent “$http_referer” ‘
    ‘”$http_user_agent” “$http_x_forwarded_for”‘;
    sendfile off;
    tcp_nopush on;

    server {
    listen 8080 default_server;
    listen [::]:8080 default_server;
    keepalive_timeout 70;
    gzip off;

    root /mnt/hls;

    server_name _;

    # add_header Strict-Transport-Security “max-age=63072000;”;
    # add_header X-Frame-Options “DENY”;

    location /tv {
    types {
    application/vnd.apple.mpegurl m3u8;
    }
    location ~* \.m3u8$ {
    add_header Cache-Control no-cache;
    }
    add_header Access-Control-Allow-Origin *;

    # First attempt to serve request as file, then as directory, then fall back to displaying a 404.
    try_files $uri $uri/ =404;
    }

    }
    }

  15. Alex 21 July 2020 / 21:47

    This worked perfectly for the default website thank you!

    I am trying to add another website to this server to stream to.

    Could you give me the config or basic steps to host another streaming site on this server?

    Apologies for asking I tried and failed.

    • Andre 22 July 2020 / 18:29

      Of course I do I have tons of examples. But before I continue…
      I’m not sure I understand you correctly. So please tell me more about what exacxtly your situation is like?
      So you want to allow a different machine to livstream to your server? Does the other machine have its own livestream built in? Or do you want to send the livetream rtmp to the webserver alsO Do you want to host only the website for that new machine?

    • Alex 23 July 2020 / 22:56

      Ty for the reply Andre. My objective to run multiple streaming websites on this webserver. Currently the root website works great. I am trying to make another website to stream to from a separate OBS server. Each website hosted will have a different stream going to it.

      Thanks!

Leave a Reply

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