Você testa a página no notebook, o player inicia e o chamado é encerrado. O espectador do outro lado abre a mesma página e recebe um indicador giratório que nunca termina. A explicação habitual é que a VPN está no servidor, então a reprodução deveria funcionar — mas é o navegador o componente que pede a playlist, e ele tem o próprio caminho de rede. Uma página embutida em um servidor com acesso privado não empresta esse acesso a quem a carrega.

Trata-se de uma página ASP.NET existente que reproduz uma fonte HLS como http://10.5.5.9:8080/live/stream.m3u8, que é um endereço privado ilustrativo. Duas disposições funcionam; uma delas provavelmente não é a que você construiu.

Mito: uma página que carrega prova o caminho da mídia

O HTML dessa página vem do seu servidor web, pela rota que o seu servidor web tiver. A playlist e os segmentos vêm da origem de mídia, pela rota que o componente solicitante tiver. Quando o player roda no navegador do espectador, são dois clientes diferentes, dois endereços de origem diferentes e, muitas vezes, dois domínios de falha diferentes. Ver o primeiro dar certo não diz nada sobre o segundo.

O que seu teste realmente provou é mais estreito do que parecia: sua máquina alcança ao mesmo tempo a página pública e o host privado de mídia. A máquina do espectador nunca fez parte do experimento.

O que a playlist pede a seguir

RFC 8216 separa as playlists de mídia, que listam segmentos, das playlists mestre, que listam outras playlists, e resolve URIs relativos em relação ao URI da playlist que os contém. É justamente essa regra que as pessoas pulam. Baixar um arquivo .m3u8 com sucesso não é um teste de reprodução, porque o arquivo baixado é um índice, não a mídia.

Siga a cadeia como o player faz: abra a playlist escolhida, depois peça os recursos que ela nomeia e então siga qualquer redirecionamento. Uma playlist servida por um servidor web acessível ainda pode apontar o espectador para um endereço privado inacessível. Da mesma forma, mover uma playlist relativa para outra URL muda a base contra a qual suas entradas são resolvidas, e por isso reescrever a primeira URL visível e parar ali costuma produzir uma playlist que parece válida mas não toca.

Visualização direta: o espectador precisa do caminho

Se os espectadores devem alcançar o host de mídia diretamente, seus dispositivos precisam da VPN aprovada ou de outro caminho privado, de DNS que resolva os nomes que você realmente usou, de permissão para alcançar esses destinos e de qualquer autenticação que o serviço de mídia exija. Verifique cada um no dispositivo do espectador, não no servidor. Um navegador em um celular com o perfil de VPN instalado mas não conectado é uma falha comum e totalmente reproduzível.

Essa disposição mantém a origem privada e empurra a exigência de acesso para o público. É uma decisão de política tanto quanto técnica, então confirme que cada espectador previsto tem permissão para manter esse caminho antes de projetar em torno dele.

Entrega pelo servidor: um único ponto de entrada controlado

A alternativa é um frontend de mídia autorizado que busca a origem pelo próprio caminho privado e republica apenas os recursos voltados ao espectador. Mantenha a playlist, os segmentos e qualquer recurso de chave coerentes com esse único ponto de entrada, ou o player buscará uma playlist reescrita pelo frontend e os segmentos direto de um endereço que o espectador não consegue alcançar.

Restrinja a origem e os caminhos permitidos nesse frontend. Uma URL arbitrária fornecida pelo usuário transforma um proxy útil em um buscador sem limites da sua rede interna, o que é um problema muito pior do que um fluxo que não toca. Coloque a origem e o prefixo de caminho em uma lista de permitidos em vez de validar a string depois do fato.

Para uma fonte HLS existente, verifique primeiro se o encaminhamento controlado basta; uma VPN no meio não implica que a transcodificação seja necessária. Depois valide a combinação real de navegador e codec, porque uma resposta acessível e um formato suportado são duas condições separadas. Mantenha o TLS, a autenticação e os requisitos de segurança do navegador da origem intactos — um player embutido não é uma exceção a eles.

Teste a cadeia, não a URL

Execute as verificações a partir do componente que realmente fará cada requisição e trate cada etapa como seu próprio 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.ts

Depois repita no navegador do próprio espectador com o fluxo previsto, não com um padrão de teste da sua mesa. Carregamento da página, carregamento da playlist, obtenção do segmento e uma falha de autorização são quatro resultados distintos, e você quer ter observado os quatro antes de chamar isso de resolvido. Não instale um plugin de navegador antigo porque um exemplo velho reproduziu assim um fluxo; a peça que falta costuma ser o caminho do espectador ou a URL do segmento sem assinatura.

Quando a disposição for deliberada, escreva-a em uma linha: quem busca a mídia, por qual caminho e o que o espectador tem permissão de pedir. Essa frase resolve a maioria das discussões futuras sobre para quem o fluxo realmente é.

Artigos relacionados