我正在使用Singleton获取录音机,但getUserMedia是异步的,我必须等待回调结束才能返回录音机对象。混合使用同步和异步可能不是一个好选择,但我不知道该怎么做,因为我无法使getUserMedia同步。
这个想法是调用SoundRecorder.getInstance(),它将要求用户允许麦克风访问所有麦克风,并能够在我需要的任何时候获得记录器实例。
问题出现在第一次呼叫时:
var recorder=SoundRecorder.getInstance()
记录器值为"未定义",则它对其他调用正常工作。
这是我下面的代码。谢谢你的帮助。
var SoundRecorder=(function(){
var instance = null;
function init () {
var dfd = $.Deferred();
if (instance == null) {
navigator.getUserMedia({audio: true},
function(stream) {
var audioContext = new AudioContext();
var input = audioContext.createMediaStreamSource(stream);
console.log('Media stream created.');
input.connect(audioContext.destination);
console.log('Input connected to audio context destination.');
instance = new Recorder(input);
dfd.resolve('recorder created');
},
function (e) {
dfd.reject('No live audio input');
notify('error', 'No live audio input: ' + e);
});
} else {
dfd.resolve('recorder already created');
}
return dfd.promise();
}
function waitFor(p){
if (p.state() == "resolved" || p.state() == "rejected") {
return instance;
} else {
setTimeout(waitFor, 500, p);
}
}
return {
getInstance: function() {
var promise = init();
promise.then(function () {
console.log('init success');
}, function () {
console.log('init failed');
});
return waitFor(promise);
}
}
})();
最后我放弃了使用singleton,只使用回调。我做了一个技巧,只调用getUserMedia一次,并使用一个输入隐藏字段来处理不同的状态:如果用户允许麦克风访问,则为"启用";如果不支持网络音频,则为为"禁用";当用户被要求访问时,为"访问"。我觉得不那么优雅,但它很管用。我希望有一天这能帮助到别人;-)