Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AudioLock

A lightweight macOS menu bar utility that keeps your selected audio output device locked.

一个用于锁定 macOS 默认音频输出设备的轻量菜单栏工具。

AudioLock menu preview

English

Screenshot

The menu preview above shows AudioLock locked to a selected output device.

Features

  • Locks the macOS default audio output to a device selected by stable CoreAudio UID.
  • Immediately restores the locked output when AirPods, Bluetooth headphones, HDMI displays, or USB devices change the system default.
  • Routes one running app to another physical output device without changing the macOS default output.
  • Restores app routes after app relaunch or target-device reconnect using bundle identifiers and device UIDs.
  • Uses event-driven CoreAudio listeners—no polling timer and near-zero idle CPU usage.
  • Keeps the locked UID while a device is disconnected and automatically restores it when the device returns.
  • Restores lock state after relaunch and wake from sleep.
  • Supports Launch at Login with SMAppService.
  • Fully localized in English and Simplified Chinese, with a Follow System option.
  • Native SwiftUI MenuBarExtra interface with no Dock icon.

Installation

  1. Clone this repository.
  2. Open AudioLock.xcodeproj in Xcode.
  3. Build and run the AudioLock scheme.
  4. For regular use, copy the built AudioLock.app to /Applications.

The project uses local ad-hoc signing by default so it can build without a paid Apple Developer account. You can select your Personal Team in Xcode if preferred.

Usage

  1. Click the AudioLock speaker icon in the menu bar.
  2. Open Output and select the default output device you want to use.
  3. Choose Lock Output.
  4. AudioLock keeps that device as the default output until you turn off Lock Output.

For per-app routing, open App Audio Routing…, choose Add Route, then select a running app and a target output. macOS asks for System Audio Recording access the first time a route starts. Disabling or deleting a route immediately restores the app's normal output.

If the locked device disconnects, AudioLock preserves its UID and reports it as unavailable. It automatically switches back when the device reconnects.

Requirements

  • macOS 14.2 Sonoma or later
  • Xcode 16 or later to build from source

How It Works

AudioLock reads output devices and their stable UIDs through CoreAudio. It listens to both kAudioHardwarePropertyDefaultOutputDevice and kAudioHardwarePropertyDevices with AudioObjectAddPropertyListenerBlock.

When locked, the listener queue compares the current default device with the cached locked device ID and calls AudioObjectSetPropertyData immediately if they differ. UI and model updates happen afterward on the main thread, keeping the recovery path as short as the public CoreAudio API allows. Repeated callbacks caused by AudioLock's own set operation are harmless because the target is already the default.

App routing is independent of the default-output lock. AudioLock resolves an app's current CoreAudio process objects from its persistent bundle identifier, creates a private process tap with AudioHardwareCreateProcessTap, and uses CATapMutedWhenTapped so that process no longer reaches the default hardware while the tap is read. A private aggregate device connects the tap to the selected physical output. Its real-time IOProc uses a preallocated lock-free ring buffer and Apple's AudioConverter for sample-rate and channel conversion. The private tap and aggregate device are destroyed whenever the route stops or becomes unavailable.

Protected media may decline system-audio capture. AudioLock reports such a route as unavailable and does not attempt to bypass DRM.

Build

xcodebuild \
  -project AudioLock.xcodeproj \
  -scheme AudioLock \
  -configuration Debug \
  build

xcodebuild \
  -project AudioLock.xcodeproj \
  -scheme AudioLock \
  -configuration Debug \
  test

Privacy

AudioLock does not connect to the network, collect data, run analytics or telemetry, record audio, store audio, or upload audio. When a user enables an app route, PCM buffers are processed only in memory and sent directly to the selected local output device through public CoreAudio APIs.

License

AudioLock is available under the MIT License.


中文

截图

上方菜单预览展示了 AudioLock 锁定到指定输出设备时的状态。

功能

  • 使用稳定的 CoreAudio UID 锁定所选 macOS 默认音频输出设备。
  • 当 AirPods、蓝牙耳机、HDMI 显示器或 USB 设备改变系统默认输出时立即恢复锁定设备。
  • 将某个正在运行的应用单独路由到另一台物理输出设备,不改变 macOS 默认输出。
  • 使用 Bundle ID 和设备 UID,在应用重启或目标设备重连后自动恢复路由。
  • 采用事件驱动的 CoreAudio 监听,不使用轮询定时器,空闲 CPU 占用接近零。
  • 锁定设备断开时保留 UID,设备重新连接后自动恢复。
  • App 重启和 Mac 睡眠唤醒后自动恢复锁定状态。
  • 使用 SMAppService 支持登录时启动。
  • 完整支持 English、简体中文和跟随系统。
  • 使用原生 SwiftUI MenuBarExtra,不显示 Dock 图标。

安装

  1. 克隆本仓库。
  2. 使用 Xcode 打开 AudioLock.xcodeproj
  3. 编译并运行 AudioLock Scheme。
  4. 日常使用时,将编译得到的 AudioLock.app 复制到 /Applications

项目默认使用本地 ad-hoc 签名,无需付费 Apple Developer 账号即可编译;也可以在 Xcode 中选择自己的 Personal Team。

使用方法

  1. 点击菜单栏中的 AudioLock 扬声器图标。
  2. 打开 输出 子菜单,选择希望使用的默认输出设备。
  3. 点击 锁定输出
  4. 在关闭 锁定输出 前,AudioLock 会持续保持该设备为默认输出。

如需单独路由应用,打开 应用音频路由…,点击 添加路由,然后选择正在运行的应用和目标设备。首次启动路由时,macOS 会请求“系统音频录制”权限。关闭或删除路由后,该应用会立即恢复正常输出。

锁定设备断开时,AudioLock 会保留设备 UID 并显示设备不可用;设备重新连接后会自动切回。

系统要求

  • macOS 14.2 Sonoma 或更高版本
  • 从源码编译需要 Xcode 16 或更高版本

工作原理

AudioLock 通过 CoreAudio 获取输出设备及其稳定 UID,并使用 AudioObjectAddPropertyListenerBlock 同时监听默认输出设备和音频设备列表变化。

锁定状态下,CoreAudio 监听队列会直接比较当前默认设备与缓存的锁定设备 ID;如不一致,立即调用 AudioObjectSetPropertyData 恢复输出。UI 和状态刷新随后才回到主线程执行,因此恢复路径保持在公开 CoreAudio API 所允许的最短范围。应用自身的设置操作即使再次触发事件,也会因为设备已经一致而自然结束,不会形成循环。

应用路由与默认输出锁完全独立。AudioLock 使用持久化 Bundle ID 找到应用当前的 CoreAudio Process AudioObject,调用 AudioHardwareCreateProcessTap 创建私有 Process Tap,并通过 CATapMutedWhenTapped 让该进程在 Tap 被读取时不再进入默认硬件混音。私有 Aggregate Device 将 Tap 接到目标物理设备;实时 IOProc 使用预分配的无锁环形缓冲和 Apple AudioConverter 处理采样率及声道差异。路由停止或不可用时,Tap 和 Aggregate Device 会立即销毁。

受保护媒体可能拒绝系统音频捕获。AudioLock 会将该路由标记为不可用,不会尝试绕过 DRM。

编译

xcodebuild \
  -project AudioLock.xcodeproj \
  -scheme AudioLock \
  -configuration Debug \
  build

xcodebuild \
  -project AudioLock.xcodeproj \
  -scheme AudioLock \
  -configuration Debug \
  test

隐私

AudioLock 不联网、不收集数据、不使用分析或遥测、不录音、不保存音频,也不上传音频。只有在用户启用应用路由时,PCM 缓冲才会在内存中实时处理,并通过公开 CoreAudio API 直接送到所选本地输出设备。

许可证

AudioLock 使用 MIT License

About

A lightweight macOS menu bar utility that keeps your selected audio output device locked.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages