Le média audio sécurisé ne se lit pas sur Safari au premier clic

(Probablement depuis la mise à jour vers la version stable 2.5.0) les fichiers audio multimédias sécurisés ne se lisent pas sur Safari au premier clic. Il faut deux ou trois clics sur l’icône de lecture pour démarrer l’audio. Au cours des premiers clics, aucune requête n’est reçue par le serveur web. Ce n’est qu’au troisième clic environ que la requête est envoyée.

Cela semble être un problème lié au navigateur, car cela ne se produit que sur Safari, mais il est un peu suspect que cela ait commencé à se produire autour de la mise à jour vers la version 2.5.0.

Quelqu’un a-t-il une expérience similaire ?

Je ne sais pas si cela est lié ou non. Les téléchargements multimédias sécurisés expirent

@martin des idées ici ?

Je regarderai ça demain. Cela ressemble à un problème Safari si cela prend deux ou trois clics là-bas — je vais essayer sur mon iPhone.

Je peux confirmer que ce problème est présent pour moi sur iOS, à la fois avec Safari et Firefox. L’audio ne se lance qu’après plusieurs cycles de lecture/mise en pause. Le composant widget apparaît identique dans les deux cas (je pense que Firefox mobile n’est qu’une enveloppe autour du moteur de rendu mobile de Safari). J’ai testé cela sur iOS 13.5.1.

Il y a plusieurs problèmes audio assez récents dans le suivi des bogues WebKit, mais je ne suis pas sûr qu’ils soient pertinents : 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”.

Ce clip audio de w3schools fonctionne pour moi sur Safari iOS et Firefox : W3Schools Tryit Editor. Peut-être que le problème vient du fait que nous utilisons preload="none" ? C’est la seule différence à laquelle je puisse penser… ou bien que notre redirection 302 de l’URL sécurisée du média vers l’URL audio réelle cause un problème ?

Quelques indices qui me poussent à penser que c’est la redirection qui cause le problème :

Il semble qu’aucune requête ne soit envoyée au serveur lors des premiers clics, donc le problème doit se situer avant la redirection 302…

@martin as-tu pu trouver quelque chose concernant ce problème ?

Malheureusement non, j’ai été occupé sur d’autres projets. J’ai cela sur ma liste, et j’espère pouvoir m’y pencher plus en détail bientôt. Nous avons également brièvement discuté de problèmes similaires en interne.

Jusqu’à présent, cela a été une aventure… J’ai donc réussi à configurer le débogage à distance entre Chrome sur ma machine Ubuntu et Safari sur iOS sur mon iPhone, non sans quelques tribulations. Cependant, ce qui est agaçant, c’est que l’onglet Réseau reste vide, alors que c’est précisément le plus important dans ce contexte.

J’ai constaté que l’attribut preload="metadata" permet à l’audio de se lancer au premier clic dans Safari sur iOS, tandis que si l’attribut est défini sur preload="none", il faut enchaîner une séquence de Lecture > Pause > Lecture pour que l’audio se lance réellement.

J’ai testé cela avec la balise video et il semble qu’un problème similaire existe.

Le passage à preload="none" a été effectué en raison de votre rapport de bug ici : Secure media uploads expire. Nous nous trouvons désormais dans une sorte de zone crépusculaire agaçante : remettre preload sur metadata réintroduirait le problème mentionné ci-dessus. Nous avons récemment augmenté la durée de validité des URL signées à 5 minutes (FIX: Increase time of DOWNLOAD_URL_EXPIRES_AFTER_SECONDS to 5 minutes by martin-brennan · Pull Request #10160 · discourse/discourse · GitHub), ce qui rendra le bug initial moins problématique… mais il restera néanmoins un problème.

Je réfléchis encore à la question et je teste différentes solutions… Je ne suis pas certain que nous puissions avoir le meilleur des deux mondes ici. Ce n’est pas une expérience idéale pour les médias sécurisés d’exiger plusieurs clics pour être consultés.

Édition : J’ai réussi à faire fonctionner l’onglet Réseau de mon débogueur. Voici un exemple sur notre instance Discourse interne pour une balise audio avec preload="none" :

  1. Appuyer sur Lecture : GET /secure-media-uploads/dev/original/4X/6/1/8/618a6b19a07de18205cc9889cb604e414b30372b.mp3, qui renvoie un statut Finished.

  2. Appuyer sur Pause.

  3. Appuyer sur Lecture : GET presigned_url_here, qui renvoie un statut 206 Partial Content, et l’audio se charge correctement.

Ce qui est étrange ici, c’est que avec preload=“metadata”, nous obtenons exactement la même séquence de requêtes, mais avec un seul clic sur Lecture. On dirait que Safari récupère les métadonnées au premier clic sur Lecture, puis a besoin d’une pause suivie d’une nouvelle lecture pour lancer l’audio.

Je ne sais pas si ce phénomène se produit sur d’autres appareils, par exemple Android ? Je n’ai pas d’appareil pour tester dans ce cas.

C’est une session de débogage impressionnante !

Une question :

À quoi ressemble cette réponse ? Terminé n’est pas un code de réponse HTTP, n’est-ce pas ?

Merci !

Bonne question ! Et oui, vous avez raison : Finished n’est pas un code de statut. Je n’obtiens aucune information supplémentaire dans l’onglet Réseau ici :

La taille est de 0 octet et la durée est de 0 ms.

Cela m’a inspiré à configurer mitmproxy et à examiner de plus près ce qui se passe ici. Il semble que la première requête « Terminé » ne quitte pas l’appareil iOS / le navigateur Safari. Le proxy mitm n’enregistre rien avant que PLAY ne soit cliqué une deuxième fois.

Est-il logique d’utiliser preload="metadata" uniquement pour Safari (à la fois sur iOS et sur le bureau, je peux reproduire ce problème sur le bureau également) et preload="none" ailleurs ?

(Par ailleurs, cela ne semble pas se produire sur Android de mon côté, testé dans une PWA.)

Oui, je pense que nous devrons emprunter cette voie. Merci d’avoir testé sur Android et Safari pour ordinateur. L’attribut preload est actuellement cassé, donc je suppose que nous aurions besoin d’un code côté client pour détecter que le navigateur est Safari et remplacer l’attribut preload. Je vais faire quelques expériences là-dessus aujourd’hui.

Pour m’assurer d’avoir bien compris, le bug réapparaîtra pour l’audio lorsque Safari effectuera une segmentation du téléchargement au-delà de la limite des 5 minutes ?

Oui, mais avec ce nouveau correctif, je pense pouvoir contourner le problème en modifiant l’attribut preload uniquement lorsque le post contenant le média devient visible (par exemple, lors du défilement). Le souci est que, une fois les métadonnées récupérées depuis l’URL sécurisée du média, l’URL signée est générée et utilisée dans le lecteur, avec une expiration de 5 minutes. Ainsi, si vous ne lancez pas la lecture dans ce délai, l’URL sera expirée.

Je me demande si je peux utiliser JavaScript pour lancer puis mettre en pause le média, et si cela a un impact sur les requêtes de contenu partiel 206 envoyées par la suite, qui ne semblent pas être soumises à l’expiration de l’URL signée. Je pourrais me tromper, je dois encore faire quelques tests.

Édition : J’ai confirmé moi-même sur un appareil Android utilisant Chrome que ce problème n’existe pas là-bas.

Avec l’aval de @martinwoodward, j’ai effectué aujourd’hui plusieurs commits qui remplacent l’utilisation de preload="metadata" pour tous les éléments audio/vidéo dans tous les contextes, y compris les médias sécurisés. Cela devrait résoudre le problème décrit ici.

Notez que si l’utilisateur reste sur la page plus de 5 minutes, il ne pourra probablement plus lire l’audio ou la vidéo, car les URL sécurisées ne sont actuellement valides que pendant 5 minutes.

Désolé pour la réponse tardive — ce problème est en effet résolu maintenant :tada:

Merci @pmusaraj et @martin !