Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Fix browser text to speech cannot resume and cancel #2378

Merged
merged 1 commit into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ const playAnswerTextPart = () => {
if (audioList.value[currentAudioIndex.value] !== utterance.value?.text) {
window.speechSynthesis.cancel()
}
if (window.speechSynthesis.paused) {
if (window.speechSynthesis.paused && audioList.value[currentAudioIndex.value] === utterance.value?.text) {
window.speechSynthesis.resume()
return
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code you provided has a minor issue in the conditional logic within the playAnswerTextPart function:

Issue:
In the updated line,

if (window.speexSynthesis.paused && audioList.value[currentAudioIndex.value] === utterance.value?.text) {

the condition is incorrect because it checks both conditions simultaneously. The intent seems to be only to resume speech synthesis only when there's an active text match, but the current check also includes speechSynthesis.paused, which doesn't necessarily have the correct context.

Optimization/Suggestion:
To fix this, we can directly resume only if the utterance text matches the current audio list item and if speechSynthesis is paused:

// Check if speech is paused AND current text is different
if (window.speechSynthesis.paused && audioList.value[currentAudioIndex.value] !== utterance.value?.text) {
  // Resume speech with the current text
  window.speechSynthesis.resume();
}

This change ensures that resume() will only happen when the voice recognition system is idle and not speaking a previous answer, preventing unexpected resumption of a pause state due to unmatched texts.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ const playAnswerTextPart = () => {
if (audioList.value[currentAudioIndex.value] !== utterance.value?.text) {
window.speechSynthesis.cancel()
}
if (window.speechSynthesis.paused) {
if (window.speechSynthesis.paused && audioList.value[currentAudioIndex.value] === utterance.value?.text) {
window.speechSynthesis.resume()
return
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provided code looks clean and properly checks whether to resume speech synthesis or cancel it based on current conditions. There are no irregularities, potential issues, or significant optimizations noted at this time.

If you have any specific concerns about the implementation or need further assistance with integrating it into a larger application, feel free to ask!

Expand Down
8 changes: 8 additions & 0 deletions ui/src/views/chat/pc/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,14 @@ const clickListHandle = (item: any) => {
currentChatName.value = item.abstract
if (currentChatId.value !== 'new') {
getChatRecord()

// 切换对话后,取消暂停的浏览器播放
if (window.speechSynthesis.paused && window.speechSynthesis.speaking) {
window.speechSynthesis.resume()
nextTick(() => {
window.speechSynthesis.cancel()
})
}
}
}
if (common.isMobile()) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provided code is primarily concerned with handling chat interactions and updating audio playback state when changing chats. Here are some points to consider:

  1. Suspension Handling: The if block checks if the browser speech synthesis is both paused and speaking (window.speechSynthesis.paused && window.speechSynthesis.speaking) before resuming it. It then cancels any existing speech using nextTick(, which ensures that the next tick of the event loop runs after the cancel operation completes.

  2. Comments Consistency: The comments are consistent throughout the file but lack descriptions about their purpose within the context of the larger function.

  3. Code Organization: The code seems well-organized for its functionality related to handling chat clicks and controlling speech synthesis.

  4. Functionality Checks: Ensure there are no other parts of the application relying on this logic that might not handle changes correctly.

Overall, the code appears functional without major issues. If you need further debugging or optimization suggestions, additional testing under different conditions would be recommended.

Expand Down