11496 sujets

JavaScript, DOM et API Web HTML5

Pages :
Bonjour tout le monde,

Je suis entrain de créer un player audio HTML5 + javascript + CSS et je dois dire que je ne maitrise pas totalement Javascript.

Je cherche le moyen de lancer automatiquement l'audio suivant quand celui en cours se termine. Après moultes recherches, j'ai compris que je devais utiliser addEventListener, mais malgrès la lecture de différents cours sur le sujet, je crois que je l'utilise toujours mal.

Quelqu'un pourrait me dire ce qui ne va pas dans mon code s'il vous plait ?


Voici le code javascript
<script>
function loadSong(elt, e,idPlayer) {
if(!e) var e = window.event;
document.getElementById(idPlayer).src=elt.href;
document.getElementById(idPlayer).load();
document.getElementById(idPlayer).play();
return false;
}
 
window.onload = function() {
 
//init du player A
links = document.getElementById("playlist").getElementsByTagName("a");
for(var i = 0; i<links.length; i++) {
links[ i].onclick=function(e) { return loadSong(this, e,"player"); };
//je met un espace avant le i entre crochet sinon le code bugue dans alsacreations, mais y'a pas d'espace en vrai dans mon code
}
 
//init du player B
links = document.getElementById("playlist2").getElementsByTagName("a");
for(var i = 0; i<links.length; i++) {
links[ i].onclick=function(e) { return loadSong(this, e,"player2"); };
}
 
}
 
// Lancer l'audio suivant si l'audio en cours est fini pour le player A
document.getElementById(idPlayer).addEventListener('ended', function() { 
links = document.getElementById("playlist").getElementsByTagName("a");
for(var i = 0; i<links.length; i++) {
i=i+1;                                      
links[ i]=function(e) { return loadSong(this, e,"player"); };
 
}     }  
, false);
 
</script>



Et mon code html
<div> <audio tabindex="0" id="player" controls="controls">Votre navigateur ne reconnaît pas la balise audio HTML5</audio>
<ul id="playlist">
  <li><a href="http://monnaielibre.creationmonetaire.info/wp-content/uploads/2014/01/Monnaie_Libre_49.ogg">Monnaie Libre N°49</a></li>
  <li><a href="http://monnaielibre.creationmonetaire.info/wp-content/uploads/2014/01/Monnaie_Libre_48.ogg">Monnaie Libre N°48</a></li>
  <li><a href="http://monnaielibre.creationmonetaire.info/wp-content/uploads/2014/01/Monnaie_Libre_47.ogg">Monnaie Libre N°47</a></li>
  <li><a href="http://monnaielibre.creationmonetaire.info/wp-content/uploads/2014/01/Monnaie_Libre_46.ogg">Monnaie Libre N°46</a></li>
</ul>
</div>
 
</br></br>
 
<div> <audio tabindex="0" id="player2" controls="controls">Votre navigateur ne reconnaît pas la balise audio HTML5</audio>
<ul id="playlist2">
  <li><a href="http://monnaielibre.creationmonetaire.info/wp-content/uploads/2014/01/Monnaie_Libre_49.ogg">Monnaie Libre N°49</a></li>
  <li><a href="http://monnaielibre.creationmonetaire.info/wp-content/uploads/2014/01/Monnaie_Libre_48.ogg">Monnaie Libre N°48</a></li>
  <li><a href="http://monnaielibre.creationmonetaire.info/wp-content/uploads/2014/01/Monnaie_Libre_47.ogg">Monnaie Libre N°47</a></li>
  <li><a href="http://monnaielibre.creationmonetaire.info/wp-content/uploads/2014/01/Monnaie_Libre_46.ogg">Monnaie Libre N°46</a></li>
</ul>
</div>


Merci d'avance Smiley cligne
Modifié par babetine (08 Jun 2014 - 21:57)
Bon, j'avance dans ma réflexion, enfin je crois... Je pense que je dois ajouter mon code d'enchainement des morceaux dans celui de l'initialisation du player.

Pour l'instant c'est pas concluant, mais j'ai l'impression d'être sur la bonne voie...

Donc là je teste des trucs sur l'initialisation du player2 :


<script>
function loadSong(elt, e,idPlayer) {
if(!e) var e = window.event;
document.getElementById(idPlayer).src=elt.href;
document.getElementById(idPlayer).load();
document.getElementById(idPlayer).play();
return false;
}
 
window.onload = function() {
 
//init du player A
links = document.getElementById("playlist").getElementsByTagName("a");
for(var i = 0; i<links.length; i++) {
links[ i].onclick=function(e) { return loadSong(this, e,"player"); };
//je met un espace avant le i entre crochet sinon le code bugue dans alsacreations, mais y'a pas d'espace en vrai dans mon code
}
 
//init du player B
links = document.getElementById("playlist2").getElementsByTagName("a");
for(var i = 0; i<links.length; i++) {
links[ i].onclick=function(e) { return loadSong(this, e,"player2"); };

 // On passe à la musique suivante
document.getElementById('player2').addEventListener("ended",function() {
i = i + 1;
loadSong(this, e,"player2"); }, false);
}

}
 
</script>


Comme ça je suis toujours dans la boucle "for". L'idée c'est que quand je clique sur un morceau, il se joue (ça ça marche) et qu'ensuite, tant qu'il y a d'autres morceaux dans la playlist, le suivant se lance automatiquement (ça, ça ne marche pas encore).
Modérateur
Bonjour,

Voici un exemple avec des addEventListener (il faudra remplacer les audio00x.ogg par ceux que tu as effectivement sur ton site). Note que pour le window.onload, il est mieux d'utiliser aussi un addEventLsitener.


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
</head>
<body>
<ul id="playlist">
<li>
<audio id="audio1" controls preload>
<source src="audio001.ogg">
</audio>
</li>
<li>
<audio id="audio2" controls preload>
<source src="audio002.ogg">
</audio>
</li>
<li>
<audio id="audio3" controls preload>
<source src="audio003.ogg">
</audio>
</li>
<li>
<audio id="audio4" controls preload>
<source src="audio004.ogg">
</audio>
</li>
</ul>
<script>
function playNext()
{
	this.nextInTheList.play();
}

function playList()
{
	var audioList,k,km,nextInTheList;
	audioList=document.getElementById("playlist").getElementsByTagName("audio");
	km=audioList.length;
	for (k=0;k<km;k++)
	{
		if (k<(km-1)) nextInTheList=k+1; else nextInTheList=0;
		audioList[k].nextInTheList=audioList[nextInTheList]
		audioList[k].addEventListener("ended",playNext,false);
	}
}
window.addEventListener("load",playList,false);

</script>

EDIT: remplacement du "next" initial par "nextInTheList"

</body>
</html>

Modifié par parsimonhi (05 Jun 2014 - 19:34)
Bonjour Parcimonhi, et merci pour ta réponse.

Malheureusement cela ne fonctionne pas exactement comme je le voudrais.

Ta solution marche, mais je me retrouve avec 4 players l'un en dessous de l'autre, un par audio (en même temps normal, c'est ce que prévoit la balise <audio>, donc pas de surprise).

Toutefois j'ai essayé de l'adapter à ma forme de player avec playlist, et là ça ne marche plus.


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">

</head>
<body>

<div> 
<audio tabindex="0" id="player" preload="auto" controls="controls">
		<source src="http://monnaielibre.creationmonetaire.info/wp-content/uploads/2014/01/Monnaie_Libre_49.ogg">
	Votre navigateur ne reconnaît pas la balise audio HTML5
</audio>
<ul id="playlist">
  <li><a href="http://monnaielibre.creationmonetaire.info/wp-content/uploads/2014/01/Monnaie_Libre_49.ogg">Monnaie Libre N°49</a></li>
  <li><a href="http://monnaielibre.creationmonetaire.info/wp-content/uploads/2014/01/Monnaie_Libre_48.ogg">Monnaie Libre N°48</a></li>
  <li><a href="http://monnaielibre.creationmonetaire.info/wp-content/uploads/2014/01/Monnaie_Libre_47.ogg">Monnaie Libre N°47</a></li>
  <li><a href="http://monnaielibre.creationmonetaire.info/wp-content/uploads/2014/01/Monnaie_Libre_46.ogg">Monnaie Libre N°46</a></li>
</ul>
</div>

<script>
function playNext()
{
	this.nextInTheList.play();
}

function playList()
{
	var audioList,k,km,nextInTheList;
	audioList=document.getElementById("playlist").getElementsByTagName("a");
	km=audioList.length;
	for (k=0;k<km;k++)
	{
		if (k<(km-1)) nextInTheList=k+1; else nextInTheList=0;
		audioList[k].nextInTheList=audioList[nextInTheList]
		audioList[k].addEventListener("ended",playNext,false);
	}
}
window.addEventListener("load",playList,false);

</script>



</body>
</html>


Je vais me renseigner sur le "window.addEnventListener", Smiley cligne
Modérateur
Bonjour,

Comme je m'attendais à la question, et que j'avais prévu la réponse, je suggère de cacher les players qui ne jouent rien. C'est assez facile, il n'y a que quelques lignes à rajouter à la solution que j'avais proposé (deux lignes de style sur les balises li et deux lignes de javascript pour cacher les players qui ne jouent qui ne jouent pas et afficher celui qui joue) :


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<style>

li {display:none;}
li:first-of-type {display:block;}

</style>
</head>
<body>
<ul id="playlist">
<li>
<audio id="audio1" controls preload>
<source src="audio1.ogg">
</audio>
</li>
<li>
<audio id="audio2" controls preload>
<source src="audio2.ogg">
</audio>
</li>
<li>
<audio id="audio3" controls preload>
<source src="audio3.ogg">
</audio>
</li>
<li>
<audio id="audio4" controls preload>
<source src="audio4.ogg">
</audio>
</li>
</ul>
<script>
function playNext()
{
	this.parentNode.style.display="none";
	this.nextInTheList.parentNode.style.display="block";
	this.nextInTheList.play();
}

function playList()
{
	var audioList,k,km,nextInTheList;
	audioList=document.getElementById("playlist").getElementsByTagName("audio");
	km=audioList.length;
	for (k=0;k<km;k++)
	{
		if (k<(km-1)) nextInTheList=k+1; else nextInTheList=0;
		audioList[k].nextInTheList=audioList[nextInTheList]
		audioList[k].addEventListener("ended",playNext,false);
	}
}
window.addEventListener("load",playList,false);
</script>
</body>
</html>


Je pense que c'est mieux d'avoir plusieurs players même cachés, car quand tu passes d'un morceau à l'autre, la transition sera plus fluide, les morceaux ayant toutes les chances d'être déjà téléchargés, ce qui ne sera pas forcément le cas si tu les donnes comme paramètre au dernier moment à ton player unique.

Amicalement,
Modifié par parsimonhi (06 Jun 2014 - 21:31)
Modérateur
Bonjour,

Note que ton code ne peut pas marcher parce que l'event "ended" concerne la balise audio, et pas la balise a.

Note aussi que le format ogg n'est pas reconnu par tous les navigateurs et qu'en pratique, il faut donner plusieurs sources aux players (en .ogg, en .wav, en .mp3 ...). Si tu as construit tous tes players dès le chargement de la page, c'est facile, il suffit de rajouter autant de <source> que nécessaire (une pour chaque format) à chaque player. Si par contre, tu dois affecter une nouvelle source à ton player unique à chaque fois qu'il a fini, ce sera un poil plus compliqué.

Voilà le code qui fait marcher ton player unique (et en supposant donc que tu n'as qu'un seul format de fichier audio) :
<script>
function playNext()
{
	var audioPlayer,audioSource,audioList,k,km,kNext;
	audioPlayer=document.getElementById("player");
	audioSource=document.getElementById("source");
	audioList=document.getElementById("playlist").getElementsByTagName("a");
	k=audioPlayer.currentInTheList;
	km=audioList.length;
	if (k<(km-1)) kNext=k+1; else kNext=0;
	audioSource.src=audioList[kNext].href;
	audioPlayer.currentInTheList=kNext;
	audioPlayer.load();
	audioPlayer.play();
}

function preparePlayer()
{
	var audioPlayer;
	audioPlayer=document.getElementById("player");
	audioPlayer.addEventListener("ended",playNext,false);
	audioPlayer.currentInTheList=0;
}
window.addEventListener("load",preparePlayer,false);
</script>

EDIT : changement du nom de playList() en preparePlayer(), et suppression de déclaration de variables devenues inutiles.

Amicalement,
Modifié par parsimonhi (06 Jun 2014 - 22:45)
Ah Parcimonhi,

Je te remercie vraiment beaucoup, je vais tester tes codes et voir comment les adapter.

Je sais bien que ta solution de différents players marche, mais ce qu'il y a de bien avec une playlist, c'est de permettre à l'auditeur de cliquer sur le morceau qu'il veut. Alors s'il ne voit pas les audios de la playlist, ça me parait compliqué. C'est pour ça que je fais une playlist.

Pour ce qui est du chargement, je fais le choix de l'économie. Ne sera chargé sur le moment que l'audio que l'auditeur voudra jouer, puis le suivant.

Parce que là je présente un code plutôt simple, mais ensuite je rajoute du php parce qu'en fait mes playlists seront automatisées (et ça marche, je te rassure, je ne me base pas sur du vent, j'ai juste un problème sur l'enchainement des pistes).

Pour les formats ogg, wav ou mp3, là aussi c'est une question de choix. Jusqu'à présent je ne pouvais faire écouter que des sons au format mp3 (dans un flash player). Grace au player HTML5, je pourrais mixer avec des ogg ou des wav. Mais je n'en double aucun. Et chacun-e est responsable de son navigateur. Moi j'ai fait le choix d'en avoir un de compatible. Je ne m'adapterai pas aux navigateurs. Je pense que le HTML5 est l'avenir et les navigateurs sont d'ailleurs entrain de tous s'y adapter. Je pense que l'époque où les webmasters essayaient de s'adapter à tous les navigateurs est révolue. (en même temps je ne suis pas codeuse, donc je peux me planter). (Si tu cliques sur mon profil, tu verras mon site, tu pourras voir comment je compte utiliser le player ou les players puisque j'envisage d'en mettre deux ou 3 dans la nouvelle version du site).

Par rapport à hier, j'ai fait des recherches sur "window.addEnventListener", et pour remplacer "window.onload", j'avais choisi la technique "addLoadEvent" trouvée ici : http://www.htmlgoodies.com/beyond/javascript/article.php/3724571
Je ne sais pas laquelle des deux méthodes est la mieux, je vais faire des recherches.


EDIT : j'ai testé ta solution de player unique, et non, ou alors j'ai loupé un truc, je vais regarder à nouveau.
Je te montre quand même mon essai ici : http://blogsaudio.dmmworld.com/PLAYERhtml5/nouvelessai01.php
Bon, de mon coté j'ai avancé aussi, donc je te montre où j'en suis : http://blogsaudio.dmmworld.com/PLAYERhtml5/PLAYERclosure.html

L'enchainement marche (mais mal, lire dans le cadre du player comment c'est foutraque), avec un ou plusieurs players. Là j'en ai mis qu'un avec des audios de 5 secondes pour pas s'embrouiller davantage.

Mon html :

<div> 	
	<audio tabindex="0" id="player" controls="controls">
		<source src="PLAYERclosureAUDIOS/01.mp3">
		Votre navigateur ne reconnaît pas la balise audio HTML5
	</audio>

	<ul id="playlist">
		<li><a href="PLAYERclosureAUDIOS/01.mp3">Audio 1</a></li>
		<li><a href="PLAYERclosureAUDIOS/02.mp3">Audio 2</a></li>
		<li><a href="PLAYERclosureAUDIOS/03.mp3">Audio 3</a></li>
		<li><a href="PLAYERclosureAUDIOS/04.mp3">Audio 4</a></li>
		<li><a href="PLAYERclosureAUDIOS/05.mp3">Audio 5</a></li>
		<li><a href="PLAYERclosureAUDIOS/06.mp3">Audio 6</a></li>
		<li><a href="PLAYERclosureAUDIOS/07.mp3">Audio 7</a></li>
		<li><a href="PLAYERclosureAUDIOS/08.mp3">Audio 8</a></li>
		<li><a href="PLAYERclosureAUDIOS/09.mp3">Audio 9</a></li>
		<li><a href="PLAYERclosureAUDIOS/10.mp3">Audio 10</a></li>
	</ul>

	<ul id="signature"><br/>
		Pour l'instant ca merde au niveau de l'enchainement.<br/>Tu peux cliquer sur nimporte quel audio, il se jouera, et ensuite, a la fin du morceau, il jouera l'audio 1, puis 2 et ainsi de suite jusqu'a 10. <br/>
		Si tu cliques sur nimporte quel audio, il arrive au bout, il joue l'audio 1, puis tant que l'audio n'arrive pas a la fin, tu peux cliquer sur nimporte quels autres audios, si tu en laisses un arriver au bout, il jouera l'audio 2.<br/>
	</ul>

</div>



Mon javascript :

<script>

    function loadSong(elt, e,player) {
		if(!e) var e = window.event;
			document.getElementById(player).src=elt.href;
			document.getElementById(player).load();
			document.getElementById(player).play();
		return false;
	}

function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}

addLoadEvent(function() {
var links = document.getElementById("playlist").getElementsByTagName("a");
for(var i = 0; i<links.length; i++) {
links[ i].onclick=function(e) { return loadSong(this, e,"player"); };
//je met un espace avant le i entre crochet sinon le code bugue dans alsacreations, mais y'a pas d'espace en vrai dans mon code

// On passe à la musique suivante
document.getElementById('player').addEventListener("ended",function() {

if (i > 0) {
i = i - 1;
} 
else {
i = links.length; 
}
document.getElementById('player').src=links[ i];
document.getElementById('player').load();
document.getElementById('player').play();
}, false);		
	
}
	
})

</script>



En cherchant, cherchant et recherchant, je crois que je dois créer une closure, afin que la première valeur de i quand je clique puisse être prise en compte pour le addEventListener. Parce que pour l'instant je n'arrive pas à obtenir le i qui correspond au lien cliqué. Sauf qu'en lisant des tutos sur la closure, j'ai l'impression qu'il y en a déjà une, mais dans tous les cas je n'arrive pas à récupérer ce premier i cliqué.
Modifié par babetine (07 Jun 2014 - 10:27)
Modérateur
Bonjour,

1) A propos de ton test de mon exemple avec un player unique qui ne marche pas : il faut rajouter "id="source" à l'élément <source> du player parce que je l'utilise ensuite dans le code javascript pour y mettre le morceau suivant une fois le morceau précédent fini (mea culpa, je n'avais pas mis le code html correspondant).

2) A propos de la mise à disposition d'une playlist dans le cas où on met plusieurs audio en cachant ceux qui ne jouent pas : rien ne t'empêche de rajouter en plus, en dessous des balises audio des players, ta liste <ul> qui contient tous tes liens. Ceci étant, au lieu de liens, tu pourrais plutôt mettre des <button> avec chacun un "onclick" dont la fonction associée démarrera le player correspondant si on clique sur le bouton.

3) A propos de "addEventListener" : utilise "addEventListener" préférentiellement à tout autre méthode. "addEventListener" est désormais bien supporté partout et on n'a plus besoin de bricoler comme auparavant. Note surtout que les navigateurs qui sont capables de gérer la balise audio (qui est la clé de voute de ton projet) comprennent (tous?) "addEventListener". Du coup, les solutions de type "addLoadEvent" n'ont pas d'intérêt selon moi dans ton cas.

2) A propos des closures : c'est sûr que dès qu'on a un code un peu complexe avec gestion d'évènements, timeout, ..., on peut avoir des problèmes de visibilité de variables et de passage de paramètres. Personnellement, et même si c'est considéré (avec raison) par certains comme étant non orthodoxe, je préfèrerai ici simplifier pendant la phase de validation du concept et ajouter l'information dans l'élément HTML audio lui-même (en choisissant un nom d'attribut suffisamment exotique pour ne pas risquer d'écraser la valeur d'un attribut préexistant). C'est ce que j'ai fait dans mon dernier exemple (player unique) en rajoutant l'attribut "currentInTheList" à l'élément audio. En ajoutant éventuellement d'autres attributs, ça permet de savoir à tout moment qui joue quoi et ce qu'il faut arrêter ou démarrer dans les cas complexes où on jongle par exemple entre deux players, et où l'utilisateur peut démarrer à tout moment un autre morceau en cliquant sur l'autre player ou dans une liste de morceau à part. Mais en production, je crée en général un objet global pour l'ensemble du code. Dans cet objet, on peut stocker toutes les informations qu'on veut sous forme de propriétés de l'objet, propriétés contenant éventuellement des références à d'autres objets dans les cas complexes. Du coup, on a accès depuis n'importe quelle fonction à ces informations (toutes les fonctions du code étant elles-même des méthodes de l'objet ou d'objets référencés dans l'une des propriétés de l'objet global).

5) A propos du preload des morceaux : ok, je comprends que tu ne souhaites pas précharger tous tes morceaux dès l'affichage initiale de la page. Pour ce qui est des temps de latence entre deux morceaux quand on utilise un player pour plusieurs morceaux, tu peux éventuellement utiliser 2 players, l'un qui joue, et pendant ce temps, l'autre qui précharge le morceau suivant.

Amicalement,
Modifié par parsimonhi (07 Jun 2014 - 13:22)
Modérateur
Bonjour,

A propos des attributs ajoutés à l’élément HTML audio : j'aurais plutôt dû mettre un nom commençant par "data-" qui est prévu par la standard HTML.

Dans ton code, tu pourrais donc utiliser un "data-k" pour stocker la valeur de i proprement.

Ton code devient (en supprimant au passage cet horrible addLoadEvent()) :


<script>
function loadSong(elt, e,player)
{
	if (!e) var e = window.event;
	document.getElementById(player).src=elt.href;
	document.getElementById(player).load();
	document.getElementById(player).play();
	return false;
}

function preparePlayer()
{
	var links = document.getElementById("playlist").getElementsByTagName("a");
	for (var z = 0; z<links.length; z++)
	{
		links[z].onclick=function(e) { return loadSong(this, e,"player"); };
		// On passe a la musique suivante
		document.getElementById('player').addEventListener("ended",function() {
			var k=this.getAttribute("data-k");
			if (k > 0) k = k - 1; else k = links.length;
			this.setAttribute("data-k",k);
			document.getElementById('player').src=links[k];
			document.getElementById('player').load();
			document.getElementById('player').play();
			}, false);
		document.getElementById('player').setAttribute("data-k",0);
	}
}

window.addEventListener("load",preparePlayer,false);
</script>


EDIT (08/06/2014) : ne pas utiliser ce code en l'état. Il n'est pas complètement débogué. Il faudrait ajouter un parseInt autour du getAttribute, il faudrait soustraire 1 de links.length à la ligne if (k > 0) k = k - 1; else k = links.length;, il faudrait rajouter un .href à links[k], et il faudrait sortir le addEventListener concernant l'évènement "ended" de la boucle pour un meilleur fonctionnement.

Amicalement,
Modifié par parsimonhi (08 Jun 2014 - 09:32)
Re Parsimonhi Smiley biggrin

1) J'ai rajouté ' id="source" ' et ton exemple de player unique marche (enfin) pour l'enchainement, en boucle : http://blogsaudio.dmmworld.com/PLAYERhtml5/nouvelessai01.php MERCI Smiley lol

Du coup, si je pars sur cette méthode, je dois trouver aussi le moyen de lire les audios quand on les clique, et vérifier que l'enchainement continue de fonctionner normalement. Je cherche, je croise les doigts...


2) Très bonne idée, je la testerai si le 1) échoue Smiley cligne

3) Super, tu as l'air de maitriser le sujet, je prend note ! Des "addEventListener" avant tout !

4) Hmm Hummm ! Oui bien sûr.... (non, j'ai rien compris, je vais devoir relire ce paragraphe calmement une dizaine de fois j'avoue Smiley cligne )

5) Je garde l'idée sous le coude.

Merci Parcimonhi
Ouaou, tu es prolifiques !

Alors je récapitule :

- ta première version du player (sans onclick dans le code) : http://blogsaudio.dmmworld.com/PLAYERhtml5/nouvelessai01.php
enchainement : oki
onclick : non
boucle : oui (mais qu'elle y soit ou pas m'est égal)

- ta seconde version (avec onclick et "data-k") : http://blogsaudio.dmmworld.com/PLAYERhtml5/nouvelessai02.php
enchainement : oki
onclick : non
boucle : non (mais qu'elle y soit ou pas m'est égal)

En tout cas tu m'aides à simplifier grandement le code, et je comprend comment ça fonctionne, y'a du progrès Smiley ravi
En fait il manquait de rattacher le i à links.onclick pour la seconde version Smiley cligne

Du coup : http://blogsaudio.dmmworld.com/PLAYERhtml5/nouvelessai02.php
enchainement : oki
onclick : oki
boucle : non (mais qu'elle y soit ou pas m'est égal)

Cependant on retrouve le même problème que pour le mien : l'enchainement semble totalement indépendant des onclicks. Tu peux cliquer nimporte quel audio, ça s'enchainera par le second morceau, puis le troisième... même si tu cliques à chaque fois sur plusieurs autres audios...
Modérateur
Bonjour,

Bon, je me demande quand on va y arriver ! Smiley cligne

J'ai rajouté un addEventListener pour l'event "play" de l'élément audio afin de faire une action à chaque fois que le player commence à jouer un morceau (l'idée étant d'une part de stocker dans l'attribut "data-k" l'indice du morceau qui va être joué à ce moment là, et éventuellement d'indiquer quel morceau est en cours de lecture dans la liste des morceaux : j'ai pour l'instant juste changé la couleur du texte de gris à noir, mais ça peut être tout ce qu'on veut). En faisant ça, on sait quel morceau est joué même quand l’utilisateur clique directement dans la liste des morceaux. Le fonctionnement global devient plus robuste.

Il n'est pas bon d'utiliser dans les fonctions qui sont en paramètre des addEventListener le paramètre i qui est un indice de boucle, car celui-ci y prendra la valeur qu'il a en fin de boucle systématiquement.

J'ai aussi fait en sorte qu'on passe toujours par la fonction loadSong quelque soit la manière qu'on utilise pour faire commencer un morceau (soit en cliquant sur le player, soit quand il démarre à la suite d'un autre, soit quand on clique dans la liste des morceaux). J'ai du coup modifié un peu cette fonction pour qu'on puisse l'appeler de n'importe où.

J'ai aussi remplacé i par z pour ne plus avoir à penser à modifier les i entre crochets qui ont pour effet de mettre le texte en italique.

Voilà ce que ça donne :


function loadSong(link,playerId)
{
	var player=document.getElementById(playerId);
	player.src=link.href;
	player.load();
	player.play();
}

function preparePlayer()
{
	var links=document.getElementById("playlist").getElementsByTagName("a");
	var player=document.getElementById('player');
	var z;
	for (z=0;z<links.length;z++)
		links[z].onclick=function(e) {loadSong(this,"player");return false;};
	player.addEventListener("play",function() {
		var k,km=links.length;
		for (k=0;k<km;k++)
		{
			if (this.src==links[k].href)
			{
				this.setAttribute("data-k",k);
				links[k].style.color="black";
			}
			else links[k].style.color="grey";
		}
	},false);
	player.addEventListener("ended",function() {
		var k=parseInt(this.getAttribute("data-k"));
		if (k<(links.length-1)) k++;else k=0;
		loadSong(links[k],"player");
	},false);
}

window.addEventListener("load",preparePlayer,false);


EDIT (08/06/2014) : correction d'une grosse étourderie dans le code de preparePlayer(), mais qui n'avait cependant aucune conséquence sur le résultat (j'avais initialement laissé trainer les player.addEventListener() dans la boucle for (z=0;z<links.length;z++) ... ce qui n'avait pas de sens).

Amicalement,
Modifié par parsimonhi (08 Jun 2014 - 00:30)
Ouaou, vraiment très impressionée je suis !

Ta dernière version se trouve ici, oui sur ce lien cliquable. Comme rajouté dans le cadre gris, tout fonctionne SAUF l'enchainement du fichier source quand on clique directement sur le bouton "play" avec le morceau suivant, alias le second morceau.

J'ai rajouté un tout petit peu de code (la variable audioSource), et j'arrive à faire l'enchainement nickel du bouton "play" avec le morceau suivant, MAIS dans une première version (oui clique) le premier morceau reste tout le temps en noir même quand il n'est pas joué, et dans une deuxième version (oui oui, clique aussi) le premier morceau reste tout le temps en gris même quand il est joué Smiley lol

Je cherche donc une troisième version ou ce premier morceau se comporterait comme les autres Smiley ravi


(PS : t'as quel âge ? C'est ton métier ? Parce que là, sans ton aide, j'étais à mille lieux de trouver la solution...)

MERCI et à très vite pour la dernière version, je fais des essais là...

EDIT : Yeahhhhhhhhhhh ! Tout fonctionne à merveille.

Tu peux appercevoir le résultat en cliquant ici.

MERCI Parcimonhi Smiley biggrin
Modifié par babetine (08 Jun 2014 - 09:44)
Ah ben non, pas encore, pffff lollll Smiley lol

Problème : si on clique directement sur les audios de la playlist, celui cliqué et celui d'avant sont en rouge Smiley biggol
Modérateur
Bonjour,

Ton problème pour le premier morceau semble dû au fait que dans le HTML, tu mets ton source audio dans une balise <source>. Si tu mets directement le source audio comme valeur de l'attribut src de la balise audio, je pense que mon code marchait en l'état même pour le premier morceau.


<audio tabindex="0" id="player" preload="auto" controls="controls" src="PLAYERclosureAUDIOS/01.mp3">


Si tu mets le source comme valeur de l'attribut src de la balise <source> (ce qui est sans doute mieux d'ailleurs), dans ce cas, il faut modifier le code javascript en faisant référence à l'endroit où est ce source : partout où on a un player.src ou this.src, on peut mettre respectivement un player.getElementsByTagName("source")[0].src ou this.getElementsByTagName("source")[0].src (si tu mets un id="source" à <source> comme c'est le cas dans ton exemple, tu peux aussi utiliser document.getElementById("source").src).

La modification que tu as faites revient à ça, mais pour le premier morceau seulement.

Amicalement,

PS: concernant mon âge et ma profession, disons que je suis un vieux geek qui a fait beaucoup d'informatique, mais qui fait complètement autre chose actuellement.
Modérateur
Bonjour,

Si tu souhaites mettre en rouge le premier morceau choisi par l'internaute (que ce soit en cliquant sur le bouton play du lecteur audio, ou en cliquant sur un morceau de la liste), en noir le morceau en cours de lecture (si ce n'est pas le premier choisi par l'internaute), et en gris les autres, il faut encore un peu modifier le code en gardant la trace du premier morceau choisi dans un attribut supplémentaire de la balise audio, attribut que j'ai appelé "data-0" dans le code ci-dessous (cette fois-ci, j'ai mis le html pour qu'il n'y ait pas d'ambiguïté). Il y a deux endroits où il faut donner une valeur à "data-0" : à la fin de preparePlayer() (cas où l'internaute clique sur le bouton "play" du lecteur audio sans jamais avoir sélectionné de morceau dans la liste avant), et dans la fonction onclik() (cas où l'internaute clique sur un morceau de la liste). Ensuite, on utilise la valeur de "data-0" dans la fonction exécutée à chaque évènement "play" pour savoir quel lien doit être en rouge.


<div> 
<audio tabindex="0" id="player" preload="auto" controls="controls">
		<source id="source" src="PLAYERclosureAUDIOS/01.mp3">
	Votre navigateur ne reconnaît pas la balise audio HTML5
</audio>
	<ul id="playlist">
		<li><a href="PLAYERclosureAUDIOS/01.mp3">Audio 1</a></li>
		<li><a href="PLAYERclosureAUDIOS/02.mp3">Audio 2</a></li>
		<li><a href="PLAYERclosureAUDIOS/03.mp3">Audio 3</a></li>
		<li><a href="PLAYERclosureAUDIOS/04.mp3">Audio 4</a></li>
		<li><a href="PLAYERclosureAUDIOS/05.mp3">Audio 5</a></li>
		<li><a href="PLAYERclosureAUDIOS/06.mp3">Audio 6</a></li>
		<li><a href="PLAYERclosureAUDIOS/07.mp3">Audio 7</a></li>
		<li><a href="PLAYERclosureAUDIOS/08.mp3">Audio 8</a></li>
		<li><a href="PLAYERclosureAUDIOS/09.mp3">Audio 9</a></li>
		<li><a href="PLAYERclosureAUDIOS/10.mp3">Audio 10</a></li>
	</ul>
</div>

<script>
function loadSong(link,playerId)
{
	var player=document.getElementById(playerId);
	player.getElementsByTagName("source")[0].src=link.href;
	player.load();
	player.play();
}

function preparePlayer()
{
	var links=document.getElementById("playlist").getElementsByTagName("a");
	var player=document.getElementById('player');
	var z;
	for (z=0;z<links.length;z++)
		links[z].onclick=function(e)
		{
			var k,km=links.length;
			for (k=0;k<km;k++)
				if (this==links[k])
					{player.setAttribute("data-0",k);break;}
			loadSong(this,"player");
			return false;
		};
	player.addEventListener("play",function() {
		var k,km=links.length,x;
		x=parseInt(this.getAttribute("data-0"));
		links[x].style.color="red";
		for (k=0;k<km;k++)
		{
			if (this.getElementsByTagName("source")[0].src==links[k].href)
			{
				this.setAttribute("data-k",k);
				if (k!=x) links[k].style.color="black";
			}
			else
			{
				if (k!=x) links[k].style.color="grey";
			}
		}
	},false);
	player.addEventListener("ended",function() {
		var k=parseInt(this.getAttribute("data-k"));
		if (k<(links.length-1)) k++;else k=0;
		loadSong(links[k],"player");
	},false);
	player.setAttribute("data-0",0);
}

window.addEventListener("load",preparePlayer,false);
</script>


Amicalement,
Modifié par parsimonhi (08 Jun 2014 - 12:06)
Re-bonjour Parcimonhi,

Je répond à ton avant-dernier message, parce que je dois bien avouer que mon niveau de compréhension est particulièrement lent quand ça touche à javascript (et que j'essaye de comprendre ce que je fais même si des fois ça me semble relever plus du miracle que de la logique) Smiley langue


Donc tes deux conseils marchent très bien :

- Un player avec playlist avec la source audio comme valeur de l'attribut src de la balise audio.

- Mais également un player avec playlist et la source audio dans une balise source avec un id="source".

Je lis ton dernier message en détail ce soir, parce que là je suis invitée à déjeuner et je suis déjà en retard.

Bisous, Merci infiniment, A ce soir Smiley biggrin
Parcimonhi,

Encore et toujours un grand MERCI Smiley biggrin

J'ai énormément apprécié ton aide. Pour la couleur rouge, je te remercie, mais j'avais mis du rouge essentiellement pour vérifier le comportement du code que je rajoutais, donc je ne teste pas ton dernier code, mais je suis certaine qu'il fonctionne très bien.

Puis tu m'as donné envie de m'intéresser au jeu de go Smiley ravi


Peut-être à une prochaine fois,
Bisous
Pages :