import { useEffect, useRef, useState } from "react"; import reactLogo from "./assets/react.svg"; import viteLogo from "/vite.svg"; import "./App.css"; import { client, start } from "./utils/mqtt"; import { startAudio, stopAudio, context } from "./utils/microphone"; import { arrayBufferToBase64, downSampleAudioFrame, floatTo16BitPCM, getMergedPCMData } from "./utils/audio"; let mqttData; let buffers: Float32Array[] = []; const getAudio = () => { buffers = []; startAudio((float32Arr) => { // 降比特率到 16000 const downedFloat32Arr = downSampleAudioFrame(float32Arr, context.sampleRate, 16000); // 转 base64 打包给后端 const sendItem = arrayBufferToBase64(floatTo16BitPCM(downedFloat32Arr)); // 存储一遍压缩后的音频 buffers.push(downedFloat32Arr); client.publish(mqttData.recognition_topic, sendItem); }); }; const onDownload = () => { if (buffers.length === 0) { return; } const data = getMergedPCMData(buffers); const blob = new Blob([floatTo16BitPCM(data)], { type: 'audio/wave' }); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'merged_audio.pcm'; a.click(); }; function App() { const loaded = useRef(false); const [mqttStatus, setMqttStatus] = useState(false); useEffect(() => { if (loaded.current) { return; } loaded.current = true; // 启用 MQTT 并连接 start().then(([client, data]) => { console.log("mqtt connected"); mqttData = data; setMqttStatus(true); }); }, []); return ( <>
Vite logo React logo

确保 MQTT 已连接,再点击 getAudio 开始录音,stopAudio 结束

点击 download 下载音频原始数据(Float32Array 拼接的),用 Audacity 音频软件可加载。

MQTT 连接状态:{String(mqttStatus)}

当前输入设备比特率:{context.sampleRate}hz

当前输出音频比特率:16000hz

); } export default App;