Как можно предотвратить сбои / прерывистость / сбои при использовании AudioWorklet для потоковой передачи захваченного звука? - PullRequest
0 голосов
/ 20 февраля 2019

Мы работали над клиентом аудио-чата на основе JavaScript, который запускается в браузере и отправляет аудиосэмплы на сервер через WebSocket.Ранее мы пытались использовать ScriptProcessorNode API Web Audio для получения значений образца.Это хорошо работало на наших настольных компьютерах и ноутбуках, но при передаче с портативной платформы, которую мы должны поддерживать, мы столкнулись с низким качеством звука.Мы связываем это с задокументированными проблемами с производительностью процессора сценариев (https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API).). На контроллере с размером буфера процессора сценария 2048 звук постоянно прерывался. На следующем максимальном интервале размера (4096) звук былплавно (без сбоев), но было слишком много задержки (около двух секунд).

Наши результаты ScriptProcessorNode привели к экспериментам с Audio Worklet. К сожалению, с нашей реализацией worklet качество звука хуже: и сбои, и задержкаДаже на наших ноутбуках. Мне интересно, есть ли способ настроить нашу реализацию рабочего стола, чтобы получить лучшую производительность, или же от того, что мы испытываем, можно ожидать (от "курса" для) текущего состояниязвуковые рабочие листы (проблемы с хромом 796330 , 813825 и 836306 кажутся актуальными).

Вот немного подробнее о том, что делает код:

  1. Создать MediaStreamStreamSourceNode с MediaStream, полученным из getUserMedia.
  2. Соедините исходный узел с нашей реализацией узла рабочего стола (расширяет AudioWorkletNode).
  3. Наша реализация процессора рабочего стола (расширяет AudioWorkletProcessor) буферизует блоки, которые поступают в качестве аргумента «input» в свой метод процесса.
  4. Когда буфер заполнен, используйте MessagePort для отправки содержимого буфера узлу рабочего стола.
  5. Узел рабочего стола передает содержимое буфера через соединение WebSocket.

Способ процесса ниже.Переменная «samples» представляет собой массив Float32Array, который инициализируется до размера буфера и используется повторно.Я немного поэкспериментировал с размером буфера, но это, похоже, не оказало влияния.Подход основан на руководстве в разделе 4.1 AudioWorklet: будущее веб-аудио для минимизации выделения памяти.

if (micKeyed == true) {

    if (inputs[0][0].length == framesPerBlock) {
        samples.set(inputs[0][0], currentBlockIndex * framesPerBlock);
        currentBlockIndex++;

        if (currentBlockIndex == lastBlockIndex) {
            // console.log('About to send buffer.');
            this.port.postMessage(samples);
            currentBlockIndex = 0;
        }
    } else {
        console.error("Got a block of unexpected length!!!");
    }
}
return true;

В настоящее время проводится тестирование на ПК с Chrome 72.0.3626.109 на CentOS 7Наши портативные устройства - Panasonic FZ-N1, работающие под управлением Chrome 72.0.3626.105 на Android 6.0.1.

Спасибо за чтение и за любые предложения, которые вы можете предоставить.

...