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

Воспроизведение потока PCM из API веб-аудио на Node.js

Я транслирую записанный звук PCM из браузера с помощью веб-аудио api.

Я передаю его с помощью binaryJS (соединение с веб-сайтами) на сервер nodejs, и я пытаюсь воспроизвести этот поток на сервере с помощью модуля динамиков npm.

Это мой клиент. Звуковые буферы - это первый неперемещенный 32-разрядный линейный ИКМ IEEE с номинальным диапазоном от -1 до +1. Я беру один из двух каналов PCM, чтобы начать и потопить его ниже.

var client = new BinaryClient('ws://localhost:9000');
var Stream = client.send();

recorder.onaudioprocess = function(AudioBuffer){
    var leftChannel = AudioBuffer.inputBuffer.getChannelData (0);
    Stream.write(leftChannel);
}

Теперь я получаю данные в виде буфера и пытаюсь записать его в объект динамика из пакета npm.

var Speaker = require('speaker');

var speaker = new Speaker({
  channels: 1,          // 1 channel
  bitDepth: 32,         // 32-bit samples
  sampleRate: 48000,     // 48,000 Hz sample rate
  signed:true
});

server.on('connection', function(client){
    client.on('stream', function(stream, meta){
        stream.on('data', function(data){
            speaker.write(leftchannel);
        });
    });
});

В результате получается высокий визг на моем ноутбуке, который явно не является тем, что записывается. Это тоже не обратная связь. Я могу подтвердить, что буферы записи на клиенте действительны, так как я пытался записать их в WAV файл, и он отлично воспроизводится.

docs для динамиков и docs для AudioBuffer, о которых идет речь

Я был в тупике в течение нескольких дней. Может ли кто-то выяснить, что не так, или, возможно, предложить другой подход?

Обновление с помощью решения

Во-первых, я неправильно использовал API-интерфейс websocket. Я обновил выше, чтобы использовать его правильно.

Мне нужно было преобразовать звуковые буферы в буфер массива целых чисел. Я предпочитаю использовать Int16Array. Так как данный звуковой буфер имеет диапазон между 1 и -1, это было так же просто, как умножение на диапазон нового ArrayBuffer (32767 по -32768).

recorder.onaudioprocess = function(AudioBuffer){

    var left = AudioBuffer.inputBuffer.getChannelData (0);

    var l = left.length;
    var buf = new Int16Array(l)

    while (l--) {
        buf[l] = left[l]*0xFFFF;    //convert to 16 bit
    }

    Stream.write(buf.buffer);

}
4b9b3361

Ответ 1

Похоже, вы отправляете свой поток как объект meta.

В соответствии с документами BinaryClient.send берет объект data (поток) и объект meta в указанном порядке, Обратный вызов для события stream принимает поток (как объект BinaryStream, а не Buffer) в первом параметре, а meta объект во втором.

Вы передаете send() строку 'channel' как поток и Float32Array из getChannelData() в качестве метаобъекта. Возможно, если бы вы обменяли эти два параметра (или просто использовали client.send(leftChannel)), а затем изменили код сервера, чтобы передать stream в speaker.write вместо leftchannel (который, вероятно, должен быть переименован в meta или удален если вам это не нужно), это может сработать.

Обратите внимание, что поскольку Float32Array не является потоковым или буферным объектом, BinaryJS может попытаться отправить его в один фрагмент. Вместо этого вы можете отправить leftChannel.buffer (ArrayBuffer за этот объект).

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