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

332 lines
12 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--<!DOCTYPE html>-->
<!--<html lang="zh">-->
<!--<head>-->
<!-- <meta charset="UTF-8">-->
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">-->
<!-- <title>语音识别系统</title>-->
<!-- <style>-->
<!-- body {-->
<!-- font-family: Arial, sans-serif;-->
<!-- max-width: 800px;-->
<!-- margin: 0 auto;-->
<!-- padding: 20px;-->
<!-- background-color: #f5f5f5;-->
<!-- }-->
<!-- .container {-->
<!-- background-color: white;-->
<!-- padding: 30px;-->
<!-- border-radius: 10px;-->
<!-- box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);-->
<!-- }-->
<!-- h1 {-->
<!-- color: #333;-->
<!-- text-align: center;-->
<!-- }-->
<!-- .btn {-->
<!-- background-color: #4CAF50;-->
<!-- color: white;-->
<!-- padding: 12px 24px;-->
<!-- border: none;-->
<!-- border-radius: 5px;-->
<!-- cursor: pointer;-->
<!-- font-size: 16px;-->
<!-- margin: 10px;-->
<!-- touch-action: manipulation;-->
<!-- }-->
<!-- .btn:hover {-->
<!-- background-color: #45a049;-->
<!-- }-->
<!-- .btn:disabled {-->
<!-- background-color: #cccccc;-->
<!-- cursor: not-allowed;-->
<!-- }-->
<!-- .record-btn {-->
<!-- background-color: #f44336;-->
<!-- padding: 15px 30px;-->
<!-- font-size: 18px;-->
<!-- }-->
<!-- .record-btn:hover {-->
<!-- background-color: #d32f2f;-->
<!-- }-->
<!-- .record-btn.recording {-->
<!-- background-color: #ff9800;-->
<!-- animation: pulse 1s infinite;-->
<!-- }-->
<!-- @keyframes pulse {-->
<!-- 0% {-->
<!-- transform: scale(1);-->
<!-- }-->
<!-- 50% {-->
<!-- transform: scale(1.05);-->
<!-- }-->
<!-- 100% {-->
<!-- transform: scale(1);-->
<!-- }-->
<!-- }-->
<!-- .stream-result {-->
<!-- margin-top: 20px;-->
<!-- padding: 15px;-->
<!-- border-radius: 5px;-->
<!-- background-color: #e3f2fd;-->
<!-- min-height: 50px;-->
<!-- }-->
<!-- .recording-indicator {-->
<!-- text-align: center;-->
<!-- margin: 10px 0;-->
<!-- font-weight: bold;-->
<!-- color: #ff9800;-->
<!-- display: none;-->
<!-- }-->
<!-- .error-message {-->
<!-- color: #f44336;-->
<!-- background-color: #ffebee;-->
<!-- padding: 10px;-->
<!-- border-radius: 5px;-->
<!-- margin: 10px 0;-->
<!-- display: none;-->
<!-- }-->
<!-- /* 移动端适配 */-->
<!-- @media screen and (max-width: 768px) {-->
<!-- body {-->
<!-- padding: 10px;-->
<!-- }-->
<!-- .container {-->
<!-- padding: 15px;-->
<!-- }-->
<!-- .btn {-->
<!-- width: 100%;-->
<!-- margin: 10px 0;-->
<!-- padding: 15px;-->
<!-- font-size: 18px;-->
<!-- }-->
<!-- .record-btn {-->
<!-- padding: 20px;-->
<!-- font-size: 20px;-->
<!-- }-->
<!-- }-->
<!-- @media screen and (max-width: 480px) {-->
<!-- h1 {-->
<!-- font-size: 24px;-->
<!-- }-->
<!-- }-->
<!-- </style>-->
<!--</head>-->
<!--<body>-->
<!--<div class="container">-->
<!-- <h1>实时语音识别系统</h1>-->
<!-- <div>-->
<!-- <p>按住下方按钮开始录音,识别结果将实时显示</p>-->
<!-- <button class="btn record-btn" id="recordBtn">按住录音-->
<!-- </button>-->
<!-- <div class="error-message" id="errorMessage"></div>-->
<!-- </div>-->
<!-- <div class="recording-indicator" id="recordingIndicator">正在录音和识别...</div>-->
<!-- <div class="stream-result" id="recordStreamResult" style="display: none;"></div>-->
<!--</div>-->
<!--<script>-->
<!-- let websocket;-->
<!-- const recordButton = document.getElementById('recordBtn');-->
<!-- const status = document.getElementById('recordingIndicator');-->
<!-- const recordStreamResult = document.getElementById('recordStreamResult');-->
<!-- let mediaRecorder;-->
<!-- let audioChunks = [];-->
<!-- let isRecording = false;-->
<!-- let isRecorderInitialized = false;-->
<!-- // connectWebSocket();-->
<!-- // 初始化录音功能-->
<!-- async function initRecorder() {-->
<!-- if (isRecorderInitialized) return; // 避免重复初始化-->
<!-- try {-->
<!-- const stream = await navigator.mediaDevices.getUserMedia({audio: true});-->
<!-- mediaRecorder = new MediaRecorder(stream);-->
<!-- isRecorderInitialized = true;-->
<!-- // 监听录制的数据-->
<!-- mediaRecorder.addEventListener('dataavailable', event => {-->
<!-- audioChunks.push(event.data);-->
<!-- });-->
<!-- // 录音停止后处理数据-->
<!-- mediaRecorder.addEventListener('stop', () => {-->
<!-- status.textContent = '正在上传...';-->
<!-- // 将音频数据组合成 Blob-->
<!-- const audioBlob = new Blob(audioChunks, {type: 'audio/wav'}); // 可根据需要改为 audio/wav 等-->
<!-- audioChunks = []; // 清空缓存-->
<!-- // websocket.send(audioBlob)-->
<!-- // 发送到后端-->
<!-- uploadAudioToBackend(audioBlob);-->
<!-- });-->
<!-- } catch (err) {-->
<!-- console.error('无法访问麦克风:', err);-->
<!-- status.textContent = '麦克风访问被拒绝或不可用';-->
<!-- showError('无法访问麦克风,请检查权限设置');-->
<!-- }-->
<!-- }-->
<!-- // 开始录音-->
<!-- function startRecording() {-->
<!-- // 如果录音器尚未初始化,则初始化-->
<!-- if (!isRecorderInitialized) {-->
<!-- initRecorder().then(() => {-->
<!-- // 初始化成功后开始录音-->
<!-- if (isRecorderInitialized && mediaRecorder && mediaRecorder.state !== 'recording') {-->
<!-- audioChunks = [];-->
<!-- mediaRecorder.start();-->
<!-- isRecording = true;-->
<!-- recordButton.textContent = '正在录音...';-->
<!-- status.textContent = '录音中...';-->
<!-- status.style.display = 'block';-->
<!-- recordStreamResult.style.display = 'block';-->
<!-- recordStreamResult.innerHTML = '<h3>实时识别结果:</h3><p>正在识别...</p>';-->
<!-- }-->
<!-- }).catch(err => {-->
<!-- console.error('初始化失败:', err);-->
<!-- status.textContent = '初始化录音失败';-->
<!-- });-->
<!-- } else if (mediaRecorder && mediaRecorder.state !== 'recording') {-->
<!-- audioChunks = [];-->
<!-- mediaRecorder.start();-->
<!-- isRecording = true;-->
<!-- recordButton.textContent = '正在录音...';-->
<!-- status.textContent = '录音中...';-->
<!-- status.style.display = 'block';-->
<!-- recordStreamResult.style.display = 'block';-->
<!-- recordStreamResult.innerHTML = '<h3>实时识别结果:</h3><p>正在识别...</p>';-->
<!-- }-->
<!-- }-->
<!-- // 停止录音-->
<!-- function stopRecording() {-->
<!-- if (mediaRecorder && mediaRecorder.state === 'recording') {-->
<!-- mediaRecorder.stop();-->
<!-- isRecording = false;-->
<!-- recordButton.textContent = '按住说话';-->
<!-- status.textContent = '已停止';-->
<!-- }-->
<!-- }-->
<!-- // 显示错误信息-->
<!-- function showError(message) {-->
<!-- const errorElement = document.getElementById('errorMessage');-->
<!-- errorElement.textContent = message;-->
<!-- errorElement.style.display = 'block';-->
<!-- setTimeout(() => {-->
<!-- errorElement.style.display = 'none';-->
<!-- }, 5000); // 5秒后隐藏错误信息-->
<!-- }-->
<!-- // 上传音频到后端-->
<!-- async function uploadAudioToBackend(blob) {-->
<!-- const formData = new FormData();-->
<!-- formData.append('file', blob, 'recording.wav'); // 文件名可自定义-->
<!-- try {-->
<!-- const response = await fetch('http://192.168.1.2:5000/transcribe', {-->
<!-- method: 'POST',-->
<!-- body: formData-->
<!-- });-->
<!-- if (response.ok) {-->
<!-- const result = await response.json();-->
<!-- console.log('上传成功:', result);-->
<!-- status.textContent = '上传成功!';-->
<!-- recordStreamResult.innerHTML += `<p>${result.result}</p>`;-->
<!-- } else {-->
<!-- status.textContent = '上传失败';-->
<!-- }-->
<!-- } catch (error) {-->
<!-- console.error('上传出错:', error);-->
<!-- status.textContent = '上传失败:网络错误';-->
<!-- }-->
<!-- }-->
<!-- // 初始化事件监听-->
<!-- recordButton.addEventListener('mousedown', () => {-->
<!-- if (!isRecording) startRecording();-->
<!-- });-->
<!-- recordButton.addEventListener('mouseup', () => {-->
<!-- if (isRecording) stopRecording();-->
<!-- });-->
<!-- // 支持移动端touch事件-->
<!-- recordButton.addEventListener('touchstart', (e) => {-->
<!-- e.preventDefault(); // 防止默认行为-->
<!-- if (!isRecording) startRecording();-->
<!-- });-->
<!-- recordButton.addEventListener('touchend', (e) => {-->
<!-- e.preventDefault();-->
<!-- if (isRecording) stopRecording();-->
<!-- });-->
<!-- // 建立WebSocket连接-->
<!-- function connectWebSocket() {-->
<!-- // 处理不同协议的情况-->
<!-- let wsUrl = "ws://localhost:5000/ws/stream_transcribe";-->
<!-- if (window.location.protocol === "https:") {-->
<!-- wsUrl = "wss://localhost:5000/ws/stream_transcribe";-->
<!-- }-->
<!-- websocket = new WebSocket(wsUrl);-->
<!-- websocket.onopen = function (event) {-->
<!-- console.log("WebSocket连接已建立");-->
<!-- };-->
<!-- websocket.onmessage = function (event) {-->
<!-- // 更新识别结果-->
<!-- const currentContent = recordStreamResult.innerHTML;-->
<!-- // 如果是第一次收到结果,替换"正在识别..."提示-->
<!-- if (currentContent.includes("正在识别...")) {-->
<!-- recordStreamResult.innerHTML = '<h3>实时识别结果:</h3><p>' + event.data + '</p>';-->
<!-- } else {-->
<!-- // 否则追加结果-->
<!-- const newContent = currentContent.replace('</p>', '') + event.data + '</p>';-->
<!-- recordStreamResult.innerHTML = newContent;-->
<!-- }-->
<!-- };-->
<!-- websocket.onerror = function (error) {-->
<!-- console.log("WebSocket错误:", error);-->
<!-- showError('连接服务器失败,请检查服务器是否运行');-->
<!-- recordStreamResult.innerHTML = '<h3>实时识别结果:</h3><p>识别出错,请查看控制台了解详情</p>';-->
<!-- };-->
<!-- websocket.onclose = function (event) {-->
<!-- console.log("WebSocket连接已关闭");-->
<!-- if (event.wasClean) {-->
<!-- console.log(`连接关闭,代码=${event.code},原因=${event.reason}`);-->
<!-- } else {-->
<!-- console.log('连接意外中断');-->
<!-- }-->
<!-- };-->
<!-- }-->
<!--</script>-->
<!--</body>-->
<!--</html>-->