MortenMoulder
MortenMoulder

Reputation: 6648

Call function when <audio> is at specific time

I am currently doing some fun website, which requires audio cues (I assume that's the name?). I want the site to do something, when the song has been played for exactly X amount of time.

I can easily get the current time using element.currentTime, but I have no clue how to say: when element.currentTime == 5.2, runFunction() - If you know what I mean. Is there some kind of way this could be done? My current test code:

<----AUDIO WILL START PLAYING---->
http://jsfiddle.net/jfL4mcnh/

$("<audio id='audioElement'>").appendTo("body");
$("#audioElement").attr("src", "http://mp3ornot.com/songs/1B.mp3").attr("autoplay", "autoplay");

setInterval(function() {
    //for some reason, $("#audioElement").currentTime won't work, so we're going old fashion
    time = document.getElementById("audioElement").currentTime;
    console.log(time);
}, 1000);

Also, I forgot to say this, I cannot do a setTimeout() and hit at the exact moment I want in milliseconds, because the audio can take some extra time to load, while the actual code runs exactly when it has been "seen", if you know what I mean. So no countdown. I need to be exact here.

Upvotes: 3

Views: 1665

Answers (3)

Toni Leigh
Toni Leigh

Reputation: 4971

See this jsfiddle here

I've added the following line to the JavaScript setInterval() function:

if (time > 5.2) {
    myFunction();
}

myFunction() does a console.log, which you'll see in the console.

The reason I used > rather than === is that the time reported is never precise due to fluctuations in processing. A Boolean in the condition would solve this problem:

triggered = false;
if (time > 5.2 && !triggered) {
    triggered = true;
    myFunction();
}

Upvotes: 0

Maximillian Laumeister
Maximillian Laumeister

Reputation: 20359

If you need greater resolution than ontimeupdate provides, you can use a setInterval instead.

Live Demo (sound and alert box only!):

$("<audio id='audioElement'>").appendTo("body");
$("#audioElement").attr("src", "http://mp3ornot.com/songs/1B.mp3").attr("autoplay", "autoplay");

var triggered = false;

var ael = document.getElementById("audioElement");
var interval = setInterval(function(){
    console.log(ael.currentTime);
    if (!triggered && ael.currentTime >= 5.2) {
        triggered = true;
        alert("5.2 seconds reached");
    }
    if (ael.ended) clearInterval(interval);
}, 50);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

JSFiddle Version: http://jsfiddle.net/jfL4mcnh/15/

Upvotes: 1

MortenMoulder
MortenMoulder

Reputation: 6648

Well, I have done it myself.. It seems.

http://jsfiddle.net/jfL4mcnh/13/

$("#audioElement").bind("timeupdate", function() {
    var currentTime = parseInt(this.currentTime, 10);
    if(currentTime == 2) { 
        console.log("2 seconds in");
        $(this).unbind("timeupdate");
    }
});

You can bind timeupdate to it, then unbind it (apparently it runs the code 4 times, so I have to unbind it).

EDIT: Nope, it doesn't update fast enough to make it perfect on point. It increments each ~300ms it seems.

Upvotes: 0

Related Questions