I’ve been thinking for a long time about setting up another simple VPS for Mikulski_Radio Youtube stream. Because unlike other sites, Youtube is very sensitive to even short disconnects: the slightest sneeze and the broadcast has to be recreated. Especially sad in those cases when you need to make changes to the radio script and, accordingly, restart it. And it’s just cool to save all the accumulated likes for “endless” broadcasting. The good thing is that by default (unlike other platforms), Youtube gives an additional backup key, which is needed just in order to switch to the backup stream in case the main stream goes down.
When I set up a stream stub on a new VPS for this (according to my instructions) nd put it into operation, I thought, why not look for a solution for all other sites?
I logically assumed that the craftsmen had to come up with some kind of upgrade for the Nginx-rtmp module. And indeed, the first query in Google brought me to a set of Nginx-rtmp-backup scripts published on Github..
DISCLAIMER: I am not a programmer and not a linuxoid, but only a copy-paster-enthusiast who shares what he could figure out. Therefore, it is possible that knowledgeable experts may find some points or formulations incorrect or ridiculous. The submission of this material assumes that you have a basic level of knowledge of linux terminal commands, and also understand the principle of operation and configuration of the Nginx-Rtmp module. Anyway, the following articles and tutorials will help you figure it out: Your own Restream Server(Nginx RTMP) How I Made My Stream Radio 24/7(Ffplayout) Creating a 24/7 stream(Liquidsoap) Creating a 24/7 stream part 2(Liquidsoap)
Nginx-rtmp-backup
The essence of this solution is simple, but a little tricky when trying to explain.
In the Nginx-rtmp module, three Rtmp applications/addresses (application) are created: the main stream (main), the backup (backup) and the final (out).
For the main and backup configs, special operators are specified that respond to publishing (exec_publish) or stopping streams (exec_publish_done).
These operators send a shell command to the terminal to activate the desired script responsible for starting/stopping an instance of avconv, ffmpeg or gstreamer to choose from.
avconv|ffmpeg|gstreamer copies all the parameters of the main/backup stream encoder and broadcasts it to out – visible to the viewer.
It turns out the following:
- main & backup in parallel, they begin their playback
- avconv|ffmpeg|gstreamer picks up main and starts broadcasting it to out
- main stops for some reason
- the first instance of avconv|ffmpeg|gstreamer for main is closed and a new one is started, which picks up backup and starts broadcasting it out
- when main restores its playback, avconv|ffmpeg|gstreamer closes backup and directs main to out again.
At the same time, the additional load of these processes is small (in my case, with a 720p stream with a 3000k bitrate):
- 2-3.5% CPU and 15mb RAM for gstreamer instance
- 1.5-2.5% CPU; 10mb RAM for nginx worker process
The only disadvantage of this approach is that it takes several seconds to switch sources, and therefore it is not possible to configure seamless switching to an emergency flow. However, gstreamer has the lowest latency and compared to ffmpeg does it in a couple of moments.
And I also have some doubts about the stability of gstreamer in 24/7 mode. So far, it has not yet been possible to test at a noticeably long distance in order to draw any conclusions on this score.
Installation and Configuration
Detailed instructions and comments are attached on Github and inside the scripts themselves, so there should be no problems. However, since we will use gstreamer, which is not provided as an option in the repository of the original source, we will use the already modified fork.
Let’s assume that we already have Nginx installed and an Rtmp module for it (tutorial).
You will need gstreamer:
sudo apt-get install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools
We go to a directory that can be read by Nginx, clone the repository there and open the folder we just copied:
cd /usr/local/share
sudo git clone https://github.com/hosseini92/nginx-rtmp-backup.git
cd nginx-rtmp-backup
Now you need to edit config.sh
There you can change the names for Rtmp-applications (instead of main, backup, out), determine the behavior (whether backup will switch back to main when it resumes or not) and choose what to use as a gasket (avconv|ffmpeg|gst). But, in order not to get confused, we will leave everything by default, except
# username for nginx worker processes
NGINX_USER="nobody"
# group for NGINX_USER
NGINX_GROUP="nogroup"
We specify here our login and the sudo user group (you can view them by entering the id command into the terminal).
Next, we grant the rights to execute the init.sh and run it:
sudo chmod a+x init.sh
sudo ./init.sh
Now you can edit the Nginx config.
Be sure to change the very first line user and enter the user name there, which was specified earlier in NGINX_USER. By default, www-data is defined there (or something like that). I just lost a lot of time on this, since mismatched names led to exec statements not running scripts.
user <USER>;
Now go down to the rtmp section and add the following:
rtmp {
server {
listen 1935;
application out {
live on;
}
application main {
live on;
play_restart on;
exec_publish /usr/local/share/nginx-rtmp-backup/main_publish.sh $name;
exec_publish_done /usr/local/share/nginx-rtmp-backup/main_publish_done.sh $name;
}
application backup {
live on;
play_restart on;
exec_publish_done /usr/local/share/nginx-rtmp-backup/backup_publish_done.sh $name;
}
}
}
Accordingly, no one forbids in out to register the limits to any desired sites, allow publication only from certain IP addresses, prohibit connecting to main and out and any other desired settings. The main thing is that the lines with exec_publish and exec_publish_done remain in their places. For example:
rtmp {
server {
listen 1935;
chunk_size 4096;
allow publish 127.0.0.1;
deny publish all;
application out {
live on;
push rtmp://stream.dlive.tv/live/<key>;
push rtmp://a.rtmp.youtube.com/live2/<key>;
}
application main {
live on;
play_restart on;
allow play 127.0.0.1;
deny play all;
exec_publish /usr/local/share/nginx-rtmp-backup/main_publish.sh $name;
exec_publish_done /usr/local/share/nginx-rtmp-backup/main_publish_done.sh $name;
}
application backup {
live on;
play_restart on;
exec_publish_done /usr/local/share/nginx-rtmp-backup/backup_publish_done.sh $name;
}
}
}
Now it remains only to run the streams at the appropriate addresses and with the same key. Let’s say we come up with the key – stream, then:
For main it will be rtmp://your.domain/main/stream
For backup, respectively, rtmp://your.domain/backup/stream
The final broadcast will be available at: rtmp://your.domain/out/stream
and on all sites where you have designated the source’s restream.
Logs are saved to the directory: /var/log/nginx-rtmp-backup