无缝音频循环到任意位置

Posted

技术标签:

【中文标题】无缝音频循环到任意位置【英文标题】:Seamless audio loop to an arbitrary position 【发布时间】:2013-06-17 16:07:14 【问题描述】:

我最喜欢 MOD 格式的一件事是能够循环回歌曲中的任何给定点,这使其非常适合具有“前奏”和“主循环”的歌曲。

当然,MP3 做不到。

到目前为止,我做过这样的事情:

<audio src="/path/to/song.mp3" onEnded="this.currentTime = 12.345;"></audio>

其中浮点值是主循环开始的时间。

虽然这可行,但音频重新启动时会出现明显的几分之一秒的停顿。我可以通过将目标时间设置在应有的时间前一点来减轻这种暂停的影响,因此节拍至少保持更接近的时间,但这并不是很理想。

我能想到的主要替代方法是手动循环音频文件(例如,在 Audacity 中通过复制粘贴)以制作比最可能需要的更长的歌曲,但问题在于会造成大量硬盘空间和带宽的浪费,也解决不了人们喜欢一首歌就停下来听很久的问题。

所以我想知道是否有任何方法可以循环 MP3 流。如果我正确理解格式,我应该能够确定主循环在文件中的哪个位置(以字节为单位)开始(以秒为单位),所以理论上我可以构造一个无限循环的流。但是,HTM5 音频会支持这样的流吗?

【问题讨论】:

你看过this site on gapless looping?它不包括html5,但它确实谈到了mp3文件中需要有什么循环的理论。 @AShelly 虽然这很有趣,但它只适用于要循环回到开头的文件,而不是任意点。 只是觉得我应该指出另一个 SO 问题:Looping Audio HTML5 @Kolink 如果我没记错的话,它也适用于延伸到轨道末端的循环。由于最后一帧必须是固定样本数的倍数,因此用静音填充。如果这适用于您的情况,填充/偏移开头可能有助于填充最后一帧。 +1 参考 MOD :D 怀旧在我的皮肤下蔓延... 【参考方案1】:

尝试每次测量延迟:

function playSeamless(clip, next) 
    if(!next) 
        next = clip.cloneNode(true);
        next.controls = false;
    

    var start = Date.now();
    clip.play();

    setTimeout(function() 
        var time = (Date.now() - start) / 1000;
        var position = clip.currentTime;
        var delay = time - position;

        setTimeout(function() 
            // Set desired currentTime on next here and adjust delay above
            playSeamless(next, clip);
        , (clip.duration - clip.currentTime - delay * 2.35) * 1000 | 0);
    , 200);


playSeamless(yourAudioClip);

它更好,但并不完全准确,所以我需要调整* 2.35 或使其成为减法或其他东西。

【讨论】:

SeamlessLoop 使用类似的策略。在网上找到这个github.com/Hivenfour/SeamlessLoop/blob/master/SeamlessLoop.js。

以上是关于无缝音频循环到任意位置的主要内容,如果未能解决你的问题,请参考以下文章

std::transform 到任意容器

如何从导航堆栈中的任何位置弹出到任意视图控制器

使用T4模板动态生成邮件内容并储存到任意位置

使用 Rcpp 将矩阵四舍五入到任意精度

均匀分布映射到任意分布

如何将数据集下载到 Torch 中的任意位置?