Как воспроизвести аудиопотоки, записанные с помощью WebRTC?
Я пытаюсь создать экспериментальное приложение для потоковой передачи аудио в режиме реального времени с client 1
в client 2
,
Поэтому, следуя некоторым урокам и вопросам на ту же тему, я использовал WebRTC и binaryjs. Пока это то, что я получаю
1- Client 1
а также Client 2
подключился к BinaryJS для отправки / получения фрагментов данных.
2- Client 1
использовал WebRTC для записи аудио и постепенной отправки его в BinaryJS
3- Client 2
получает куски и пытается их воспроизвести.
Ну, я получаю ошибку в последней части. Это сообщение об ошибке, которое я получаю:
Uncaught RangeError: источник слишком велик
на Float32Array.set (родной)
И это код:
Клиент 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': невозможно установить буфер после того, как он уже был установлен
Вероятно, потому что я устанавливаю это каждый раз, когда я получаю новый кусок данных.
1 ответ
ДОМАШНЕЕ исключение AudioBufferSourceNode
означает, что вам нужно создать новый AudioBufferSourceNode
за каждый новый Audiobuffer
что вы создаете. Так что-то вроде
sourceNode = new AudioBufferSourceNode(audioContext, {buffer: audioBuffer})
И AudioBuffer
имеет Float32Array
s. Вам нужно конвертировать вашиInt16Array
к Float32Array
прежде чем назначить егоAudioBuffer
, Вероятно, достаточно хорошо, чтобы разделить все на 32768.