2013-02-28 13 views
6

Ho il seguente codice JS per un gioco basato su tela.Riproduci audio tramite JS con sovrapposizione

var EXPLOSION = "sounds/explosion.wav"; 

function playSound(str, vol) { 
    var snd = new Audio(); 
    snd.src = str; 
    snd.volume = vol; 
    snd.play(); 
} 

function createExplosion() { 
    playSound(EXPLOSION, 0.5); 
} 

Questo funziona, tuttavia invia una richiesta del server per scaricare il file audio ogni volta che viene chiamato. In alternativa, se dichiaro l'oggetto audio in anticipo:

var snd = new Audio(); 
snd.src = EXPLOSION; 
snd.volume = 0.5; 

function createExplosion() { 
    snd.play(); 
} 

Questo funziona, se la funzione createExplosion viene chiamato prima il suono è finito di giocare, non gioca il suono a tutti. Ciò significa che è consentito solo un singolo playthrough del file audio alla volta e che in scenari in cui si verificano più esplosioni non funziona affatto.

C'è un modo per riprodurre correttamente un file audio più volte sovrapponendosi a se stesso?

+1

finito per andare con utilizzando la libreria AudioFX: http: // codeincomplete .com/posts/2011/9/17/revisiting_html5_audio/ –

risposta

0

Prova questo:

(function() { 
    var snds = {}; 
    window.playSound(str,vol) { 
     if(!snds[str]) (snds[str] = new Audio()).src = str; 
     snds[str].volume = vol; 
     snds[str].play(); 
    } 
})(); 

Poi la prima volta che si chiami esso preleverà il suono, ma ogni volta, dopo che sarà riutilizzare lo stesso oggetto sonoro.


EDIT: Si può anche precaricare con i duplicati per consentire al suono di giocare più di una volta in un momento:

(function() { 
    var snds = {} 
    window.playSound = function(str,vol) { 
     if(!snds[str]) { 
      snds[str] = [new Audio()]; 
      snds[str][0].src = str; 
     } 
     var snd = snds[str], pointer = 0; 
     while(snd[pointer].playing) { 
      pointer++; 
      if(pointer >= snd.length) { 
       snd.push(new Audio()); 
       snd[pointer].src = str; 
      } 
     } 
     snd[pointer].volume = vol; 
     snd[pointer].play(); 
    }; 
})(); 

Si noti che questo invierà richieste multiple se si gioca il suono si sovrappongono troppo stessa molto, ma dovrebbe tornare Not Modified molto rapidamente e lo farà solo se lo giochi più volte di quanto hai fatto in precedenza.

+0

Questo ha lo stesso problema. Il suono verrà riprodotto, ma tentando di riprodurlo nuovamente prima che un'istanza precedente abbia terminato di riprodurlo, il suono non verrà riprodotto affatto. Sembra che ci sia un problema con play() in un oggetto audio prima che sia finito. –

+0

La mia solita soluzione a questo è di costruire un array. Modificherò la mia risposta con quello. –

+0

Sembra non funzionare, ma ho un'idea approssimativa di ciò che stai cercando di fare. –

0

Stavo cercando questo per anni in un gioco di tetris che sto costruendo e penso che questa soluzione sia la migliore.

function playSoundMove() { 
    var sound = document.getElementById("move"); 
    sound.load();  
    sound.play(); 
} 

basta averlo caricato e pronto per andare.

1

Si potrebbe semplicemente duplicare il nodo con cloneNode() e play() quel nodo duplicato.

mio elemento audio assomiglia a questo:

<audio id="knight-audio" src="knight.ogg" preload="auto"></audio> 

e ho un onClick ascoltatore che fa proprio questo:

function click() { 
    const origAudio = document.getElementById("knight-audio"); 
    const newAudio = origAudio.cloneNode() 
    newAudio.play() 
} 

E poiché l'elemento audio non sta per essere visualizzato, è in realtà non è necessario collegare il nodo a qualcosa.

Ho verificato lato client e lato server che Chrome tenta solo di scaricare il file audio una volta.

Avvertenze: Non sono sicuro degli impatti delle prestazioni, dal momento che nel mio sito questa clip non viene riprodotta più di ~ 40x al massimo per una pagina. Potrebbe essere necessario pulire i nodi audio se stai facendo qualcosa di molto più grande di quello?

0

Basandosi più memoria rispetto tempo di processo, siamo in grado di fare una serie di molteplici cloni del Audio e poi riprodurli in ordine:

function gameSnd(){ 
    this.t = new Audio('sounds/tick.wav'); 
    this.v = new Audio('sounds/victory.wav'); 
    this.c = 0; 
    this.ticks=[]; 
    for(var i = 0; i<10;i++) 
    this.ticks.push(this.t.cloneNode()); 

    this.tick = function(){ 
    this.c = (this.c + 1)%10; 
    this.ticks[this.c].play(); 
    } 

    this.victory = function(){ 
    this.v.play(); 
    } 

} 
Problemi correlati