You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pygame中pg.mixer.music.get_busy()在音乐播放时返回False,且取消暂停会跳过当前音乐的问题求助

pygame中pg.mixer.music.get_busy()在音乐播放时返回False,且取消暂停会跳过当前音乐的问题求助

我来帮你分析问题根源,以及对应的修复方案:

核心问题1:错误使用play()恢复暂停的音乐

你当前在取消暂停时调用pg.mixer.music.play(0)是完全错误的操作:

  • play()方法会从头开始播放当前加载的音乐,而不是从暂停位置继续
  • 更关键的是,这个调用存在时间差问题:在同一帧中,pg.mixer.music.get_busy()可能还没来得及更新为True,就触发了下一首歌曲的加载逻辑,直接导致当前歌曲被跳过

正确的恢复暂停操作应该使用pg.mixer.music.unpause(),它会直接从暂停位置继续播放,并且会立即将get_busy()的状态更新为True。

核心问题2:get_busy()的特性与逻辑冲突

pg.mixer.music.get_busy()的设计特性是:当音乐处于暂停状态时,它会返回False。你当前的下一首加载逻辑是:

if Mlist and not(pg.mixer.music.get_busy()) and not(pause):

这个条件本身逻辑是成立的(暂停时pause为True,不会触发加载),但错误的恢复播放方式(用play()而非unpause())导致在取消暂停的瞬间,get_busy()还保持False,同时pause被设为False,刚好满足加载下一首的条件,最终导致当前歌曲被跳过。

修复后的完整代码

import os
import pygame as pg
from random import shuffle

# 获取音乐列表并打乱顺序
Mlist = os.listdir("playlist")
shuffle(Mlist)

pg.init()
# 显式初始化混音器,避免环境兼容性问题
pg.mixer.init()

size = [800, 600]
screen = pg.display.set_mode(size)
clock = pg.time.Clock()

pause = False
running = True
current_song_idx = 0  # 用索引跟踪播放位置,比随机选择+删除更高效

while running:   
    for event in pg.event.get():
        if event.type == pg.QUIT:
            running = False
        if event.type == pg.KEYDOWN:
            if pause:
                # 正确的取消暂停方式:从暂停位置继续播放
                pg.mixer.music.unpause()
                pause = False
            else:
                pause = True
                pg.mixer.music.pause()
    
    # 播放下一首的逻辑:列表非空、音乐未在播放、未处于暂停状态
    if Mlist and not pg.mixer.music.get_busy() and not pause:
        if current_song_idx < len(Mlist):
            song = Mlist[current_song_idx]
            current_song_idx += 1
            pg.mixer.music.load(f"playlist/{song}")
            pg.mixer.music.play()
        else:
            # 所有歌曲播放完毕,可根据需求改为循环播放或退出
            # 示例:重置索引重新循环
            current_song_idx = 0
            shuffle(Mlist)
    
    pg.display.flip()
    clock.tick(30)

# 规范退出方式
pg.quit()

额外优化建议

  1. 显式初始化pg.mixer.init():虽然pg.init()会初始化所有模块,但显式初始化混音器能避免部分环境下的兼容性问题
  2. 用索引遍历列表:比每次choice+remove的效率更高,且能确保每首歌只播放一次(如需随机可在循环时重新打乱)
  3. 歌曲循环逻辑:示例中在所有歌曲播放完毕后重置索引并重新打乱列表,你可以根据需求调整为停止播放或其他逻辑

这样修改后,暂停/恢复功能会正常工作,不会再出现取消暂停时跳过当前歌曲的问题。

备注:内容来源于stack exchange,提问作者Bublek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 17:19:50