Подтвердить что ты не робот

API веб-аудио для прямой трансляции?

Нам нужно потоковое воспроизведение live аудио (от медицинского устройства) к веб-браузерам с задержкой от трех до трех дней (предположим, 200 мс или менее задержка сети). Сегодня мы используем плагин для браузера (NPAPI) для декодирования, фильтрации (высокий, низкий, диапазон) и воспроизведения аудиопотока (доставляемого через веб-сокеты).

Мы хотим заменить плагин.

Я смотрел различные демоверсии Web Audio API, и большинство наших требуемых функций (воспроизведение, управление усилением, фильтрация), похоже, доступный в Web Audio API. Однако мне непонятно, может ли Web Audio API использоваться для потоковых источников, поскольку большая часть веб-аудио API использует короткие звуки и/или аудиоклипы.

Можно ли использовать API веб-аудио для воспроизведения потокового аудио в реальном времени?

Обновление (11-фев-2015):

После немного большего количества исследований и локального прототипирования я не уверен, что потоковая передача аудио в реальном времени с помощью Web Audio API возможна. Поскольку Web Audio API decodeAudioData​​strong > не предназначен для обработки случайных фрагментов аудиоданных (в нашем случае поставляется через WebSockets). Кажется, нужен весь "файл", чтобы правильно его обработать.

См. stackoverflow:

Теперь с помощью createMediaElementSource можно подключить элемент <audio> к API веб-аудио, но мой опыт в том, что элемент <audio> вызывает огромное количество сквозных задержки (15-30 с), и, похоже, нет никаких средств для снижения задержки до менее 3-5 секунд.

Я думаю, что единственным решением является использование WebRTC с API Web Aduio. Я надеялся избежать WebRTC, так как это потребует значительных изменений в нашей серверной реализации.

Обновление (12 февраля 2015 г.) Часть I:

Я не полностью уничтожил тег <audio> (нужно закончить мой прототип). Как только я это исключил, я подозреваю, что createScriptProcessor (устаревший, но все еще поддерживаемый) будет хорошим выбором для нашей среды, поскольку я мог бы "потопить" (через WebSockets) наши данные ADPCM в браузер, а затем (в JavaScript) преобразовать его в PCM. Подобно тому, что в библиотеке Скотта (см. Ниже), используется с помощью createScriptProcessor. Этот метод не требует, чтобы данные были в размерах "кусков" и критических сроках в качестве подхода decodeAudioData.

Обновление (12 февраля 2015 г.) Часть II:

После большего тестирования я исключил интерфейс <audio> в интерфейс веб-аудио API, потому что, в зависимости от типа источника, сжатия и браузера, конечная задержка может составлять 3-30 секунд. Это оставляет метод createScriptProcessor (см. Сообщение Скотта ниже) или WebRTC. После обсуждения с нашими лицами, принимающими решения, было решено, что мы примем подход WebRTC. Я предполагаю, что это сработает. Но это потребует изменений в нашем коде на стороне сервера.

Я собираюсь отметить первый ответ, так что "вопрос" закрыт.

Спасибо, что слушал. Не стесняйтесь добавлять комментарии по мере необходимости.

4b9b3361

Ответ 1

Да, для потоковой передачи можно использовать API веб-аудио (вместе с AJAX или Websockets).

В принципе, вы вытаскиваете (или отправляете в случае с Websockets) некоторые фрагменты длины n. Затем вы декодируете их с помощью API веб-аудио и ставите их в очередь для воспроизведения один за другим.

Поскольку API веб-аудио имеет высокоточную синхронизацию, вы не услышите никаких "швов" между воспроизведением каждого буфера, если вы правильно планируете.

Ответ 2

Я написал поточную систему веб-аудио API, в которой я использовал веб-работников, чтобы все управление веб-сокетами связывалось с node.js, так что поток браузера просто воспроизводит аудио... отлично работает на ноутбуках, поскольку мобильные телефоны отстают от их внедрения веб-сокетов внутри веб-работников, вам нужно не меньше, чем леденец, чтобы он работал как закодированный... Я отправил полный исходный код здесь

Ответ 3

Подробнее о комментариях о том, как играть кучу отдельных буферов, хранящихся в массиве, каждый раз переставляя последнюю из них:

Если вы создаете буфер через createBufferSource(), то он имеет событие onended, к которому вы можете подключить обратный вызов, который будет срабатывать, когда буфер достигнет своего конца. Вы можете сделать что-то подобное, чтобы поочередно воспроизводить различные куски в массиве:

function play() {
  //end of stream has been reached
  if (audiobuffer.length === 0) { return; }
  let source = context.createBufferSource();

  //get the latest buffer that should play next
  source.buffer = audiobuffer.shift();
  source.connect(context.destination);

  //add this function as a callback to play next buffer
  //when current buffer has reached its end 
  source.onended = play;
  source.start();
}

Надеюсь, что это поможет. Я все еще экспериментирую с тем, как все это гладко и гладко, но это хорошее начало и отсутствие во многих онлайн-сообщениях.