diff --git a/node-server/assets/muddy_files.html b/node-server/assets/muddy_files.html
index 2c5bf7f..bc0822c 100644
--- a/node-server/assets/muddy_files.html
+++ b/node-server/assets/muddy_files.html
@@ -43,9 +43,7 @@
-
+
diff --git a/node-server/assets/script.js b/node-server/assets/script.js
index bbb1ee0..e1dc4b5 100644
--- a/node-server/assets/script.js
+++ b/node-server/assets/script.js
@@ -1,4 +1,4 @@
-// 1. Sélection des éléments DOM
+/* // 1. Sélection des éléments DOM
const vinyl = document.getElementById('vinyl');
const audio = document.getElementById('audio');
const progress = document.getElementById('progress');
@@ -148,4 +148,157 @@ audio.addEventListener('ended', () => {
} else {
isPlaying = false;
}
+}); */
+
+// === Variables DOM ===
+const vinyl = document.getElementById('vinyl');
+const progress = document.getElementById('progress');
+const currentTimeEl = document.getElementById('currentTime');
+const durationEl = document.getElementById('duration');
+const backwardBtn = document.getElementById('backward');
+const forwardBtn = document.getElementById('forward');
+const loopBtn = document.getElementById('loop');
+
+// === Web Audio ===
+let audioCtx;
+let buffer;
+let source;
+let startTime = 0;
+let offset = 0;
+let isPlaying = false;
+let playbackRate = 1;
+let isLooping = false;
+
+// === Socket + Vitesse ===
+let idleTimeout = null;
+let lastPosition = null;
+let lastTime = null;
+
+// === Initialisation Audio (doit être déclenchée par une interaction utilisateur) ===
+async function initAudio() {
+ audioCtx = new (window.AudioContext || window.webkitAudioContext)();
+ const response = await fetch('sounds/muddy_files.mp3'); // adapte ici
+ const arrayBuffer = await response.arrayBuffer();
+ buffer = await audioCtx.decodeAudioData(arrayBuffer);
+ durationEl.textContent = formatTime(buffer.duration);
+}
+
+// === Lecture ===
+function startPlayback() {
+ if (isPlaying || !buffer) return;
+ source = audioCtx.createBufferSource();
+ source.buffer = buffer;
+ source.playbackRate.value = playbackRate;
+ source.loop = isLooping;
+ source.connect(audioCtx.destination);
+ source.start(0, offset);
+ startTime = audioCtx.currentTime;
+ isPlaying = true;
+
+ source.onended = () => {
+ isPlaying = false;
+ if (isLooping) {
+ offset = 0;
+ startPlayback();
+ }
+ };
+}
+
+function stopPlayback() {
+ if (!isPlaying) return;
+ source.stop();
+ offset += (audioCtx.currentTime - startTime) * playbackRate;
+ isPlaying = false;
+}
+
+function updateSpeed(speed) {
+ const MIN_SPEED = 1;
+ const MAX_SPEED = 100;
+
+ if (Math.abs(speed) < MIN_SPEED) {
+ stopPlayback();
+ return;
+ }
+
+ let normSpeed = Math.min(Math.max(speed, MIN_SPEED), MAX_SPEED);
+ playbackRate = 0.5 + ((normSpeed - MIN_SPEED) / (MAX_SPEED - MIN_SPEED)) * 0.5;
+
+ if (isPlaying) {
+ stopPlayback();
+ startPlayback();
+ }
+}
+
+// === Socket.io ===
+const socket = io();
+
+socket.on('position', (position) => {
+ const now = Date.now();
+
+ if (lastPosition !== null && lastTime !== null) {
+ const deltaPos = position - lastPosition;
+ const deltaTime = (now - lastTime) / 1000;
+ const speed = deltaPos / deltaTime;
+
+ clearTimeout(idleTimeout);
+
+ if (Math.abs(speed) < 1) {
+ stopPlayback();
+ return;
+ }
+
+ if (speed < 0) {
+ stopPlayback();
+ offset = Math.max(0, offset + speed * 0.01); // ajuste sensibilité
+ } else {
+ updateSpeed(speed);
+ }
+ }
+
+ lastPosition = position;
+ lastTime = now;
+
+ idleTimeout = setTimeout(() => {
+ stopPlayback();
+ }, 300);
});
+
+// === Contrôles UI ===
+vinyl.addEventListener('click', () => {
+ if (!audioCtx) initAudio().then(startPlayback);
+ else if (isPlaying) stopPlayback();
+ else startPlayback();
+});
+
+backwardBtn.addEventListener('click', () => {
+ offset = Math.max(0, offset - 10);
+});
+
+forwardBtn.addEventListener('click', () => {
+ offset = Math.min(buffer.duration, offset + 10);
+});
+
+loopBtn.addEventListener('click', () => {
+ isLooping = !isLooping;
+ loopBtn.style.backgroundColor = isLooping ? 'white' : 'transparent';
+ loopBtn.style.color = isLooping ? '#18344b' : 'white';
+});
+
+// === Affichage rotation & temps ===
+function formatTime(time) {
+ const minutes = Math.floor(time / 60);
+ const seconds = Math.floor(time % 60);
+ return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
+}
+
+function updateVinylRotation() {
+ if (!buffer) return;
+ currentRotation = (offset / buffer.duration) * 360 * 3;
+ vinyl.style.transform = `rotate(${currentRotation}deg)`;
+}
+
+setInterval(() => {
+ if (isPlaying) updateVinylRotation();
+ currentTimeEl.textContent = formatTime(offset + (audioCtx.currentTime - startTime) * playbackRate);
+}, 100);
+