Как синхронизировать обратные вызовы getUserMedia в синглтоне
Я использую Singleton, чтобы получить аудио-рекордер, но getUserMedia является асинхронным, и я должен дождаться окончания обратных вызовов, чтобы вернуть объект рекордера. Возможно, это не лучший выбор для смешивания синхронного и асинхронного, но я не вижу, как я могу это сделать, потому что не могу сделать getUserMedia синхронным.
Идея состоит в том, чтобы вызвать SoundRecorder.getInstance(), который попросит пользователя разрешить доступ к микрофону один для всех и иметь возможность получить экземпляр рекордера в любое время, когда мне нужно.
Проблема при первом звонке:
var рекордер = 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);
}
}
}) ();
1 ответ
Наконец, я отказался от использования синглтона, чтобы использовать только обратные вызовы. Я сделал трюк, чтобы просто вызвать getUserMedia один раз со скрытым полем ввода, которое я использую для обработки другого статуса: "включено", если пользователь разрешил доступ к микрофону, "отключено", если веб-аудио не поддерживается, "доступ", когда доступ спросил пользователя. Я думаю, что не так элегантно, но это работает. Я надеюсь, что это может помочь кому-нибудь однажды;-)