Salta el contingut

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

mkdir -p streaming-video-NOMCOGNOM/{config,html,videos,hls}
cd streaming-video-NOMCOGNOM

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

docker-compose up -d

Verifica que el contenidor està funcionant:

docker ps
docker logs streaming-video-NOMCOGNOM

Part 2: Streaming amb OBS Studio

Pas 1: Configurar OBS Studio

  1. Obre OBS Studio
  2. Ves a ConfiguracióEmissió
  3. Configura:
  4. Servei: Personalitzat
  5. Servidor: rtmp://localhost:1935/live
  6. Clau d'emissió: stream-NOMCOGNOM (amb el teu cognom)

Pas 2: Afegir fonts

  1. Afegeix una font (webcam, captura de pantalla, fitxer de vídeo, etc.)
  2. Afegeix un element de Text amb el teu nom complet visible

Pas 3: Iniciar l'emissió

  1. Fes clic a Iniciar emissió
  2. Obre el navegador a http://localhost:8080
  3. 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:

http://localhost:8080/hls/stream-NOMCOGNOM.m3u8

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

docker exec streaming-video-NOMCOGNOM ls -lh /tmp/hls/

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

  1. docker ps mostrant el contenidor en execució amb el teu nom
  2. Pàgina web (http://localhost:8080) reproduint el stream amb el teu nom visible
  3. OBS Studio o comanda ffmpeg configurats amb la URL RTMP personalitzada
  4. Estadístiques (http://localhost:8080/stat) mostrant el stream actiu
  5. Directori HLS (ls -lh /tmp/hls/) mostrant els fitxers generats
  6. VLC reproduint el stream HLS

Fitxers a incloure

  • docker-compose.yml personalitzat
  • config/nginx.conf personalitzat
  • html/index.html personalitzat

Document PDF

Crea un document que inclogui:

  1. Portada amb el teu nom complet i data
  2. Captures de pantalla amb el teu nom visible
  3. Fitxers de configuració (YAML, Nginx, HTML)
  4. Respostes a les qüestions amb càlculs detallats
  5. Reflexió final (200-300 paraules):
  6. Dificultats trobades (latència, qualitat, configuració)
  7. Diferències entre RTMP i HLS observades
  8. Avantatges/desavantatges del streaming adaptatiu
  9. 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


Data de creació: Gener 2025 Autor: Curs M0375 - Serveis de Xarxa i Internet