Servidor de Streaming con Nginx-RTMP: Guía Completa de Configuración

Introducción

El streaming en vivo se ha convertido en una herramienta de comunicación esencial para creadores de contenido, educadores, empresas y jugadores en todo el mundo. Mientras que plataformas como Twitch, YouTube Live y Facebook Live ofrecen soluciones listas para usar, alojar tu propio servidor de streaming proporciona control, privacidad y flexibilidad sin precedentes. El módulo Nginx-RTMP transforma el poderoso servidor web Nginx en una plataforma de streaming completa capaz de manejar múltiples streams simultáneos, transcodificar video en tiempo real y distribuir contenido a varias plataformas.

Esta guía completa te guía a través de la construcción de un servidor de streaming de grado profesional usando Nginx con el módulo RTMP (Real-Time Messaging Protocol). Aprenderás cómo configurar ingesta RTMP, configurar HLS (HTTP Live Streaming) para reproducción web, implementar restreaming multiplataforma, agregar autenticación y seguridad, optimizar para baja latencia y monitorear rendimiento.

Ya sea que estés creando una solución de streaming privada para tu organización, construyendo una plataforma para contenido educativo, configurando un servidor de streaming de juegos o desarrollando una base para una plataforma de video personalizada, esta guía proporciona todo lo necesario para desplegar infraestructura de streaming lista para producción en Linux.

Descripción General del Caso de Uso

¿Por Qué Alojar Tu Propio Servidor de Streaming?

Ejecutar un servidor de streaming autoalojado ofrece ventajas significativas sobre depender únicamente de plataformas de terceros:

Privacidad y Control Completos: Tu contenido permanece en infraestructura que controlas. Sin algoritmos decidiendo visibilidad de contenido, sin cambios inesperados de políticas y sin preocupaciones de censura de plataformas.

Cero Tarifas de Plataforma: Las plataformas de streaming comerciales a menudo cobran por características avanzadas, bitrates más altos o almacenamiento aumentado. El autoalojamiento elimina tarifas continuas de plataforma.

Características Personalizadas: Implementa autenticación personalizada, integra con sistemas existentes, agrega overlays especializados o construye características interactivas únicas imposibles en plataformas comerciales.

Distribución Multiplataforma: Retransmite simultáneamente a múltiples plataformas (Twitch, YouTube, Facebook) desde una sola fuente, gestionando todo desde una ubicación central.

Menor Latencia: El streaming RTMP directo puede lograr latencia subsegundo, crucial para aplicaciones interactivas, juegos, subastas o eventos en vivo donde la interacción en tiempo real importa.

Almacenamiento Ilimitado: Graba streams con solo tu capacidad de almacenamiento como límite, sin restricciones arbitrarias de plataforma o políticas de eliminación.

Control de Marca: Experiencias de streaming completamente white-label con reproductores personalizados, marca y interfaces de usuario sin marcas de agua de plataforma o recomendaciones.

Escenarios Comunes de Despliegue

Comunicaciones Corporativas: Empresas transmitiendo reuniones internas, sesiones de capacitación o anuncios a toda la compañía con privacidad garantizada e integración con sistemas de autenticación existentes.

Streaming Educativo: Escuelas y universidades entregando conferencias en vivo, seminarios o programas de educación a distancia con archivos grabados e integración personalizada del sistema de gestión de aprendizaje.

Torneos de Juegos: Organizaciones de esports transmitiendo competiciones con feeds de baja latencia a múltiples plataformas simultáneamente, overlays personalizados y capacidades de repetición instantánea.

Vigilancia y Monitoreo: Sistemas de seguridad transmitiendo múltiples feeds de cámara a estaciones de monitoreo centralizadas con capacidades de grabación y reproducción.

Organizaciones Religiosas: Iglesias, mezquitas, templos y sinagogas transmitiendo servicios a miembros de la congregación que no pueden asistir en persona, con archivos permanentes.

Redes de Creadores de Contenido: Plataformas multi-creador donde numerosos streamers transmiten a través de infraestructura compartida con gestión centralizada y analíticas.

Eventos en Vivo: Conferencias, conciertos, webinars y talleres transmitidos a audiencias con integración opcional de venta de entradas, Q&A e archivo de alta calidad.

Capacidades Técnicas

Un servidor Nginx-RTMP correctamente configurado proporciona:

  • Ingesta RTMP: Aceptar streams de OBS Studio, Streamlabs, XSplit y otro software de transmisión
  • Transcodificación HLS: Convertir RTMP a HLS para reproducción basada en navegador sin plugins
  • Streaming Multi-Bitrate: Streaming de bitrate adaptativo para espectadores con ancho de banda variable
  • Grabación: Grabación automática de streams en vivo a archivos de video
  • Funcionalidad DVR: Pausar, rebobinar y reproducir streams en vivo
  • Soporte de Múltiples Aplicaciones: Aplicaciones de streaming separadas para diferentes propósitos
  • Estadísticas y Monitoreo: Métricas en tiempo real sobre espectadores, bitrates y rendimiento del servidor
  • Restreaming: Reenviar streams a plataformas externas automáticamente

Requisitos

Requisitos del Sistema

Requisitos Mínimos (Stream Individual, 720p):

  • CPU: 2 núcleos a 2.5+ GHz (Intel Core i3 o AMD Ryzen 3)
  • RAM: 2GB
  • Almacenamiento: 20GB (más para almacenamiento de grabaciones)
  • Red: 10 Mbps subida (para streaming 720p a 3-4 Mbps bitrate)
  • SO: Ubuntu 20.04/22.04, Debian 11/12, CentOS 8, Rocky Linux 8/9

Requisitos Recomendados (Múltiples Streams, 1080p con transcodificación):

  • CPU: 4+ núcleos a 3.0+ GHz (Intel Core i5/i7 o AMD Ryzen 5/7)
  • RAM: 8GB
  • Almacenamiento: 100GB+ SSD (para grabaciones y caché de transcodificación)
  • Red: 50+ Mbps ancho de banda de subida
  • SO: Ubuntu 22.04 LTS (recomendado)

Requisitos de Alto Rendimiento (Muchos streams simultáneos, 4K, transcodificación pesada):

  • CPU: 8+ núcleos a 3.5+ GHz (Intel Xeon o AMD EPYC)
  • RAM: 16GB+
  • Almacenamiento: 500GB+ SSD NVMe
  • Red: 100+ Mbps ancho de banda dedicado con baja latencia
  • SO: Ubuntu 22.04 LTS con optimizaciones de kernel

Consideraciones de Ancho de Banda

Requisitos de Bitrate de Streaming:

  • 480p (SD): 1-2 Mbps
  • 720p (HD): 3-5 Mbps
  • 1080p (Full HD): 5-8 Mbps
  • 1440p (2K): 8-12 Mbps
  • 2160p (4K): 15-25 Mbps

Calcular ancho de banda total: (Número de streams simultáneos × bitrate) + (Número de espectadores × bitrate)

Por ejemplo, alojando 5 streams 1080p simultáneos con 100 espectadores:

  • Ingesta: 5 streams × 6 Mbps = 30 Mbps
  • Espectadores: 100 espectadores × 6 Mbps = 600 Mbps
  • Total: ~630 Mbps

Las Redes de Entrega de Contenido (CDN) reducen significativamente los requisitos de ancho de banda del servidor para audiencias grandes.

Requisitos de Software

Dependencias de Compilación: Compilador GCC, make, herramientas de compilación y bibliotecas de desarrollo para compilar Nginx con módulo RTMP.

FFmpeg: Requerido para transcodificación, grabación y conversión de formato. Versión 4.0 o más nueva recomendada.

Certificados SSL/TLS: Let's Encrypt para entrega HTTPS de streams HLS (opcional pero recomendado).

Reproductores de Video: Video.js, HLS.js o reproductores HTML5 personalizados para reproducción basada en navegador.

Requisitos de Red

Puertos Abiertos:

  • 1935/TCP: Protocolo de streaming RTMP (streams entrantes)
  • 80/TCP: HTTP para entrega HLS (si no se usa servidor web separado)
  • 443/TCP: HTTPS para entrega HLS segura
  • 8080/TCP: Página de estadísticas opcional

Configuración de Firewall: Permitir conexiones entrantes en puertos RTMP y HTTP/HTTPS.

Red de Baja Latencia: Menor latencia mejora experiencia de streaming. Latencia sub-50ms a streamers ideal.

Conocimientos Previos Requeridos

  • Competencia en línea de comandos de Linux
  • Comprensión básica de códecs de video y protocolos de streaming
  • Familiaridad con configuración de servidor web Nginx
  • Conocimiento de configuración de red (puertos, firewalls, DNS)
  • Operación básica de software de transmisión de video (OBS Studio recomendado)

Configuración Paso a Paso

Paso 1: Preparación del Sistema y Actualizaciones

Conecta a tu servidor Linux vía SSH y actualiza paquetes del sistema:

# Ubuntu/Debian
sudo apt update && sudo apt upgrade -y

# CentOS/Rocky Linux
sudo dnf update -y

Instala herramientas de compilación esenciales y dependencias:

# Ubuntu/Debian
sudo apt install -y build-essential libpcre3 libpcre3-dev libssl-dev \
    zlib1g-dev git wget unzip

# CentOS/Rocky Linux
sudo dnf groupinstall -y "Development Tools"
sudo dnf install -y pcre-devel openssl-devel zlib-devel git wget unzip

Paso 2: Instalar FFmpeg

FFmpeg maneja transcodificación y grabación de video.

Ubuntu/Debian:

sudo apt install -y ffmpeg

CentOS/Rocky Linux:

# Habilitar repositorio EPEL
sudo dnf install -y epel-release

# Habilitar repositorio RPM Fusion
sudo dnf install -y --nogpgcheck \
    https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-$(rpm -E %rhel).noarch.rpm

# Instalar FFmpeg
sudo dnf install -y ffmpeg

Verificar instalación:

ffmpeg -version

Paso 3: Descargar Nginx y Módulo RTMP

Crear directorio de trabajo:

cd /tmp

Descargar código fuente de Nginx (usar última versión estable):

wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -xzf nginx-1.24.0.tar.gz

Descargar nginx-rtmp-module:

git clone https://github.com/arut/nginx-rtmp-module.git

Paso 4: Compilar Nginx con Módulo RTMP

Navegar al directorio de código fuente de Nginx:

cd nginx-1.24.0

Configurar compilación con módulo RTMP:

./configure \
    --prefix=/etc/nginx \
    --sbin-path=/usr/sbin/nginx \
    --modules-path=/usr/lib64/nginx/modules \
    --conf-path=/etc/nginx/nginx.conf \
    --error-log-path=/var/log/nginx/error.log \
    --http-log-path=/var/log/nginx/access.log \
    --pid-path=/var/run/nginx.pid \
    --lock-path=/var/run/nginx.lock \
    --http-client-body-temp-path=/var/cache/nginx/client_temp \
    --http-proxy-temp-path=/var/cache/nginx/proxy_temp \
    --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
    --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
    --http-scgi-temp-path=/var/cache/nginx/scgi_temp \
    --user=nginx \
    --group=nginx \
    --with-http_ssl_module \
    --with-http_realip_module \
    --with-http_addition_module \
    --with-http_sub_module \
    --with-http_dav_module \
    --with-http_flv_module \
    --with-http_mp4_module \
    --with-http_gunzip_module \
    --with-http_gzip_static_module \
    --with-http_random_index_module \
    --with-http_secure_link_module \
    --with-http_stub_status_module \
    --with-http_auth_request_module \
    --with-threads \
    --with-stream \
    --with-stream_ssl_module \
    --with-http_slice_module \
    --with-file-aio \
    --with-http_v2_module \
    --add-module=/tmp/nginx-rtmp-module

Compilar e instalar:

make -j$(nproc)
sudo make install

Este proceso toma varios minutos dependiendo del rendimiento de la CPU.

Paso 5: Crear Usuario y Directorios de Nginx

Crear usuario nginx:

sudo useradd -r -M -s /sbin/nologin nginx

Crear directorios requeridos:

sudo mkdir -p /var/cache/nginx/client_temp
sudo mkdir -p /var/cache/nginx/proxy_temp
sudo mkdir -p /var/cache/nginx/fastcgi_temp
sudo mkdir -p /var/cache/nginx/uwsgi_temp
sudo mkdir -p /var/cache/nginx/scgi_temp

sudo mkdir -p /var/www/html/hls
sudo mkdir -p /var/www/html/dash
sudo mkdir -p /var/www/html/recordings

sudo chown -R nginx:nginx /var/www/html
sudo chown -R nginx:nginx /var/cache/nginx

Paso 6: Configurar Nginx con RTMP

Crear configuración principal de Nginx:

sudo nano /etc/nginx/nginx.conf

Agregar la siguiente configuración completa:

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

# Configuración RTMP
rtmp {
    server {
        listen 1935;
        chunk_size 4096;
        allow publish 127.0.0.1;
        deny publish all;

        # Aplicación principal de streaming en vivo
        application live {
            live on;
            record off;

            # Empaquetado HLS
            hls on;
            hls_path /var/www/html/hls;
            hls_fragment 3;
            hls_playlist_length 60;

            # Deshabilitar consumo del stream desde nginx como rtmp
            deny play all;
        }

        # Aplicación de grabación
        application recording {
            live on;
            record all;
            record_path /var/www/html/recordings;
            record_suffix -%Y%m%d-%H%M%S.flv;
            record_unique on;

            hls on;
            hls_path /var/www/html/hls;
            hls_fragment 3;
            hls_playlist_length 60;
        }

        # Aplicación de streaming con autenticación
        application secure {
            live on;

            # Habilitar autenticación de clave de stream
            on_publish http://localhost/auth;

            hls on;
            hls_path /var/www/html/hls;
            hls_fragment 3;
            hls_playlist_length 60;
        }
    }
}

# Configuración HTTP
http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    # Entrega HLS
    server {
        listen 80;
        server_name _;

        # Entrega de stream HLS
        location /hls {
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            root /var/www/html;
            add_header Cache-Control no-cache;
            add_header Access-Control-Allow-Origin *;
        }

        # Entrega de stream DASH
        location /dash {
            root /var/www/html;
            add_header Cache-Control no-cache;
            add_header Access-Control-Allow-Origin *;
        }

        # Grabaciones
        location /recordings {
            root /var/www/html;
            autoindex on;
            add_header Access-Control-Allow-Origin *;
        }

        # Estadísticas
        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl {
            root /etc/nginx;
        }

        # Página de reproductor de prueba
        location /player {
            root /var/www/html;
            index player.html;
        }
    }
}

Guardar y salir.

Paso 7: Crear Servicio Systemd

Crear archivo de servicio systemd:

sudo nano /etc/systemd/system/nginx.service

Agregar el siguiente contenido:

[Unit]
Description=Servidor de Streaming RTMP Nginx
After=network.target

[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

Habilitar e iniciar Nginx:

sudo systemctl daemon-reload
sudo systemctl enable nginx
sudo systemctl start nginx

Verificar estado:

sudo systemctl status nginx

Paso 8: Configurar Firewall

Abrir puertos requeridos:

# UFW (Ubuntu/Debian)
sudo ufw allow 1935/tcp comment 'RTMP'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'

# Firewalld (CentOS/Rocky Linux)
sudo firewall-cmd --permanent --add-port=1935/tcp
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Paso 9: Crear Reproductor HTML de Prueba

Crear un reproductor de prueba simple:

sudo mkdir -p /var/www/html/player
sudo nano /var/www/html/player/player.html

Agregar este reproductor HTML5 usando Video.js:

<!DOCTYPE html>
<html>
<head>
    <title>Reproductor de Stream RTMP</title>
    <link href="https://vjs.zencdn.net/8.6.1/video-js.css" rel="stylesheet" />
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background: #1a1a1a;
            color: #fff;
        }
        h1 {
            text-align: center;
        }
        .video-container {
            max-width: 900px;
            margin: 0 auto;
        }
        .info {
            background: #2a2a2a;
            padding: 20px;
            margin-top: 20px;
            border-radius: 5px;
        }
    </style>
</head>
<body>
    <h1>Reproductor de Stream en Vivo</h1>

    <div class="video-container">
        <video id="my-video" class="video-js vjs-default-skin" controls preload="auto"
               width="900" height="506" data-setup='{}'>
            <source src="http://TU_IP_SERVIDOR/hls/stream.m3u8" type="application/x-mpegURL">
        </video>
    </div>

    <div class="info">
        <h2>Información del Stream</h2>
        <p><strong>URL RTMP:</strong> rtmp://TU_IP_SERVIDOR/live</p>
        <p><strong>Clave de Stream:</strong> stream</p>
        <p><strong>URL de Reproducción HLS:</strong> http://TU_IP_SERVIDOR/hls/stream.m3u8</p>
    </div>

    <script src="https://vjs.zencdn.net/8.6.1/video.min.js"></script>
</body>
</html>

Reemplaza TU_IP_SERVIDOR con la dirección IP real de tu servidor.

Establecer permisos:

sudo chown -R nginx:nginx /var/www/html/player

Paso 10: Probar la Configuración de Streaming

Configurar OBS Studio (o software de transmisión similar):

  1. Descargar e instalar OBS Studio desde obsproject.com
  2. Abrir OBS Studio
  3. Ir a Configuración > Stream
  4. Seleccionar "Personalizado" como Servicio
  5. Ingresar Servidor: rtmp://TU_IP_SERVIDOR/live
  6. Ingresar Clave de Stream: stream
  7. Hacer clic en Aceptar

Iniciar Streaming:

  1. Agregar fuentes a OBS (webcam, captura de pantalla, etc.)
  2. Hacer clic en "Iniciar Transmisión"
  3. OBS debería conectarse a tu servidor

Ver Stream:

Abrir navegador y navegar a:

http://TU_IP_SERVIDOR/player/player.html

El stream debería aparecer después de unos segundos de buffering.

Configuración

Configuración de Aplicaciones RTMP

El módulo RTMP soporta múltiples aplicaciones para diferentes propósitos.

Aplicación Básica de Streaming en Vivo:

application live {
    live on;
    record off;

    # Permitir publicación desde IPs específicas
    allow publish 192.168.1.0/24;
    allow publish 10.0.0.0/8;
    deny publish all;

    # Permitir reproducción desde cualquier lugar
    allow play all;

    # Configuración HLS
    hls on;
    hls_path /var/www/html/hls;
    hls_fragment 3;
    hls_playlist_length 60;
    hls_cleanup on;
}

Aplicación de Grabación:

application recording {
    live on;

    # Grabar todos los streams
    record all;
    record_path /var/www/html/recordings;
    record_suffix -%Y%m%d-%H%M%S.flv;
    record_unique on;
    record_max_size 1024M;
    record_max_frames 2;

    # Opcional: ejecutar comando cuando finaliza grabación
    exec_record_done ffmpeg -i $path -codec copy /var/www/html/recordings/$basename.mp4;
}

Streaming Multi-Bitrate:

application live {
    live on;

    # Crear múltiples variantes de calidad
    exec ffmpeg -i rtmp://localhost/live/$name
        -c:v libx264 -preset veryfast -tune zerolatency -b:v 5000k -maxrate 5000k -bufsize 10000k -s 1920x1080 -c:a aac -b:a 128k -f flv rtmp://localhost/hls/$name_1080p
        -c:v libx264 -preset veryfast -tune zerolatency -b:v 3000k -maxrate 3000k -bufsize 6000k -s 1280x720 -c:a aac -b:a 128k -f flv rtmp://localhost/hls/$name_720p
        -c:v libx264 -preset veryfast -tune zerolatency -b:v 1500k -maxrate 1500k -bufsize 3000k -s 854x480 -c:a aac -b:a 96k -f flv rtmp://localhost/hls/$name_480p;
}

application hls {
    live on;
    hls on;
    hls_path /var/www/html/hls;
    hls_fragment 3;
    hls_playlist_length 60;
    hls_variant _1080p BANDWIDTH=5128000;
    hls_variant _720p BANDWIDTH=3128000;
    hls_variant _480p BANDWIDTH=1596000;
}

Autenticación de Stream

Implementar autenticación de clave de stream para prevenir streaming no autorizado:

Crear script de autenticación:

sudo nano /var/www/html/auth.php
<?php
// Autenticación simple de clave de stream
$valid_keys = [
    'clave_secreta_1' => 'streamer1',
    'clave_secreta_2' => 'streamer2',
    'clave_secreta_3' => 'streamer3'
];

$stream_key = $_POST['name'] ?? '';

if (array_key_exists($stream_key, $valid_keys)) {
    http_response_code(200);
    echo "OK";
} else {
    http_response_code(403);
    echo "Forbidden";
}
?>

Instalar PHP:

sudo apt install php-fpm -y

Configurar Nginx para PHP:

Agregar al bloque server HTTP:

location /auth {
    fastcgi_pass unix:/var/run/php/php-fpm.sock;
    fastcgi_param SCRIPT_FILENAME /var/www/html/auth.php;
    include fastcgi_params;
}

Actualizar aplicación RTMP:

application secure {
    live on;
    on_publish http://localhost/auth;

    hls on;
    hls_path /var/www/html/hls;
}

Optimización de Configuración HLS

Configuración de Baja Latencia:

hls on;
hls_path /var/www/html/hls;
hls_fragment 2;           # Fragmentos más pequeños = menor latencia
hls_playlist_length 10;    # Playlist más corta = menor latencia
hls_cleanup on;
hls_nested on;             # Organizar por nombre de stream

Configuración de Alta Compatibilidad:

hls on;
hls_path /var/www/html/hls;
hls_fragment 6;            # Fragmentos más grandes = mejor compatibilidad
hls_playlist_length 60;
hls_type live;
hls_continuous on;         # No reiniciar en desconexión

Restreaming a Múltiples Plataformas

Configurar restreaming automático a Twitch, YouTube y Facebook:

application multistream {
    live on;

    # Stream a Twitch
    push rtmp://live.twitch.tv/app/TU_CLAVE_STREAM_TWITCH;

    # Stream a YouTube
    push rtmp://a.rtmp.youtube.com/live2/TU_CLAVE_STREAM_YOUTUBE;

    # Stream a Facebook
    push rtmps://live-api-s.facebook.com:443/rtmp/TU_CLAVE_STREAM_FACEBOOK;

    # HLS local
    hls on;
    hls_path /var/www/html/hls;
    hls_fragment 3;
    hls_playlist_length 60;
}

Los streamers usan esta aplicación para transmitir simultáneamente a todas las plataformas:

rtmp://TU_IP_SERVIDOR/multistream/TU_CLAVE_STREAM

Configuración DVR y Time-Shift

Habilitar funcionalidad DVR para pausar/rebobinar:

application dvr {
    live on;

    # Habilitar HLS DVR
    hls on;
    hls_path /var/www/html/hls;
    hls_fragment 6;
    hls_playlist_length 3600;  # 1 hora de DVR
    hls_type event;            # Tipo event para DVR
    hls_continuous on;
}

Configuración de Página de Estadísticas

Copiar hoja de estilos de estadísticas:

sudo wget https://raw.githubusercontent.com/arut/nginx-rtmp-module/master/stat.xsl -O /etc/nginx/stat.xsl

Acceder a estadísticas en: http://TU_IP_SERVIDOR/stat

Optimización

Optimización de Procesos Worker

Optimizar procesos worker de Nginx basados en núcleos de CPU:

# Establecer al número de núcleos de CPU
worker_processes auto;

events {
    worker_connections 4096;  # Aumentar para muchas conexiones concurrentes
    use epoll;                # Optimización específica de Linux
    multi_accept on;
}

Ajuste de Rendimiento RTMP

rtmp {
    server {
        listen 1935;
        chunk_size 4096;      # Predeterminado, puede aumentar a 8192 para mejor rendimiento
        max_connections 1000; # Limitar conexiones totales

        application live {
            live on;

            # Limitar bitrate
            max_bitrate 10000k;

            # Configuración de buffer
            buffer 5s;

            # Descartar clientes lentos
            drop_idle_publisher 10s;

            # Sincronización
            sync 10ms;
        }
    }
}

Optimización de Transcodificación FFmpeg

Aceleración por Hardware con GPU NVIDIA:

exec ffmpeg -hwaccel cuda -hwaccel_output_format cuda -i rtmp://localhost/live/$name
    -c:v h264_nvenc -preset fast -b:v 3000k -maxrate 3000k -bufsize 6000k -s 1280x720
    -c:a aac -b:a 128k -f flv rtmp://localhost/hls/$name_720p;

Optimización CPU:

exec ffmpeg -threads 4 -i rtmp://localhost/live/$name
    -c:v libx264 -preset veryfast -tune zerolatency -profile:v baseline
    -b:v 3000k -maxrate 3000k -bufsize 6000k -s 1280x720
    -c:a aac -b:a 128k -f flv rtmp://localhost/hls/$name_720p;

Optimización de Buffer de Red

Ajuste TCP a nivel de sistema:

sudo nano /etc/sysctl.conf

Agregar:

# Aumentar tamaños de buffer TCP
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864

# Optimizar manejo de conexiones
net.ipv4.tcp_max_syn_backlog = 8192
net.core.netdev_max_backlog = 5000
net.core.somaxconn = 1024

# Habilitar TCP Fast Open
net.ipv4.tcp_fastopen = 3

Aplicar cambios:

sudo sysctl -p

Optimización de Almacenamiento

Usar SSD/NVMe para fragmentos HLS:

La generación HLS involucra muchas escrituras de archivos pequeños. El almacenamiento rápido mejora significativamente el rendimiento.

Tmpfs para archivos HLS temporales (reduce I/O de disco):

sudo mkdir -p /tmp/hls
sudo mount -t tmpfs -o size=2G tmpfs /tmp/hls

Actualizar nginx.conf:

hls_path /tmp/hls;

Hacer persistente a través de reinicios agregando a /etc/fstab:

tmpfs /tmp/hls tmpfs defaults,size=2G 0 0

Balanceo de Carga de Múltiples Servidores

Para despliegues a gran escala, usar múltiples servidores de streaming:

Servidor de Origen (recibe streams):

application origin {
    live on;
    push rtmp://edge1.ejemplo.com/live;
    push rtmp://edge2.ejemplo.com/live;
}

Servidores Edge (entregan a espectadores):

application live {
    live on;
    pull rtmp://origin.ejemplo.com/origin/$name;

    hls on;
    hls_path /var/www/html/hls;
}

Usar DNS round-robin o balanceador de carga para distribuir tráfico de espectadores entre servidores edge.

Resolución de Problemas

Stream No Aparece

Verificar si Nginx está recibiendo el stream:

# Verificar estadísticas RTMP
curl http://localhost/stat

# Verificar registro de errores de nginx
sudo tail -f /var/log/nginx/error.log

# Verificar que puerto 1935 está escuchando
sudo netstat -tlnp | grep 1935

Verificar conexión OBS:

En OBS, verificar barra de estado inferior. Debería mostrar indicador "En vivo" verde con bitrate.

Verificar firewall:

# UFW
sudo ufw status

# Firewalld
sudo firewall-cmd --list-all

Asegurar que puerto 1935 esté permitido.

Verificar permisos de directorio HLS:

ls -la /var/www/html/hls

Debería ser propiedad del usuario nginx:

sudo chown -R nginx:nginx /var/www/html/hls

Problemas de Reproducción

Archivos HLS no se generan:

# Verificar si directorio HLS existe y tiene permisos de escritura
ls -la /var/www/html/hls/

# Observar creación de nuevos archivos .ts y .m3u8
watch -n 1 ls -la /var/www/html/hls/

Errores CORS en consola del navegador:

Asegurar que encabezados CORS estén configurados:

location /hls {
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods "GET, OPTIONS";
}

Alta latencia:

Reducir tamaño de fragmento HLS:

hls_fragment 2;
hls_playlist_length 10;

Problemas de buffering:

Verificar ancho de banda del espectador:

  • 480p requiere 1-2 Mbps
  • 720p requiere 3-5 Mbps
  • 1080p requiere 5-8 Mbps

Implementar streaming de bitrate adaptativo con múltiples variantes de calidad.

Alto Uso de CPU

Identificar causa:

# Verificar uso de CPU de workers nginx
top -p $(pgrep nginx | tr '\n' ',' | sed 's/,$//')

# Verificar procesos ffmpeg
ps aux | grep ffmpeg

Soluciones:

  • Reducir complejidad de transcodificación (usar presets más rápidos)
  • Limitar número de variantes de calidad
  • Usar aceleración por hardware (codificación GPU)
  • Aumentar recursos de CPU

Optimizar configuración FFmpeg:

exec ffmpeg -threads 2 -i rtmp://localhost/live/$name
    -c:v libx264 -preset ultrafast -tune zerolatency
    -c:a copy -f flv rtmp://localhost/hls/$name;

Problemas de Grabación

Grabaciones no se guardan:

# Verificar permisos de directorio de grabación
ls -la /var/www/html/recordings/

# Establecer permisos correctos
sudo chown -R nginx:nginx /var/www/html/recordings/
sudo chmod 755 /var/www/html/recordings/

Verificar espacio disponible en disco:

df -h /var/www/html/recordings/

Errores de disco lleno:

Implementar limpieza automática:

record_max_size 2048M;  # Limitar tamaño de archivo de grabación

# O usar trabajo cron para eliminar grabaciones antiguas
0 2 * * * find /var/www/html/recordings -name "*.flv" -mtime +7 -delete

Autenticación No Funciona

Verificar estado de PHP-FPM:

sudo systemctl status php-fpm

Verificar script de autenticación:

curl -X POST -d "name=clave_secreta_1" http://localhost/auth

Debería retornar "OK" para claves válidas, "Forbidden" para inválidas.

Verificar registro de errores de nginx:

sudo tail -f /var/log/nginx/error.log

Buscar errores de FastCGI o autenticación.

Caídas de Conexión

Aumentar timeouts:

rtmp {
    server {
        timeout 60s;
        ping 30s;
        ping_timeout 30s;
    }
}

Verificar estabilidad de red:

# Prueba de ping
ping -c 100 TU_IP_SERVIDOR

# Verificar pérdida de paquetes
mtr TU_IP_SERVIDOR

Aumentar tamaños de buffer:

application live {
    live on;
    buffer 10s;  # Aumentar buffer
}

Características Avanzadas

SSL/TLS para Streaming Seguro

Instalar Certbot para Let's Encrypt:

sudo apt install certbot -y

Obtener certificado:

sudo certbot certonly --standalone -d stream.ejemplo.com

Configurar HTTPS en nginx:

server {
    listen 443 ssl http2;
    server_name stream.ejemplo.com;

    ssl_certificate /etc/letsencrypt/live/stream.ejemplo.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/stream.ejemplo.com/privkey.pem;

    location /hls {
        types {
            application/vnd.apple.mpegurl m3u8;
            video/mp2t ts;
        }
        root /var/www/html;
        add_header Cache-Control no-cache;
        add_header Access-Control-Allow-Origin *;
    }
}

Reproductor de Video Personalizado con Controles

Crear reproductor avanzado con selección de calidad:

<!DOCTYPE html>
<html>
<head>
    <title>Reproductor de Stream Avanzado</title>
    <link href="https://vjs.zencdn.net/8.6.1/video-js.css" rel="stylesheet" />
    <link href="https://cdn.jsdelivr.net/npm/videojs-contrib-quality-levels@2/dist/videojs-contrib-quality-levels.css" rel="stylesheet" />
</head>
<body>
    <video id="player" class="video-js vjs-default-skin" controls width="1280" height="720">
        <source src="https://stream.ejemplo.com/hls/stream.m3u8" type="application/x-mpegURL">
    </video>

    <script src="https://vjs.zencdn.net/8.6.1/video.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/videojs-contrib-quality-levels@2/dist/videojs-contrib-quality-levels.min.js"></script>
    <script>
        var player = videojs('player', {
            liveui: true,
            controls: true,
            autoplay: true,
            preload: 'auto'
        });
    </script>
</body>
</html>

Notificaciones Webhook

Ejecutar scripts en eventos de stream:

application live {
    live on;

    # Ejecutar al iniciar stream
    on_publish http://localhost/webhook/publish;

    # Ejecutar al finalizar stream
    on_publish_done http://localhost/webhook/publish_done;

    # Ejecutar al iniciar reproducción
    on_play http://localhost/webhook/play;
}

Crear manejador webhook:

<?php
// /var/www/html/webhook/publish.php

$stream = $_POST['name'] ?? 'unknown';
$timestamp = date('Y-m-d H:i:s');

// Registrar evento
file_put_contents('/var/log/nginx/stream_events.log',
    "$timestamp - Stream iniciado: $stream\n", FILE_APPEND);

// Enviar notificación (email, Slack, Discord, etc.)
// Ejemplo: mail('[email protected]', 'Stream Iniciado', "Stream $stream está ahora en vivo");

http_response_code(200);
?>

Conclusión

Ahora tienes un servidor de streaming completamente funcional de grado profesional impulsado por Nginx-RTMP. Esta configuración proporciona capacidades de streaming de nivel empresarial con control completo sobre tu contenido, experiencia del espectador y datos.

Logros clave de esta guía:

  • Infraestructura de streaming personalizada independiente de plataformas comerciales
  • Entrega multi-formato soportando ingesta RTMP y reproducción HLS
  • Configuración lista para producción con autenticación, grabación y monitoreo
  • Rendimiento optimizado para baja latencia y alto número de espectadores concurrentes
  • Base de escalabilidad lista para expansión con balanceo de carga e integración CDN
  • Características avanzadas incluyendo streaming multi-bitrate, DVR y restreaming multiplataforma

La arquitectura modular permite mejoras incrementales. Comienza con streaming básico y agrega progresivamente características como transcodificación, autenticación, analíticas e integración de red de entrega de contenido a medida que crecen los requisitos.

Recuerda monitorear regularmente el rendimiento del servidor, implementar respaldos regulares de archivos de configuración y grabaciones, y mantener Nginx y FFmpeg actualizados para mejoras de seguridad y rendimiento. El panorama de streaming evoluciona continuamente, así que mantenerte informado sobre nuevos protocolos (como SRT y WebRTC) y técnicas de optimización asegura que tu infraestructura permanezca de vanguardia.

Ya sea alojando streams personales, construyendo una plataforma para creadores de contenido, entregando comunicaciones corporativas o creando contenido educativo, esta base Nginx-RTMP proporciona la flexibilidad y potencia necesarias para operaciones de streaming profesionales.

¡Feliz streaming!