Как воспроизвести фрагменты аудиопотока, записанные с помощью WebRTC?

1

Я пытаюсь создать экспериментальное приложение, которое передает аудио в реальном времени от client 1 к client 2.

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

1- Client 1 и Client 2 подключились к BinaryJS для отправки/приема блоков данных.

2- Client 1 использовал WebRTC для записи звука и постепенно отправлял его в BinaryJS

3- Client 2 получает куски и пытается их воспроизвести.

Ну, я получаю ошибку в последней части. Это сообщение об ошибке, которое я получаю:

Uncound RangeError: источник слишком большой

на Float32Array.set(native)

И это код:

Клиент 1

var WSClient;
var AudioStream;

function load(){
    var session = {
        audio: true,
        video: false
    };

    var recordRTC = null;

    navigator.getUserMedia(session, startRecording, onError);
    WSClient = new BinaryClient('ws://localhost:9001');
    WSClient.on('open',function(){
        console.log('client opened')
        AudioStream = WSClient.createStream();
    })
}

function startRecording(stream){
    var context = new AudioContext();
    var audio_input = context.createMediaStreamSource(stream);
    var buffer_size = 2048;

    var recorder = context.createScriptProcessor(buffer_size, 1, 1);

    recorder.onaudioprocess = function(e){
        console.log('chunk')
        var left = e.inputBuffer.getChannelData(0);
        AudioStream.write(left);
    };

    audio_input.connect(recorder);
    recorder.connect(context.destination);
}

Клиент 2

var WSClient;
var audioContext;
var sourceNode;

function load(){
    audioContext = new AudioContext();
    sourceNode = audioContext.createBufferSource();
    sourceNode.connect(audioContext.destination);

    sourceNode.start(0);

    WSClient = new BinaryClient('ws://localhost:9001');

    WSClient.on('open',function(){
        console.log('client opened');
    });

    WSClient.on('stream', function(stream, meta){
        // collect stream data
        stream.on('data', function(data){
            console.log('received chunk')
            var integers = new Int16Array(data);
            var audioBuffer = audioContext.createBuffer(1, 2048, 4410);
            audioBuffer.getChannelData(0).set(integers); //appearently this is where the error occurs
            sourceNode.buffer = audioBuffer;
        });
    });
}

сервер

var wav = require('wav');
var binaryjs = require('binaryjs');

var binaryjs_server = binaryjs.BinaryServer;

var server = binaryjs_server({port: 9001});

server.on('connection', function(client){
    console.log('server connected');

    var file_writter = null;

    client.on('stream', function(stream, meta){
        console.log('streaming', server.clients)
        //send to other clients
        for(var id in server.clients){
            if(server.clients.hasOwnProperty(id)){
                var otherClient = server.clients[id];
                if(otherClient != client){
                    var send = otherClient.createStream(meta);
                    stream.pipe(send);
                }
            }
        }
    });

    client.on('close', function(stream){
        console.log('client closed')
        if(file_writter != null) file_writter.end();
    });
});

Ошибка возникает здесь:

audioBuffer.getChannelData(0).set(integers);

Поэтому у меня есть два вопроса:

Можно ли отправить куски, которые я захватил в client 1 а затем воспроизвести их в client 2?

Какая сделка с ошибкой, которую я имею?

Спасибо, парни!

@edit 1

Поскольку я получаю фрагменты кода из других вопросов, я все еще пытаюсь понять это. Я прокомментировал строку в коде client 2 которая создает Int16Array и теперь я получаю другую ошибку (но я не знаю, какая версия кода вернее):

Uncaught DOMException: Не удалось установить свойство "buffer" в "AudioBufferSourceNode": не удается установить буфер после того, как он уже установлен

Наверное, потому что я настраиваю его каждый раз, когда получаю новый кусок данных.

Теги:
audio
web-audio
webrtc

1 ответ

0

DOMException об AudioBufferSourceNode означает, что вам нужно создать новый AudioBufferSourceNode для каждого нового Audiobuffer. Так что-то вроде

sourceNode = new AudioBufferSourceNode(audioContext, {buffer: audioBuffer})

И AudioBuffer имеет Float32Array s. Вам необходимо преобразовать Int16Array в Float32Array прежде чем назначать его AudioBuffer. Наверное, достаточно хорошо, чтобы разделить все на 32768.

  • 0
    Эй, спасибо за твой ответ. Но правильный ли это подход? Создание нового источника каждый раз, когда я получаю новый кусок?
  • 0
    Учитывая текущий код, да, я думаю, что это единственный путь. Это не здорово. Я не очень знаком с WebRTC и тому подобным, но могут быть и другие способы, с помощью которых ваш сервер может просто передавать данные, скажем, на аудиоэлемент, который вы можете подключить к WebAudio.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню