When working with audio elements (<audio>
) or contexts(AudioContext
), you can check their currentTime
property to know exactly the play time of your buffer.
All of this is fine an dandy until I created multiple sources (or AudioBufferSourceNode
) in a single AudioContext
.
The sources could be played at different times, therefore I would need to know their corresponding currentTime
's, to illustrate:
Some base code for you to work off:
buffer1 = [0,1,0]; //not real buffers
buffer2 = [1,0,1];
ctx = new AudioContext();
source1 = ctx.createBufferSourceNode();
source1.buffer = buffer1;
source1.connect(ctx.destination);
source1.start(0);
source2 = ctx.createBufferSourceNode();
source2.buffer = buffer2;
source2.connect(ctx.destination);
setTimeout(1000/*some time later*/){
source2.start(0);
}
setTimeout(1500/*some more time later*/){
getCurrentTime();
}
function getCurrentTime(){
/* magic */
/* more magic */
console.log("the sources currentTime values are obviously 1500 (source1) and 500 (source2).");
}
What I usually do is create a wrapper for the audio source node that keeps track of the playback state. I've tried to minimise the code below to show the basics.
The core idea is to keep track of the time the sound is started and the time the sound is 'paused' and use those values to get the current time and to resume playback from the paused position.
I put a working example on codepen
function createSound(buffer, context) {
var sourceNode = null,
startedAt = 0,
pausedAt = 0,
playing = false;
var play = function() {
var offset = pausedAt;
sourceNode = context.createBufferSource();
sourceNode.connect(context.destination);
sourceNode.buffer = buffer;
sourceNode.start(0, offset);
startedAt = context.currentTime - offset;
pausedAt = 0;
playing = true;
};
var pause = function() {
var elapsed = context.currentTime - startedAt;
stop();
pausedAt = elapsed;
};
var stop = function() {
if (sourceNode) {
sourceNode.disconnect();
sourceNode.stop(0);
sourceNode = null;
}
pausedAt = 0;
startedAt = 0;
playing = false;
};
var getPlaying = function() {
return playing;
};
var getCurrentTime = function() {
if(pausedAt) {
return pausedAt;
}
if(startedAt) {
return context.currentTime - startedAt;
}
return 0;
};
var getDuration = function() {
return buffer.duration;
};
return {
getCurrentTime: getCurrentTime,
getDuration: getDuration,
getPlaying: getPlaying,
play: play,
pause: pause,
stop: stop
};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With