【问题标题】:Call function when <audio> is at specific time<audio> 在特定时间时调用函数
【发布时间】:2015-09-18 21:43:15
【问题描述】:

我目前正在做一些有趣的网站,它需要音频提示(我猜是这个名字?)。我希望网站在歌曲播放了 X 时间后做点什么。

我可以使用element.currentTime 轻松获取当前时间,但我不知道怎么说:when element.currentTime == 5.2, runFunction() -如果你明白我的意思。有什么办法可以做到这一点吗?我当前的测试代码:


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);

另外,我忘了说这个,我不能在我想要的毫秒内执行setTimeout(),因为音频可能需要一些额外的时间来加载,而实际代码在它已经运行的时候完全运行“看到”,如果你知道我的意思。所以没有倒计时。我需要在这里准确。

【问题讨论】:

    标签: javascript jquery html audio


    【解决方案1】:

    如果您需要比ontimeupdate 提供的分辨率更高的分辨率,您可以改用setInterval

    现场演示(仅限声音和警报框!):

    $("<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);
    &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"&gt;&lt;/script&gt;

    JSFiddle 版本:http://jsfiddle.net/jfL4mcnh/15/

    【讨论】:

    • 这和我的很接近.. 不是吗? ontimeupdate 理论上应该和.bind("timeupdate") 一样吧?我看到我的 timeupdate 不会立即更新,所以我不能让它在 5.25 秒时触发。它将像 0.888、1.212、1.559 等一样递增。它不会是 0.001、0.002。你的也一样:(
    • @Snorlax 如果您需要更好的分辨率,可以使用setInterval 而不是ontimeupdate。我使用它的最佳分辨率约为 50 毫秒。我认为没有办法获得完美的毫秒精度。请参阅上面对我的答案的修改。
    • 我想我可以使用 setInterval,然后在 currentTime > 5.25 时停止轮询,例如。然后让它每 5-10 毫秒轮询一次。这应该不会给客户端 PC 带来太多负担。对吧?
    • setInterval 轮询在低于大约 50 毫秒的分辨率下不起作用 - currentTime 不会更新得那么快,因此您将获得重复的 currentTime 值,并且计算机只会旋转它的轮子。但是是的,您完全可以在 5.25 秒后停止轮询,只需将 clearInterval 调用放在第一个 if 语句中,然后删除第二个 if 语句。
    【解决方案2】:

    嗯,我自己做的..似乎。

    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");
        }
    });
    

    你可以绑定timeupdate到它,然后解绑(显然它运行代码4次,所以我必须解绑它)。

    编辑:不,它的更新速度不够快,不足以使其完美。它似乎每增加约 300 毫秒。

    【讨论】:

    • 它运行代码 4 次,因为 currentTime 在 2.22.42.6 等处触发。而不是将当前时间浮点数解析为 int,请参阅我的答案以获得更清洁解决方案。谢谢!
    • 嗯,有道理。我现在就回复你。
    • 另一个需要注意的重要事项是,如果浏览器卡顿并且在第二秒内没有注册timeupdate 事件,则此解决方案将失败。
    【解决方案3】:

    看到这个jsfiddle here

    我在 JavaScript setInterval() 函数中添加了以下行:

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

    myFunction() 执行 console.log,您将在控制台中看到。

    我使用&gt; 而不是=== 的原因是由于处理过程中的波动,报告的时间永远不会准确。条件中的布尔值可以解决这个问题:

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

    【讨论】:

    • 那行不通。阅读我的问题的最后一部分,因为我忘了说,所以我刚刚添加了它。音频文件可能需要额外的时间来加载
    • 这不是倒计时,它会定期轮询,然后在音频播放达到设定的时间长度后响应,如果音频需要一段时间才能加载,那么在当前时间之前它会相应地更长报告为 5.2 秒 - 我在这里模拟了这个:jsfiddle.net/jfL4mcnh/12
    • 是的,但是如果音频文件加载延迟 3 秒会发生什么,因为请求滞后?然后Javascript会出错:)
    • 这个答案会导致事件多次触发。提问者希望它只被调用一次。
    • @MaximillianLaumeister 实际上,当更多相关的 cmets 添加到我优先考虑的答案中时,我正在处理该添加 - triggered 变量,例如您的答案,是解决此问题的好方法
    猜你喜欢
    • 1970-01-01
    • 2012-08-07
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多