Inspired by an article that @Fabio wrote, I spent this afternoon configuring an nginx to serve video streams.
Almost everything works, except that apparently my letsencrypt configuration has broken (aaargh). Well, it can still be used with a non-matching certificate until I get to fix it.
And then I tried to install OBS Studio, and discovered that my laptop is too old, and it doesn't even try to load.
:(
maybe. I'm not sure if I have the motivation to go down that sinkhole.
At the moment I don't really have plans for any kind of streaming; it was just something cool to do together-ish with the lug.
Dirette video con NGINX e OBS Studio
In questi giorni di reclusione forzata, si fa affidamento a internet per portare avanti le nostre vite: telelavoro, videoconferenze, scuola online.
In questo piccolo articolo, vediamo come configurare un nostro server per fare dirette online, in alternativa a Youtube, Facebook, etc etc.
Cosa serve
- un server, magari una VPS, con una buona disponibilità di banda
- conoscenze base di linux, bash, ssh, e cose così
- colla vinilica
- forbici con la punta arrotondata
Protocolli e software
Il protocollo più usato per le dirette video è RTMP
Per funzionare, una sorgente invia un flusso di dati a un server che si occupa di rigirare il flusso ai vari client che lo richiedono.
Questo è il motivo per cui serve avere banda disponibile. Una diretta con 10 spettatori occuperà 10 x banda necessaria per il video
in uscita più quella in ingresso per la sorgente.
È possibile far funzionare il server su un RaspberryPI a casa? Puo' essere, ma non potrete avere molti spettatori, a seconda della vostra connessione a internet.
Come sorgente useremo OBS Studio, come server NGINX, che è più conosciuto come server web, ma esiste un modulo che supporta rtmp.
Come client potremmo usare VLC, o altri player che supportano RTMP, ma vogliamo che la diretta sia visibile da una pagina web.
Fortunatamente NGINX supporta anche HLS, un protocollo di stream video basato su http, che permette di visualizzare la diretta in un browser, grazie a librerie javascript come video.js.
NGINX lo faremo girare su un server con Debian 10 "buster".
In questo articolo presumiamo che non ci sia già un server web in esecuzione (tipo Apache o altri)
Installiamo e configuriamo il server
installiamo nginx e il modulo rtmp
# apt install nginx libnginx-mod-rtmp
Il modulo rtmp ha una sua configurazione da mettere nel file /etc/nginx.conf
. Per facilitarci la vita, creaiamo una cartella che conterrà la configurazione per rtmp
# mkdir -p /etc/nginx/rtmp.d
e nel file /etc/nginx.conf
aggiungiamo
rtmp {
include /etc/nginx/rtmp.d/*;
}
Aggiungiamo la configurazione di rtmp. NGINX si occuperà di creare i segmenti video e la playlist m3u8
necessari per il protocollo HLS, dobbiamo dirgli dove. Glieli faremo salvare in /tmp/hls
.
Creiamo il file /etc/nginx/rtmp.d/hls
server {
listen 1935;
ping 30s;
notify_method get;
application live {
live on;
# sample HLS
hls on;
hls_path /tmp/hls;
hls_sync 100ms;
hls_fragment 3;
hls_playlist_length 60;
allow play all;
}
}
NGINX sarà in ascolto per lo stream rtmp sulla porta 1935, la porta di default del protocollo.
Ora configuriamo la parte web.
Sostituiamo il contenuto del file /etc/nginx/sites-available/default
con:
server {
listen 80;
listen [::]:80;
server_name ilmioserver.it;
root /var/www/html;
location / {
index index.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';
# 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;
video/mp2t ts;
}
root /tmp;
}
# rtmp stat
location /stats {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
# rtmp control
location /control {
rtmp_control all;
}
}
Con questo file configuriamo:
- la radice del nostro web server, da dove verrà servita la pagina agli spettatori, che sarà salvata in
/var/www/html
- il percorso (
/hls
) da cui saranno serviti i file video, presi da/tmp/hls
. È lo stesso percorso impostato nella configurazione della parte rtmp. - due percorsi di 'supporto', compresa una pagina di statistiche sugli stream.
Verifichiamo che la configurazione non contenga errori di sintassi:
# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Ottimo. Ricarichiamo la configurazione.
# systemctl reload nginx
La pagina di visualizzazione
Creiamo il file /var/www/html/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://vjs.zencdn.net/7.1/video-js.min.css" rel="stylesheet">
<script src="https://vjs.zencdn.net/7.1/video.min.js"></script>
</head>
<body>
<video id="player" class="video-js vjs-default-skin" controls >
<source src="/hls/mystream.m3u8" type="application/x-mpegURL" />
</video>
<script>
var options, video;
options = {
autoplay: true,
muted: true
};
video = videojs('player', options);
</script>
</body>
</html>
notiamo l'indirizzo della sorgente video: src="/hls/mystream.m3u8"
: mystream
sarà l'identificativo della diretta da utilizzare nella configurazione di OBS.
Per finire, aggiungiamo il foglio di stile per le statistiche. Usiamo quello di esempio installato col pacchetto:
# gunzip /usr/share/doc/libnginx-mod-rtmp/examples/stat.xsl.gz -c > /var/www/html/stat.xsl
le statistiche saranno raggiungibili su http://miodominio.it/stats
.
In onda
Installiamo OBS Studio.
Al primo avvio, eseguiamo la configurazione guidata.
Scegliamo 'Ottimizza per le dirette'
Segliamo una risoluzione e un framerate (FPS). Io ho scelto 1280x720
a 30 FPS.
Ora configuriamo il servizio di streaming. Scegliamo "Personalizzato...".
Come server inseriamo rtmp://miodominio.it/live/
Come 'Codice delle dirette' mettiamo mystream
. Nota: è lo stesso nome utilizzato per la sorgente video nella pagina html, mystream.m3u8
Viene eseguito un test che ottimizza le impostazioni.
A questo punto aggiungiamo delle fonti in OBS e pigiamo su "Avvia la diretta". Vi rimando alla documentazione di OBS per la cofigurazione di scene e fonti.
La diretta sarà visibile con un browser su http://miodominio.it/
o con un lettore video, come VLC, aprendo l'indirizzo http://miodominio.it/hls/mystream.m3u8
Interattività
Questo sistema permette di avere una diretta video "uno a molti" tipo televisione. Ma questo è internet, è interattivo! Vogliamo poter ricevere domande e commenti dai nostri spettatori mentre siamo in diretta.
I servizi proprietari di streaming mettono a disposizione una chat a corredo del video. È una buona idea, facciamolo anche noi!
Ovviamente non ci metteremo a scrivere un sistema di chat, ma useremo uno dei più usati e storici sistemi su internet: IRC.
In particolare, inseriremo un client IRC web nella pagina, configurato per collegarsi a un canale predefinito. Da qui gli utenti potranno interagire tra loro e con noi (che terremo un client IRC aperto durante la diretta).
Utiliziamo KiwiIRC come client IRC web. La documentazione ci dice che il formato dell'url per indicare il canale da utilizzare è https://kiwiirc.com/nextclient/#irc://irc.freenode.net/#<nome del canale>
. (ci colleghiamo alla rete irc di freenode)
Aggiungiamo quindi il seguente pezzo di codice html nella pagina index.html
, appena sotto il tag </video>
<iframe width="100%" height="600"
src="https://kiwiirc.com/nextclient/#irc://irc.freenode.net/#ilmiocanale"></iframe>
(ricordiamoci di mettere il nome del canale corretto)
Conclusioni
Abbiamo creato da zero un semplice servizio di streaming live interattivo.
Da qui è possibile modificare il sistema per supportare più live in contemporanea: basta creare una pagina con il corretto nome dello stream come sorgente video e il corretto canale irc per la chat.
Una nota sulla sicurezza: il server RTMP è in ascolto su internet senza alcun sistema di autenticazione. Chiunque puo' avviare uno stream.
Una soluzione puo' essere mettere il server RTMP in ascolto solo su localhost, modificando il file /etc/nginx/rtmp.d/hls
server {
listen localhost:1935;
[...]
e utilizzare un tunnel ssh per collegarsi:
$ ssh -L 1935:localhost:1935 utente@miodominio.it
In questo caso, OBS dovrà collegarsi a rtmp://localhost/live
Esistono altre possibilità per autenticare la connessione RTMP, ma le indagheremo in un prossimo articolo.
Paolo Pedaletti likes this.
Paolo Pedaletti reshared this.
Then I got more interested in extracting the information than in actually reading it for a while, because... I'm like that.
Elena ``of Valhalla'' likes this.
from instagram.com/ortolanileo/
Leo: "and now some tips to live this day with lightheartedness!"
"you can read a good book"
"or study a foreign language"
"or exercise"
"or tidying wardrobes"
"or"
Tv: "tearing down this wall will cost you $ 3000, but you'll have the well-lit kitchen you wanted!"
Hypolite Petovan likes this.
What's new in #confy today:
- nice button in headbar to update main menu list or event cached data
- nice overlay toaster to show notifications
- main menu data is updated automatically at start if older than one day
- event cache is updated automatically at open (if network is available).
- event data is downloaded asynchronously. This leave the UI responsive while downloading.
- talk detail page show "conflicting" starred talks
- Remind upcoming starred events with a system notification
What's wrong in #confy today:
- flatpak doesn't work anymore (see #1. I think it's related to sandbox permissions, but I can't understand how fix it. So, flatpak building in builds.sr.ht is disabled.
- The "+" button ("Add event from URL") is just a placeholder. More work must be done to support it correctly
- apart from event data, other downloads are still sync and block the ui
- I still have issues with Leaflet and folding.... I'm missing something here...
please, send help...
What's missing, in "likely it will land" order:
- Download all data asynchronously.
- An app menu is needed, with things like "options" and "back to event list" ...
- An options window, with things like "update event cache every" and "clear all cached data"
- The "Map" page is still a placeholder
- Support for FOSDEM's room status API
Thib reshared this.
#WIP #confy #flatpak built on sourcehut build service, with a nice artifact. :)
builds.sr.ht/~fabrixxm/job/165…
still a test. Next step, trigger build of master branch when pushed.
#InCoWriMo wrapup...
#InCoWriMo has finished, time for a bit of wrapup.
On feb 20th I had written 21 letters, which a) was my bare minimum objective b) meant that I was perfectly on time. Then SnowCamp happened, and it was great, but it also meant I just stopped writing (aaahhh, too many things to dooooooo. ugh, post-conference blues).
Yesterday at the last possible minute I finished one letter and a handful of postcards, so I'm at 25; I still have two letters I really want to write anyway, and then I don't know if I want to look for two other things to write, even if I'm late, or just be happy with 27.
I've also started three correspondences that will hopefully continue beyond February (yay!).
And now, back to the regular avatar…
We had a very nice experience (keeping the video stream at minimum), and friends abroad were able to join us!
I only missed the pizza together 😄
like this
But Jami was very unreliable for me
yes. also for me.
I was told Jitsi was bought by a company and other messengers should be preferred.
Never heard of.
Anyway, Jitsi Meet it's fully opensource and self-hostable. Don't see any problem..
Found:
jitsi.org/news/we-have-a-new-h…
8×8 announced it has acquired the Jitsi team and our technology from Atlassian
"from Atlassian" looks like an improvement, to me.
Again, all the source code is available :)
Sandro
in reply to Fabio • •