Как извлечь необработанный звук PCM прямо из браузера без преобразования или зависания пользовательского интерфейса?Javascript

Форум по Javascript
Ответить
Anonymous
 Как извлечь необработанный звук PCM прямо из браузера без преобразования или зависания пользовательского интерфейса?

Сообщение Anonymous »

*Я создаю интерфейс React + Vite. В приложении у меня есть модуль преобразования голоса в текст, использующий Azure Speech SDK. Я захватываю аудио в браузере и отправляю фрагменты аудио PCM каждые 100 мс через WebSocket в службу Python.
В настоящее время я конвертирую фрагменты в клиенте (например, преобразование с понижением частоты/формата), и это преобразование вызывает зависание пользовательского интерфейса и не является оптимальным — клиент должен быть легким.
Я хотел бы знать: есть ли способ извлечь PCM аудиофрагменты непосредственно из браузера — без дорогостоящего преобразования на стороне клиента — чтобы клиент выполнял минимальную работу и отправлял «готовый к использованию» PCM на сервер?
*
// Recording Start Method

const handleStartRecording = async (
callBack: () => void,
socketInfo: WebSocket | null = socket.current
): Promise => {
try {
const mediaStream = await navigator.mediaDevices.getUserMedia({
audio: { channelCount: 1, sampleRate: 16000 }
})

const systemStream = await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: true
})

const audioContext = new AudioContext({ sampleRate: 16000 })
const destination = audioContext.createMediaStreamDestination()

if (systemStream?.getAudioTracks()?.length > 0) {
const micSource = audioContext.createMediaStreamSource(mediaStream)
const systemSource = audioContext.createMediaStreamSource(systemStream)

micSource.connect(destination)
systemSource.connect(destination)
} else {
console.warn("System audio was not shared. Only microphone will be captured.")
}
await audioContext.audioWorklet.addModule("/processor.js")
const pcmNode = new AudioWorkletNode(audioContext, "pcm-processor", {
channelCount: 1
})

const destinationStreamSource = audioContext.createMediaStreamSource(
destination.stream
)
destinationStreamSource.connect(pcmNode)
pcmNode.port.onmessage = (event) => {
const pcmChunk = event.data
if (
stateRef?.current === "RECORDING" &&
pcmChunk &&
pcmChunk.length > 0 &&
socketInfo?.readyState === WebSocket.OPEN
) {
socketInfo.send(pcmChunk.buffer)
}
}
setRecording(true)
setState("RECORDING")
setIsStarted(true)
setAudioContextState(audioContext)
setMediaStream(mediaStream)
setSystemStream(systemStream)
callBack()
} catch (err) {
console.error("Error capturing audio:", err)
}
}

// processor.js

class AudioProcessor extends AudioWorkletProcessor {
constructor() {
super()
this.buffer = []
this.bufferSize = sampleRate * 0.1
}

floatTo16BitPCM(float32Array) {
const int16Array = new Int16Array(float32Array.length)
for (let i = 0; i < float32Array.length; i++) {
let s = Math.max(-1, Math.min(1, float32Array))
int16Array = s < 0 ? s * 0x8000 : s * 0x7fff
}
return int16Array
}

process(inputs) {
const input = inputs?.[0]
if (!input || input.length === 0) return true

const inputChannel = input[0]
this.buffer.push(...inputChannel)

if (this.buffer.length >= this.bufferSize) {
const int16Chunk = this.floatTo16BitPCM(this.buffer)
this.port.postMessage(int16Chunk)
this.buffer = []
}

return true
}
}

registerProcessor("pcm-processor", AudioProcessor)



Подробнее здесь: https://stackoverflow.com/questions/798 ... sion-or-ui
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»