Servicio de retransmisión de fuentes de streaming en vivo

En el proyecto reciente nos enfrentamos a un problema: la dirección de reproducción proporcionada por la gateway de IPTV era demasiado alta en calidad para los dispositivos del cliente. Además, no existía una dirección con calidad estándar. Utilizaremos ffmpeg como capa de servicio de retransmisión para reducir la calidad de la fuente original.

  1. Script de inicio del serivcio
#!/bin/bash

DIRECTORIO_BASE="/var/www/hls"
DIRECTORIO_LOGS="/var/log/proxy_stream"
EJECUTABLE_FFMPEG="/opt/ffmpeg-6.1/bin/ffmpeg"

RESOLUCION="640:360"
CUADROS_POR_SEGUNDO=25
BITRATE_VIDEO="512k"
BITRATE_AUDIO="128k"

DURACION_SEGMENTO=4
MAX_SEGMENTOS=8

mkdir -p "$DIRECTORIO_BASE"
mkdir -p "$DIRECTORIO_LOGS"

# ===============================
# Listado de canales
# ===============================
CANALES=(
"canal_español|http://192.168.1.100:8080/stream/espana.m3u8"
"canal_deportes|http://192.168.1.101:8080/stream/deportes.m3u8"
)

# ===============================
# Iniciar代理 individual
# ===============================
iniciar_canal() {

NOMBRE=$1
DIRECCION_ORIGEN=$2

DIRECTORIO_SALIDA="$DIRECTORIO_BASE/$NOMBRE"
ARCHIVO_LOG="$DIRECTORIO_LOGS/$NOMBRE.log"

mkdir -p "$DIRECTORIO_SALIDA"
rm -f "$DIRECTORIO_SALIDA"/*.ts "$DIRECTORIO_SALIDA"/*.m3u8

while true
do

echo "$(date) Iniciando $NOMBRE" >> "$ARCHIVO_LOG"

"$EJECUTABLE_FFMPEG" \
-loglevel warning \
-reconnect 1 \
-reconnect_streamed 1 \
-reconnect_delay_max 3 \
-analyzeduration 15000000 \
-probesize 15000000 \
-fflags +genpts+nobuffer+fastseek \
-i "$DIRECCION_ORIGEN" \
-map 0:v -map 0:a \
-vf scale=$RESOLUCION:force_original_aspect_ratio=decrease,pad=640:360:(ow-iw)/2:(oh-ih)/2 \
-r $CUADROS_POR_SEGUNDO \
-c:v libx264 -preset veryfast -tune zerolatency -b:v $BITRATE_VIDEO -maxrate 800k -bufsize 1600k \
-c:a aac -b:a $BITRATE_AUDIO -ac 2 -ar 48000 \
-shortest \
-f hls \
-hls_time $DURACION_SEGMENTO \
-hls_list_size $MAX_SEGMENTOS \
-hls_flags delete_segments+append_list+omit_endlist \
-hls_segment_filename "$DIRECTORIO_SALIDA/stream_%05d.ts" \
"$DIRECTORIO_SALIDA/stream.m3u8" >> "$ARCHIVO_LOG" 2>&1

echo "$(date) $NOMBRE reiniciando conexión" >> "$ARCHIVO_LOG"

sleep 3

done

}

# ===============================
# Iniciar todos los canales
# ===============================

for elemento in "${CANALES[@]}"
do

NOMBRE=$(echo $elemento | cut -d'|' -f1)
DIRECCION_ORIGEN=$(echo $elemento | cut -d'|' -f2)

iniciar_canal "$NOMBRE" "$DIRECCION_ORIGEN" &

echo "Iniciando canal $NOMBRE"

done

echo ""
echo "=============================="
echo "Servicio de retransmisión iniciado"
echo "Ejemplos de direcciones de reproducción:"
echo "http://IP_DEL_SERVidor/hls/canal_español/stream.m3u8"
echo "http://IP_DEL_SERVidor/hls/canal_deportes/stream.m3u8"
echo "=============================="

Script de inicio2. Script de parada

#!/bin/bash

echo "Deteniendo servicio de retransmisión..."

# Terminar procesos del script de inicio
PIDS_SCRIPT=$(pgrep -f iniciar_canal.sh)
if [ -n "$PIDS_SCRIPT" ]; then
    echo "Procesos del script encontrados: $PIDS_SCRIPT"
    kill -9 $PIDS_SCRIPT
    sleep 2
else
    echo "No se encontraron procesos del script"
fi

# Terminar todos los procesos de FFmpeg
PIDS_FFMPEG=$(pgrep -f "ffmpeg.*stream")
if [ -n "$PIDS_FFMPEG" ]; then
    echo "Procesos ffmpeg encontrados: $PIDS_FFMPEG"
    kill -9 $PIDS_FFMPEG
    sleep 1
else
    echo "No se encontraron procesos ffmpeg"
fi

# Limpiar archivos de segmento restantes
rm -f /var/www/hls/*/*.ts

echo "Servicio de retransmisión detenido."

Script de parada3. Instalación de ffmpeg. Es un proceso straightforward que no detallaremos aquí.

  1. Configuración de nginx
server {
    listen       8080;
    server_name  _;

    # Configuración para HLS
    location /hls {
        root /var/www;

        types {
            application/vnd.apple.mpegurl  m3u8;
            video/mp2t                     ts;
        }

        add_header Cache-Control no-cache;
        add_header X-Content-Type-Options nosniff;
    }

    # Endpoint de verificación de estado
    location /status {
        return 200 "Servicio activo\n";
        add_header Content-Type text/plain;
    }
}

Configuración nginx5. Según los logs de inicio, se puede proceder a realizar pruebas de extracción de stream en el cliente VCL o cualquier reproductor compatible con HLS.

Etiquetas: FFmpeg HLS streaming Nginx iptv

Publicado el 9-2 02:23