Tu flujo HLS privado se carga para ti, no para tus espectadores
La página carga porque tu servidor llega a la cámara; el navegador sigue solicitando la lista de reproducción. Decide quién hace la petición y luego prueba la cadena.
Pruebas la página en tu portátil, el reproductor arranca y el ticket se cierra. El espectador del otro lado abre la misma página y obtiene un indicador de carga que nunca termina. La explicación habitual es que la VPN está en el servidor, así que la reproducción debería funcionar — pero es el navegador el componente que pide la lista de reproducción, y tiene su propia ruta de red. Una página incrustada en un servidor con acceso privado no presta ese acceso a quien la carga.
Se trata de una página ASP.NET existente que reproduce una fuente HLS como http://10.5.5.9:8080/live/stream.m3u8, que es una dirección privada ilustrativa. Funcionan dos disposiciones; una de ellas probablemente no es la que construiste.
Mito: una página que carga demuestra la ruta de los medios
El HTML de esa página viene de tu servidor web, por la ruta que tenga tu servidor web. La lista de reproducción y los segmentos vienen del origen de medios, por la ruta que tenga el componente que hace la petición. Cuando el reproductor se ejecuta en el navegador del espectador, son dos clientes distintos, dos direcciones de origen distintas y a menudo dos dominios de fallo distintos. Ver que el primero tiene éxito no dice nada sobre el segundo.
Lo que tu prueba demostró en realidad es más estrecho de lo que parecía: tu máquina llega a la vez a la página pública y al host privado de medios. La máquina del espectador nunca formó parte del experimento.
Qué pide la lista de reproducción a continuación
RFC 8216 separa las listas de reproducción de medios, que enumeran segmentos, de las listas maestras, que enumeran otras listas, y resuelve los URI relativos contra el URI de la lista que los contiene. Esa regla es la parte que la gente se salta. Descargar con éxito un archivo .m3u8 no es una prueba de reproducción, porque el archivo descargado es un índice, no los medios.
Sigue la cadena tal como lo hace el reproductor: abre la lista seleccionada, luego pide los recursos que nombra y luego sigue cualquier redirección. Una lista servida a través de un servidor web accesible todavía puede apuntar al espectador a una dirección privada inaccesible. Del mismo modo, mover una lista relativa a otra URL cambia la base contra la que se resuelven sus entradas, y por eso reescribir la primera URL visible y detenerse ahí suele producir una lista que parece válida pero no puede reproducirse.
Visualización directa: el espectador necesita la ruta
Si los espectadores deben llegar directamente al host de medios, sus dispositivos necesitan la VPN aprobada u otra ruta privada, un DNS que resuelva los nombres que realmente usaste, permiso para llegar a esos destinos y cualquier autenticación que exija el servicio de medios. Comprueba cada cosa en el dispositivo del espectador y no en el servidor. Un navegador en un teléfono con el perfil de VPN instalado pero sin conectar es un fallo frecuente y totalmente reproducible.
Esta disposición mantiene privado el origen y traslada el requisito de acceso al público. Es una decisión de política tanto como técnica, así que confirma que cada espectador previsto tiene permiso para tener esa ruta antes de diseñar en torno a ella.
Entrega desde el servidor: un único punto de entrada controlado
La alternativa es un frontend de medios autorizado que obtiene el origen por su ruta privada y republica solo los recursos que ve el espectador. Mantén la lista, los segmentos y cualquier recurso de clave coherentes con ese único punto de entrada, o el reproductor descargará una lista reescrita a través del frontend y los segmentos directamente desde una dirección a la que el espectador no puede llegar.
Restringe el origen y las rutas permitidas en ese frontend. Una URL arbitraria proporcionada por el usuario convierte un proxy útil en un descargador sin restricciones de tu red interna, que es un problema mucho peor que un flujo que no se reproduce. Incluye el origen y el prefijo de ruta en una lista de permitidos en lugar de validar la cadena a posteriori.
Para una fuente HLS existente, comprueba primero si basta con el reenvío controlado; una VPN en medio no implica que haga falta transcodificar. Luego valida la combinación real de navegador y códec, porque una respuesta accesible y un formato compatible son condiciones separadas. Mantén intactos el TLS, la autenticación y los requisitos de seguridad del navegador del origen — un reproductor incrustado no es una excepción a ellos.
Prueba la cadena, no la URL
Ejecuta las comprobaciones desde el componente que realmente hará cada petición y trata cada paso como su propio resultado:
curl -s http://10.5.5.9:8080/live/stream.m3u8
curl -s -o /dev/null -w '%{http_code}\n' http://10.5.5.9:8080/live/segment-000123.tsLuego repítelo en el navegador del propio espectador con el flujo previsto, no con un patrón de prueba de tu escritorio. La carga de la página, la carga de la lista, la obtención del segmento y un fallo de autorización son cuatro resultados distintos, y quieres haber observado los cuatro antes de darlo por arreglado. No instales un complemento de navegador antiguo porque un ejemplo viejo reprodujo así un flujo; la pieza que falta suele ser la ruta del espectador o la URL del segmento sin firmar.
Cuando la disposición sea deliberada, escríbela en una línea: quién obtiene los medios, por qué ruta y qué puede pedir el espectador. Esa frase zanja la mayoría de las discusiones futuras sobre para quién es realmente el flujo.