Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

111
Vistas
Fading in and out Web Audio Loop

I'm recording some audio in the browser and then want to loop it seamlessly, avoiding clicks etc when starting. This means fading it and out.

I can ramp the volume up and down once, but I can't find anyway to trigger Web Audio's 'ramp to value at time' every time the loop starts again.

Is there an easy way to do this? I've got 10 of these buffers looping so I'd like to avoid lots of costly setinterval checks if possible...

            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);
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Consider listening to the ended event and re-trigger the playback:

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>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda