*Я создаю интерфейс 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
Как извлечь необработанный звук PCM прямо из браузера без преобразования или зависания пользовательского интерфейса? ⇐ Javascript
Форум по Javascript
1761546441
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[i]))
int16Array[i] = 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)
Подробнее здесь: [url]https://stackoverflow.com/questions/79801506/how-to-extract-raw-pcm-audio-directly-from-the-browser-without-conversion-or-ui[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия