Python playsound设置block=False时音频无法播放问题
问题产生原因
两个异常的根源和playsound库的实现逻辑、tkinter的运行机制直接相关:
- 默认
block=True时,playsound会在当前调用线程同步执行音频解码、播放全流程,直到音频播放结束才会返回。而tkinter的UI渲染、事件响应全部运行在主线程,一旦主线程被播放逻辑占用,就无法处理窗口重绘、鼠标键盘点击等事件,直接表现为窗口冻结无响应。 - 设置
block=False后播放失败有两个核心诱因:一是playsound的非阻塞模式启动的是守护线程,调用返回后如果没有持有播放实例的引用,相关资源会被Python垃圾回收机制立刻回收,守护线程还没完成音频加载就被直接终止;二是1.3.0及以上版本的playsound在Windows平台下非阻塞模式本身存在实现bug,依赖的窗口消息循环无法正常工作,直接导致播放失败。
修复方法
优先推荐自主管理播放线程的方案,完全规避库本身的非阻塞逻辑bug,跨平台兼容性最好:
import threading from playsound import playsound as psound # 类内播放方法修改为如下实现 def play_aux(self, audio_dir): # 若需要切歌时自动停止上一首,可在此处补充终止旧播放线程的逻辑 # 启动独立非守护线程运行阻塞模式的播放逻辑 play_thread = threading.Thread( target=psound, args=(audio_dir,), daemon=False ) play_thread.start() # 将线程对象绑定为类实例属性,避免被GC回收导致播放意外中断 self.current_play_thread = play_thread
如果你使用的是1.2.2版本(最后一个非阻塞逻辑无明显已知bug的稳定版)的playsound,也可以用更轻量的写法,核心是必须持有播放实例的引用,不能让它作为临时局部变量被回收:
from playsound import playsound as psound def play_aux(self, audio_dir): # 把返回的播放对象挂载到实例属性上,延长生命周期 self.current_sound = psound(audio_dir, block=False)
补充说明
playsound是定位极简的单文件播放库,原生不提供暂停、进度拖动、音量调节、播放状态回调等音乐播放器必备能力,如果后续需要扩展功能,建议直接替换为pygame.mixer或者simpleaudio这类功能更完善的音频库,长期维护成本更低。
内容的提问来源于stack exchange,提问作者SwirX
相关产品推荐
相关产品推荐

