基于Webkit的聊天应用:语音识别关键词触发消息发送实现
Great question! Let's modify your existing speech recognition code to support sending messages either when you say "send" or when you pause speaking for a short period. Here's how to do it, building on your current implementation:
Step 1: Fix Syntax Issues & Add Helper Function
First, let's clean up a minor syntax error in your interim transcripts styling and add a helper function to trigger the existing send logic (reusing the ConversationPanel.inputKeyDown function that handles Enter presses).
Step 2: Implement Keyword & Pause Triggers
We'll add two key features:
- Detect when the transcript includes "send" (case-insensitive), clean the message, and send it immediately.
- Use a timeout to detect natural speech pauses (1.5 seconds of inactivity) and send the accumulated message automatically.
Modified Full Code
Here's your updated script with all changes integrated:
</label> --> <label for="textInput" class="inputOutline"> <div id="textInput" class="input responsive-column" type="text" onkeydown="/*globals CanvasJS */ ConversationPanel.inputKeyDown(event, this)"></div> </label> <button onclick="startConverting();"><i class="fa fa-microphone"></i></button> <script type="text/javascript"> var r = document.getElementById('textInput'); function startConverting() { if ('webkitSpeechRecognition' in window) { var speechRecognizer = new webkitSpeechRecognition(); speechRecognizer.continuous = true; speechRecognizer.interimResults = true; speechRecognizer.lang = 'en-IN'; speechRecognizer.start(); var finalTranscripts = ''; var sendTimeout; // Timeout to detect speech pauses // Helper function to trigger message send (simulates Enter key press) function sendMessage(inputElement) { // Create a synthetic Enter key event const enterEvent = new KeyboardEvent('keydown', { key: 'Enter', keyCode: 13, bubbles: true, cancelable: true }); // Call the existing send logic ConversationPanel.inputKeyDown(enterEvent, inputElement); // Reset transcripts after sending finalTranscripts = ''; // Clear any pending pause timeout if (sendTimeout) clearTimeout(sendTimeout); } speechRecognizer.onresult = function(event) { var interimTranscripts = ''; // Clear any existing timeout if new speech is detected if (sendTimeout) clearTimeout(sendTimeout); for (var i = event.resultIndex; i < event.results.length; i++) { var transcript = event.results[i][0].transcript; transcript = transcript.replace("\n", "<br>"); // Fix string replacement syntax if (event.results[i].isFinal) { finalTranscripts += transcript; } else { interimTranscripts += transcript; } } // Check for "send" keyword first (case-insensitive) if (finalTranscripts.toLowerCase().includes('send')) { // Remove "send" from the message (preserve actual content) let cleanedMessage = finalTranscripts.replace(/\bsend\b/gi, '').trim(); if (cleanedMessage) { r.innerHTML = cleanedMessage; sendMessage(r); } else { // If only "send" was spoken, clear the input r.innerHTML = ''; finalTranscripts = ''; } } else { // Show combined final + interim transcripts r.innerHTML = finalTranscripts + '<span style="color:#999;">' + interimTranscripts + '</span>'; // Set timeout to send after 1.5 seconds of inactivity (pause) sendTimeout = setTimeout(() => { if (finalTranscripts.trim()) { r.innerHTML = finalTranscripts; sendMessage(r); } }, 1500); } }; speechRecognizer.onerror = function(event) { // You can add error handling here (e.g., log the error) console.error('Speech recognition error:', event.error); }; } else { r.innerHTML = 'Please update Google Chrome to use speech recognition.'; } } </script>
Key Changes Explained
Helper Function
sendMessage:- Creates a synthetic Enter key event to trigger your existing
ConversationPanel.inputKeyDownfunction, ensuring consistency with your keyboard-based send logic. - Resets the transcript and clears any pending pause timeout after sending.
- Creates a synthetic Enter key event to trigger your existing
Keyword Detection:
- Checks if the final transcript includes "send" (case-insensitive using
toLowerCase()). - Cleans the message by removing all instances of "send" (using a regex to match whole words only, so it won't remove parts of other words like "sender").
- Only sends if there's actual message content left (avoids sending empty messages if the user only says "send").
- Checks if the final transcript includes "send" (case-insensitive using
Pause Detection:
- Uses a
sendTimeoutvariable to track inactivity. Every time new speech is detected, we clear the timeout. - If no new speech is detected for 1.5 seconds, the timeout triggers and sends the accumulated message.
- Adjust the
1500value (milliseconds) to make the pause detection shorter or longer based on your needs.
- Uses a
Syntax Fixes:
- Corrected the interim transcript styling (added colon to
color:#999;and closed the span tag properly). - Fixed the string replacement for newlines (assigned the result back to
transcript).
- Corrected the interim transcript styling (added colon to
This implementation should work seamlessly with your existing chat app, supporting both keyword-triggered and pause-triggered voice message sends.
内容的提问来源于stack exchange,提问作者Daniel Dalan

