Pygame Mixer播放音频一次后触发PermissionError的解决方法
解决Pygame Mixer播放音频后PermissionError的问题
错误原因
你遇到的PermissionError是因为Pygame的mixer.music模块在加载并播放音频文件后,没有及时释放文件句柄,导致后续尝试重新加载该文件时,系统判定文件仍被占用,拒绝访问。
解决方案
以下是三种无需删除文件即可多次播放同一音频的有效方法:
方法1:播放完成后卸载音乐,释放文件资源
每次播放结束后调用mixer.music.unload()主动释放文件句柄,后续就能正常重新加载文件。可通过mixer.music.get_busy()判断播放状态,确保播放完成后再执行卸载。
from pygame import mixer import urllib.request mixer.init() # 下载音频到本地 urllib.request.urlretrieve("http://www.freemusicloops.co.uk/download.aspx?did=266", "firstfile.wav") # 第一次播放 mixer.music.load("firstfile.wav") mixer.music.play() # 等待播放结束 while mixer.music.get_busy(): pass # 卸载音乐释放文件 mixer.music.unload() # 第二次播放(无权限问题) mixer.music.load("firstfile.wav") mixer.music.play()
方法2:将音频读入内存,用BytesIO加载
跳过磁盘文件直接在内存中处理音频,避免文件占用问题。用io.BytesIO存储下载的音频数据,再次播放时重置指针到开头即可。
from pygame import mixer import urllib.request from io import BytesIO mixer.init() # 直接将音频下载到内存 response = urllib.request.urlopen("http://www.freemusicloops.co.uk/download.aspx?did=266") audio_buffer = BytesIO(response.read()) # 第一次播放 mixer.music.load(audio_buffer) mixer.music.play() # 等待播放结束 while mixer.music.get_busy(): pass # 重置内存缓冲区指针,再次播放 audio_buffer.seek(0) mixer.music.load(audio_buffer) mixer.music.play()
方法3:使用Pygame Sound对象替代music模块
mixer.music适合单文件背景音乐播放,而Sound对象专为音效设计,加载后可多次播放,不会占用磁盘文件句柄,还支持同时播放多个音频。
from pygame import mixer, Sound import urllib.request from io import BytesIO mixer.init() # 下载音频到内存(也可直接从本地文件加载:sound = Sound("firstfile.wav")) response = urllib.request.urlopen("http://www.freemusicloops.co.uk/download.aspx?did=266") audio_buffer = BytesIO(response.read()) sound = Sound(audio_buffer) # 第一次播放 sound.play() # 等待播放结束(可选) while mixer.get_busy(): pass # 第二次播放,无需重新加载 sound.play()
方法对比
- 方法1:操作简单,适合需要保留本地音频文件的场景,需注意播放后及时卸载。
- 方法2:无需写入磁盘,减少IO操作,适合临时播放网络音频的场景。
- 方法3:功能更灵活,支持多音频同时播放,是短音效多次播放的最优解。
内容的提问来源于stack exchange,提问作者Tegh Singh
相关产品推荐
相关产品推荐

