7

I am working with HTML5 audio. For my use-case, I need to listen on the audio duration played and once it crosses a certain threshold, pause the audio. So something like:

$(audio).bind('timeupdate', function() {
  if (audio.currentTime >= 10){
     audio.pause();
  }
});

What I am noticing is that by the time my handler executes, audio.currentTime is around 10.12878, 10.34023 etc and hence, some little extra audio is played before it is paused.

Another question seems to have documented the same issue.The question is dated in 2012 so I am wondering if the state of the art has improved.

If not, what other ways exist to do this with more precision? I haven't worked with audio much before and I would really appreciate the help.

Community
  • 1
  • 1
Rajat
  • 32,970
  • 17
  • 67
  • 87
  • No, AFAIK HTML5 Audio API hasn't improved in that area, in fact JavaScript in it's entirety is still lacking in precise timing. Web Audio on the other hand is an exception. In fact take a look at my [post](http://stackoverflow.com/a/35918492/2813224) – zer00ne May 11 '16 at 00:07
  • Is requirement to pause audio at precisely 10.0? Why use `>=` operator? – guest271314 May 16 '16 at 14:43
  • Given the difficulty of nailing down precision to the exact 10.0, a practical attempt you may wan to try is using audio.currentTime > 9.750 (strict greater than) This gives you a 0.250 cushion before 10.0 is reached. – Only You May 19 '16 at 13:14

3 Answers3

3

According to MDN documentation, timeupdate event

The event frequency is dependant on the system load, but will be thrown between about 4Hz and 66Hz (assuming the event handlers don't take longer than 250ms to run). User agents are encouraged to vary the frequency of the event based on the system load and the average cost of processing the event each time, so that the UI updates are not any more frequent than the user agent can comfortably handle while decoding the video.

To pause audio at 10.0nnnnn, you can utilize requestAnimationFrame; if condition this.currentTime > 9.999 to call .pause() before reaching 10.000000. Note, 9.999 can be adjust to between 9.9 through 9.99750, which could also periodically pause audio at 9.99nnnn; that is, before reaching 10.0

var requestAnimationFrame = window.requestAnimationFrame;

var audio;

function trackCurrentTime() {
  // `this` : `audio`
  console.log(this.currentTime);
  if (this.currentTime > 9.999) {
    this.pause();
  } else {
    requestAnimationFrame(trackCurrentTime.bind(this))
  }
}

var request = new XMLHttpRequest();
request.open("GET", "/path/to/audio", true);
request.responseType = "blob";
request.onload = function() {
  if (this.status == 200) {
    audio = new Audio(URL.createObjectURL(this.response));
    audio.onpause = function(e) {
      console.log(e.target.currentTime)
    }
    audio.load();
    audio.play();
    trackCurrentTime.call(audio);
  }
}
request.send();

jsfiddle http://jsfiddle.net/Lg5L4qso/7/

guest271314
  • 1
  • 15
  • 104
  • 177
1

So I researched my way through this problem and came out with the following findings:

1) HTML Audio is no dice for such a scenario. Its a very limited API and doesn't offer fine grain audio control. Web Audio API is the way to go for this.

2) Web Audio API is not the easiest thing to read/understand and is perhaps weakly implemented across various browsers. Its better to find a nice wrapper around it that fallsback to web audio or flash when Web Audio is not available in a browser.

3) Some wrappers exist like howler.js, sound.js and SoundManager2. Off the three SoundManager2 seems the best fit at first thought. Demo 4G at http://www.schillmania.com/projects/soundmanager2/demo/api/ effectively solves a very similar problem as in the scenario in the question.

Update: SoundManager2 actually doesn't support the web audio api. From the technotes:

SM2 does not presently use the Webkit Audio API. It may be experimentally or more formally added at some point in the future, when the API is more universally-supported.

Rajat
  • 32,970
  • 17
  • 67
  • 87
1

HTML Audio is no dice for such a scenario. Its a very limited API and doesn't offer fine grain audio control. Web Audio API is the way to go for this.

gonz
  • 5,226
  • 5
  • 39
  • 54
h nn n n
  • 11
  • 1
  • 2
    I think you are providing an answer to the question, since OP asked for "other ways exist to do this with more precision", but you should tell more about web audio and sharing an usage example would be great too! – gonz May 19 '16 at 18:39