2011-10-09 1 views
5

Sto sperimentando il porting di una semplice utility audio chiamata VoiceWalker in Javascript. VoiceWalker è uno strumento per aiutare le persone a trascrivere l'audio, e funziona in questo modo:Come è possibile accodare una sequenza di clip audio HTML5 <audio> audio in sequenza?

VoiceWalker playing patternhttp://i.imgur.com/rafgl.png

Quindi l'idea è che essa svolge un po ', lo ripete, scoots in avanti, gioca un altro po', ripete che, scoots in avanti, ecc

ho messo insieme una funzione per riprodurre un clip audio, sembra che questo:

function clip(audio, start, stop){ 
    audio.currentTime = start; 
    audio.play(); 
    int = setInterval(function() { 
     if (audio.currentTime > stop) { 
      audio.pause(); 
      clearInterval(int); 
     } 
    }, 10); 
}  

si tratta di una proposta facile a venire con un elenco di start/stop volte che abbinare la sopra, ma c'è un problema: come faccio ad accodare le mie chiamate in modo che uno possa essere eseguito solo dopo che l'altro si è fermato?

risposta

5

Segui la struttura di altre API in JavaScript: fai in modo che la funzione di clip includa anche la funzione "che cosa fare dopo". (Termine più tecnico: "callback"). L'idea è che la funzione clip sappia quando è terminata con il suo lavoro e può quindi richiamare la richiamata al momento giusto.

Per fare un esempio, diciamo che abbiamo una funzione che lentamente precisare una parola al corpo del documento:

var spell = function(word, onSuccess) { 
    var i = 0; 
    var intervalId = setInterval(function() { 
        if (i >= word.length) { 
         clearInterval(intervalId); 
         onSuccess(); 
        } else { 
         document.body.appendChild(
          document.createTextNode(word.charAt(i))); 
         i++; 
        } 
       }, 100) 
}; 

Quando questo calcolo termina ortografia, la parola, si chiamerà onSuccess, che sarà il nostro richiamo. Una volta che abbiamo incantesimo(), possiamo provare ad usarlo:

var startIt = function() { 
    spell("hello", afterHello); 
}; 

var afterHello = function() { 
    spell("world", afterHelloWorld); 
}; 

var afterHelloWorld = function() { 
    alert("all done!"); 
}; 

Provare a richiamare Startit e vedrete fare la sua cosa.

Questo approccio ci consente di concatenare questi calcoli asincroni. Ogni buona API asincrona di JavaScript consente di definire "cosa fare dopo" al termine del calcolo. Puoi scrivere le tue funzioni per fare lo stesso.

+0

Grazie, finalmente ho capito come fare le cose in modo asincrono in Javascript. –

6

Fai clip chiamata stessa:

function clip(audio, start, stop){ 
    audio.currentTime = start; 
    audio.play(); 
    int = setInterval(function() { 
     if (audio.currentTime > stop) { 
      audio.pause(); 
      clearInterval(int); 
      // Play it again, 2 seconds further. 
      clip(audio, start + 2, stop + 2); 
     } 
    }, 10); 
} 
1
var count = 1; //initialize and set counter 
var clipstart = [0,10,20,30,40,50,60]; //initialize and set array of starting points 
var clipend = [5,15,25,35,45,55,65]; //initialize and set array of ending points 
var clip = document.getElementById('clip'); //the clip you want to work with 
var end; //initialize the current end point 
var start; //initialize the current start point 

function stop(){ //function to check if the clip needs to be stopped and asks for next track 
    if(clip.currentTime >= end){ 
    clip.pause(); //pause playback 
     //if it's not on the 2 iteration, and the there are still cues left ask for next track. 
     if(!(count == 1 && clipstart.length == 0)){ 
      skip(); 
     } 
    } 
} 

function play(){ //skip to start and play 
    clip.currentTime = start; 
    clip.play(); 
} 

function skip(){ //sets the start and end points 
    count++; 
    if(count == 2){ 
    count = 0; 
    start = clipstart.shift(); 
    end = clipend.shift(); 
    } 
    play(); 
} 

skip(); 
clip.addEventListener('timeupdate', stop); //listens for if the clip is playing, and if it is, every second run the stop function. 

un'occhiata a esso here, può essere applicato ad un elemento audio o video.

0

Ecco un modulo che farà ciò che desideri.

è impostato per giocare due secondi del clip due volte, con una breve pausain mezzo, poi avanzare il punto di partenza mezzo secondo, breve pausa di nuovo, e poi riprodurre il successivo due secondi dal nuovo punto di partenza e così via. (È possibile modificare queste impostazioni molto facilmente nelle proprietà in alto).

Questo codice si aspetta che ci sia un elemento html con id "debug" - Ho usato un paragrafo per questo. Puoi cancellare tutti i riferimenti a questo elemento, se lo desideri. (Ce ne sono quattro, la linea che inizia var d ... e le tre linee che iniziano d.innerHTML ...).

var VOICEWALKER = (function() { 
// properties 
var d = document.getElementById("debug"); 
var audio = document.getElementsByTagName('audio')[0]; 
var start = 0; 
var stop = 2; 
var advanceBy = 0.5; 
var pauseDuration = 500; // milliseconds between clips 
var intv; // reference to the setInterval timer 
var clipCount = 0; // how many times we have played this part of the clip 
var clipMax = 2; // how many times we shall play this part of the clip 

// methods 
var pauseFinished = function() { 
    d.innerHTML = "Pause finished"; 
    clip(); 
}; 

var pollClip = function() { 

    d.innerHTML = String(audio.currentTime); 

    if (audio.currentTime > stop) { 
     audio.pause(); 
     d.innerHTML = "Pause"; 
     clearInterval(intv); 

     clipCount += 1; 
     if (clipCount === clipMax) { 
      clipCount = 0; 
      // advance clip 
      start += advanceBy; 
      stop += advanceBy; 
     } 

     // pause a little 
     setTimeout(pauseFinished, pauseDuration); 
    } 


}; 

var clip = function() { 
    audio.currentTime = start; 
    audio.play(); 
    intv = setInterval(pollClip, 10); 
}; 

var init = function() { 
    audio.addEventListener('canplaythrough', clip, false); 
}; 

return { 
    init : init 
}; 
}()); 

VOICEWALKER.init();