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

183
Vistas
La interacción de sonido de Web Audio API deja de funcionar después de un tiempo

Estoy trabajando con Web Audio API para mi proyecto de javascript, y me encontré con un problema para el que parece que no puedo encontrar la respuesta en ninguna parte.

He agregado detectores de eventos para responder a los eventos de pulsación de tecla: cada vez que un usuario presiona una determinada tecla en su teclado, se reproducirá un sonido. Esto funciona por un tiempo, pero después de aproximadamente 6 segundos de presionar las teclas, sucede algo que hace que el sonido se detenga: las teclas no producirán sonido durante tal vez medio segundo, luego comenzarán a funcionar nuevamente. ¿Alguien tiene alguna idea de por qué sucede esto y cómo puedo solucionarlo?

Aquí está mi código para el detector de eventos:

 import Audio from './scripts/audio' document.addEventListener('keydown', (e) => { const audio = new Audio(); let key = e.key; audio.createNotes(key); })

y aquí está mi código para el audio:

 class Audio { constructor() { // instantiate web audio api object this.audioContext = new AudioContext(); // create gain node, gain corresponds with volume this.gainNode = this.audioContext.createGain(); this.gainNode.gain.setValueAtTime(0.08, 0); // allows volume to decrease with time this.gainNode.gain.exponentialRampToValueAtTime(0.001, this.audioContext.currentTime + 1.5); } createNotes(key) { // C4 to C5 scale, attach frequencies to corresponding keyboard value const notes = { 's': 261.63, 'd': 293.66, 'f': 329.63, 'g': 349.23, 'h': 392.00, 'j': 440.00, 'k': 493.88, 'l': 523.25, 'e': 587.33, 'r': 659.25, 't': 698.46, 'y': 783.99, 'u': 880.00, 'i': 987.77, 'o': 1046.50, 'p': 1174.66 } // if e.key corresponds with notes key, we want to play sound if (notes[key]) { // oscillator corresponds with frequency, // create oscillator node to attach frequency from notes object let oscillator = this.audioContext.createOscillator(); oscillator.frequency.setValueAtTime(notes[key], this.audioContext.currentTime); // lower gain for higher frequency notes if (notes[key] > 699) { this.gainNode.gain.setValueAtTime(0.03, this.audioContext.currentTime); } // connect oscillator node to volume node oscillator.connect(this.gainNode); // connect gain node to destination (speakers) this.gainNode.connect(this.audioContext.destination); oscillator.start(0); // tone will play for 1.5 seconds oscillator.stop(this.audioContext.currentTime + 1.5) } } } export default Audio;
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

El problema es que está creando demasiadas instancias de AudioContext. Este no es el uso previsto de la API. ¿Por qué estás creando tantas instancias? Deberías reutilizarlos.

En general, solo debería necesitar un solo AudioContext. En la página del desarrollador de mozzila se indica claramente que algunas versiones de Chrome solo admiten 6.

https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/AudioContext#google_chrome

Aquí hay una pregunta/respuesta que explica mejor el problema. Chrome no produce audio después de llegar a 50 flujos de salida de audio

Para resolver su problema, básicamente cree un solo AudioContext y hágalo accesible globalmente así:

 let globalAudioContext = new AudioContext(); class Audio { constructor() { // instantiate web audio api object // create gain node, gain corresponds with volume this.gainNode = globalAudioContext.createGain(); this.gainNode.gain.setValueAtTime(0.08, 0); // allows volume to decrease with time this.gainNode.gain.exponentialRampToValueAtTime(0.001, globalAudioContext.currentTime + 1.5); } createNotes(key) { // C4 to C5 scale, attach frequencies to corresponding keyboard value const notes = { 's': 261.63, 'd': 293.66, 'f': 329.63, 'g': 349.23, 'h': 392.00, 'j': 440.00, 'k': 493.88, 'l': 523.25, 'e': 587.33, 'r': 659.25, 't': 698.46, 'y': 783.99, 'u': 880.00, 'i': 987.77, 'o': 1046.50, 'p': 1174.66 } // if e.key corresponds with notes key, we want to play sound if (notes[key]) { // oscillator corresponds with frequency, // create oscillator node to attach frequency from notes object let oscillator = globalAudioContext.createOscillator(); oscillator.frequency.setValueAtTime(notes[key], globalAudioContext.currentTime); // lower gain for higher frequency notes if (notes[key] > 699) { this.gainNode.gain.setValueAtTime(0.03, globalAudioContext.currentTime); } // connect oscillator node to volume node oscillator.connect(this.gainNode); // connect gain node to destination (speakers) this.gainNode.connect(globalAudioContext.destination); oscillator.start(0); // tone will play for 1.5 seconds oscillator.stop(globalAudioContext.currentTime + 1.5); } } } document.addEventListener('keydown', (e) => { const audio = new Audio(); let key = e.key; console.log(e.keyCode); audio.createNotes(key); })

Si está tratando de hacer un teclado de piano, debe vincular cada tecla a un nodo de gráfico preinicializado (nodo de ganancia) y reutilizarlas.

Y la razón por la que vuelve a funcionar es porque el recolector de basura tarda en activarse.

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