Background
Whenever you deal with media be it audio or video, streaming it over a network or the internet always comes up. The amateur radio television hobby is no different. We are creating content that is being transmitted over various platforms including satellites. The QO-100 satellites has also opened up these kind of experiments for more people across the world. The Longmynd Client has proven that we want our media whether its being received or transmitted to be available on various platforms and shared in multiple ways. One of the requests that come up often for the Longmynd client is to stream this in more ways over a network or even more importantly over the internet. Technology has come a long way and there are many ways to stream audio and video. Most of the amateur television software revolves around streaming over UDP. This works fine on internal networks, but once you try to share that out over the internet then things become tricky.
I’ve made a list of various technologies I would like to experiment with in terms of streaming video. Lets see which technologies would play well in our environment and in the process have practical instructions that anybody can reproduce and experiment with. We all learn more together 😉 Also, don’t forget about the BATC Streaming that is available for ATV related activities.
In this first installment I experimented with setting up a RTMP server to get video from our DATV reception all the way to a web browser. Keep in mind that these are all experiments and nothing is production ready, but maybe it will open up the discussion and more people can experiment to improve the flows of our DATV transmissions.
I welcome any suggestions of tech to try around this topic and any discussions on improving it, or different ideas, no matter how radical.
Configure RTMP Server with Nginx and Nginx-RTMP module
Nginx is a very powerful webserver with lots of different options available. We are using Nginx in this experiment because of the Nginx-RTMP module which has all the bits for receiving a stream and making a stream available online in various formats. I did this test on an ubuntu machine, but should in theory work on most Linux distributions. First we need to get Nginx going with these steps:
sudo apt update
sudo apt install nginx
If all went well then you should have a webserver up and running. You can use a browser to confirm that its working by browsing to the ip address of the machine you installed it on. You can also use the following command to get the status of the service running:
sudo systemctl status nginx
You can find the most common nginx configurations in nginx.conf file which is normally located at /etc/nginx/nginx.conf
sudo nano /etc/nginx/nginx.conf
With the web server up and running we can now install the Nginx-RTMP module. The package to install is libnginx-mod-rtmp and can be installed on an ubuntu system using:
sudo apt install libnginx-mod-rtmp
Once this has been successfully installed we need to enable and configure this module by editing the nginx.conf file. Here is an example of a configuration you can add right at the end of the config file:
rtmp {
server {
listen 1935;
chunk_size 4096;
allow publish 127.0.0.1;
deny publish all;
application live {
live on;
record off;
hls on;
hls_path /var/www/html/stream/hls;
hls_fragment 3;
hls_playlist_length 60;
dash on;
dash_path /var/www/html/stream/dash;
}
}
}
The basic concept of this configuration is to enable the RTMP module to receive a RTMP stream from the localhost 127.0.0.1 only and to make it available on the standard 1935 port. It also adds a few configuration options to enable support for HLS and Dash which are modern streaming protocols for streaming our video directly to a browser. More on that a bit later.
This should cover the basic RTMP server but since we are playing with browser streaming as well, lets setup the server block while we are here. Server blocks are basically just configurations that specify to nginx how to deal with requests to it based on various variables such as the port we are connecting to or the domain we are connecting from. We are going to keep it simple and listen for any browser connections on port 8089:
sudo nano /etc/nginx/sites-available/rtmp
The previous command creates a new file and we can add the following content to it:
server {
listen 8089;
location / {
add_header Access-Control-Allow-Origin *;
root /var/www/html/stream;
}
}
types {
application/dash+xml mpd;
}
Things to note here is that we allow access control from other origins. This is not safe practice and if you are putting anything online then I suggest you read up a bit more on this option. We also specify that our root is located at /var/www/html/stream
. This means that when a browser connects our webserver then it will look for files to serve at that location.
Lastly we have a few basic steps left,
Lets make sure the folder of our web root exists by creating it:
sudo mkdir /var/www/html/stream
Lets enable our server block by linking the configuration file into sites-enabled:
sudo ln -s /etc/nginx/sites-available/rtmp /etc/nginx/sites-enabled/
And then lastly to enable all the configuration we have done lets reload nginx:
sudo systemctl reload nginx
Streaming our video from Longmynd/Minitiouner
For our testing we will be using the Minitiouner DATV receiver hardware from the BATC and the opensource ATV receiver software called Longmynd. We will be using the same version as used for the Longmynd client. Instructions for installing that can be found here.
Longmynd basically controls the tuner on the Minitiouner and the TS stream that it receives is made available on a UDP port. I’m using the following parameters for Longmynd to output the received UDP stream on the localhost port 4003 and I’m tuning to the QO-100 Beacon with a symbol rate of 1500 kS
longmynd -W 8080 -i 127.0.0.1 4003 -I 127.0.0.1 4002 741542 1500
Next we need to take the received stream and convert it in a format as expected for our RTMP server. If you don’t already have it installed then you can install it with:
sudo apt-get install ffmpeg
Ffmpeg has loads of parameters that can be used but for this experiment we are keeping it simple by simply taking the UDP output from Longmynd as a media input on FFMPEG and converting it to h264 for video and aac for audio as expected by the RTMP server. We are putting it all in a flv container before sending it to our RTMP server. This is not the only way to do this, but more experimentation is required for more optimal and efficient ways.
ffmpeg -i udp://127.0.0.1:4003?timeout=100000000 -c:v libx264 -preset fast -c:a aac -ar 44100 -ac 1 -f flv rtmp://localhost/live/stream
If all is going well then your received stream should now be feeding into our RTMP server
At this point you should be able to view the stream on the RTMP server using VLC. Open a network stream using the following URL (replace the <ipaddress> with the ip of where your RTMP server is installed.
rtmp://<ipaddress>/live/stream
If things aren’t working as expected at this point then I suggest you go back and make sure all the configurations are correct as specified. Your video and audio should be smooth without any issues while streaming.
Viewing the stream on the Web
At this point we have our received DATV stream going into our media server. We can consume the media stream using a player like VLC, but our main goal is to get it on a web browser. We are keeping the html side of this very simple for testing purposes. The main web video player we are using will be a library called Clappr which is an extensible media player for the web. Remember our webroot we created earlier in the nginx configuration? Will be creating our html file there to display the basic viewer. The code for the index.html file is as follow:
<html>
<head>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/@clappr/player@latest/dist/clappr.min.js"></script>
</head>
<body>
<div id="player"></div>
<script>
var player = new Clappr.Player({ source: "http://192.168.0.178:8089/hls/stream.m3u8", parentId: "#player" });
</script>
</body>
</html>
This creates a simple empty website with the player component. The player component is pointing to our HLS stream. You need to change the source section to the correct ip address of where your webserver is located and remember we configured it to listen on port 8089:
http://<ipaddress>:8089/hls/stream.m3u8
Your newly created html file goes into the following folder as per our configuration:
/var/www/html/stream
At this point you should be able to access the website with your browser, opening up the following url:
http://<ipaddress>:8089
If all went well then you should be able to view your live received stream on the web browser:
If you wanted to access this from the outside you can configure a port forwarding rule on your internet firewall/router. For example I configured mine to listen on port 80 of the external ip address and forward all traffic to my internal machine to port 8089. You will also need to change your index.html to point to the new ip address. You should now be able to access the same website from the outside of your network.
Note: there is no security in place here. This is an experiment and not production ready. If you are planning to do this on a permanent basis then you need to do some research into making all of this secure. This is your responsibility.
Conclusion, further developments and issues
So in this experiment we have got something going that where we receive a DATV signal from our hardware receiver and then through a variety of software we got it to a point where it can be viewed online in a browser. None of this has been optimized or made user friendly, but it does proof a concept that it can be done.
The first immediate improvement that we can do is to add control for Longmynd on the website. This should be fairly simple as we have web socket control of Longmynd. This would allow us to show the reception details and let us provide controls for changing the frequency, etc.
Another issue is that our Ffmpeg conversion needs to be more controlled. If you are watching something like the beacon that continually transmits then it works just fine. But once you start changing the frequency to a new signal, or a signal that is being watched falls away and is being replaced by someone else transmitting then it also needs a restart because the size, codecs etc of the received stream has most likely changed. The fix for this would be to develop some Ffmpeg management software, something that communicates to Longmynd and then if a new signal is locked on and being received to start the Ffmpeg conversion. I was pleasantly surprised to see that the video player (unlike VLC) is happy with streams changing so there shouldn’t be too much to do there. Also note that none of the above is going to work reliably on a Raspberry PI, although I do have hope for getting this going on a Jetson Nano.
Lastly we also have a bit of delay coming through the whole process. When streaming a long transmission such as an event or something along those lines, its not much of an issue. But in the normal QSO over DATV event where overs are kept short it is a bit more important to have a more real time view. There is definitely room for many improvements and I have a list of more technologies to try out and to experiment with. Stay tuned for more information and please do contact me with your ideas, suggestions and requests.
73,
Tom – ZR6TG
Brilliant as usual!
Thank you Tom.
73! de HB9IIU
Daniel
Very nice idea and concept Tom. Congrats .
This can become a very useful total concept with great flexibility.
73 ON7TU
Lucien