11525 sujets

JavaScript, DOM et API Web HTML5

Bonsoir,

Ce sujet est dans la suite de celui-ci et de celui-là dans lesquels j'explique me démener pour construire un player audio/vidéo HTML5.

Je teste encore un peu mais je suis grosso-modo arrivé à une version de base pour mon player, à un détail près : j'aimerais faire un traitement des erreurs. Ce gestionnaire d'erreurs ajoute en retour une classe "error" sur le player (pour le style), accompagné d'un attribut "inert" et d'un message d'erreur.

Le problème c'est que j'ai l'impression de me retrouver au même point que mon premier topic sur le sujet où j'avais évoqué un problème de lecture des métadonnées. J'ai simulé un fichier audio HTML5 avec un lien mort, mais mon gestionnaire d'erreur ne se déclenche qu'une fois sur 4 ou 5 chargements de page :
media.addEventListener('error', () => {
  player.setAttribute('inert', '')
  player.classList.add('error')
  if (media.error.code === 1) time.innerHTML = 'Error: ressource loading aborted'
  else if (media.error.code === 2) time.innerHTML = 'no network'
  else if (media.error.code === 3) time.innerHTML = 'resource decoding failed'
  else if (media.error.code === 4) time.innerHTML = 'Error: unsupported resource'
  else time.innerHTML = 'Error'
}, true)

Vous retrouverez le script dans son contexte complet sur cette page github.

La page de démonstration : Media Players.

Je suis un peu coincé, j'en appelle donc à votre bon vouloir Smiley confus
Modifié par Olivier C (24 Apr 2023 - 06:10)
Salut,
je ne vais pas t'aider sur ton problème, mais j'ai une autre question . Je n'arrive pas à voir où commence et finit ton tout dernier code (le html, le JavaScript). Tu mets du html au milieu du script JavaScript. C'est aussi ce que fait Dragonplayer, le lecteur que j'utilise.
Je n'ai pas réussi à reproduire ton dernier code donné sur Github.
Modérateur
Bonjour,

Olivier C a écrit :
J'ai simulé un fichier audio HTML5 avec un lien mort, mais mon gestionnaire d'erreur ne se déclenche qu'une fois sur 4 ou 5 chargements de page

Il faudrait que l'affectation au player du lien posant problème soit faite après l'exécution de la ligne media.addEventListener('error',...).

Est-ce le cas ?

Amicalement,
Bongota a écrit :
Je n'arrive pas à voir où commence et finit ton tout dernier code (le html, le JavaScript). Tu mets du html au milieu du script JavaScript. C'est aussi ce que fait Dragonplayer, le lecteur que j'utilise.

C'est normal, ce n'est pas vraiment du HTML, c'est un template, prévu comme tel par JS (note aussi l'utilisation des backquotes). Il s'agit d'un string enregistré dans une variable ("playerHTML") qui va être injectée dans le DOM, ici :
media.insertAdjacentHTML('afterend', playerHTML)

On peut même lui passer des variables (ce que je ne fais pas ici) :
const maVariable = 'Hello Bongota';
const templateString = `<div>${maVariable}</div>`;

On peut faire différemment avec - comme l'avait déjà suggéré niuxe ailleurs - des éléments de templates directement placés dans le HTML puis piloté (et hydratés) via JavaScript (je le fais par exemple pour les condition d'utilisation de mon site de démonstration). Mais alors je perdrais la souplesse de ne gérer les ressources du player qu'avec le front : ici les ressources ne sont injectées que si un éléments <audio> ou <video> avec la classe ".media" est présent.

Édit : voici un article de Rodolphe qui en parlera bien mieux que moi : Alsacreations, Les template strings en JavaScript

Et sur les templates HTML : MDN, <template>: The Content Template element

Bongota a écrit :
Je n'ai pas réussi à reproduire ton dernier code donné sur Github.

Lorsque le player sera en version 1.0**, et il est en passe de l'être, je te filerai le code de manière exploitable. J'ai encore deux/trois trucs à régler avant.

** Ce que j'appelle pompeusement "version 1.0" est une version de mon player dont les fonctionnalités sont au moins égales aux players par défaut des navigateurs (mais j'ai déjà rajouté des options supplémentaires, dépassant ainsi l'objectif de base avant même que ce dernier soit atteint).
Modifié par Olivier C (24 Apr 2023 - 16:56)
parsimonhi a écrit :
Il faudrait que l'affectation au player du lien posant problème soit faite après l'exécution de la ligne media.addEventListener('error',...).

Et oui justement. Et même, pour être plus explicite (et clair dans mon code), j'ai mis le gestionnaire d'erreur à part dans une fonction appelée en dernier :
let i = 0

for (const media of medias) {
  i++
  media.id = 'media-player' + i
  media.removeAttribute('controls')
  addPlayer(media)
  controls(media)
  error(media) // <- ici
}

Auparavant je l'avais mis en dernier dans la fonction dédiée aux contrôles (boutons et événements), ce qui revenait au même.
Modifié par Olivier C (24 Apr 2023 - 16:01)
Modérateur
Bonjour,

Je ne sais pas si tu as compris le sens de mon message.

À quel moment l'élément html audio a-t-il sa source attribué ? C'est fondamental.

Si c'est dans le html, c'est cuit. L'ajout de ton handler pour les erreurs sera forcément exécuté après l'interprétation du html par le navigateur, et ton handler ne sera sans doute jamais exécuté (ou en tout cas pas toujours) car les évènements d'erreur surviendront avant l'ajout du handler.

Il faut attribuer une source à l'élément audio via javascript, et cela après avoir ajouter les différents handlers concernant cet élément audio.

Amicalement,
Meilleure solution
@parsimonhi : waouh... t'es vraiment un as.
La source est effectivement attribuée via html, mais j'ai une idée pour contourner le problème. Je teste et je reviens.
Heureka :
const src = media.currentSrc // je lis la source présente dans le HTML.
media.src = src // je la réaffecte via JS
error(media) // on peut ainsi traiter les erreurs via un gestionnaire d'événement

Je vais rendre tout ça plus joli, mais ça fonctionne.

Chapeau bas Parsimonhi.