gpt4 book ai didi

javascript - 窗口最小化时的 AudioContext 计时问题

转载 作者:行者123 更新时间:2023-11-29 10:36:01 26 4
gpt4 key购买 nike

我按照 this article 中的说明进行操作并创建了一个 Javascript 节拍器。它使用 Web Audio API 并具有 audioContext.currentTime其核心是精确计时。

我的版本,可在 this plunker 获得, 是原版的非常简化版本,由 Chris Wilson 制作并可用 here .为了让我的工作,因为它使用一个实际的音频文件并且不通过振荡器合成声音,你需要下载 plunker 和 this audio file ,将它放在根文件夹中(这是节拍器的“滴答声”,但您可以使用任何您想要的声音)。

它就像一个魅力 - 如果不是因为如果用户最小化窗口,否则非常准确的节拍器会立即开始打嗝并且非常糟糕。我真的不明白这是什么问题。

Javascript

var context, request, buffer;
var tempo = 120;
var tickTime;

function ticking() {
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.start(tickTime);
}

function scheduler() {
while (tickTime < context.currentTime + 0.1) { //while there are notes to schedule, play the last scheduled note and advance the pointer
ticking();
tickTime += 60 / tempo;
}
}

function loadTick() {
request = new XMLHttpRequest(); //Asynchronous http request (you'll need a local server)
request.open('GET', 'tick.wav', true); //You need to download the file @ http://s000.tinyupload.com/index.php?file_id=89415137224761217947
request.responseType = 'arraybuffer';
request.onload = function () {
context.decodeAudioData(request.response, function (theBuffer) {
buffer = theBuffer;
});
};
request.send();
}

function start() {
tickTime = context.currentTime;
scheduleTimer = setInterval(function () {
scheduler();
}, 25);
}

window.onload = function () {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
context = new AudioContext();
loadTick();
start();
};

最佳答案

是的,这是因为当窗口失去焦点时,浏览器将 setTimeout 和 setInterval 限制为每秒一次。 (这样做是为了避免由于开发人员使用 setTimeout/setInterval 进行视觉动画而造成的 CPU/功率消耗,并且在选项卡失去焦点时不暂停动画。)

有两种解决方法:

1) 将“向前看”(在您的示例中为 0.1 秒)增加到大于一秒 - 例如 1.1 秒。不幸的是,这意味着您无法在更改延迟超过一秒的情况下更改内容(例如停止播放或更改速度);所以您可能只想在窗口上触发模糊事件时增加该值,并在触发窗口焦点事件时将其更改回 0.1。仍然不理想。

2) 规避节流。 :) 事实证明你可以这样做,因为 setTimeout/setInterval 在 Web Workers 中没有被限制! (这种方法最初是由我在 http://www.html5rocks.com/en/tutorials/audio/scheduling/#disqus_thread 的原始文章的评论线程中的某人建议的。)我在 https://github.com/cwilso/metronome 中为节拍器代码实现了这个。 :看看 js/metronome.js 和 js/metronomeworker.js。 Worker 基本上只是维护计时器,并将消息编码回主线程;看看https://github.com/cwilso/metronome/blob/master/js/metronome.js#L153 ,特别是看看它是如何启动的。您可以修改该代码片段并按原样使用 metronomeworker.js 来解决此问题。

关于javascript - 窗口最小化时的 AudioContext 计时问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36211993/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com