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

蓝牙设备按键控制录音:停止按键无法中断While循环求助

问题解决:蓝牙按键控制录音启停失效

问题根源

你的代码按下KEY_PAGEDOWN后进入while True死循环,这个循环会完全阻塞主线程,导致外层的蓝牙事件读取循环for event in bluetooth_device.read_loop()彻底停摆,根本接收不到KEY_PAGEUP的按键事件,自然无法触发停止录音和保存文件的逻辑。

解决方案:用线程分离录音与按键监听逻辑

把录音循环放到独立线程中运行,让主线程能持续监听蓝牙按键事件,通过全局标志控制录音线程的启停。

修改后的代码

import threading
import ecodes
from evdev import categorize
import wave
import struct

# 全局标志控制录音状态
recording = False
audio = []

def record_audio(recorder):
    global recording, audio
    audio = []  # 每次开始录音前清空旧数据
    recorder.start()
    print("Recording... press KEY_PAGEUP to stop")
    while recording:
        frame = recorder.read()
        audio.extend(frame)
    recorder.stop()

for event in bluetooth_device.read_loop():
    if event.type == ecodes.EV_KEY and event.value == 1:
        keyevent = categorize(event)      
        if keyevent.keycode == 'KEY_PAGEDOWN':
            if not recording:
                recording = True
                # 启动后台录音线程
                threading.Thread(target=record_audio, args=(recorder,), daemon=True).start()
        elif keyevent.keycode == 'KEY_PAGEUP':
            if recording:
                recording = False
                # 等待录音线程结束,确保数据完整
                while threading.active_count() > 1:
                    pass
                # 保存音频文件
                with wave.open("audio.wav", 'w') as f:
                    f.setparams((1, 2, 16000, 0, "NONE", "NONE"))
                    f.writeframes(struct.pack("h" * len(audio), *audio))
                print("Audio saved to audio.wav")

代码说明

  1. 全局标志recording:作为录音线程的开关,主线程修改该标志即可控制录音启停。
  2. 录音线程record_audio:单独处理音频读取逻辑,仅在recording为True时持续采集数据。
  3. 按键事件处理:
    • 按下KEY_PAGEDOWN时,检查未在录音则启动线程并开启录音。
    • 按下KEY_PAGEUP时,关闭录音标志,等待线程结束后再保存文件,避免数据丢失。

内容的提问来源于stack exchange,提问作者Farouk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 01:20:17