Chrome: onaudioprocess перестает вызываться через некоторое время

#google-chrome #web-audio-api #getusermedia

#google-chrome #web-audio-api #getusermedia

Вопрос:

Я использую обратный вызов onaudioprocess от ScriptProcessorNode для обработки ввода микрофона. Подключив MediaStreamSourceNode к ScriptProcessorNode, я могу получить необработанные аудиоданные в функции обратного вызова onaudioprocess. Однако примерно через 30 секунд (это время варьируется от 10 до 35 секунд) браузер перестает вызывать onaudioprocess. В следующем коде консоль.вывод журнала (‘>>’) всегда останавливается примерно через 30 секунд.

 var ctx = new AudioContext();
var BUFFER_LENGTH = 4096;
console.log('Buffer length is   '   BUFFER_LENGTH);
navigator.webkitGetUserMedia({audio: true}, function (stream) {
    var mediaStreamSource = ctx.createMediaStreamSource(stream);
    var scriptProcessor = ctx.createScriptProcessor(BUFFER_LENGTH, 1, 1);
    scriptProcessor.onaudioprocess = function (e) {
      console.log('>>');
    };
    scriptProcessor.connect(ctx.destination);
}, function(e) {
  console.error('Unable to get audio input source.');
});
  

Я перепробовал все возможные BUFFER_LENGTH (256, 512, 1024, 2048, 4096, 8192, 16384), но ситуация не изменилась (журнал останавливается через 30 секунд).
Я заметил эту проблему в последней версии Chrome (версия 35.0.1916.153) и Canary (версия 37.0.2060.3 canary.)
Кто-нибудь знает какие-либо обходные пути?

Комментарии:

1. Мне интересно, связано ли это с тем фактом, что вы возвращаете пустые e.outputbuffers в обратных вызовах onaudioprocess. Через 30 секунд, увидев пустые буферы, Chrome может захотеть сэкономить заряд батареи / вычислительную мощность и отключить обратный вызов.

2. Спасибо notthetup, я попытался скопировать входной буфер в выходной буфер в onaudioprocess. Но это не устранило проблему. Вот код: var source = e.InputBuffer.getChannelData(0); var dest = e.outputBuffer.getChannelData(0); dest.set(источник);

Ответ №1:

Это больше похоже на то, что ваш объект scriptprocessor собирает мусор. Попробуйте сохранить его в глобальной переменной и посмотреть, решит ли это проблему.

Комментарии:

1. Спасибо, Крис. Как вы сказали, сохранение ScriptProcessorNode в глобальной переменной устранило эту проблему. Но я думаю, что это поведение (сбор мусора на все еще подключенном узле) необходимо исправить. Это уже было зарегистрировано как ошибка?

2. Если я правильно помню, назначение AudioContext не поддерживает ссылку на ScriptProcessor. Таким образом, сборка мусора ScriptProcessor здесь действительно уместна, потому что ничто не имеет ссылки на него.

3. Я обнаружил открытую ошибку, которая, похоже, связана с этой проблемой: ошибки. webkit.org/show_bug.cgi?id=112521 Похоже, что патч был предложен в прошлом году, но он еще не принят.

4. В спецификации указано, что: «Любые AudioNodes, которые подключены в цикле и прямо или косвенно связаны с AudioDestinationNode AudioContext, будут оставаться активными до тех пор, пока AudioContext активен». w3.org/TR/webaudio/#lifetime-AudioNode

5. Я обнаружил эту ошибку Chrome (все еще не проверенную): code.google.com/p/chromium/issues/detail?id=360378