+
29
-

回答

支持语音识别与tts文字转语音

800_auto

main.py

<import webview
import time

class Api:
    def on_speech_result(self, result):
        """处理从前端接收的语音识别结果"""
        print(f"语音识别结果: {result}")
        # 可以在这里添加后续处理逻辑
        return result

if __name__ == '__main__':
    # 创建API实例
    api = Api()
    
    # 创建窗口
    window = webview.create_window(
        title='带音色选择的语音功能演示',
        url='index.html',
        width=900,
        height=700,
        resizable=True,
        js_api=api
    )
    
    # 启动pywebview
    webview.start(debug=True)

index.html

<!DOCTYPE html>
<html>
<head>
    <title>带音色选择的语音功能演示</title>
    <style>
        body { font-family: Arial, sans-serif; padding: 20px; max-width: 800px; margin: 0 auto; }
        .controls { margin: 20px 0; padding: 20px; border: 1px solid #eee; border-radius: 8px; }
        button { padding: 10px 20px; margin: 5px; background: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; }
        button:hover { background: #0056b3; }
        #result { margin: 20px 0; padding: 10px; border: 1px solid #ccc; min-height: 50px; border-radius: 4px; }
        .form-group { margin: 15px 0; }
        select, input[type="text"] { padding: 8px; width: 100%; max-width: 500px; border: 1px solid #ddd; border-radius: 4px; }
        label { display: block; margin-bottom: 5px; font-weight: bold; }
    </style>
</head>
<body>
    <h1>Web Speech API 演示(带音色选择)</h1>
    
    <div class="controls">
        <h3>语音识别</h3>
        <button onclick="startRecognition()">开始语音识别</button>
        <button onclick="stopRecognition()">停止语音识别</button>
        
        <div id="result">识别结果将显示在这里...</div>
        
        <h3>语音合成</h3>
        <div class="form-group">
            <label for="voiceSelect">选择音色:</label>
            <select id="voiceSelect"></select>
        </div>
        
        <div class="form-group">
            <label for="textToSpeak">输入要合成的文本:</label>
            <input type="text" id="textToSpeak" placeholder="请输入文字..." value="你好,这是一个带音色选择的语音合成示例">
        </div>
        
        <div class="form-group">
            <label>语速:</label>
            <input type="range" id="rate" min="0.5" max="2" step="0.1" value="1">
            <span id="rateValue">1</span>
        </div>
        
        <button onclick="speakText(document.getElementById('textToSpeak').value)">开始语音合成</button>
        <button onclick="cancelSpeech()">取消合成</button>
    </div>
    
    <div id="status" style="margin-top: 20px; color: #666;">状态: 就绪</div>

    <script>
        // 语音识别相关变量
        let recognition;
        let isRecognizing = false;
        
        // 语音合成相关变量
        let voices = [];

        // 页面加载完成后初始化
        window.onload = function() {
            // 初始化语音识别
            initRecognition();
            
            // 初始化语音合成
            initSpeechSynthesis();
            
            // 监听语速滑块变化
            document.getElementById('rate').addEventListener('input', function() {
                document.getElementById('rateValue').textContent = this.value;
            });
        };

        // 初始化语音识别
        function initRecognition() {
            const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
            if (!SpeechRecognition) {
                alert("您的浏览器不支持语音识别功能");
                return null;
            }

            recognition = new SpeechRecognition();
            recognition.continuous = false;
            recognition.interimResults = false;
            recognition.lang = 'zh-CN';

            recognition.onstart = function() {
                document.getElementById('status').textContent = '状态: 正在识别...';
                isRecognizing = true;
            };

            recognition.onresult = function(event) {
                const transcript = event.results[0][0].transcript;
                document.getElementById('result').textContent = transcript;
                document.getElementById('textToSpeak').value = transcript;
                window.pywebview.api.on_speech_result(transcript);
            };

            recognition.onend = function() {
                document.getElementById('status').textContent = '状态: 识别结束';
                isRecognizing = false;
            };

            recognition.onerror = function(event) {
                document.getElementById('status').textContent = `错误: ${event.error}`;
                isRecognizing = false;
            };

            return recognition;
        }

        // 初始化语音合成
        function initSpeechSynthesis() {
            if (!('speechSynthesis' in window)) {
                alert("您的浏览器不支持语音合成功能");
                return;
            }
            
            // 当可用语音列表加载完成时更新选择器
            function loadVoices() {
                voices = window.speechSynthesis.getVoices();
                const voiceSelect = document.getElementById('voiceSelect');
                
                // 清空现有选项
                voiceSelect.innerHTML = '';
                
                // 添加所有可用语音
                voices.forEach((voice, index) => {
                    const option = document.createElement('option');
                    option.value = index;
                    // 显示语音名称和语言
                    option.textContent = `${voice.name} (${voice.lang})`;
                    voiceSelect.appendChild(option);
                });
            }
            
            // 不同浏览器可能在不同时机加载语音列表
            window.speechSynthesis.onvoiceschanged = loadVoices;
            
            // 主动触发一次加载
            loadVoices();
        }

        // 开始语音识别
        function startRecognition() {
            if (isRecognizing) return;
            
            if (!recognition) {
                recognition = initRecognition();
                if (!recognition) return;
            }
            
            recognition.start();
        }

        // 停止语音识别
        function stopRecognition() {
            if (isRecognizing && recognition) {
                recognition.stop();
            }
        }

        // 语音合成
        function speakText(text) {
            if (!text) return;
            if (!('speechSynthesis' in window)) return;

            // 停止任何正在进行的语音
            window.speechSynthesis.cancel();
            
            // 获取选中的语音
            const voiceIndex = document.getElementById('voiceSelect').value;
            const selectedVoice = voices[voiceIndex];
            
            // 创建语音实例
            const utterance = new SpeechSynthesisUtterance(text);
            
            // 设置选中的语音
            if (selectedVoice) {
                utterance.voice = selectedVoice;
            }
            
            // 设置其他参数
            utterance.lang = 'zh-CN';
            utterance.rate = parseFloat(document.getElementById('rate').value); // 语速
            utterance.pitch = 1; // 音调
            utterance.volume = 1; // 音量

            // 开始合成
            window.speechSynthesis.speak(utterance);
            
            document.getElementById('status').textContent = `状态: 正在用 ${selectedVoice.name} 合成语音...`;
            utterance.onend = function() {
                document.getElementById('status').textContent = '状态: 合成完成';
            };
        }
        
        // 取消语音合成
        function cancelSpeech() {
            if ('speechSynthesis' in window) {
                window.speechSynthesis.cancel();
                document.getElementById('status').textContent = '状态: 已取消合成';
            }
        }
    </script>
</body>
</html>

网友回复

我知道答案,我要回答