Erro de CORS em vídeo: por que acontece e como resolver
Existe um tipo específico de link quebrado que enlouquece quem o encontra pela primeira vez: o vídeo abre perfeitamente quando você cola o endereço na barra do navegador, mas se recusa a funcionar quando você o coloca no seu site. Nada de erro 404, nada de arquivo apagado — o arquivo está lá, íntegro, e mesmo assim a página exibe um retângulo preto.
Nesse cenário existem dois suspeitos, e quase todo mundo culpa o errado. Um deles é o CORS; o outro é o bloqueio de hotlink. Eles produzem o mesmo sintoma, exigem correções diferentes, e o primeiro passo é saber qual dos dois se aplica ao seu caso — porque, ao contrário do que se lê por aí, CORS não é o culpado na maioria das vezes.
A regra que quase ninguém conhece
Comecemos pelo fato que economiza horas de configuração inútil: a tag <video> não precisa de CORS para reproduzir um arquivo de outro domínio.
Requisições feitas por elementos de mídia são, por padrão, do tipo no-cors. O navegador busca o arquivo, decodifica e reproduz sem exigir nenhuma autorização especial do servidor de origem. Um <video src="https://outro-dominio.com/filme.mp4"> simplesmente funciona.
Ou seja: se o seu vídeo é um arquivo comum carregado numa tag <video> e ele não toca, acrescentar cabeçalhos de CORS provavelmente não vai resolver — o problema é outro. Configurar CORS nesse caso é o equivalente a trocar o pneu porque o carro não liga.
Então quando CORS realmente morde?
Em três situações bem definidas:
- Streams HLS reproduzidos por JavaScript. Este é o caso mais comum de verdade. Bibliotecas como a hls.js não usam o carregamento nativo do vídeo: elas baixam a playlist e os segmentos por requisições de rede comuns e os entregam ao player. Essas requisições são sujeitas a CORS, e sem autorização o stream não carrega;
- Quando você usa o atributo
crossoriginna tag. Ele ativa a checagem de CORS — que estava desligada. Colocá-lo "por precaução" é uma forma clássica de criar o problema que se queria evitar; - Quando você desenha o vídeo em um
<canvas>— para gerar miniaturas, por exemplo. Sem CORS liberado, o canvas fica "contaminado" e o navegador impede a leitura dos pixels.
Fora desses casos, desconfie do outro suspeito.
O que é CORS, em português
CORS significa Cross-Origin Resource Sharing — compartilhamento de recursos entre origens diferentes. "Origem" aqui é a combinação de protocolo, domínio e porta: https://meusite.com é uma origem, https://cdn-de-videos.com é outra.
Por padrão, o navegador impede que o código de uma origem leia livremente conteúdo de outra. É uma proteção fundamental da web: sem ela, qualquer site que você visitasse poderia ler, em segundo plano, os dados do seu banco ou do seu e-mail aproveitando que você está logado neles.
Note a palavra "código". A restrição recai sobre o que o JavaScript da página consegue ler, e não sobre o que o navegador consegue exibir — é exatamente por isso que imagens e vídeos carregados por tag funcionam entre domínios, mas um stream baixado por script não. A saída oficial é o servidor autorizar explicitamente o acesso, respondendo com um cabeçalho que diz "esta origem pode me consumir". Quando esse cabeçalho não vem, o navegador bloqueia o código que pediu — e o desenvolvedor vê um player que não carrega.
Como confirmar que é CORS
O diagnóstico é rápido e tem uma assinatura inconfundível:
- Abra a página onde o vídeo falha e pressione F12;
- Vá ao painel Console;
- Procure uma mensagem contendo
Access-Control-Allow-Origin— algo como "has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource".
Se essa mensagem aparece, o caso está encerrado: o arquivo existe e o navegador está recusando por política de origem. Um sinal complementar: na aba Rede, a requisição do vídeo aparece com status 200 — o servidor entregou —, mas o player não reproduz. Arquivo entregue, uso negado.
O outro suspeito: bloqueio de hotlink
Se o seu caso é um arquivo de vídeo comum que abre na barra de endereços e falha no site, o responsável quase sempre é este — e o mecanismo é completamente diferente:
- CORS é decidido pelo navegador. O servidor entrega o arquivo normalmente; é o navegador que, ao não ver a autorização, se recusa a entregá-lo ao código que pediu. Por isso o status aparece como 200 e mesmo assim nada funciona. Só se aplica às três situações da seção anterior;
- Bloqueio de hotlink é decidido pelo servidor. Ele inspeciona o cabeçalho
Referer— que informa de qual página o pedido partiu — e recusa a entrega quando a origem não está na lista dele. Aqui o status costuma ser 403, e o arquivo nem chega ao navegador.
O status HTTP é o que separa os dois na prática: 403 aponta para hotlink (ou permissão), 200 com falha silenciosa aponta para CORS. A distinção importa porque muda quem precisa agir e como: com CORS, o dono do servidor acrescenta um cabeçalho de autorização; com hotlink, ele libera o seu domínio na configuração de proteção contra links externos — que costuma ser uma tela própria no painel da hospedagem ou da CDN, e não tem nada a ver com CORS.
Se o servidor é seu: como liberar
A correção é acrescentar o cabeçalho Access-Control-Allow-Origin na resposta dos arquivos de vídeo. Onde configurar depende de onde o arquivo está hospedado:
- Nginx — dentro do bloco que serve a pasta de mídia:
add_header Access-Control-Allow-Origin "https://meusite.com"; - Apache — com o módulo
mod_headersativo, no.htaccess:Header set Access-Control-Allow-Origin "https://meusite.com" - Amazon S3 — na aba Permissões do bucket, editando a configuração de CORS e listando as origens permitidas em
AllowedOrigins; - Cloudflare, Bunny e outras CDNs — há uma opção de CORS na configuração da zona ou do pull zone; lembre-se de limpar o cache depois, ou a resposta antiga sem o cabeçalho continuará sendo servida.
Uma palavra sobre o valor curinga *, que libera qualquer origem. Ele funciona e é apropriado para conteúdo genuinamente público — vídeos institucionais, material de divulgação. Não use em conteúdo restrito: liberar para todos significa que qualquer site pode embutir o seu vídeo consumindo a sua banda. Para conteúdo pago ou privado, liste as origens explicitamente.
Se o servidor não é seu: o que dá para fazer
Quando o vídeo está hospedado por terceiros que bloqueiam o uso externo, as opções honestas são poucas — e é bom saber disso antes de perder um dia:
- Hospede uma cópia, se você tem direito sobre o conteúdo. É a solução mais estável;
- Use o player oficial da plataforma. YouTube e Vimeo bloqueiam o arquivo bruto, mas oferecem o
<iframe>de incorporação justamente para esse uso, e ele funciona sem esbarrar em CORS; - Peça a liberação a quem administra o servidor, informando o domínio exato que precisa ser autorizado;
- Um proxy no seu servidor resolve tecnicamente, mas pense duas vezes: você passa a pagar a banda de todo o tráfego e, dependendo do conteúdo, contorna uma restrição que existia por um motivo legítimo.
O que não funciona: mexer no navegador. Extensões e a flag --disable-web-security desligam a checagem apenas na sua máquina. O vídeo passará a funcionar para você e continuará quebrado para todos os visitantes — o pior cenário possível, porque some o sintoma sem resolver o problema.
Como evitar a surpresa
Teste o link antes de construir a página em volta dele. Colar o endereço no Testador de Vídeo reproduz o cenário de origem cruzada exatamente como o seu site faria: se o vídeo toca ali, ele tocará no seu site; se falha ali mas abre na barra de endereços, você tem um caso de CORS ou hotlink nas mãos — e descobriu isso em dez segundos, e não depois da entrega. Para as demais causas de falha, o guia das 8 causas mais comuns completa o quadro.