--- title: "Servidor de streaming con Nginx RTMP y HLS en Ubuntu 24.04" description: "Monta un servidor de streaming en Ubuntu 24.04 con Nginx y el módulo RTMP: recibe emisiones de OBS con clave, sírvelas en HLS al navegador y retransmítelas." category: "Casos de Uso" language: es source: https://cubepath.com/es/docs/casos-de-uso/servidor-de-streaming-con-nginx-rtmp updated: 2026-09-25 --- # Servidor de streaming con Nginx RTMP y HLS en Ubuntu 24.04 El módulo RTMP de Nginx convierte un servidor web en un servidor de streaming: recibe la emisión de un programa como OBS Studio por el protocolo RTMP y la reparte a los espectadores, ya sea por RTMP o en formato HLS, que se reproduce en cualquier navegador. En este tutorial instalarás Nginx con el módulo RTMP en Ubuntu 24.04, protegerás la emisión con una clave, publicarás el directo en HLS con un reproductor web, y opcionalmente lo grabarás y lo retransmitirás a YouTube o Twitch. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. Para reenviar el vídeo sin transcodificar bastan 2 vCPUs y 2 GB de RAM; lo que más importa es el ancho de banda de salida. - Un usuario no root con privilegios `sudo`. - OBS Studio (u otro software compatible con RTMP) en tu ordenador para emitir. - Opcional: un dominio con un registro A apuntando a la IP del servidor, si quieres servir el directo por HTTPS. Calcula el ancho de banda: cada espectador consume aproximadamente el bitrate de la emisión. Con 3 Mbit/s y 100 espectadores simultáneos necesitas unos 300 Mbit/s de salida. ## Paso 1: Instalar Nginx y el módulo RTMP Ubuntu empaqueta el módulo RTMP como módulo dinámico de Nginx, así que no hace falta compilar nada. Instala ambos, junto con FFmpeg, que usarás para enviar una emisión de prueba: ```bash sudo apt update sudo apt install nginx libnginx-mod-rtmp ffmpeg ``` El paquete activa el módulo automáticamente. Compruébalo: ```bash ls /etc/nginx/modules-enabled/ | grep rtmp ``` ```output 50-mod-rtmp.conf ``` ## Paso 2: Crear los directorios de trabajo El módulo escribe los fragmentos HLS en disco y Nginx los sirve por HTTP. Los procesos de Nginx en Ubuntu se ejecutan como `www-data`, así que ese usuario necesita permiso de escritura: ```bash sudo mkdir -p /var/www/stream/hls sudo chown -R www-data:www-data /var/www/stream ``` ## Paso 3: Configurar el servidor RTMP La configuración RTMP no va dentro del bloque `http`, sino en un bloque `rtmp` propio en el nivel superior de la configuración. Créala en un archivo aparte: ```bash sudo nano /etc/nginx/rtmp.conf ``` ```nginx rtmp { server { listen 1935; chunk_size 4096; notify_method get; application live { live on; record off; # Comprobar la clave de emisión antes de aceptar la publicación on_publish http://127.0.0.1:8080/auth; # Los espectadores ven el directo por HLS, no por RTMP allow play 127.0.0.1; deny play all; hls on; hls_path /var/www/stream/hls; hls_fragment 3s; hls_playlist_length 60s; } } } ``` Qué hace cada directiva: - `listen 1935`: puerto estándar de RTMP. - `application live`: define la aplicación a la que se emite. La URL de emisión será `rtmp://your_server_ip/live`. - `on_publish`: antes de aceptar una emisión, Nginx hace una petición HTTP a esa URL. Si responde con un código 2xx, la emisión se acepta; si no, se rechaza. `notify_method get` hace que la petición sea GET, para poder leer sus parámetros desde Nginx. - `hls_fragment` y `hls_playlist_length`: duración de cada fragmento y del historial de la lista de reproducción. Fragmentos más cortos reducen el retraso, pero exigen más peticiones a los espectadores. Añade el archivo al final de `/etc/nginx/nginx.conf`, fuera del bloque `http`: ```bash echo 'include /etc/nginx/rtmp.conf;' | sudo tee -a /etc/nginx/nginx.conf ``` ## Paso 4: Configurar la entrega HLS y la clave de emisión Ahora configura la parte HTTP. Necesitas dos bloques `server`: uno público en el puerto 80 que sirve los fragmentos HLS y el reproductor, y otro que solo escucha en `127.0.0.1:8080` con la comprobación de la clave y la página de estadísticas, inaccesible desde fuera. Elige una clave de emisión larga y aleatoria: ```bash openssl rand -hex 16 ``` ```output 3f9c1e7a52b84d06a1c9e2f7b3d58a40 ``` Crea el sitio: ```bash sudo nano /etc/nginx/sites-available/stream ``` ```nginx server { listen 80 default_server; listen [::]:80 default_server; server_name your_domain; root /var/www/stream; index index.html; location /hls/ { types { application/vnd.apple.mpegurl m3u8; video/mp2t ts; } add_header Cache-Control no-cache; add_header Access-Control-Allow-Origin *; } } server { listen 127.0.0.1:8080; location = /auth { if ($arg_key = "your_stream_key") { return 200; } return 403; } location = /stat { rtmp_stat all; } } ``` Sustituye `your_stream_key` por la clave que generaste y `your_domain` por tu dominio (o por la IP del servidor si no tienes dominio). Con `notify_method get`, los parámetros que añada el emisor a la URL (`?key=...`) llegan a `/auth` y Nginx los lee en `$arg_key`. Desactiva el sitio por defecto, activa el nuevo y comprueba la sintaxis: ```bash sudo rm /etc/nginx/sites-enabled/default sudo ln -s /etc/nginx/sites-available/stream /etc/nginx/sites-enabled/stream sudo nginx -t ``` ```output nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful ``` Recarga Nginx y comprueba que escucha en los puertos 1935, 80 y 8080: ```bash sudo systemctl reload nginx sudo ss -tlnp | grep nginx ``` ```output LISTEN 0 511 127.0.0.1:8080 0.0.0.0:* users:(("nginx",pid=4122,fd=8),...) LISTEN 0 511 0.0.0.0:1935 0.0.0.0:* users:(("nginx",pid=4122,fd=6),...) LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=4122,fd=7),...) LISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=4122,fd=9),...) ``` ## Paso 5: Abrir los puertos en el firewall Abre el puerto RTMP para recibir emisiones y el HTTP para los espectadores. Permite SSH antes de activar UFW para no perder el acceso: ```bash sudo ufw allow OpenSSH sudo ufw allow 1935/tcp sudo ufw allow 'Nginx HTTP' sudo ufw enable ``` Si siempre emites desde la misma IP fija, puedes limitar el puerto RTMP a ella con `sudo ufw allow from your_home_ip to any port 1935 proto tcp` en lugar de abrirlo a todo el mundo. ## Paso 6: Probar con una emisión generada por FFmpeg Antes de configurar OBS, comprueba que todo funciona con una emisión de prueba generada en el propio servidor: una carta de ajuste en movimiento con un tono de audio. Sustituye `your_stream_key` por tu clave: ```bash ffmpeg -re \ -f lavfi -i testsrc2=size=1280x720:rate=30 \ -f lavfi -i sine=frequency=1000:sample_rate=48000 \ -c:v libx264 -preset veryfast -b:v 2500k -g 60 -pix_fmt yuv420p \ -c:a aac -b:a 128k \ -f flv "rtmp://127.0.0.1/live/stream?key=your_stream_key" ``` `-g 60` fuerza un fotograma clave cada 2 segundos (a 30 fps), necesario para que los fragmentos HLS se corten con regularidad. Deja el comando en marcha y, en otra terminal, comprueba que se generan los fragmentos: ```bash ls /var/www/stream/hls/ ``` ```output stream-0.ts stream-1.ts stream-2.ts stream.m3u8 ``` El nombre de los archivos es el nombre del stream (`stream`); la clave no forma parte de él y nunca aparece en la URL de los espectadores. Consulta la lista de reproducción por HTTP: ```bash curl http://127.0.0.1/hls/stream.m3u8 ``` ```output #EXTM3U #EXT-X-VERSION:3 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-TARGETDURATION:4 #EXTINF:4.000, stream-0.ts #EXTINF:4.000, stream-1.ts ``` Comprueba también que la clave funciona: repite el comando `ffmpeg` con una clave incorrecta. La conexión se rechazará y en `/var/log/nginx/error.log` verás que la notificación `on_publish` ha devuelto un error. Detén FFmpeg con `Ctrl+C`. ## Paso 7: Añadir un reproductor web Los navegadores basados en Chromium y Firefox no reproducen HLS de forma nativa, así que el reproductor usa la librería hls.js (Safari lo reproduce directamente). Crea la página: ```bash sudo nano /var/www/stream/index.html ``` ```html