Estoy grabando algo de audio en el navegador y luego quiero reproducirlo en bucle sin problemas, evitando clics, etc. al comenzar. Esto significa desvanecerlo y desaparecer.
Puedo subir y bajar el volumen una vez, pero no puedo encontrar ninguna forma de activar la "rampa al valor en el tiempo" de Web Audio cada vez que el bucle comienza de nuevo.
¿Hay una forma fácil de hacer esto? Tengo 10 de estos búferes en bucle, por lo que me gustaría evitar muchas comprobaciones costosas de intervalos si es posible...
let source = audioContext.createBufferSource(); let gain = audioContext.createGain(); gain.gain.value = 0.01; source.buffer = decodedData; songLength = decodedData.duration; source.loop = true; source.connect(gain); gain.connect(audioContext.destination); source.start(0); // fade in and out gain.gain.exponentialRampToValueAtTime(0.2, audioContext.currentTime + 1); gain.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + songLength);Considere escuchar el evento ended y vuelva a activar la reproducción:
class FadeInLoop { ctx audioBuffer gainNode isPlaying = true constructor(ctx, url) { this.ctx = ctx this.audioBuffer = fetch(url) .then(response => response.arrayBuffer()) .then(arrayBuffer => ctx.decodeAudioData(arrayBuffer)) this.gainNode = ctx.createGain() this.gainNode.connect(ctx.destination) } async start() { this.isPlaying = true const source = ctx.createBufferSource() this.source = source source.addEventListener('ended', e => { if (this.isPlaying) { // repeat unless stop() was called this.start() } }) source.connect(this.gainNode) source.buffer = await this.audioBuffer const now = this.ctx.currentTime this.gainNode.gain.setValueAtTime(Number.EPSILON, now); this.gainNode.gain.exponentialRampToValueAtTime(1, now + 0.055) source.start(0) } stop() { this.isPlaying = false this.source?.stop() } } const ctx = new AudioContext({ latencyHint: 'interactive' }) const loop = new FadeInLoop(ctx, 'https://batman.dev/static/71474264/loop.mp3') <button onclick="loop.start()">Start</button> <button onclick="loop.stop()">Stop</button>