Files
PythonProject/2.html
lingxiao865 f5c4158fc1 first commit
2025-09-18 17:50:03 +08:00

137 lines
5.4 KiB
HTML

<!--&lt;!&ndash; index.html &ndash;&gt;-->
<!--<!DOCTYPE html>-->
<!--<html lang="zh">-->
<!--<head>-->
<!-- <meta charset="UTF-8"/>-->
<!-- <title>SenseVoice + VAD 实时识别</title>-->
<!-- <style>-->
<!-- body {-->
<!-- font-family: Arial, sans-serif;-->
<!-- padding: 40px;-->
<!-- }-->
<!-- button {-->
<!-- padding: 12px 24px;-->
<!-- font-size: 16px;-->
<!-- margin: 10px 5px;-->
<!-- }-->
<!-- #result {-->
<!-- margin: 20px 0;-->
<!-- padding: 15px;-->
<!-- background: #f0f0f0;-->
<!-- border-radius: 6px;-->
<!-- }-->
<!-- </style>-->
<!--</head>-->
<!--<body>-->
<!--<h1>🎙️ SenseVoiceSmall 实时语音识别</h1>-->
<!--<button id="startBtn">开始监听</button>-->
<!--<button id="stopBtn" disabled>停止监听</button>-->
<!--<div id="status">状态:初始化中...</div>-->
<!--<div id="result">识别结果将显示在这里...</div>-->
<!--&lt;!&ndash; ONNX Runtime Web &ndash;&gt;-->
<!--<script src="https://cdn.jsdelivr.net/npm/onnxruntime-web@1.14.0/dist/ort.js"></script>-->
<!--&lt;!&ndash; vad-web &ndash;&gt;-->
<!--<script src="https://cdn.jsdelivr.net/npm/@ricky0123/vad-web@0.0.26/dist/bundle.min.js"></script>-->
<!--<script>-->
<!-- let myvad = null;-->
<!-- let websocket = null;-->
<!-- const statusDiv = document.getElementById('status');-->
<!-- const resultDiv = document.getElementById('result');-->
<!-- const startBtn = document.getElementById('startBtn');-->
<!-- const stopBtn = document.getElementById('stopBtn');-->
<!-- let audioBuffer = [];-->
<!-- const BUFFER_THRESHOLD = 1024 * 5; // 缓冲数据达到 5KB 后发送-->
<!-- // 初始化 VAD-->
<!-- async function initVAD() {-->
<!-- try {-->
<!-- myvad = await vad.MicVAD.new({-->
<!-- onSpeechStart: () => {-->
<!-- statusDiv.innerText = "🟢 检测到语音,正在发送...";-->
<!-- },-->
<!-- onSpeechEnd: (audio) => {-->
<!-- if (websocket && websocket.readyState === WebSocket.OPEN) {-->
<!-- const pcm16 = floatTo16BitPCM(audio);-->
<!-- websocket.send(pcm16);-->
<!-- statusDiv.innerText = `📤 发送语音段 (${audio.length} 个采样点)`;-->
<!-- }-->
<!-- },-->
<!-- // onFrameProcessed: (probs, frame) => {-->
<!-- // // 可以调整阈值,比如 > 0.3 就认为可能是语音-->
<!-- // const isLikelySpeech = probs.isSpeech > 0.3;-->
<!-- // audioBuffer.push(frame); // 缓存每一段音频数据-->
<!-- //-->
<!-- // if (isLikelySpeech && websocket?.readyState === WebSocket.OPEN) {-->
<!-- // const pcm16 = floatTo16BitPCM(frame);-->
<!-- // websocket.send(pcm16);-->
<!-- // }-->
<!-- // }-->
<!-- });-->
<!-- statusDiv.innerText = "✅ VAD 初始化完成,点击【开始监听】";-->
<!-- } catch (err) {-->
<!-- statusDiv.innerText = `❌ VAD 加载失败: ${err.message}`;-->
<!-- }-->
<!-- }-->
<!-- // 连接 WebSocket-->
<!-- function connectWebSocket() {-->
<!-- websocket = new WebSocket('ws://localhost:8000/ws/asr');-->
<!-- websocket.onopen = () => {-->
<!-- statusDiv.innerText = "🟢 WebSocket 已连接";-->
<!-- };-->
<!-- websocket.onmessage = (e) => {-->
<!-- try {-->
<!-- const data = JSON.parse(e.data);-->
<!-- resultDiv.innerText = data.text || "";-->
<!-- } catch {-->
<!-- resultDiv.innerText = e.data;-->
<!-- }-->
<!-- };-->
<!-- websocket.onerror = (e) => {-->
<!-- statusDiv.innerText = "❌ WebSocket 错误";-->
<!-- };-->
<!-- websocket.onclose = () => {-->
<!-- statusDiv.innerText = "🔌 已断开连接,正在重连...";-->
<!-- setTimeout(connectWebSocket, 3000); // 重连-->
<!-- };-->
<!-- }-->
<!-- // Float32 → 16-bit PCM-->
<!-- function floatTo16BitPCM(float32Array) {-->
<!-- const buffer = new ArrayBuffer(float32Array.length * 2);-->
<!-- const view = new DataView(buffer);-->
<!-- for (let i = 0; i < float32Array.length; i++) {-->
<!-- const s = Math.max(-1, Math.min(1, float32Array[i]));-->
<!-- const val = s < 0 ? s * 0x8000 : s * 0x7FFF;-->
<!-- view.setInt16(i * 2, val, true);-->
<!-- }-->
<!-- return buffer;-->
<!-- }-->
<!-- // 控制按钮-->
<!-- startBtn.addEventListener('click', () => {-->
<!-- if (myvad) myvad.start();-->
<!-- startBtn.disabled = true;-->
<!-- stopBtn.disabled = false;-->
<!-- });-->
<!-- stopBtn.addEventListener('click', () => {-->
<!-- if (myvad) myvad.stop();-->
<!-- startBtn.disabled = false;-->
<!-- stopBtn.disabled = true;-->
<!-- statusDiv.innerText = "⏸️ 已停止监听";-->
<!-- });-->
<!-- // 启动-->
<!-- window.onload = () => {-->
<!-- initVAD();-->
<!-- connectWebSocket();-->
<!-- };-->
<!--</script>-->
<!--</body>-->
<!--</html>-->