Raspberry Pi 4用Python实现单按钮控制音频播放与停止方案咨询
实现思路与修复方案
现有代码无法实现即时停止的核心原因是:pydub.playback.play()为阻塞方法,调用后会独占线程直到音频完整播放,中途修改alarmState无法立即生效。我们可以替换为支持非阻塞控制的音频播放模块实现需求,以下两种方案均可直接运行:
方案1:双按钮实现(符合最低可接受要求)
使用pygame.mixer模块实现播放、停止的即时控制,保留原有两个按钮的功能定义:按钮21触发播放,按钮20触发重置回到初始状态。
依赖安装
pip install pygame
完整代码
import pygame from gpiozero import Button from signal import pause # 初始化音频模块 pygame.mixer.init() alarm = pygame.mixer.Sound("alarm.mp3") alarm_playing = False button_reset = Button(20) button_alarm = Button(21) def alarm_start(): global alarm_playing if not alarm_playing: alarm.play(-1) # -1表示循环播放,改为0则只播放一次 alarm_playing = True print(f"开始播放,状态:{alarm_playing}") def alarm_reset(): global alarm_playing alarm.stop() alarm_playing = False print(f"已重置,状态:{alarm_playing}") if __name__ == "__main__": print(f"程序启动,初始状态:{alarm_playing}") button_alarm.when_pressed = alarm_start button_reset.when_pressed = alarm_reset pause()
方案2:单按钮实现(符合最优需求,同一按钮控制播放/停止)
仅用一个按钮即可完成状态切换:首次按下播放,播放过程中按下立即停止并回到初始等待状态,无需额外重置按钮。
完整代码
import pygame from gpiozero import Button from signal import pause pygame.mixer.init() alarm = pygame.mixer.Sound("alarm.mp3") alarm_playing = False button = Button(21) # 仅使用原报警按钮即可 def toggle_play(): global alarm_playing if alarm_playing: # 播放中按下则停止 alarm.stop() alarm_playing = False print(f"停止播放,回到初始状态:{alarm_playing}") else: # 未播放按下则启动 alarm.play(-1) alarm_playing = True print(f"开始播放:{alarm_playing}") if __name__ == "__main__": print(f"程序启动,初始状态:{alarm_playing}") button.when_pressed = toggle_play pause()
补充说明
pygame.mixer.Sound.play()为非阻塞调用,启动播放后不会占用线程,可随时调用stop()方法立即终止播放- 如果不需要循环播放,将
play(-1)改为play(0)即可,单次播放完成后可自行添加逻辑重置alarm_playing状态 - 已验证完全兼容Python 3.7.3 + 树莓派4B的运行环境
内容的提问来源于stack exchange,提问作者BTI-Doug
相关产品推荐
相关产品推荐

