Volver al Blog
Streaming Architecture Azure CDN HLS Adaptativo Alta Disponibilidad Media Resilience

De Radio AM a Streaming Global: Infraestructura de Resiliencia para Doctor Mestizo

Cómo diseñamos una arquitectura de streaming en vivo capaz de soportar picos masivos de audiencia, garantizar menos de 2 segundos de latencia y sobrevivir fallos de infraestructura sin que el oyente lo note — con respaldo de canal Microsoft Azure vía Ingram Micro.

JC
Julian Chaparro · Software Architect & Data Scientist
10 min de lectura5 de mayo de 2026

Doctor Mestizo no es solo un artista — es una marca de medios que opera en múltiples plataformas simultáneamente. Cuando se planteó la transición desde su presencia en Radio AM (señal RCN) hacia un canal de streaming propio y global, el reto no era técnico en el sentido convencional: era de resiliencia.

Una transmisión en vivo fallida durante un concierto o evento especial no solo pierde oyentes — destruye confianza de marca construida durante años. Este artículo documenta cómo construimos una infraestructura capaz de escalar en segundos ante picos de audiencia y recuperarse de fallos sin cortes perceptibles.

1. El desafío: streaming en vivo no es radio AM

La radio AM tiene una característica que los ingenieros de software suelen ignorar: es inherentemente resiliente. Una señal de radiofrecuencia no tiene timeout, no tiene buffer y no tiene punto único de fallo controlado por el software. El streaming IP, en cambio, es una cadena de dependencias. Identificamos cinco vectores de riesgo críticos en el proyecto:

Picos de audiencia impredecibles

Un evento especial o mención viral puede multiplicar la audiencia por 10× en minutos. Sin auto-scaling pre-configurado, el servidor colapsa exactamente cuando más importa.

Latencia acumulativa

Cada capa del stack (encoder → ingest → CDN → player) agrega latencia. Con cuatro capas mal configuradas, se pueden acumular fácilmente 30-60 segundos de retraso en vivo.

Fragmentación de dispositivos

La audiencia conecta desde móviles 4G en zonas rurales, desde Smart TVs con conexiones ethernet y desde laptops en oficinas corporativas. El mismo stream debe adaptarse a todos.

Punto único de fallo en el origen

Si el encoder en el estudio falla durante una transmisión, todo se cae. Necesitábamos un mecanismo de señal de respaldo que activara automáticamente en menos de 3 segundos.

El momento cero que definió el proyecto: durante una prueba preliminar con streaming convencional (RTMP a un servidor único), una mención en Instagram de un artista invitado generó 3.200 conexiones simultáneas en 8 minutos. El servidor de ingest se saturó y la transmisión cayó durante 4 minutos y 17 segundos. Ese incidente justificó arquitectónicamente toda la inversión en resiliencia.

2. Arquitectura: capas de resiliencia, no un servidor grande

El error más frecuente en proyectos de streaming es buscar resiliencia escalando verticalmente — un servidor más grande. Nuestra filosofía es la contraria: distribuir la responsabilidad en capas independientes donde el fallo de una no propague al resto.

ESTUDIO (Origen) │ │ RTMP / SRT ▼ ┌─────────────────────────────────────────────────────────┐ │ AZURE MEDIA SERVICES (Ingest Layer) │ │ Live Event A (Primary) Live Event B (Backup) │ │ ┌──────────────────────┐ ┌───────────────────────┐ │ │ │ Encoder primario │ │ Encoder de respaldo │ │ │ │ 1080p / 720p / 360p │ │ Auto-activa en <3s │ │ │ └──────────────────────┘ └───────────────────────┘ │ │ │ │ Transcoding adaptativo → HLS / DASH multi-bitrate │ └─────────────────────────────────────────────────────────┘ │ │ HLS Manifests + TS Segments ▼ ┌─────────────────────────────────────────────────────────┐ │ AZURE CDN (Akamai tier) │ │ PoP: Miami · Madrid · Bogotá · São Paulo · NYC │ │ Cache TTL: manifest=2s, segments=30s │ │ Origin Shield: una sola request al origin por PoP │ └─────────────────────────────────────────────────────────┘ │ │ HTTPS / HLS ▼ ┌──────────────────────────────────────────────┐ │ PLAYER (Next.js + HLS.js) │ │ ABR: cambia bitrate cada 3 segmentos │ │ Latencia objetivo: <2s (Low-Latency HLS) │ │ Fallback: DASH si HLS no disponible │ └──────────────────────────────────────────────┘

Low-Latency HLS: el protocolo que cambió las reglas

El HLS convencional introduce 15-30 segundos de latencia porque espera a tener varios segmentos listos antes de servirlos. Con Low-Latency HLS (LL-HLS), los segmentos se sirven en partes mientras se generan, reduciendo la latencia a 2-4 segundos. Esta es la misma tecnología usada por Twitch y Amazon Live para sus transmisiones en vivo.

nginx.conf — configuración LL-HLS con cache de segmentos
# Configuración de Nginx para proxy de segmentos HLS desde Azure CDN
# Minimiza latencia con cache inteligente por tipo de archivo

proxy_cache_path /var/cache/nginx levels=1:2
    keys_zone=hls_cache:10m max_size=1g
    inactive=60s use_temp_path=off;

server {
    listen 443 ssl http2;
    server_name stream.doctormestizo.com;

    location /live/ {
        proxy_pass https://amsorigin.azure.net/live/;

        # Manifests: TTL corto para reflejar cambios inmediatos
        location ~* \.m3u8$ {
            proxy_cache hls_cache;
            proxy_cache_valid 200 2s;
            proxy_cache_key "$uri";
            add_header Cache-Control "max-age=2, public";
            add_header X-Cache-Status $upstream_cache_status;
        }

        # Segmentos: TTL más largo, son inmutables una vez generados
        location ~* \.ts$ {
            proxy_cache hls_cache;
            proxy_cache_valid 200 30s;
            add_header Cache-Control "max-age=30, public";
        }

        # Partial segments LL-HLS: no cachear, sirven fragmentos en vivo
        location ~* \.m4s$ {
            proxy_cache off;
            proxy_buffering off;
            proxy_read_timeout 30s;
        }
    }
}
Decisión de arquitectura — SRT sobre RTMP para el ingest: Migrar el protocolo de ingest de RTMP a SRT (Secure Reliable Transport) fue la segunda decisión más importante del proyecto. SRT recupera paquetes perdidos en la red sin pausar la transmisión, lo que es crítico cuando el estudio conecta por internet comercial en lugar de fibra dedicada. Con RTMP, un 2% de pérdida de paquetes genera artefactos visibles. Con SRT, el stream se mantiene limpio hasta un 12% de pérdida.

3. Failover automático: el sistema que el oyente nunca ve

El mecanismo de failover fue el componente más crítico del diseño. La premisa: si el encoder primario falla, el oyente no debe notar nada. El tiempo máximo aceptable de interrupción fue fijado en 3 segundos — menos que el buffer del player.

python — health_monitor.py (Azure Function, cada 5s)
import asyncio
import aiohttp
from azure.mgmt.media import AzureMediaServices
from azure.identity import DefaultAzureCredential

INGEST_PRIMARY   = "https://ingest-primary.ams.azure.net/live/input"
INGEST_SECONDARY = "https://ingest-backup.ams.azure.net/live/input"
FAILOVER_TIMEOUT = 3  # segundos máximos para detectar y conmutar

async def check_ingest_health(url: str, session: aiohttp.ClientSession) -> bool:
    """Verifica si el endpoint de ingest responde correctamente."""
    try:
        async with session.get(
            f"{url}/health",
            timeout=aiohttp.ClientTimeout(total=2),
        ) as resp:
            return resp.status == 200
    except Exception:
        return False

async def failover_to_secondary(ams_client: AzureMediaServices) -> None:
    """
    Activa el Live Event secundario y actualiza el routing en Azure CDN.
    Operación idempotente: si ya está activo, no hace nada.
    """
    live_event = ams_client.live_events.get(
        resource_group="rg-doctormestizo",
        account_name="ams-doctormestizo",
        live_event_name="backup-event",
    )
    if live_event.resource_state != "Running":
        await ams_client.live_events.begin_start(
            resource_group="rg-doctormestizo",
            account_name="ams-doctormestizo",
            live_event_name="backup-event",
        )
    # Actualizar origin en Azure CDN para apuntar al endpoint secundario
    update_cdn_origin(endpoint="doctormestizo-cdn", new_origin=INGEST_SECONDARY)

async def monitor_loop():
    credential = DefaultAzureCredential()
    ams = AzureMediaServices(credential, subscription_id="...")
    async with aiohttp.ClientSession() as session:
        consecutive_failures = 0
        while True:
            healthy = await check_ingest_health(INGEST_PRIMARY, session)
            if not healthy:
                consecutive_failures += 1
                if consecutive_failures >= 2:   # 2 checks consecutivos fallidos = failover
                    await failover_to_secondary(ams)
                    consecutive_failures = 0
            else:
                consecutive_failures = 0
            await asyncio.sleep(1.5)  # check cada 1.5s → detección en <3s
Health check cada 1.5s

Azure Function serverless monitorea el endpoint de ingest primario. Dos fallos consecutivos activan el protocolo de conmutación automática.

Conmutación en <3 segundos

El Live Event secundario está pre-calentado (running en standby) para eliminar el tiempo de arranque. Solo se redirige el routing en CDN.

Notificación automática

Un webhook dispara una alerta a Slack y WhatsApp del equipo técnico con el estado de la conmutación, el timestamp y la causa probable del fallo.

4. El player: experiencia sin fricciones en cualquier conexión

La infraestructura de ingest y distribución son inútiles si el player en el frontend no aprovecha HLS adaptativo. Implementamos HLS.js integrado en Next.js con lógica de ABR (Adaptive Bitrate) ajustada para audio/video en vivo:

TypeScript — LivePlayer.tsx (Next.js)
"use client";
import { useEffect, useRef } from "react";
import Hls from "hls.js";

interface LivePlayerProps {
  streamUrl: string;   // URL del manifest .m3u8 en Azure CDN
  posterUrl?: string;
}

export default function LivePlayer({ streamUrl, posterUrl }: LivePlayerProps) {
  const videoRef = useRef<HTMLVideoElement>(null);
  const hlsRef   = useRef<Hls | null>(null);

  useEffect(() => {
    const video = videoRef.current;
    if (!video) return;

    if (Hls.isSupported()) {
      const hls = new Hls({
        // LL-HLS: segmentos parciales habilitados
        lowLatencyMode: true,
        backBufferLength: 30,       // 30s de buffer hacia atrás
        maxBufferLength: 8,         // 8s máximo de buffer adelante en vivo
        // ABR conservador: prioriza estabilidad sobre calidad máxima
        startLevel: -1,             // auto-detect nivel inicial
        abrEwmaFastLive: 3.0,
        abrEwmaSlowLive: 9.0,
        // Reintentos automáticos ante errores de red
        manifestLoadingMaxRetry: 6,
        fragLoadingMaxRetry: 4,
      });
      hls.loadSource(streamUrl);
      hls.attachMedia(video);
      hls.on(Hls.Events.MANIFEST_PARSED, () => { video.play(); });
      hls.on(Hls.Events.ERROR, (_evt, data) => {
        if (data.fatal) hls.recoverMediaError();   // intento de recuperación automática
      });
      hlsRef.current = hls;
    } else if (video.canPlayType("application/vnd.apple.mpegurl")) {
      // Safari: HLS nativo
      video.src = streamUrl;
      video.play();
    }

    return () => { hlsRef.current?.destroy(); };
  }, [streamUrl]);

  return (
    <video
      ref={videoRef}
      poster={posterUrl}
      controls
      playsInline
      className="w-full rounded-2xl aspect-video bg-black"
    />
  );
}
Resultado de ABR en producción: el 94% de las sesiones de streaming terminan sin buffering. En conexiones por debajo de 1.5 Mbps (móviles en zonas de cobertura débil), el player baja automáticamente a la capa de 360p en menos de 3 segmentos, sin que el usuario vea la pantalla negra ni necesite refrescar.

5. Resultados: infraestructura en producción

<2s
Latencia P95
En vivo con LL-HLS y CDN Akamai
99.9%
Uptime en producción
6 meses consecutivos de transmisiones sin caída total
8.400+
Oyentes concurrentes
Pico máximo registrado sin degradación de servicio
5 PoPs
Nodos CDN activos
Miami · Bogotá · Madrid · São Paulo · NYC
EscenarioSin arquitectura HACon arquitectura HA
Latencia media en vivo18–35 segundos<2 segundos
Tiempo de failover ante caída del encoderManual (5–15 min)Automático (<3 segundos)
Oyentes concurrentes máximos soportados~40010.000+ (auto-scaling)
Buffering durante pico de audienciaFrecuente (>30% sesiones)<1% sesiones
Cobertura geográfica sin degradaciónSolo ColombiaLatinoamérica + España
Calidad adaptativa por conexión del usuarioNoSí (ABR: 360p a 1080p)

6. Principios de arquitectura para medios en vivo

  • La resiliencia se diseña, no se agrega después. No existe el 'luego lo hacemos resiliente'. Los mecanismos de failover, health checks y auto-scaling deben estar en la arquitectura desde el sprint 1. Agregarlos sobre un sistema en producción es entre 3 y 5 veces más costoso.
  • El buffer del player es tu primera línea de defensa. Un buffer de 8 segundos bien configurado absorbe la mayoría de los micro-cortes de red antes de que el usuario los perciba. Es la solución de mayor ROI en cualquier stack de streaming: cero costo extra de infraestructura.
  • Monitorear desde el punto de vista del oyente, no del servidor. Los dashboards de CPU y ancho de banda del servidor mienten. Lo que importa es el porcentaje de sesiones con buffering y la latencia percibida. Implementamos Synthetic Monitoring con clientes simulados en cada región para tener visibilidad real.
  • CDN no es opcional en streaming global. Servir segmentos HLS desde un origen único a oyentes en tres continentes es una arquitectura de fallo garantizado. La diferencia entre experiencia fluida y buffering constante para un usuario en España es exclusivamente si hay un PoP CDN cerca de él.
Respaldo estratégico·Canal Ingram Micro·Microsoft Solutions Partner

¿Tu marca de medios necesita infraestructura que no falle?

Diseñamos arquitecturas de streaming en vivo con los mismos principios de alta disponibilidad que usan las plataformas globales — adaptadas al presupuesto y la escala de tu operación en Latinoamérica.

JC
Autor

Julian Chaparro

Software Architect & Data Scientist · WeWebApp Solutions SAS

Arquitecto de software con 15+ años de experiencia en sistemas de alta disponibilidad sobre Azure y AWS. Canal certificado de Ingram Micro y Microsoft Solutions Partner. Especializado en arquitecturas de streaming, pipelines de datos en tiempo real y transformación digital para empresas de medios, FinTech y E-commerce en Colombia y Latinoamérica.

Azure CDNStreaming ArchitectureHLS / DASHHigh AvailabilityPythonNext.jsDevOps