javascript - Safari — 在前几个之后无法创建振荡器

标签 javascript safari es6-promise web-audio-api

我正在尝试使用 WebAudio API,但在使其与 Safari 一起正常工作时遇到问题。我的实验在 Firefox 和 Chrome 上运行正常。

我编写了一个 Promisified 函数来播放单个音符,然后尝试使用该函数播放一系列音符。

仅在 Safari 上,前四个注释后会失败,并显示以下消息:

Unhandled Promise Rejection: TypeError: null is not an object (evaluating 'context.createOscillator')

好的,我还没有处理这个错误,但是为什么我会收到这个错误?它建议限制四个振荡器。

function tone(frequency,duration) {
	return new Promise(function (resolve,reject) {
		var audioContext = window.AudioContext || window.webkitAudioContext;
		var context=new audioContext;
		var oscillator = context.createOscillator();
		oscillator.frequency.value = frequency;
		oscillator.connect(context.destination);
		oscillator.type='sawtooth';
		oscillator.start(context.currentTime);
		oscillator.stop(context.currentTime+duration);
		oscillator.onended=resolve;
	});
}
document.querySelector('button#play-test').onclick=function(event) {
	tone(130.81,1)
	.then(()=>tone(146.83,1))
	.then(()=>tone(164.81,1))
	.then(()=>tone(174.61,1))
	.then(()=>tone(196.00,1))
	;
};
<button id="play-test">Play</button>

最佳答案

限制在于您可以同时运行的 AudioContext 数量。

某些浏览器有这样的限制,因为 AudioContext 需要来自硬件(声卡)的资源,并且该硬件有限制。

因此请重构您的代码,以便它不会每次都创建新的 AudioContext:

// create a single audio context
var context = new (window.AudioContext || window.webkitAudioContext)();

function tone(frequency, duration) {
  return new Promise(function(resolve, reject) {
    var oscillator = context.createOscillator();
    oscillator.frequency.value = frequency;
    oscillator.connect(context.destination);
    oscillator.type = 'sawtooth';
    oscillator.start(context.currentTime);
    oscillator.stop(context.currentTime + duration);
    oscillator.onended = resolve;
  });
}
document.querySelector('button#play-test').onclick = function(event) {
  tone(130.81, 1)
    .then(() => tone(146.83, 1))
    .then(() => tone(164.81, 1))
    .then(() => tone(174.61, 1))
    .then(() => tone(196.00, 1))
    .catch(console.error);
};
<button id="play-test">Play</button>

关于javascript - Safari — 在前几个之后无法创建振荡器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60961828/

相关文章:

javascript - 无论如何,限制平移时更新谷歌地图

javascript - stub 未执行回调(Javascript)

css - 为什么我的页面在 Safari 和 firefox 中的起始位置比在 Chrome 中高?

ssl - Safari 不断重新加载带有自定义 CA 证书的页面

Javascript Promise 返回值

javascript - 在 JavaScript 中从生成器创建数组

javascript - .click 子div 但不触发单击parent Div?

javascript - Safari 出现文本输入问题,用户输入文本时选择文本,导致文本丢失

javascript - promise 解决得太快

asynchronous - 在javascript中,一个返回promise并重试内部异步过程最佳实践的函数