Detectar automaticamente ou rejeitar uploads de vídeo VP9 incompatíveis com o iOS Safari

Recentemente descobri que vários vídeos em meu fórum Discourse auto-hospedado estavam falhando silenciosamente ao serem reproduzidos no iPhone e iPad. Após investigação, a causa raiz foi que os vídeos haviam sido codificados com o codec VP9 dentro de um container MP4 — uma combinação que o iOS Safari não consegue reproduzir.

Como isso acontece

O Facebook (e possivelmente outras plataformas) às vezes entrega vídeos codificados em VP9 quando os usuários baixam seu conteúdo. Quando esses arquivos são carregados no Discourse, são aceitos sem problemas — a extensão .mp4 não indica qual codec está dentro. Em navegadores de desktop e no Android, os vídeos reproduzem normalmente, então o problema passa despercebido. No iOS Safari, o vídeo mostra uma miniatura e um botão de play, mas ao tocar nele, aparece apenas um indicador girando. Os usuários geralmente assumem que se trata de um problema de rede e seguem em frente sem relatar.

Por que é difícil detectar

  • A extensão do arquivo (.mp4) é idêntica à de um arquivo H.264 funcional
  • Navegadores de desktop suportam VP9, então administradores que testam em desktop não veem nenhum problema
  • Usuários de iOS muitas vezes não relatam falhas individuais de mídia, especialmente quando outros conteúdos no mesmo post estão visíveis e reproduzíveis
  • Não há nenhum aviso ou erro visível para o administrador

Solução sugerida

Ao fazer o upload de vídeo, o Discourse poderia inspecionar o codec do vídeo (o ffprobe já está disponível no container Docker) e:

  1. Rejeitar o upload com uma mensagem clara explicando que o VP9 não é suportado no iOS, pedindo que o usuário re-codifique para H.264, ou
  2. Transcodificar automaticamente o vídeo para H.264 no momento do upload (semelhante ao que algumas plataformas fazem para normalizar uploads)

A Opção 1 é menos complexa e já representaria uma melhoria significativa. A Opção 2 seria ideal para uma experiência de usuário totalmente fluida.

Ambiente

  • Discourse auto-hospedado em Docker, armazenamento local (sem S3)
  • Versão do Discourse: 2026.4.0-latest
  • Proxy reverso Apache na frente do nginx do Discourse

Solução alternativa

Para administradores que encontrarem esse problema, a correção envolve:

  1. Identificar arquivos VP9 com ffprobe
  2. Re-codificar para H.264 com ffmpeg -c:v libx264 -profile:v main -level 3.1 -r 30 -movflags +faststart
  3. Atualizar os campos sha1, url e filesize na tabela uploads
  4. Atualizar os tokens de URL curta upload:// no markdown bruto dos posts afetados
  5. Reassinar (rebake) os posts afetados

Este é um processo manual não trivial que a maioria dos administradores de fórum não está equipada para realizar.

1 curtida

Para a transcodificação automática, você pode conferir Discourse Video Stream :movie_camera:.

A transcodificação local automática funciona, mas entregar isso de forma segura para a maioria das configurações é o principal problema.

2 curtidas

Obrigado pela dica sobre o plugin Video Stream, @Falco. Para um fórum de entusiastas pequeno como o meu, adicionar uma dependência de um serviço de terceiros pago parece mais do que o problema exige — embora eu possa entender o apelo para sites com alto tráfego e uso intensivo de vídeo.

Sua observação sobre a transcodificação local é interessante. Durante o processo de correção, executei manualmente o ffmpeg nos 9 arquivos afetados no meu VPS, e o servidor lidou com isso sem problemas. Entendo a preocupação em fazer isso de forma síncrona durante o upload — picos de CPU, timeouts e pressão no disco são riscos reais. Mas uma abordagem com trabalho assíncrono em segundo plano resolveria a maioria dessas preocupações? O upload seria concluído normalmente, e a transcodificação ocorreria em uma tarefa enfileirada logo em seguida — semelhante ao modo como o Discourse já lida com a geração de miniaturas de imagens. O vídeo simplesmente não seria reproduzível no iOS até que a tarefa fosse concluída, o que parece ser uma troca aceitável.

Mesmo sem uma transcodificação completa, uma opção mais leve — detectar o codec VP9 no momento do upload e, nesse caso, rejeitá-lo com uma mensagem de erro clara ou marcá-lo no painel de administração — ajudaria muito administradores de hospedagem própria que podem não ter o conhecimento técnico para diagnosticar falhas silenciosas de reprodução no iOS.

1 curtida

Vídeo é um pouco mais complicado, pois existem tantas maneiras pelas quais um usuário poderia fazer upload malicioso de algo para monopolizar a CPU, especialmente nas muitas instâncias auto-hospedadas com 1 vCPU.

Posso tentar explorar um plugin aqui, para que se torne uma opção que o administrador só acessará se estiver confortável com as compensações.

3 curtidas