Pràctica: Streaming de Vídeo amb Nginx-RTMP i Docker
Objectius
En aquesta pràctica aprendràs a:
- Configurar un servidor de streaming de vídeo amb Nginx-RTMP
- Generar streams HLS (HTTP Live Streaming) per streaming adaptatiu
- Transmetre vídeo en temps real utilitzant OBS Studio o ffmpeg
- Crear una pàgina web personalitzada per reproduir el stream
- Treballar amb diferents qualitats de vídeo (transcoding)
Durada estimada
4-5 hores
Requisits previs
- Docker i Docker Compose instal·lats
- Coneixements bàsics de vídeo i codecs
- OBS Studio instal·lat (opcional, es pot usar ffmpeg)
- Fitxer de vídeo de prova (MP4, MKV, etc.)
Introducció
RTMP (Real-Time Messaging Protocol) és un protocol desenvolupat per Adobe per streaming d'àudio i vídeo. Nginx-RTMP és un mòdul de Nginx que permet crear servidors de streaming capaços de:
- Rebre streams RTMP des d'encoders (OBS, ffmpeg, etc.)
- Transcodificar a múltiples qualitats
- Generar streams HLS per reproducció en navegadors
- Gravar streams automàticament
HLS (HTTP Live Streaming) és el protocol d'Apple que divideix el vídeo en segments petits (.ts) i usa un fitxer índex (.m3u8) per streaming adaptatiu.
Part 1: Configuració del Servidor Nginx-RTMP
Pas 1: Crear l'estructura de directoris
IMPORTANT: Substitueix NOMCOGNOM pel teu nom i cognom en minúscules sense espais (exemple: streaming-video-fbarragan).
Pas 2: Crear el fitxer nginx.conf
Crea el fitxer config/nginx.conf amb la següent configuració:
worker_processes auto;
rtmp_auto_push on;
events {}
rtmp {
server {
listen 1935;
listen [::]:1935 ipv6only=on;
application live {
live on;
record off;
# Permet connexions des de qualsevol lloc (NOMÉS per proves locals)
allow publish all;
allow play all;
# Genera HLS
hls on;
hls_path /tmp/hls;
hls_fragment 3;
hls_playlist_length 60;
# Transcoding a múltiples qualitats
exec ffmpeg -i rtmp://localhost:1935/live/$name
-c:v libx264 -c:a aac -b:v 2500k -b:a 128k -vf "scale=1920:1080" -preset veryfast -g 60 -f flv rtmp://localhost:1935/hls/$name_1080p
-c:v libx264 -c:a aac -b:v 1000k -b:a 128k -vf "scale=1280:720" -preset veryfast -g 60 -f flv rtmp://localhost:1935/hls/$name_720p
-c:v libx264 -c:a aac -b:v 500k -b:a 96k -vf "scale=854:480" -preset veryfast -g 60 -f flv rtmp://localhost:1935/hls/$name_480p;
}
application hls {
live on;
hls on;
hls_path /tmp/hls;
hls_fragment 3;
hls_playlist_length 60;
hls_nested on;
hls_variant _1080p BANDWIDTH=2628000,RESOLUTION=1920x1080;
hls_variant _720p BANDWIDTH=1128000,RESOLUTION=1280x720;
hls_variant _480p BANDWIDTH=596000,RESOLUTION=854x480;
}
}
}
http {
server {
listen 8080;
server_name streaming-NOMCOGNOM.local;
location / {
root /usr/share/nginx/html;
index index.html;
}
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /usr/share/nginx/html;
}
}
}
Personalització obligatòria:
- Substitueix NOMCOGNOM al server_name pel teu cognom
Pas 3: Crear el docker-compose.yml
version: '3.8'
services:
nginx-rtmp-NOMCOGNOM:
image: tiangolo/nginx-rtmp:latest
container_name: streaming-video-NOMCOGNOM
ports:
- "1935:1935" # Port RTMP
- "8080:8080" # Port HTTP
volumes:
- ./config/nginx.conf:/etc/nginx/nginx.conf:ro
- ./html:/usr/share/nginx/html
- ./hls:/tmp/hls
- ./videos:/videos:ro
restart: unless-stopped
networks:
- streaming-net-NOMCOGNOM
networks:
streaming-net-NOMCOGNOM:
driver: bridge
Personalització obligatòria:
- Substitueix totes les aparicions de NOMCOGNOM pel teu nom i cognom
Pas 4: Crear la pàgina web de reproducció
Crea el fitxer html/index.html:
<!DOCTYPE html>
<html lang="ca">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Streaming Vídeo - NOMCOGNOM</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;
color: #ff6b6b;
}
.video-container {
margin: 30px 0;
background: #2d2d2d;
padding: 20px;
border-radius: 10px;
}
.video-js {
width: 100%;
height: 500px;
}
.info {
background: #333;
padding: 15px;
border-radius: 5px;
margin-top: 20px;
}
.stream-url {
background: #444;
padding: 10px;
border-radius: 3px;
font-family: monospace;
overflow-x: auto;
}
</style>
</head>
<body>
<h1>🎥 Streaming de Vídeo - VOSTRENOM VOSTRECOGNOM</h1>
<div class="video-container">
<video id="live-stream" class="video-js vjs-default-skin" controls preload="auto">
<source src="http://localhost:8080/hls/stream-NOMCOGNOM.m3u8" type="application/x-mpegURL">
</video>
</div>
<div class="info">
<h2>Informació del Stream</h2>
<p><strong>Stream key:</strong> <code>stream-NOMCOGNOM</code></p>
<p><strong>URL RTMP per OBS/ffmpeg:</strong></p>
<div class="stream-url">
rtmp://localhost:1935/live/stream-NOMCOGNOM
</div>
<p><strong>URL HLS per reproduir:</strong></p>
<div class="stream-url">
http://localhost:8080/hls/stream-NOMCOGNOM.m3u8
</div>
<p><strong>Estadístiques del servidor:</strong> <a href="http://localhost:8080/stat" target="_blank">Veure estadístiques</a></p>
</div>
<script src="https://vjs.zencdn.net/8.6.1/video.min.js"></script>
<script>
var player = videojs('live-stream', {
liveui: true,
html5: {
hls: {
enableLowInitialPlaylist: true,
smoothQualityChange: true,
overrideNative: true
}
}
});
</script>
</body>
</html>
Personalització obligatòria:
- Substitueix VOSTRENOM VOSTRECOGNOM pel teu nom complet
- Substitueix totes les aparicions de NOMCOGNOM
Pas 5: Iniciar el servidor
Verifica que el contenidor està funcionant:
Part 2: Streaming amb OBS Studio
Pas 1: Configurar OBS Studio
- Obre OBS Studio
- Ves a Configuració → Emissió
- Configura:
- Servei: Personalitzat
- Servidor:
rtmp://localhost:1935/live - Clau d'emissió:
stream-NOMCOGNOM(amb el teu cognom)
Pas 2: Afegir fonts
- Afegeix una font (webcam, captura de pantalla, fitxer de vídeo, etc.)
- Afegeix un element de Text amb el teu nom complet visible
Pas 3: Iniciar l'emissió
- Fes clic a Iniciar emissió
- Obre el navegador a
http://localhost:8080 - Hauries de veure el teu stream en directe amb streaming adaptatiu (múltiples qualitats)
Part 3: Streaming amb ffmpeg (alternativa a OBS)
Si no tens OBS o vols automatitzar, usa ffmpeg:
ffmpeg -re -i /path/al/teu/video.mp4 \
-c:v libx264 -preset veryfast -b:v 3000k \
-c:a aac -b:a 128k \
-f flv rtmp://localhost:1935/live/stream-NOMCOGNOM
Opcions:
- -re: Llegeix l'entrada a velocitat nativa (temps real)
- -i: Fitxer d'entrada
- -c:v libx264: Codec de vídeo H.264
- -preset veryfast: Velocitat d'encoding
- -b:v 3000k: Bitrate de vídeo
- -f flv: Format FLV per RTMP
Part 4: Proves i Verificació
1. Verifica el stream amb VLC
Obre VLC i reprodueix la URL:
2. Consulta les estadístiques
Obre: http://localhost:8080/stat
Hauries de veure: - Nombre de clients connectats - Bitrate del stream - Durada de la connexió - Estadístiques de transcoding
3. Verifica els fitxers HLS generats
Hauries de veure fitxers .m3u8 (playlists) i .ts (segments de vídeo).
Qüestions
Qüestió 1: Formats i Protocols
Completa la següent taula comparativa:
| Característica | RTMP | HLS | DASH |
|---|---|---|---|
| Protocol transport | |||
| Latència típica | |||
| Suport en navegadors | |||
| Format segments | |||
| Streaming adaptatiu |
Qüestió 2: Càlculs de Bitrate
Calcula l'amplada de banda necessària per:
a) Transmetre un stream a 1080p@30fps amb H.264 (bitrate mitjà: 5 Mbps) a 100 espectadors simultanis.
b) Si el servidor també genera versions a 720p (2,5 Mbps) i 480p (1 Mbps), i 50 usuaris veuen a 1080p, 30 a 720p i 20 a 480p, quina és l'amplada de banda total de sortida?
c) Quin seria el tamany aproximat d'1 hora de vídeo gravat a 1080p amb els paràmetres anteriors?
Qüestió 3: Transcoding
Explica:
a) Què és el transcoding i per què és necessari en streaming?
b) Quina diferència hi ha entre transcoding "on-the-fly" (en temps real) i pregravat?
c) Per què utilitzem el preset "veryfast" a la configuració? Quins altres presets existeixen i quin impacte tenen?
Lliurament
Captures de pantalla obligatòries
- docker ps mostrant el contenidor en execució amb el teu nom
- Pàgina web (
http://localhost:8080) reproduint el stream amb el teu nom visible - OBS Studio o comanda ffmpeg configurats amb la URL RTMP personalitzada
- Estadístiques (
http://localhost:8080/stat) mostrant el stream actiu - Directori HLS (
ls -lh /tmp/hls/) mostrant els fitxers generats - VLC reproduint el stream HLS
Fitxers a incloure
docker-compose.ymlpersonalitzatconfig/nginx.confpersonalitzathtml/index.htmlpersonalitzat
Document PDF
Crea un document que inclogui:
- Portada amb el teu nom complet i data
- Captures de pantalla amb el teu nom visible
- Fitxers de configuració (YAML, Nginx, HTML)
- Respostes a les qüestions amb càlculs detallats
- Reflexió final (200-300 paraules):
- Dificultats trobades (latència, qualitat, configuració)
- Diferències entre RTMP i HLS observades
- Avantatges/desavantatges del streaming adaptatiu
- Possibles millores o optimitzacions
Criteris d'Avaluació
| Criteri | Puntuació |
|---|---|
| Servidor Nginx-RTMP funcional amb transcoding | 2,5 punts |
| Streaming RTMP correcte (OBS o ffmpeg) | 2,0 punts |
| Pàgina web personalitzada funcionant | 1,5 punts |
| HLS amb múltiples qualitats operatiu | 2,0 punts |
| Captures de pantalla completes i amb personalització | 1,0 punt |
| Respostes a qüestions correctes | 1,0 punt |
| TOTAL | 10,0 punts |
Penalitzacions: - -2,0 punts si no hi ha personalització amb el nom de l'estudiant - -1,5 punts si el transcoding no funciona (només 1 qualitat disponible) - -1,0 punt si falta el nom visible al vídeo emès
Recursos Addicionals
- Nginx-RTMP Module Documentation
- HLS Specification (RFC 8216)
- OBS Studio
- ffmpeg Documentation
- Video.js HLS Player
Data de creació: Gener 2025 Autor: Curs M0375 - Serveis de Xarxa i Internet