Как уменьшить звук, записанный с микрофона в реальном времени в JavaScript?
Я использую следующий JavaScript для записи аудио и отправки его на сервер веб-сокета:
const recordAudio = () =>
new Promise(async resolve => {
const constraints = {
audio: {
sampleSize: 16,
channelCount: 1,
sampleRate: 8000
},
video: false
};
var mediaRecorder;
const stream = await navigator.mediaDevices.getUserMedia(constraints);
var options = {
audioBitsPerSecond: 128000,
mimeType: 'audio/webm;codecs=pcm'
};
mediaRecorder = new MediaRecorder(stream, options);
var track = stream.getAudioTracks()[0];
var constraints2 = track.getConstraints();
var settings = track.getSettings();
const audioChunks = [];
mediaRecorder.addEventListener("dataavailable", event => {
audioChunks.push(event.data);
webSocket.send(event.data);
});
const start = () => mediaRecorder.start(30);
const stop = () =>
new Promise(resolve => {
mediaRecorder.addEventListener("stop", () => {
const audioBlob = new Blob(audioChunks);
const audioUrl = URL.createObjectURL(audioBlob);
const audio = new Audio(audioUrl);
const play = () => audio.play();
resolve({
audioBlob,
audioUrl,
play
});
});
mediaRecorder.stop();
});
resolve({
start,
stop
});
});
Это для STT в реальном времени, и сервер websocket отказался отправлять какой-либо ответ. Я проверил отладкой, что sampleRate не меняется на 8 кГц. При исследовании я обнаружил, что это известная ошибка как в chrome, так и в firefox. Я нашел некоторые другие ресурсы, такие как stackru1 и IBM_STT, но я понятия не имею, как адаптировать его к моему коду. Вышеупомянутые полезные ресурсы относятся к буферу, но все, что у меня есть, это mediaStream (поток) и event.data (blob) в моем коде. Я новичок в javascript и Audio Api, поэтому, пожалуйста, извините, если я сделал что-то не так.
Если это поможет, у меня есть эквивалентный код Python для отправки данных с микрофона на сервер websocket, который работает. Используемая библиотека = Pyaudio. Код:
p = pyaudio.PyAudio()
stream = p.open(format="pyaudio.paInt16",
channels=1,
rate= 8000,
input=True,
frames_per_buffer=10)
print("* recording, please speak")
packet_size = int((30/1000)*8000) # normally 240 packets or 480 bytes
frames = []
#while True:
for i in range(0, 1000):
packet = stream.read(packet_size)
ws.send(packet, binary=True)
1 ответ
Для выполнения понижающей дискретизации в реальном времени выполните следующие действия:
Сначала получите экземпляр потока, используя это:
const stream = await navigator.mediaDevices.getUserMedia(constraints);
Создать источник медиа потока из этого потока.
var input = audioContext.createMediaStreamSource(stream);
Создайте обработчик сценариев, чтобы вы могли играть с буферами. Я собираюсь создать скрипт-процессор, который будет непрерывно отбирать 4096 сэмплов из потока, иметь 1 входной канал и 1 выходной канал.
var scriptNode = audioContext.createScriptProcessor(4096, 1, 1);
Подключите ваш вход с помощью scriptNode. Вы можете подключить узел сценария к месту назначения согласно вашему требованию.
input.connect(scriptNode); scriptNode.connect(audioContext.destination);
Теперь в script Processor есть функция onaudioprocess, где вы можете делать все, что захотите, с 4096 выборками. var downsample будет содержать (1/ коэффициент выборки) количество пакетов. floatTo16BitPCM преобразует это в нужный вам формат, поскольку исходные данные находятся в 32-битном формате с плавающей запятой.
var inputBuffer = audioProcessingEvent.inputBuffer; // The output buffer contains the samples that will be modified and played var outputBuffer = audioProcessingEvent.outputBuffer; // Loop through the output channels (in this case there is only one) for (var channel = 0; channel < outputBuffer.numberOfChannels; channel++) { var inputData = inputBuffer.getChannelData(channel); var outputData = outputBuffer.getChannelData(channel); var downsampled = downsample(inputData); var sixteenBitBuffer = floatTo16BitPCM(downsampled); }
Ваш sixteenBitBuffer будет содержать данные, которые вам необходимы.
Функции для понижающей дискретизации и floatTo16BitPCM описаны в этой ссылке API Watson: IBM Watson Speech to Text Api
Вам не понадобится экземпляр MediaRecorder. Watson API с открытым исходным кодом, и вы можете найти более рациональный подход к тому, как они реализовали его для своего варианта использования. Вы должны быть в состоянии спасти важные функции из их кода.