Code HTML (sera téléchargé via LittleFS dans l'EEPROM)

Les 3 composants du bandeau ci-dessus résument ce projet : comment piloter un DFPlayer via une interface web

Rien de compliqué dans ce code : on reçoit par Copier/coller, on traite et je mets dans un champ le résultat obtenu.
Retour vers le tuto du projet :

Le code HTML de l'utilitaire


          <html> 
         
         
              <head> 
                  <title>Mon cyberlecteur MP3 </title> 
                  <meta name="viewport" content="width=device-width, initial-scale=1"> 
         		 <meta content="text/html; charset=utf-8" http-equiv="content-type">
         		 <script type="text/javascript" src="LIST/liste.json"> </script>
         
          <meta charset="utf-8">
          <link rel="stylesheet" type="text/css" href="CSS/style.css">
          <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"> </script>
          <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"> </script> 
         
         
          <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css">
          <link rel="preconnect" href="https://fonts.googleapis.com">
          <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
          <link href="https://fonts.googleapis.com/css2?family=Codystar&family=Big Shoulders Display&display=swap" rel="stylesheet">
          <link href="https://fonts.googleapis.com/css2?family=Fugaz+One&display=swap" rel="stylesheet">
          <link rel="stylesheet" href="http://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
          <script src="https://code.jquery.com/jquery-1.12.4.js"> </script>
          <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"> </script>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/11.0.2/bootstrap-slider.min.js"> </script>
          <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-slider/11.0.2/css/bootstrap-slider.min.css">
         
         	 <script type="text/javascript">
         
         
         // ici, on va afficher le contenu de la Playlist en cours..
         var client = new XMLHttpRequest ();
         client.open ('GET', 'PlayList.txt');
         client.onload = function () 
         	{
         	//alert(client.responseText)
         	zaza=client.responseText;
         	afficherListeEnCours(zaza);
                      }//fin fonction
                      
          client.send ();
          
          
         
          
                       
          </script>
         
          <script type="text/javascript">
         function VisualiserPlaylist() {
         		$.ajax({ 
         		   url : "/VISUALISER", 
         		    type: 'GET',
         		    success : recupDonnees,
         		    error : messageErreur
         		})
         }
         
         function recupDonnees(data) {// peut-être à supprimer
             //alert(data);
             afficherListeEnCours(data);
             //do some stuff
         }
         function ViderPoubelle() {
         $("#poubelle").html("");
         }
         
         function afficherListeEnCours(PL) {
               $("#listePlayListe").html("");
               ListeAJouer=PL;
         
         
         finMorceau=0;
         title="";
         cpt=0
         
         	finListe = ListeAJouer.lastIndexOf("@")+1;
         	finMorceau =ListeAJouer.indexOf("@",0);
                while ((finMorceau  < finListe)&(finMorceau!=-1))
                         {  
                             cpt++;         
                          finMorceau =ListeAJouer.indexOf("@",0);
                          finListe = ListeAJouer.lastIndexOf("@")+1;
                          mes="FinMorceau vaut : "+finMorceau+" et finListe vaut : "+finListe;
                          aJouer= ListeAJouer.substring(0, finMorceau); //on extrait le prochain morceau..
                    
                         ListeAJouer = ListeAJouer.substring(finMorceau+1, finListe);  //on supprime le morceau, plus précisément je ne garde que le reste..
                       tempD =aJouer.substring(0, 2);//je décompose par exemple 02*0050
                       tempM =aJouer.substring(3,7);
                    		title = identifierMorceau(tempD, tempM, 1);// là, je vais récupérer le titre dans les Jsons stockés sur disque
                  	if (title != "false")
                  
                           {
                           
                  		    // alert(tempD+title+cpt);  
                  		        var divList = document.createElement('div');//ici, je crée un élément de type div, une énumération...
                  		        divList.id=aJouer;
                  		        divList.name=cpt;//je crée un indice de la liste
                  		        divList.classList.add("liste");
                  		        var Param = document.createElement("a");
                  		        Param.innerHTML =title;
                  		      	divList.appendChild(Param);
                  		      	document.getElementById("listePlayListe").appendChild(divList);// qui sera triable par dragage, in english !
                  		     }
                  		     else {
                  		     	
                  		     }
                  
               		        
               		     } //while
                      }//fin fonction
          </script>
          <script>
         // ci-dessous une fonction essentielle : la communication en permanence (toutes les 2 secondes, en fait...) entre le site web (la page internet) et le microprocesseur esp D1R1.
               var ReqAjax = null;
               if (window.XMLHttpRequest)  { ReqAjax =new XMLHttpRequest(); }
               else    { ReqAjax =new ActiveXObject("Microsoft.XMLHTTP"); }
           
         
               //  demarrer le timer qui cadence l'actualisation des champs de la page
               var myVar = setInterval(actualiser, 2000);    
               function actualiser(){
                 ReqAjax.open("GET","/ACTUALISER",true);  //***envoyer une requete ***
                 ReqAjax.send();
                 ReqAjax.onreadystatechange = function(){
                     if(ReqAjax.readyState == 4 && ReqAjax.status==200) { //***Traiter la réponse***
                         var reponse = this.responseText;//là, c'est la magie d'AJAX, qui nettoie tout du sol au plafond ! Alors que j'ai envoyé une requète au serveur, celui-ci m'envoie sa réponse, et je peux donc modifier par le biais du DOM des éléments de ma page, sans tout recharger...
                         var rep = reponse.split(" ");//je fractionne les diverses demandes faites au DFP sur ses états
                      document.getElementById('MESSAGE').innerHTML = reponse; //Pour voir ce qui se passe !
                         
         					 if(rep[0]=="Lecture"){
         					     document.getElementById('Message2').innerHTML = "En lecture";
         					     document.getElementById('LED').className = "led-red";
         					 }else{
         					     document.getElementById('Message2').innerHTML = "Arrêt lecture";
         					     document.getElementById('LED').className = "led-green";
         					}
         				$('#SliderSon').val(rep[1]); // le réglage actuel du volume
                
         		       if(rep[2]=="1"){// les réglages EQ...(avec une gestion archaique des boutons radios...)
         		       $('#Normal').addClass('active');
         		       $('#Pop').removeClass('active');
         		       $('#Rock').removeClass('active');
         		       $('#Jazz').removeClass('active');
         		       $('#Classique').removeClass('active');
         		       $('#Basses').removeClass('active');
         		       } 
         		       if(rep[2]=="2"){// les réglages EQ...(avec une gestion archaique des boutons radios...)
         		       $('#Normal').removeClass('active');
         		       $('#Pop').addClass('active');
         		       $('#Rock').removeClass('active');
         		       $('#Jazz').removeClass('active');
         		       $('#Classique').removeClass('active');
         		       $('#Basses').removeClass('active');
         		       } 
         		       if(rep[2]=="3"){// les réglages EQ...(avec une gestion archaique des boutons radios...)
         		       $('#Normal').removeClass('active');
         		       $('#Pop').removeClass('active');
         		       $('#Rock').addClass('active');
         		       $('#Jazz').removeClass('active');
         		       $('#Classique').removeClass('active');
         		       $('#Basses').removeClass('active');
         		       } 
         		       if(rep[2]=="4"){// les réglages EQ...(avec une gestion archaique des boutons radios...)
         		       $('#Normal').removeClass('active');
         		       $('#Pop').removeClass('active');
         		       $('#Rock').removeClass('active');
         		       $('#Jazz').addClass('active');
         		       $('#Classique').removeClass('active');
         		       $('#Basses').removeClass('active');
         		       } 
         		       if(rep[2]=="5"){// les réglages EQ...(avec une gestion archaique des boutons radios...)
         		       $('#Normal').removeClass('active');
         		       $('#Pop').removeClass('active');
         		       $('#Rock').removeClass('active');
         		       $('#Jazz').removeClass('active');
         		       $('#Classique').addClass('active');
         		       $('#Basses').removeClass('active');
         		       } 
         		       if(rep[2]=="6"){// les réglages EQ...(avec une gestion archaique des boutons radios...)
         		       $('#Normal').removeClass('active');
         		       $('#Pop').removeClass('active');
         		       $('#Rock').removeClass('active');
         		       $('#Jazz').removeClass('active');
         		       $('#Classique').removeClass('active');
         		       $('#Basses').addClass('active');
         		       } 
                
         	           var titre=identifierMorceau(rep[3], rep[4], 1); //ici, je récupère le titre du morceau en cours...
         	           var artiste=identifierMorceau(rep[3], rep[4], 2); // ainsi que l'artiste
         	           document.getElementById("PlayEnCours").innerHTML=titre; //... que j'affiche ici
         	           document.getElementById("texteintermediaire").innerHTML="interprète actuellement"; //... que j'affiche ici
         	           document.getElementById("ArtisteEnCours").innerHTML=artiste; //... que j'affiche ici
         	           const str1 = rep[3];
         	           dossier =(str1.padStart(2, '0')); // je rajoute des zéros devant
         	           const str2 = rep[4];
         	           valeur =(str2.padStart(4, '0')); 
         	           
         	        var ndos=dossier+"*"+valeur ;  //ici, je reconstruis le codage du morceau envoyé par dfp player pour le surligner          
                         const myNodelist = document.getElementById("listePlayListe").getElementsByTagName("div");// ici, je récupère la liste avec les éventuels ajouts, par ses ID
                                  for(var i = 0; i  < myNodelist.length; ++i){
                                    if( myNodelist[i].id == ndos){
                                    myNodelist[i].className = "playing";
                                    }else{
                                   // myNodelist[i].className = "cssPlayListe";
                                    }
                                	}
                            
                     }
                 }
               }
         
              </script>
             
              <script>
         function identifierMorceau(dossier, valeur, typeRecherche) {
         
         const str1 = valeur;
         valeur =(str1.padStart(4, '0')); // je rajoute des zéros devant
         const str2 = dossier;
         dossier =(str2.padStart(2, '0')); // je rajoute des zéros devant
         for (var cpt=1;cpt <=NombreDisques();cpt++) {
              var Dat = window['vinyl' + cpt];//attribution dynamique des noms de variables
              data_json=Dat;//
         	
         	//alert(data_json);
         	if(data_json==""){
         	return('false');
         	}
         
         
         	     var variListe = JSON.parse(data_json);
         	     for (var i=0;i <variListe.Titres.length;i++) {
         		      if (variListe.Titres[i].num == valeur && dossier == variListe.Titres[i].dos){
         		       //alert(valeur + ' trouvée. Le titre est = '+variListe.Titres[i].titre);
         				if (typeRecherche == 1){
         				result= variListe.Titres[i].titre;
         				return result;
         				}
         				if (typeRecherche == 2){
         				result= variListe.Titres[i].aut;
         				return result;
         			}
         		      }
         	     }
         	     
         	} 
         	return('false');    
         }
         
         
         
         
              </script>
             
           
         
          </head> 
              <body>
             
         
          <div class="jumbotron text-center">
            <h2>Projet de mini Juke-Box MP3 </h2>
            <h3 id="MESSAGE3"> </h3>
              <p>
           Mini lecteur MP3  <em>télécommandé via internet </em> </p> 
           
            <h4> <i>by Pierre Saunière </i> </h4>
         
           </div>
          </div>  
          <form id = "formID" action='/playlist' class='coin' style=" border-style: solid; width: 90%; margin: 0 auto;">
             <div class="form-group" style ="text-align: center;">
               <h3>Partie élaboration de la playlist </h3>
                <a > </i>
               Pour sélectionner plus d'un titre d'un disque, cliquer lentement pour faire une sélection multiple </a>
         
         
          <!-- data parent of the collapsibles -->
          <div id="accordion" > <!--Abracadabra-->
          </div>
         	
         	
          <br>
         
         
         
         
         
         
          <br>
         
         
          </div>
              </form>
          
            <br>
         
             
           
              <br>   <br>
            <div class='coinbis'  style=" border-style: solid; width: 90%; margin: 0 auto;">
               <div class="media-left media-middle">
               </div>
               <div class="form-group" style ="text-align: center;">
                               <h3> <span ID ="LED"> </span>Playlist en cours </h3>
             
         
             <div class="cssPlayListe" style=" font-family: 'Fugaz One', cursive; font-size: 3rem; color:  cornflowerblue;" ; id="ArtisteEnCours"> </div>
             <div class="cssPlayListe"  id="texteintermediaire"> </div>
         
             <div class="afficheur" id="PlayEnCours">Pas de titre actuellement... </div>
         		 <br>
               <div id="affiche"> </div>
         	 <div class="liste" id="stockageListe">
          		 <div class="cssPlayListe" id="listePlayListe">
         
         		  </div>	   <br> <button  class="btn btn-primary"  style=" margin: 0 auto;" onclick="EnregistrerPlaylist('listePlayListe');">Enregistrer la liste </button>
         		 
         		  <button  class="btn btn-primary"  style=" margin: 0 auto;" onclick="VisualiserPlaylist();">Visualiser la liste en cours </button>		 
         		  <button  class="btn btn-primary"  style=" margin: 0 auto;" onclick="ViderPoubelle();">Vider la corbeille </button> <br>
         		  <br> <br>
         		 
         		  <p style="color: red;">Pour supprimer des éléments de la liste, les glisser ici... </p>
         		 <div class="cssPlayListe" id="poubelle"> </div>
         		 
         		 </div>
         		  <div id="afficheListe"> </div>
          
          </div>
            <br>
           
            </div>
           
           </div>
               
                 
          <div class="container ">
            <div class="row ">
              <div class="col-sm-4 ">
             
                <h3> <i class="bi bi-volume-up" style="font-size: 3rem; color: cornflowerblue;"> </i> Son </h3>
                    <div class="p-3 mb-2 bg-warning text-dark alu" style="padding: 5px;">
                <p> <label data-theme="b" >Réglage du volume du son : </label>
         
                         <div style="height: 25px;" style="margin-bottom: 12px;">
                        	 <a  onclick="BaisserSon()" role="button">
                        		 <span style="float: left;">
                        		 <i class="bi  bi-volume-down-fill" style="font-size: 2rem; color: black; "> </i>
                        	 </span>
         	               	 </a>
                        	 <a  onclick="AugmenterSon()" role="button">
                        		 <span style="float: right;">
                        		 <i class="bi bi-volume-up-fill" style="font-size: 2rem; color: black;"> </i>
                        		 </span>
                        		 </a>
                        	 </div>
                 <input onchange="ChangementVolume()" type="range" min="0" max="30" class="form-range" id="SliderSon"  value="12"/>
                
               </div>
         
         
                <div class="text-center " >
                    <h4> <i class="bi bi-music-note-beamed" style="font-size: 3rem; color: cornflowerblue;"> </i> Equalizer </h4>
                           <div class="p-3 mb-2 bg-warning text-dark alu" style="padding: 5px;"> <br>
                     <img src="IMG/equalizer.jpg" class="" style="width:110px"> <br> <br>
                         <div class="btn-group-vertical">
         		            <a id = "Normal" class="btn btn-primary btn-sm " onclick="EQNormal()"  role="button">Normal </a>
         		            <a id = "Pop" class="btn btn-primary btn-sm" onclick="EQPop()"  role="button">Pop </a>
         		            <a id = "Rock" class="btn btn-primary btn-sm " onclick="EQRock()" role="button">Rock </a>
         		            <a id = "Jazz" class="btn btn-primary btn-sm" onclick="EQJazz()" role="button">Jazz </a>
         		            <a id = "Classique" class="btn btn-primary btn-sm" onclick="EQClassique()" role="button">Classique </a>
         		            <a id = "Basses" class="btn btn-primary btn-sm" onclick="EQBasses()" role="button">Basses </a>
                    		 </div>  
                    		 </div>   
                </div>
            </div>
              <div class="col-sm-4 text-center ">
                <h3> <i class="bi bi-music-note-beamed" style="font-size: 3rem; color: cornflowerblue;"> </i> Playlist </h3>
                <div class="p-3 mb-2 bg-warning text-dark alu" style="padding: 5px;">
         	        <div class="btn-group-vertical"> <br>
         	       <a class="btn btn-success btn-sm bi bi-music-note-beamed " onclick="FctnJOUER_PLAYLIST()" role="button"> Jouer la playlist enregistrée </a>
         	       <a class="btn btn-success btn-sm bi bi-music-note-beamed " onclick="FctnJOUER_PLAYLIST_actuelle()" role="button"> Jouer la playlist actuelle </a>
         	       <a class="btn btn-primary btn-sm bi bi-music-note-beamed " onclick="FctnConsultation()" role="button">  Consulter la playlist </a>
         	       <a class="btn btn-danger btn-sm bi bi-music-note-beamed " onclick="FctnEffacer()" role="button"> Effacer la playlist </a>
         	       <a class="btn btn-primary btn-sm bi bi-music-player-fill" onclick="FctnPlay()" role="button">   Play  </a>
         	       <a class="btn btn-primary btn-sm bi bi-stop-btn" onclick="FctnStop()"  role="button">   Stop  </a>
         	       <a class="btn btn-primary btn-sm bi bi-skip-backward-btn-fill" onclick="FctnPrecedent()" role="button">   Précédent  </a>
         	       <a class="btn btn-primary btn-sm bi bi-skip-forward-btn" onclick="FctnSuivant()"  role="button">   Suivant  </a>
         	       <a class="btn btn-primary btn-sm bi bi-hourglass-bottom" onclick="JouerAleatoirement()" role="button"> Aléatoire  </a>
         	       <a class="btn btn-danger btn-sm bi bi-tools " onclick="Reseter()" role="button"> Reset </a>
         	      </div>
              <span id="MESSAGE" style="display: inline-block; border-style: solid;width: 100%;"> </span> <br> <br>
         
              </div>
              </div>
         
         
         	 <div class="col-sm-4">
             
                <h3> <i class="bi-tools" style="font-size: 2rem; color: cornflowerblue;"> </i> Utilisation </h3>        
                <p>Le matériel </p>
            <div class="media">
               <div class="media-left">
                 <img src="IMG/dfplayer.png" class="media-object" style="width:60px">
                 <br>
                
                 <p  id="Message2"> </p>
                </div>
               <div class="media-body">
                 <h4 class="media-heading">DFPlayer </h4>
                  <p> <em>Un petit lecteur MP3 pilotable par commandes envoyées sur un port série... </em> </p>
               </div>
             </div>
            <span style="display: inline-block; border-style: solid;width: 100%;"> </span> <br>
           
           
            <div class="media">
               <div class="media-left">
                 <img src="IMG/D1R1.png" class="media-object" style="width:60px">
                 <br>
                 <div ID ="LED" class="led-green"> </div>
                 <p  id="Message2"> </p>
                </div>
               <div class="media-body">
                 <h4 class="media-heading">D1R1 </h4>
                  <p> <em>Ces commandes sont envoyées et reçues, ainsi que les différentes données textuelles (playlist + définition des dossiers présents sur la carte SD) et graphiques (site Web, images, CSS...) sur une carte ESP8266 avec mémoire flash </em> </p>
               </div>
             </div>
            <span id="stockage" style="display: inline-block; border-style: solid;width: 100%;">
            </span> <br>
                
              
               <!-- Media middle -->
               <div class="media">
            
         
                 <div class="media-body">
                   <h4 class="media-heading">Utilitaire </h4>
                   <p > <a href="preparation.html"> Pour jisonner vos fichiers (verbe du premier groupe) </a> </p>
                
                  
                  
         
                 
                 
                 </div>
               </div>
             </div>
            </div>
           
           
            </div>
           
             
           
                 <script  type="text/javascript">
           function NombreDisques() { // cette fonction, faut-il le préciser, retourne le nombre de variables vinyl1, vinyl2, etc.. disponibles
                let cpt=1;
               // A = [];
                while (cpt  <2000){// je n'en aurai pas plus de 2000. Il doit y avoir un moyen plus élégant, mais pas le temps d'y réfléchir aujourd'hui. Je modifierai un jour...
                cpt++;
                var Dat = window['vinyl' + cpt];//attribution dynamique des noms de variables
                if(typeof Dat === 'undefined') {// passage en revue de toutes les variables vinyl1, vinyl2, etc jusqu'à plus soif... Le plus soif étant lorsque le typeof vaut undefined. 
                  return cpt-1;
                }
           
             	}
             	return false;
           }
                
                
                 </script>  
         
         
          <script type="text/javascript" > 
         // script de remplissage d'accordéons
         //ici, on va créer le nombre de dossiers/disques présents automatiquement dans la liste "Elaboration de la playlist"
         
         
         
         let cpt=NombreDisques();
         		for (var numDisque = 1; numDisque  < (cpt+1); numDisque++) {
         			let dossier= "Disque n°"+numDisque;
         			let collaps = "collapsible"+numDisque;
         			let malist="MaListe"+numDisque;
         			str1 = toString(numDisque); // pour gérer DFP qui veut des noms de dossiers en 01, 02, etc.		
         			j=(numDisque.toString());   // idem
         			let nom="**"+j.padStart(2, '0'); // idem
         			let monID="titredisque"+numDisque;
         			var Dat = window['vinyl' + numDisque];//attribution dynamique des noms de variables
         			var Lis = ('MaListe' + numDisque); // idem...
         			var TitreDisque=('titredisque' + numDisque);// c'est pour ajouter l'auteur après le numéro de dossier (ou du disque...)
         			var DefDisque = document.createElement('div');//on crée un div pour l'onglet entier de l'accordéon
         				DefDisque.classList.add('card', 'bg-warning');
         				var Le_div = document.createElement('div');// puis je crée un div conteneur du titre
         				Le_div.classList.add('card-header');
         				var Le_a = document.createElement('a');// avec son a et ses attributs
         				Le_a.classList.add('card-link', 'collapsed');
         				Le_a.style.cssText = " font-family: 'Fugaz One', cursive; font-size: 2rem; color: red;" ;
         				Le_a.setAttribute("data-toggle","collapse");
         				Le_a.setAttribute("data-parent","accordion");
         				Le_a.href="#"+collaps;
         				Le_a.id=monID;
         				Le_a.textContent = dossier;// le titre en question avec l'indextation automatique
         				Le_div.appendChild(Le_a);// établissement de lea hiérarchie
         				DefDisque.appendChild(Le_div);// idem
         				
         
         			var ContenuDisque = document.createElement('div');// puis un conteneur d'accordéon
         			ContenuDisque.classList.add('collapse');
         			ContenuDisque.id=collaps;// avec l'indextation automatique
         			var cont = document.createElement('div');
         			cont.classList.add('card-footer');
         			var divListe = document.createElement('div');
         			divListe.id=malist;
         			var morceaux = JSON.parse(Dat);// et là je remplis les div de chaque morceau (les morceaux de musiques en lisant et exploitant les définitions Json. C'est un peu le cœur de la page, où JavaScript est bien exploité !
         			
         				    for(let i = 0; i  < morceaux.Titres.length; i++) { // remplissage pour chacun des disques de tous les titres
         				      var monMorceau = document.createElement('div');
         				      var Parametre1 = document.createElement('p');
         				      var Parametre2 = document.createElement('b');
         				      var Parametre3 = document.createElement('b');
         				      
         				    	monMorceau.id = morceaux.Titres[i].dos +"*"+morceaux.Titres[i].num;   //on pourra ainsi identifier le morceau par son id...      
         						    			      
         						// Parametre1.innerHTML =' Artiste :  <b>' + morceaux.Titres[i].aut + ' </b>' + ' Numéro :   <b>' + morceaux.Titres[i].num + ' </b>' + ' Titre :   <b>' + morceaux.Titres[i].titre +' </b>';
         
         				      Parametre1.innerHTML =  morceaux.Titres[i].titre ;
         				      monMorceau.appendChild(Parametre1);
         				      divListe.appendChild(monMorceau); 
         				    }				    
         				    auteur=morceaux.Titres[1].aut;// je prends le premier de la liste
         				   // alert(auteur);
         				Le_a.insertAdjacentHTML('beforeend', " : "+auteur); 			
         			cont.appendChild(divListe);
         			ContenuDisque.appendChild(cont);
         			DefDisque.appendChild(ContenuDisque);
         			document.getElementById("accordion").appendChild(DefDisque); 
         		
           	}
         
          </script>
         
            
            
          
         
            
           <script > 
         function ChangementVolume() {
              var valSon = $('#SliderSon').val();
              //alert("Je passe ici !");
             $.ajax({
                url : "/ENVOYER_COMMANDE*v*"+valSon+"@",
                 type: 'GET',
                 success : handleData,
                 error : messageErreur
             })
         }
         
         
         
         
         
         
         function shuffle(array) {
         
           for (let i = array.length - 1; i > 0; i--) {
             let j = Math.floor(Math.random() * (i + 1));
             let temp = array[i];
             array[i] = array[j];
             array[j] = temp;
           }
           return array;
         }
         
         
         function JouerAleatoirement() {
         
         	var plList = "";
         	let cpt=NombreDisques();
         	var plList = "";
         		for (var numDisque = 1; numDisque  < (cpt+1); numDisque++) {
         			let malist="MaListe"+numDisque;
         
         			const myNodelist = document.getElementById(malist).getElementsByTagName("div");// ici, je récupère les div de chaque collapsible (élément s'ouvrant en accordéon...
         
         	       for(var i = 0; i  < myNodelist.length; ++i){
         	           plList += myNodelist[i].id + '@';
         	       }
         	       
            		}
         	let myArray = plList.split('@');//je crée un tableau, pour pouvoir utiliser une fonction aléatoire
         	myArray;
         	const result = shuffle(myArray);//je le redistribue de manière aléatoire
         	
         	reglageMaxiTableau=70;// pour une question de mémoire, je vais limiter le nombre de morceaux
         	let max;
         		if (myArray.length>reglageMaxiTableau){
         		max=reglageMaxiTableau;
         		}else{
         		max=myArray.length;
         		}
         		let tabListe=[];
         		for (i=0; i <= max; i++){
         		tabListe.push(myArray[i]);
         		}
         	
         	let liste = tabListe.join('@')+ "@";//puis j'en recrée une chaine prête à envoyer au DFP
         	
         	
         	$("#afficheListe").html(liste);// pour regarder ce qui se passe, à supprimer en fin
            		
            		
         	
         	$.ajax({ //ici, j'envoie l'ordre d'enregistrer dans la mémoire disque la playliste en cours...
         	   url : "/JOUER_ALEATOIRE"+liste+ "@", // je balise la fin par un autre @
         	    type: 'GET',
         	    success : handleData,
         	    error : messageErreur
         	})
         }
         
         
         function FctnJOUER_PLAYLIST_actuelle() {
         
         	const myNodelist = document.getElementById("listePlayListe").getElementsByTagName("div");// ici, je récupère la liste avec les éventuels ajouts, par ses ID
         		var plList = "";
         		       for(var i = 0; i  < myNodelist.length; ++i){
         		           plList += myNodelist[i].id + "@";
         		       }
         	
         		//$("#afficheListe").html(plList);// pour regarder ce qui se passe, à supprimer en fin
         
              
             $.ajax({ //ici, j'envoie l'ordre d'enregistrer dans la mémoire disque la playliste en cours...
                url : "/JOUER_PLACTUELLE"+plList+ "@", // je balise la fin par un autre @
                 type: 'GET',
                 success : handleData,
                 error : messageErreur
             })
         }
         
         
         function EnregistrerPlaylist() {
         
         	const myNodelist = document.getElementById("listePlayListe").getElementsByTagName("div");// ici, je récupère la liste avec les éventuels ajouts, par ses ID
         		var plList = "";
         		       for(var i = 0; i  < myNodelist.length; ++i){
         		           plList += myNodelist[i].id + "@";
         		       }
         	 
         		//$("#afficheListe").html(plList);// pour regarder ce qui se passe, à supprimer en fin
         
              
             $.ajax({ //ici, j'envoie l'ordre d'enregistrer dans la mémoire disque la playliste en cours...
                url : "/ENREGISTRER_PLAYLIST"+plList+ "@", // je balise la fin par un autre @
                 type: 'GET',
                 success : handleData,
                 error : messageErreur
             })
         }
         
           function AugmenterSon() {
               $.ajax({
                  url : "/ENVOYER_COMMANDE*+*@",
                   type: 'GET',
                   success : handleData,
                   error : messageErreur
               })
           }
           
           function BaisserSon() {
               $.ajax({
                  url : "/ENVOYER_COMMANDE*-*@",
                   type: 'GET',
                   success : handleData,
                   error : messageErreur
               })
           }
           function EQNormal() {
               $.ajax({
                  url : "/ENVOYER_COMMANDE*y*1@",
                   type: 'GET',
                   success : handleData,
                   error : messageErreur
               })
           }
           function EQPop() {
                    // alert("Je passe ici !");
               $.ajax({
                   url : "/ENVOYER_COMMANDE*y*2@",
                   type: 'GET',
                   success : handleData,
                   error : messageErreur
               })
           }
           function EQRock() {
               $.ajax({
                  url : "/ENVOYER_COMMANDE*y*3@",
                   type: 'GET',
                   success : handleData,
                   error : messageErreur
               })
           }
           
           function EQJazz() {
               $.ajax({
                  url : "/ENVOYER_COMMANDE*y*4@",
                   type: 'GET',
                   success : handleData,
                   error : messageErreur
               })
           }
           function EQClassique() {
               $.ajax({
                  url : "/ENVOYER_COMMANDE*y*5@",
                   type: 'GET',
                   success : handleData,
                   error : messageErreur
               })
           }
           function EQBasses() {
               $.ajax({
                  url : "/ENVOYER_COMMANDE*y*6@",
                   type: 'GET',
                   success : handleData,
                   error : messageErreur
               })
           }
           
           
           function handleData() {
             //alert("Ça marche !");
             return true;
               //do some stuff
           }
           
           function messageErreur() {
              alert("Pas de DFPlayer mini connecté !!");
           }
           
           function FctnJOUER_PLAYLIST() {
               $.ajax({
                  url : "/JOUER_PLAYLIST",
                   type: 'GET',
                   success : handleData,
                   error : messageErreur
               })
           }
           
           function FctnConsultation() {
               $.ajax({
                  url : "/DOWNLOAD",
                   type: 'GET',
                   success : handleData,
                   error : messageErreur
               })
           }
           
           function FctnEffacer() {
               $.ajax({
                  url : "/EFFACER",
                   type: 'GET',
                   success : handleData,
                   error : messageErreur
               })// la partie concernant D1R1
               $("#listePlayListe").html("");// et la partie affichage !
           }
           
           
           function FctnPlay() {
               $.ajax({
                  url : "/ENVOYER_COMMANDE*s*@",
                   type: 'GET',
                   success : handleData,
                   error : messageErreur
               })
           }
           
           
           function FctnStop() {
               $.ajax({
                  url : "/ENVOYER_COMMANDE*b*@",
                   type: 'GET',
                   success : handleData,
                   error : messageErreur
               })
           }
           
           function FctnPrecedent() {
               $.ajax({
                  url : "/ENVOYER_COMMANDE*X*@",
                   type: 'GET',
                   success : handleData,
                   error : messageErreur
               })
           }
           
           function FctnSuivant() {
               $.ajax({
                  url : "/ENVOYER_COMMANDE*Y*@",
                   type: 'GET',
                   success : handleData,
                   error : messageErreur
               })
           }
           
         
         
         function Reseter() {
             $.ajax({
                url : "/ENVOYER_COMMANDE*w*@",
                 type: 'GET',
                 success : handleData,
                 error : messageErreur
             })
         }
           
         
           
             </script>
           
          <script src="JVST/Sortable.js"> </script>
         
         
          <script type="text/javascript">
         // ci-dessous, je vais gérer la partie à la fois sortable et glissable des titres de morceaux.
         
         	let compt=NombreDisques();
         	//un objet sortable par Disque (Titre d'accodéon)
         	for (var numDisque = 1; numDisque  < (compt+1); numDisque++) {
         			malist="MaListe"+numDisque;
         			new Sortable(document.getElementById(malist), {
         		  	group: 'shared',
         		     multiDrag: true,
         		     selectedClass: "selected",
         		     onEnd: function(evt) {
         		         for (let i in evt.items) {
         		           Sortable.utils.deselect(evt.items[i]);
         		         }
         		       },
         		    	fallbackTolerance: 3, // So that we can select items on mobile
         		         
         		    animation: 150
         			});
         
         	      }
         	       
         
         
         //puis la playliste finale
         new Sortable(document.getElementById('listePlayListe'), {
         group: 'shared',
            multiDrag: true,
            selectedClass: "selected",
            onEnd: function(evt) {
                for (let i in evt.items) {
                  Sortable.utils.deselect(evt.items[i]);
                }
              },
           	fallbackTolerance: 3, // So that we can select items on mobile
         
             animation: 150
         });
         
         
         //et une liste qui servira de poubelle, pour jeter des éléments
         new Sortable(document.getElementById('poubelle'), {
             group: {
             	    multiDrag: true, // Enable multi-drag
                selectedClass: "selected",
             
                 name: 'shared',
                 pull: 'clone',
                 onEnd: function(evt) {
                     for (let i in evt.items) {
                       Sortable.utils.deselect(evt.items[i]);
                     }
                   }
                 
             },
             animation: 150
         });
         
         
         
         $(document).ready(function(){
         Lister("listePlayListe");
         });
          </script>
         
         
         
              </body>
          </html>
                   
          

C'est tout

J'espère que ce projet trouvera un écho favorable parmi les internautes. Si vous voulez me contacter, voici mon email (à retaper, pour éviter la collecte automatique d'emails...)