(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.
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.
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 :
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.
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" :
Appuyer sur Lecture : GET /secure-media-uploads/dev/original/4X/6/1/8/618a6b19a07de18205cc9889cb604e414b30372b.mp3, qui renvoie un statut Finished.
Appuyer sur Pause.
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.
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 :
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.