【问题标题】:Safari — Cannot create Oscillator after the first fewSafari — 在前几个之后无法创建振荡器
【发布时间】:2020-07-12 16:02:11
【问题描述】:

我正在尝试使用 WebAudio API,但无法使其与 Safari 一起正常工作。我的实验适用于 Firefox 和 Chrome。

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

仅在 Safari 上,前四个音符后失败并显示以下消息:

未处理的 Promise Rejection: TypeError: null is not an object (evalating '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>

【问题讨论】:

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


    【解决方案1】:

    限制是您可以同时运行的 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>

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多