You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何中断pyttsx3语音播报与playsound音频播放?

解决音频播放与语音播报的中断问题

我完全懂你现在的困扰——playsound的阻塞播放逻辑和pyttsx3runAndWait()的阻塞特性,直接导致没法中途中断操作。下面给你两套落地可行的方案,分别搞定歌曲播放和语音播报的中断需求:

一、替换playsoundpygame.mixer实现歌曲可中断播放

playsound本质是阻塞式运行,很难中途停止,而pygame.mixer支持非阻塞播放,还能随时调用停止方法。具体步骤如下:

  1. 先安装依赖库:
pip install pygame keyboard
  1. 示例代码:
import pygame
import pyttsx3
import keyboard

engine = pyttsx3.init()

def play_song(song_name):
    pygame.mixer.init()
    try:
        pygame.mixer.music.load(song_name)
        pygame.mixer.music.play()
        # 监听按键,这里设为按'q'停止播放,你可以自定义按键
        while pygame.mixer.music.get_busy():
            if keyboard.is_pressed('q'):
                pygame.mixer.music.stop()
                print("歌曲已停止")
                break
    except pygame.error:
        engine.say("I couldn't find the song.")
        engine.runAndWait()
    finally:
        pygame.mixer.quit()

# 模拟用户输入逻辑
user_input = input("Enter command: ")
if "play" in user_input:
    song_name = user_input[5:] + ".mp3"
    play_song(song_name)

二、解决pyttsx3的语音播报中断问题

pyttsx3engine.stop()之所以不生效,核心原因是runAndWait()会阻塞主线程,导致你根本没机会触发停止操作。解决思路是把播报任务放到子线程,让主线程专门负责监听中断信号:

方案1:基于pyttsx3的多线程实现

import pyttsx3
import threading
import keyboard

engine = pyttsx3.init()
is_speaking = False

def speak(text):
    global is_speaking
    is_speaking = True
    engine.say(text)
    engine.runAndWait()
    is_speaking = False

def stop_speech():
    global is_speaking
    if is_speaking:
        engine.stop()
        is_speaking = False
        print("语音播报已中断")

# 绑定中断按键,这里设为按's'停止播报
keyboard.add_hotkey('s', stop_speech)

# 测试长文本播报
speak_thread = threading.Thread(
    target=speak, 
    args=("This is a long test speech. You can press 's' to stop me at any time.",)
)
speak_thread.start()

# 主线程可继续处理其他逻辑,这里等待播报线程结束
while speak_thread.is_alive():
    pass

方案2:用gTTS+pygame替代pyttsx3

如果pyttsx3的方案还是有兼容性问题,可以用gTTS生成语音文件,再用pygame播放,这样就能和歌曲播放共用一套中断逻辑:

  1. 安装依赖库:
pip install gTTS pygame keyboard
  1. 示例代码:
from gtts import gTTS
import pygame
import keyboard
import os

def speak_and_interrupt(text):
    # 生成临时语音文件
    tts = gTTS(text=text, lang='en')
    temp_file = "temp_speech.mp3"
    tts.save(temp_file)
    
    # 用pygame播放并监听中断
    pygame.mixer.init()
    pygame.mixer.music.load(temp_file)
    pygame.mixer.music.play()
    
    while pygame.mixer.music.get_busy():
        if keyboard.is_pressed('s'):
            pygame.mixer.music.stop()
            print("语音播报已中断")
            break
    
    pygame.mixer.quit()
    os.remove(temp_file)  # 清理临时文件

# 测试中断功能
speak_and_interrupt("I couldn't find the song. Press 's' to stop this message right now.")

小提示

  • keyboard库在Windows下需要管理员权限才能正常监听按键,如果你不想用它,也可以换成pynput库,用法逻辑类似。
  • 多线程处理时,注意全局变量的线程安全,不过这里的is_speaking只是简单状态标记,不会有问题。

内容的提问来源于stack exchange,提问作者gozdekurtulmus

火山引擎 最新活动