tomarai85/dualsense-bridge
GitHub: tomarai85/dualsense-bridge
该项目将 PS5 DualSense 手柄通过蓝牙变为 macOS 的麦克风和桌面控制器,纯软件实现,无需额外硬件。
Stars: 0 | Forks: 0
# dualsense-bridge
**将 PS5 DualSense 的内置麦克风用作真正的 macOS 麦克风——通过
Bluetooth,纯软件实现,无需额外硬件——并用手柄驱动 Claude Code(或你的
整台 Mac)。**
麦克风是其中新颖的部分。Sony 的文档、macOS 以及标准库都将
DualSense 麦克风视为仅限 USB 或无法通过 Bluetooth 使用,而那些
确实能无线捕获音频的项目则需要 Raspberry Pi Pico 接收器。而这个项目不需要:麦克风音频在控制器的 HID 输入
报告内以 Opus 编码,因此它可以在主机端被解码,并路由到
任何应用程序都可以选择其作为麦克风的虚拟 CoreAudio 设备。
它内置于一整套完整的“沙发编程”桥接器中——左摇杆控制光标,右摇杆
滚动,按钮负责回车 / Esc / 粘贴 / 窗口分割,通过手柄自带的麦克风进行按键说话,拨动摇杆即可切换 macOS Space。启动
全屏游戏时,手柄会自动移交控制权;退出游戏后,控制权又会自动回来。
## 为什么
智能体编程改变了输入方式的问题。驱动 Claude Code 主要就是
*阅读、批准、微调* —— 只需要几个按键、一个光标,以及(有了语音
输入后)几乎不需要打字。这种工作负载用游戏手柄来处理比
键盘更合适。这个桥接器让 DualSense 成为了一流的 Mac 输入设备,
同时又不妨碍你在同一台机器上用同一个手柄玩真正的游戏。
## 你能得到什么
- **将 DualSense 麦克风作为 macOS 输入** —— 它的 Bluetooth 麦克风音频(Opus,
嵌入在 HID 报告流中)在主机端解码,并作为一个
可选的 **"DualSense Mic"** 输入设备公开。无需 USB 线缆,无需 Pico 接收器,无需
耳塞。长按肩键进行按键说话,可在你听写时传输音频,而在
其他时间保持静音(详情及安全启用协议见
`docs/MIC-RESEARCH.md`)。
- **常驻摇杆鼠标** —— 径向盲区 + 指数响应曲线:轻微
倾斜即可实现像素级精准,完全倾斜可快速跨越三个显示器。
- **专用于终端工作的完整按键映射** —— 回车、Esc、Ctrl+C、粘贴、
拖拽选择后复制、右键点击、窗口分割、标签页、带
自动重复的箭头键。可在 `config.toml` 中重新映射(完整映射及微调见 `LAYOUT.md`)。
- **拨动摇杆切换 Space**(长按 R1 + 拨动):发送真实的
Ctrl+方向键,使焦点随之转移并播放原生动画;
具备速度辅助,因此在你拇指还在移动时就会触发。
- **语音按键说话** 绑定在肩键上(此处绑定至 Aqua Voice;
绑定只是一个组合键 —— 你可以将其指向任意听写热键)。
- **游戏共存**:*全屏*游戏会独占手柄
(在 HID 层级释放 —— 游戏会将其视为普通控制器)。*窗口化*
游戏或启动器不会抢占手柄。退出或按下 Cmd-Tab,桥接器会自动
重新获取控制权。
- **持久化服务**:包含一个已签名的包装应用 + LaunchAgent,因此
辅助功能授权在重启和代码编辑后依然有效。
## 安全设计(有趣的部分)
在正在运行的游戏旁边合成输入极其危险,因此“绝不将输入
泄漏到错误的地方”是第一原则,由四个独立的层级强制执行:
1. **每次触发的输出门控** —— 每个合成事件(按键和鼠标,按下
和松开)在发送前的一瞬间都会检查最前面的应用程序。游戏
在最前面、锁屏或任何错误 => 事件被丢弃。默认关闭(安全失效)。
2. **HID 释放** —— 全屏游戏会获得设备的*独占权*;
在你游玩时,桥接器在结构上是不存在的。
3. **有序、去抖动的状态转换** —— 按住的按键会针对
上一个桌面应用被释放(绝不进行全局释放),按住的鼠标按键会被丢弃;
进入/离开游戏模式时经过了去抖动处理,因此加载画面不会使其反复跳动。
4. **光标下窗口防护** —— 在任何游戏拥有的
窗口上方点击都会被丢弃,即使在另一个显示器上的窗口化游戏也是如此(光标*移动*会放行,因此
游戏窗口绝不会困住指针)。
仲裁机制可以区分桌面应用、窗口化游戏、全屏游戏
(基于交叉的覆盖检测,>=98% 的显示屏)以及锁屏。
156 个单元测试确保了这些原则。
## 运行
持久化服务(推荐 —— 在会话终止和重启后依然有效):
```
./dsbridge install # build DSBridge.app + load the KeepAlive LaunchAgent
# then ONE-TIME: grant DSBridge.app Accessibility (pane auto-opens)
./dsbridge kick # restart the managed bridge (after python-side edits; no re-grant)
./dsbridge status # agent + process + last log
./dsbridge uninstall # back to manual mode
```
手动 / 开发模式(随启动会话终止而结束):
```
./dsbridge start # operator bridge (--talk), nohup + auto-restart
./dsbridge stop
./dsbridge start --pretty # live human-readable view of all inputs (verification)
```
直接运行(前台):`.venv/bin/python src/dsread.py --talk|--pretty|--json`
单一所有者:实例通过独占的 flock(`.dsread.lock`)+
旧实例清理机制进行仲裁,因此 launchd 实例和
手动实例绝不会发生重复注入;未获得授权的实例会发出明显的等待提示,而不是静默地
丢弃事件。
## 要求 / 权限
- macOS(在 Tahoe 26.x,Apple Silicon 上测试),通过 Bluetooth 连接的 DualSense。
- `brew install hidapi`;python 依赖项位于 `.venv`(`hidapi`、`pyobjc`)中。
- 用于 CGEvent 注入的 **辅助功能**:仅需授权一次 **DSBridge.app**(TCC
将 python 子进程作为责任进程归因于它)。仅在 `install` 重新构建启动器时
才需要重新授权;`kick` 永远不需要。
- 若要阻止 PS/Home 键打开 macOS 的游戏应用:
`defaults write com.apple.GameController bluetoothPrefsMenuLongPressAction -integer 0`(恢复原状 = 1)。
- 提示:连接控制器时,macOS 会自动启用“游戏”专注模式
(静默通知)。禁用方法:系统设置 > 专注模式 > 游戏。
## 真实的局限性
- **Bluetooth 闲置休眠**:DualSense 固件在无
物理输入约 10 分钟后会休眠,主机发送的任何内容都无法
重置该计时器(光条和触觉反馈保活信号均经过了实际测试并被
反驳)。按下一次 PS 键即可重新唤醒,桥接器会自动重新获取。USB
永远不会休眠。
- 在 Bluetooth 下,macOS 不公开触控板-XY / IMU(USB 可解锁这些功能;
已在路线图中)。在操作系统层面上,麦克风的情况也是如此 —— macOS 永远不会在 BT 下呈现它 ——
但桥接器无论如何都能提供该功能,方法是在主机端解码手柄的
HID 音频流(这就是上文提到的核心特性)。
- Space 切换依赖于系统事件按键代码(~毫秒级)+ 原生滑动
动画;合成的 CGEvent Ctrl+方向键无法触及当前 macOS 上的 Mission Control
(测试了 32 种变体矩阵,记录在 `src/keysend.py` 中)。
## 仓库导览
```
src/dsread.py reader daemon: HID parse loop, arbitration state machine, mover thread
src/focusgate.py frontmost classification (desktop/windowed game/fullscreen/lock) + output gates
src/keysend.py gated CGEvent key synthesis + pid-targeted failsafe release
src/mousesend.py gated CGEvent mouse: move/scroll/click/drag + seam-crossing warp
src/dsreport.py BT input report parser
config.toml user-editable button->action map LAYOUT.md full map + design notes
dsbridge install/kick/start/stop/status app/ wrapper-app source
tests/ the never-leak invariant suite (156 tests)
```
`.venv/bin/python -m pytest -q`
MIT 许可证。
标签:CoreAudio, DualSense, HID协议, 游戏手柄映射, 语音输入, 逆向工具, 驱动与外设交互