我正在尝试使用WebAudio API,但是在使其与Safari一起正常工作时遇到问题。我的实验可以在Firefox和Chrome上正常运行。
我编写了一个Promisified函数来演奏单个音符,然后尝试使用该功能来演奏一系列音符。
仅在Safari上,它在前四个注释后显示以下消息失败:
未处理的承诺拒绝:TypeError:null不是对象(正在评估“ 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/