如何在Linux中用Python捕获未提交至DBus的蓝牙播放暂停事件
解决蓝牙音箱播放/暂停按钮事件捕获问题
方法1:通过evdev直接读取输入事件
既然evtest能检测到KEY_PLAYCD按键事件,可使用Python的evdev库直接读取对应输入设备,监听按键动作。
- 安装依赖库:
pip install evdev
确定目标输入设备:
运行sudo evtest,找到能触发KEY_PLAYCD事件的设备路径(如/dev/input/eventX)。监听代码示例:
from evdev import InputDevice, categorize, ecodes # 替换为你的蓝牙音箱对应的输入设备路径 device = InputDevice('/dev/input/eventX') print(f"已启动监听: {device.name}") for event in device.read_loop(): if event.type == ecodes.EV_KEY: key_event = categorize(event) if key_event.scancode == ecodes.KEY_PLAYCD: if key_event.keystate == key_event.key_down: print("播放/暂停按钮按下") # 这里调用mpv的播放暂停控制逻辑 # 例如:player.toggle_pause() elif key_event.keystate == key_event.key_up: print("播放/暂停按钮释放")
注意:运行脚本需root权限,或执行
sudo usermod -aG input $USER给当前用户添加输入设备访问权限,之后重新登录生效。
方法2:监听蓝牙AVCTP事件
从btmon输出可见,音箱通过AV/C Passthrough发送了播放按键事件,可通过两种方式处理:
方式A:配置BlueZ转发事件到DBus
编辑/etc/bluetooth/media.conf,确保配置项:
Enable=Source,Sink,MediaPlayer1
重启蓝牙服务:
sudo systemctl restart bluetooth
之后再用dbus-monitor --system查看,若事件正常转发,即可通过dbus-python监听对应信号。
方式B:直接解析HCI原始数据包
若BlueZ未转发事件,可直接监听HCI套接字解析蓝牙数据包(需root权限):
import socket import struct # 创建HCI原始套接字 s = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI) s.bind(("hci0",)) # 设置过滤器只接收HCI事件 filter_mask = struct.pack("<I", 0x00000010) s.setsockopt(socket.SOL_HCI, socket.HCI_FILTER, filter_mask) while True: data = s.recv(1024) # 解析AVCTP Passthrough命令中的PLAY操作码 if len(data) > 20 and data[14] == 0x7c: op_code = data[17] if op_code == 0x44: print("PLAY按键按下") # 执行mpv播放暂停操作 elif op_code == 0xc4: print("PLAY按键释放")
结合mpv控制
捕获到按键事件后,通过python-mpv库控制播放暂停:
import mpv player = mpv.MPV() def toggle_playback(): player.toggle_pause() # 在按键按下事件触发时调用toggle_playback()
内容的提问来源于stack exchange,提问作者sydd
相关产品推荐
相关产品推荐

