rewind
This commit is contained in:
parent
60bb918f54
commit
911049a2fe
@ -43,7 +43,9 @@
|
|||||||
<button id="forward">10s +</button>
|
<button id="forward">10s +</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<audio id="audio"
|
||||||
|
src="muddy_files.mp3"
|
||||||
|
data-reverse-src="muddy_files_reverse.mp3"></audio>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
/* // 1. Sélection des éléments DOM
|
// 1. Sélection des éléments DOM
|
||||||
const vinyl = document.getElementById('vinyl');
|
const vinyl = document.getElementById('vinyl');
|
||||||
const audio = document.getElementById('audio');
|
const audio = document.getElementById('audio');
|
||||||
const progress = document.getElementById('progress');
|
const progress = document.getElementById('progress');
|
||||||
@ -148,157 +148,4 @@ audio.addEventListener('ended', () => {
|
|||||||
} else {
|
} else {
|
||||||
isPlaying = false;
|
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('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);
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user