Как предотвратить сбои / прерывистость / сбои при использовании AudioWorklet для потоковой передачи захваченного звука?

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

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

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

  1. Создайте MediaStreamStreamSourceNode с MediaStream, полученным из getUserMedia.
  2. Подключите исходный узел к нашей реализации узла рабочего стола (расширяет AudioWorkletNode).
  3. Наша реализация процессора рабочих процессов (расширяет AudioWorkletProcessor) буферизует блоки, которые поступают в качестве аргумента "input" в его метод процесса.
  4. Когда буфер заполнен, используйте MessagePort для отправки содержимого буфера узлу рабочего стола.
  5. Узел Worklet передает содержимое буфера через соединение 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.

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

0 ответов

Другие вопросы по тегам