Mídia de áudio segura não é reproduzida no Safari na primeira clique

(Provavelmente desde a atualização para a versão 2.5.0 estável) os arquivos de áudio de mídia segura não são reproduzidos no Safari ao primeiro clique. São necessários dois ou três cliques no ícone de play para iniciar o áudio. Nos primeiros cliques, nenhuma solicitação é recebida no servidor web. Apenas o terceiro clique, mais ou menos, envia a solicitação.

Parece ser um problema do navegador, já que ocorre apenas no Safari, mas é um pouco suspeito que isso tenha começado a acontecer por volta da atualização para a versão 2.5.0.

Alguém tem experiência relacionada?

Não tenho certeza se isso está relacionado ou não. Uploads de mídia segura expiram

@martin, alguma ideia aqui?

Vou dar uma olhada amanhã. Parece ser um problema do Safari se levar dois ou três cliques lá – vou testar no meu iPhone.

Posso confirmar que isso está com bugs para mim no iOS, tanto no Safari quanto no Firefox. O áudio não toca até que várias ações de tocar/pausar sejam realizadas. O componente do widget aparece igual em ambos (acho que o Firefox mobile é apenas um wrapper sobre o motor de renderização do Safari mobile). Testei isso no iOS 13.5.1.

Há vários problemas de áudio bastante recentes no rastreador de bugs do WebKit, mas não tenho certeza se algum deles é relevante: https://bugs.webkit.org/buglist.cgi?bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&field0-0-0=product&field0-0-1=component&field0-0-2=alias&field0-0-3=short_desc&field0-0-4=status_whiteboard&field0-0-5=content&no_redirect=1&order=changeddate%20DESC%2Cbug_status%2Cpriority%2Cassigned_to%2Cbug_id&query_format=advanced&type0-0-0=substring&type0-0-1=substring&type0-0-2=substring&type0-0-3=substring&type0-0-4=substring&type0-0-5=matches&value0-0-0=audio&value0-0-1=audio&value0-0-2=audio&value0-0-3=audio&value0-0-4=audio&value0-0-5="audio".

Este trecho de áudio do w3schools funciona para mim no Safari e no Firefox do iOS: W3Schools Tryit Editor. Possivelmente, o problema é que usamos preload="none"? Essa é a única diferença que consigo pensar… ou será que nosso redirecionamento 302 da URL segura de mídia para a URL real do áudio está causando algum problema?

Algumas pistas possíveis que me levam a pensar que é o redirecionamento causando o problema:

Parece que não há nenhuma requisição enviada ao servidor nos primeiros cliques, então o problema deve estar antes do 302…

@martin você conseguiu encontrar algo sobre esse problema?

Infelizmente não, tenho estado ocupado com outros projetos. Tenho isso na minha lista, no entanto, e espero começar a analisá-lo mais detalhadamente em breve. Também discutimos brevemente questões semelhantes internamente.

Até agora, isso tem sido uma aventura… Consegui configurar a depuração remota entre o Chrome no meu Ubuntu e o Safari no iOS no meu iPhone, com muitas tribulações. No entanto, de forma irritante, a aba Rede está vazia, o que é, de certa forma, a mais importante para isso.

Percebi que definir preload="metadata" faz com que o áudio seja reproduzido no primeiro clique no Safari no iOS, enquanto, se definido como preload="none", é necessária uma sequência de Reproduzir > Pausar > Reproduzir para que o áudio realmente toque.

Testei isso com video e parece que existe um problema semelhante.

A mudança para preload="none" foi feita por causa do seu relatório de bug aqui: Secure media uploads expire. Estamos agora em uma espécie de zona crepuscular irritante, pois voltar a definir preload como metadata reintroduzirá o problema mencionado acima. Recentemente, aumentamos o tempo de expiração das URLs assinadas para 5 minutos: FIX: Increase time of DOWNLOAD_URL_EXPIRES_AFTER_SECONDS to 5 minutes by martin-brennan · Pull Request #10160 · discourse/discourse · GitHub, então o bug original será menos um problema agora… mas ainda será um problema.

Ainda estou pensando sobre isso e mexendo nas coisas… Não tenho certeza se podemos ter o melhor dos dois mundos aqui. Não é uma experiência ideal para mídias seguras exigirem múltiplos cliques para serem visualizadas.

Edição: Consegui fazer a aba Rede do meu depurador funcionar. Um exemplo em nossa instância interna do Discourse para uma tag audio com preload="none":

  1. Pressione Reproduzir: GET /secure-media-uploads/dev/original/4X/6/1/8/618a6b19a07de18205cc9889cb604e414b30372b.mp3, que retorna um status de Finished.

  2. Pressione Pausar.

  3. Pressione Reproduzir: GET presigned_url_here, que retorna um status de 206 Partial Content, e o áudio carrega corretamente.

O estranho aqui é que com preload=“metadata” obtemos exatamente a mesma sequência de requisições, com apenas um clique em Reproduzir. É como se o Safari buscasse os metadados no primeiro clique em Reproduzir e, em seguida, precisasse de uma pausa e de mais um clique em Reproduzir para tocar o áudio.

Não tenho certeza se isso acontece em outros dispositivos, como Android? Não tenho um dispositivo para testar lá.

Essa sessão de depuração é impressionante!

Uma pergunta:

Como é essa resposta? Concluído não é um código de resposta HTTP, certo?

Obrigado!

Boa pergunta! E sim, você está correto: Finished não é um código de status. Não obtenho nenhuma informação adicional na aba de Rede aqui:

O tamanho é 0B e o tempo é 0ms.

Isso me inspirou a configurar o mitmproxy e dar outra olhada no que está acontecendo aqui. Parece que a primeira solicitação “Concluída” não está saindo do dispositivo iOS / navegador Safari. O proxy mitm não registra nada até que o botão PLAY seja clicado pela segunda vez.

Faria sentido usar preload="metadata" apenas para o Safari (tanto iOS quanto desktop, consigo reproduzir isso no desktop também) e preload="none" em outros lugares?

(Além disso, isso não parece estar acontecendo no Android para mim; testei em um PWA.)

Sim, acho que teremos que seguir por esse caminho. Obrigado por testar no Android e no Safari para Desktop também. O atributo preload está com problemas no momento, então acho que precisaríamos de algum código do lado do cliente para detectar que o navegador é o Safari e substituir o atributo preload. Farei alguns experimentos com isso hoje.

Para garantir que entendi corretamente, o bug voltará a ocorrer no áudio quando o Safari criar um ponto de divisão de download após a marca de 5 minutos?

Sim, mas com essa nova correção, acho que consigo contornar isso alterando o atributo preload apenas quando a postagem com a mídia entra na tela (por exemplo, ao rolar a página). O problema é que, uma vez que os metadados são buscados a partir da URL segura da mídia, a URL assinada é gerada e usada no player, expirando em 5 minutos. Portanto, se você não clicar em reproduzir dentro desses 5 minutos, a URL terá expirado.

Estou pensando se posso usar JavaScript para reproduzir e depois pausar a mídia, e se isso faz alguma diferença nas solicitações de conteúdo parcial 206 enviadas posteriormente, que parecem não estar sujeitas à expiração da URL assinada. Posso estar errado, preciso testar mais um pouco.

Edição: Confirmei em um dispositivo Android usando o Chrome que esse problema não existe lá.

Com a aprovação de @martinwoodward, fiz algumas alterações hoje que alteram o uso para preload="metadata" em todos os elementos de áudio/vídeo em todos os contextos, incluindo mídia segura. Isso deve corrigir o problema descrito aqui.

Observe que, se o usuário permanecer na página por mais de 5 minutos, provavelmente não conseguirá reproduzir o áudio ou o vídeo, pois as URLs seguras são válidas apenas por 5 minutos no momento.

Desculpe pela resposta tardia — esse problema realmente foi resolvido agora :tada:

Obrigado, @pmusaraj e @martin!