Python SpeechRecognition设录音时长后如何实现倒计时(Pygame场景)
解决Pygame循环中录音时长控制与同步倒计时的问题
核心问题在于sr.Recognizer.listen()是阻塞式方法,直接调用会卡住Pygame主循环,导致倒计时无法实时更新。结合phrase_time_limit参数精准控时的同时,需要用多线程分离录音任务和UI渲染(倒计时),避免互相阻塞。
实现思路
- 将录音逻辑放到子线程中执行,主线程专注于Pygame的事件处理和倒计时显示
- 通过
phrase_time_limit参数强制限制录音时长,确保录音精准停止 - 主线程通过实时计算剩余时间,同步更新倒计时UI
- 录音结束后,主线程检测到状态变化,保存音频文件
完整代码示例
import pygame import speech_recognition as sr import threading import time # 初始化Pygame pygame.init() screen = pygame.display.set_mode((400, 200)) pygame.display.set_caption("录音倒计时") font = pygame.font.SysFont(None, 60) # 全局状态变量 recording_active = False remaining_time = 0 audio_data = None def record_task(duration, source, recognizer): """子线程执行的录音任务""" global recording_active, audio_data try: # 用phrase_time_limit精准控制录音时长 audio_data = recognizer.listen(source, phrase_time_limit=duration) finally: # 录音结束后标记状态 recording_active = False def start_recording(duration): """启动录音的入口函数""" global recording_active, remaining_time, audio_data if not recording_active: recording_active = True remaining_time = duration audio_data = None # 初始化识别器与麦克风 r = sr.Recognizer() with sr.Microphone() as source: r.adjust_for_ambient_noise(source) # 适配环境噪音,提升录音质量 # 启动后台录音线程 threading.Thread(target=record_task, args=(duration, source, r), daemon=True).start() # Pygame主循环 running = True clock = pygame.time.Clock() target_duration = 6 # 设定的录音时长(可改为用户选择的数值) while running: screen.fill((255, 255, 255)) # 处理事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # 按下空格键启动录音 if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE: start_recording(target_duration) # 处理录音状态与倒计时 if recording_active: # 基于Pygame时钟更新剩余时间(每秒60帧,精准计算) frame_time = clock.tick(60) / 1000 remaining_time -= frame_time if remaining_time < 0: remaining_time = 0 # 渲染倒计时文本 time_text = font.render(f"剩余: {int(remaining_time) + 1}秒", True, (0, 0, 0)) screen.blit(time_text, (60, 70)) else: # 渲染启动提示 prompt_text = font.render("按空格开始录音", True, (0, 0, 0)) screen.blit(prompt_text, (50, 70)) # 录音结束后保存音频 if audio_data is not None: with open("recording.wav", "wb") as f: f.write(audio_data.get_wav_data()) audio_data = None # 重置状态,避免重复保存 pygame.display.flip() pygame.quit()
关键细节说明
- 多线程分离:录音任务在后台线程执行,不会阻塞Pygame的UI渲染,确保倒计时实时更新
- 精准控时:
phrase_time_limit=duration参数会让listen()在指定时长后自动停止录音,解决原代码录音超时问题 - 倒计时计算:用
clock.tick(60)获取每帧的耗时,以此更新剩余时间,比单纯time.sleep()更适配Pygame循环 - 状态同步:通过全局变量
recording_active和audio_data实现主线程与子线程的状态同步
内容的提问来源于stack exchange,提问作者user20884512
相关产品推荐
相关产品推荐

