Follow the steps below to set up your own streaming server.
- About
- Getting Started
- Set Up
- Build Your Receiver
- Build Your Broadcaster
- Add SSL
- Configure OBS
- Configure Analytics and Firewall
- Build Your Viewer
- Go Live
- Keep Your Stream Secure
- Donate
- Parting Shot
I have directly seen the power that big tech has over our lives. In a very small way, I'd like to push back against that trend towards an unaccountable inhumane centralized quasi-corporate-government machine and dissent against the power it wields over us. I don't want to continue seeing voices of dissent and critique marginalized and cancelled by big tech at the behest of governments and corporations simply for offering alternative opinion that is contrary to and critical of the experts and authorities. While that statement includes the last three and a half years for sure, it also includes marginalized and alternative opinions about many events and actions throughout history. The solution to the problem of big tech is to decentralize the internet. We should have independent spaces online that preserve privacy and allow genuine community among like minded individuals and polite dissenters. Here, I will show you how to create your own live streaming server which is one piece of that larger solution puzzle. While, I built this project on a very small cheap compute instance, this streaming server application is a fully scalable secure model that can be used on more powerful compute instances to broadcast your live stream (radio or video) content to thousands of followers similar to what Twitch, Youtube, Facebook, Rumble, Discord and others provide. This application will also work very well on a Raspberry PI 4B for those who want additional privacy, security and ownership. Follow these steps below to begin the process of becoming unstoppable by big tech.
Thanks, Jason
- download obs : https://obsproject.com
- purchase domain : https://domains.squarespace.com
- create cloud account
- create linode account : https://www.linode.com
- create aws account : https://aws.amazon.com
- access your cloud account
- linode account : https://cloud.linode.com/linodes
- aws/lightsail : https://lightsail.aws.amazon.com/ls/webapp/home/instances
- create your instance with
ubuntu 20.04
- Hate cloud computers? This entire project can exist on a Rasberry PI 4B
- linode account : https://cloud.linode.com/linodes
- point your domain to your created instance's ip
- navigate to your domain dns
- create an A record
- enter a subdomain or leave blank or @
- address - enter instance ip address
- TTL - 60 seconds or minimum
SSH into your instance and let's begin setting up your streaming server, we'll first update the instance and then install our server application called NGINX
- update instance
sudo apt update
sudo apt upgrade
- install nginx - server application
sudo apt install nginx
- check status
systemctl status nginx
ctl
+c
to exit the server
If Nginx is running correctly, you will see a green Active status.
Now, let's set up your receiver so your server can receive your live stream signal.
-
install nginx rmtp module, our receiver module
sudo apt install libnginx-mod-rtmp
-
restart nginx
sudo systemctl restart nginx
systemctl status nginx
ctl + c
to exit -
configure nginx to receive stream
sudo nano /etc/nginx/nginx.conf
-
copy and insert this code below at the bottom of the page
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record off;
# allow publish YOUR_LOCAL_IP_ADDRESS;
# deny publish all;
# Setup HLS
hls on;
hls_path /mnt/hls/;
hls_fragment 3;
hls_playlist_length 60;
#deny play all;
allow play all;
}
}
}
- after pasting click
ctl
+s
and thenctl
+x
Now, let's set up your broadcaster so your server can beam your live stream signal to surfers on your website.
- configure nginx to broadcast the stream
sudo nano /etc/nginx/sites-available/default
delete all existing code and paste the code below :
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html;
server_name your domain name;
location / {
try_files $uri $uri/ =404;
}
location ~ ^/live/?$ {
rewrite ^/live/?$ /stream.html break;
}
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias /mnt/hls/;
expires -1;
add_header 'Cache-Control' 'no-cache';
}
}
- after pasting click
ctl
+s
and thenctl
+x
Now, let's set up the security of your server and application. These next steps require that you've purchased a domain and followed the steps to set up an A record. It can take a while for this to work. So if it fails, give it some time before trying again.
-
install certbot and let's encrypt
sudo apt-get install certbot python3-certbot-nginx
-
create the ssl for your domain
sudo certbot --nginx -d your domain name
-
automate the renewal of your domain ssl
sudo certbot renew --dry-run
-
add a cron job to manage the renewal
sudo crontab -e
-
enter this line at the bottom and save and exit
0 12 */10 * * /usr/bin/certbot renew --quiet
-
see active scheduled cron jobs
sudo crontab -l
-
-
recheck nginx after certbot completes
sudo nano /etc/nginx/sites-available/default
should see changes and 443 code added
Now, let's set up your OBS software to broadcast to your receiver
-
Open OBS Studio on your PC or Mac.
-
Click on
Settings
in the bottom right of the OBS Studio window. -
In the settings panel, click on
Stream
. -
Here, under
Service
, selectCustom...
. -
In the
Server
field, enter the RTMP URL of your Nginx server. The URL would be in the format:rtmp://<Your_Server_IP>/live
. -
set your stream key, that will be needed later.
YOUR_STREAM_KEY
- FYI you will need your stream key to be used in building the viewer -
Click on
Apply
and thenOK
.
TCP Dump allows us to do some checks on the live stream when it is broadcasting which will allow troubleshooting if the need arise
-
install tcpdump to see the operation of the livestream
sudo apt-get install tcpdump
sudo tcpdump -i any port 1935
ctl
+c
to exit the stream -
open firewall port 1935 on lightsail it is closed, this is done in networking on the instance
-
open firewall port 433 on lightsail it is closed, this is done in networking on the instance
Now, let's set up your front page lobby so that surfers can visit your website and listen to or watch your live stream. I designed the front end code to be stylish and responsive, functional on both desktop and mobile browsers. There's a lot going on so I won't waste your time to discuss it. Big thanks to PicoCSS for amazing semantic CSS which is what is used to style the front end. Also using VideoJS, a free video player that handles HLS streams. Don't worry if you don't understand what I just said, just copy and paste and you'll have an amazing lobby for your surfers to visit.
-
You'll Need
YOUR_STREAM_KEY
andYOUR_DOMAIN_NAME
- only replace the key and domain but keep the
/hls/
and.m3u8
https://YOUR_DOMAIN_NAME/hls/YOUR_STREAM_KEY.m3u8
- only replace the key and domain but keep the
-
paste this code to create the viewer page and open it
sudo nano /var/www/html/stream.html
-
copy this code and paste it in the nano editor, make the changes to add your stream key and domain name. It has to be done twice. One for the audio and one for the video.
<!DOCTYPE html>
<html>
<head>
<title>My Streaming Server || Better Call Jason</title>
<meta name="author" content="Jason Nobles">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@1/css/pico.min.css">
<style>
@media only screen and (min-width: 992px) {
article {
width: 800px;
margin: auto;
}
video {
width: 700px;
height: 450px;
}
audio {
width: 700px;
}
}
body > main {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: calc(100vh - 7rem);
padding: 1em;
}
article {
overflow: hidden;
text-align: center;
}
@media only screen and (max-width: 768px) {
video {
width: 100%;
height: auto;
}
audio {
width: 100%;
}
}
</style>
</head>
<body>
<main>
<nav>
<ul>
<li></li>
</ul>
<ul>
<li><strong>bcj.one/live</strong></li>
</ul>
<ul>
<li></li>
</ul>
</nav>
<article>
<div>
<hgroup>
<h1>My Streaming Server</h1>
<h2>Video</h2>
</hgroup>
<link href="https://vjs.zencdn.net/8.5.2/video-js.css" rel="stylesheet" />
<script src="https://vjs.zencdn.net/8.5.2/video.min.js"></script>
<div data-vjs-player>
<video id="my_video_1"
class="video-js vjs-default-skin vjs-fluid vjs-16-9 vjs-big-play-centered"
controls
preload='auto'
data-setup='{}'>
<source src="https://YOUR_DOMAIN_NAME/hls/YOUR_STREAM_KEY.m3u8" type="application/x-mpegURL">
</video>
</div>
</div>
<br>
<br>
<div>
<hgroup>
<h2>Audio</h2>
</hgroup>
<div data-vjs-player>
<audio
id="my_audio_1"
class="video-js vjs-default-skin vjs-fluid"
controls
preload="auto"
>
<source src="https://YOUR_DOMAIN_NAME/hls/YOUR_STREAM_KEY.m3u8" type="application/x-mpegURL">
</audio>
</div>
</div>
</article>
</main>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script src="https://cdn.jsdelivr.net/npm/videojs-contrib-hls.js@latest"></script>
<script>
var player = videojs('my_video_1');
player.play();
var player2 = videojs('my_audio_1');
player2.play();
</script>
<script>
const themeApplier = {
// Config
darkScheme: "dark",
rootAttribute: "data-theme",
// Init
init() {
this.applyScheme();
},
// Apply dark scheme
applyScheme() {
document
.querySelector("html")
.setAttribute(this.rootAttribute, this.darkScheme);
},
};
// Init
themeApplier.init();
</script>
</body>
</html>
-
after pasting click
ctl
+s
and thenctl
+x
-
Now create your livestream and try it out!
The last thing to do is to test the configurations. If the response says ok, then you are all set. If you run into an issue look at the errors and try to figure it out. If you need help, please reach out. Most times, errors at this stage are typos or code syntax errors. Enter the two commands below
sudo nginx -t
if everything is good and the status is okay then :
sudo systemctl restart nginx
This restarts the service and you are now ready to broadcast your live stream.
-
for troubleshooting your stream use tcpdump to see the operation of the livestream. If you are receiving a stream to the server the command below will be overwhelmed with data, if just an empty screen then something is wrong with your set up.
sudo tcpdump -i any port 1935
press
ctl
+c
to exit the stream
Prevent anyone else from broadcasting to your server by making the following changes. Only deploy these changes once you have fully tested and determined the system is working as intended.
- configure nginx to receive only the stream from your ip address. Get your real IP and enter it in the provided code. You cannot broadcast from behind a VPN. The entire streaming server is a VPN on its own.
sudo nano /etc/nginx/nginx.conf
- copy and insert this code below with the changes at the bottom of the page. Make sure to replace
YOUR_LOCAL_IP_ADDRESS
with your real IP address
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record off;
allow publish YOUR_LOCAL_IP_ADDRESS;
deny publish all;
# Setup HLS
hls on;
hls_path /mnt/hls/;
hls_fragment 3;
hls_playlist_length 60;
#deny play all;
allow play all;
}
}
}
-
after pasting click
ctl
+s
and thenctl
+x
-
now one more time let's test our configs:
sudo nginx -t
if everything is good and the status is okay then :
sudo systemctl restart nginx
This restarts the service and you are now ready to broadcast your live stream and you are the only one that can stream to your server now.
This project was months in development from the idea to full execution. Once I had a fully working model I tested it repeatedly on many different compute instances. I spent weeks in tutorial preparation trying to make it as easy as possible for a novice or an expert to own their own live stream server as conveniently as possible. While I make it all look very easy to do, there are a lot of complex things involved here. From the back end to the front end, everything is built to help you succeed. If my tutorial has helped you out, please email me at everydayjason@protonmail.com and tell me about it. I can't wait to hear about your successes! And, please consider making a BTC or LTC donation below.
Thanks for your support!
And remember as James Evan Pilato says:
Don't Hate The Media, Become The Media!