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.
- 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í.
- 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.