Files
PythonProject/1.html

332 lines
12 KiB
HTML
Raw Permalink Normal View History

2025-09-18 17:50:03 +08:00
<!--<!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>-->