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协议, 游戏手柄映射, 语音输入, 逆向工具, 驱动与外设交互