Work

Server Video Streaming con NGNIX

14 Ago , 2019  

La soluzione descritta in questo articolo consentirà a chiunque abbia un browser funzionante, inclusi smartphone e tablet, di poter fruire di video in diretta.

Utilizzeremo HTTP Live Streaming (HLS).

HLS è stato sviluppato da Apple Inc.

Funziona suddividendo il flusso generale in una sequenza di piccoli download di file basati su HTTP,
ognuno dei quali carica un breve pezzo di un flusso potenzialmente illimitato.

Un elenco di flussi disponibili, codificato con bit rate diversi, viene inviato al client utilizzando una playlist M3U estesa.

Basato sullo standard HTTP, supera i controlli dei firewalls o dei proxys che permettono l’uso del protocollo.

Di contro la latenza sarà più bassa se paragonata ad altri protocolli come RTMP.

La soluzione qui proposta è quella di utilizzare il protocollo RTMP per inviare il flusso dalla sorgente video al cloud e quindi convertirlo in HLS usando NGINX.
Se si desidera utilizzare Apache o un altro server Web per servire lo stream, questo può essere fatto facilmente.

NGINX ha un modulo RTMP molto efficiente, per usarlo configuriamo NGINX con il supporto per RTMP.

Installa NGNIX su MacOS

Usa brew per installare nginx :

brew install nginx

Dopo l’installazione esegui:
sudo nginx

Test dell’istallazione
Apri il browser e vai all’URL:

http://localhost:8080

Configurazione
nginx.conf su Mac dopo linstallazione con brew si trova su:
/usr/local/etc/nginx/nginx.conf

Adesso andiamo a modificare il file di configurazione nginx prima di avviarlo.

Apri il file “/usr/local/etc/nginx/nginx.conf” e abilita RTMP e HLS seguendo l’esempio seguente (nota che ho usato l’utente www-data poiché ho installato apache che usa www-data come utente):

user  www-data;
worker_processes  1;
error_log  logs/error.log debug;
events {
    worker_connections  1024;
}
http {
     sendfile off;
     tcp_nopush on;
     directio 512;
     default_type  application/octet-stream;
     server {
        listen       localhost:2222;
        server_name  $hostname;
        location / {
                root /var/nginx_www;
                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/hls;
        }
        # rtmp stat
        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }
        location /stat.xsl {
            # you can move stat.xsl to a different location
            root /usr/build/nginx-rtmp-module;
        }
        # rtmp control
        location /control {
            rtmp_control all;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
rtmp {
    server {
        listen localhost: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;
        }
    }
}

Con questa configurazione sia il server http che i server rtmp ascolteranno su localhost con http sulla porta 2222 e rtmp sullo standard 1935.

I file e la playlist HLS verranno generati e inseriti in “/ tmp / hls” (specificato da hls_path / tmp / hls;)

Per inviare il flusso al server da un dispositivo possiamo usare un tunnel ssh sulla porta 1935 e mappare la porta locale del dispositivo 1935 alla porta del server remoto 1935

$ ssh -L1935:remoteserver:1935

Per rendere lo streaming accessibile da un browser è disponibile un video player javascript video.js che può essere incorporato in una normale pagina 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="http://yourserver.ext/hls/mystream.m3u8" type="application/x-mpegURL" />
      </video>
  
  <script>
    var options, video;
    options = {
      autoplay: true,
      muted: true
    };
    video = videojs('player', options);
  </script>
  </body>
</html>

la linea con

<source src="http://yourserver.ext/hls/mystream.m3u8" type="application/x-mpegURL" />

indica al browser dove si trova la sorgente del flusso.

In NGINX l’applicazione rtmp si chiama live e il nome del file .m3u8 è mystream.m3u8.

Deve corrispondere all’URL del flusso rtmp pubblicato

rtmp: // localhost / live / MyStream

Poiché lo stream è composto da file regolari che sono frammenti di video, è sufficiente esporre la directory che li contiene al mondo esterno. Ad esempio creando un alias con apache2, all’interno della configurazione di virtualhost

Alias /hls "/tmp/hls"   
<Directory "/tmp/hls">
  Options FollowSymLinks
  AllowOverride All
  Order allow,deny
  Allow from all
  Require all granted
</Directory>

e assicurarsi che la directory /tmp/hls sia accessibile dall’utente con cui viene eseguito apache.

L’esempio funziona con apache e il programma di esempio di streaming opencv + ffmpeg + rtmp per generare il flusso

Like
Like Love Haha Wow Sad Angry


Comments are closed.

RSS Open school