프로젝트 소개

## 프로젝트 개요 AirPods Voice 입력기는 네이티브 macOS 메뉴 막대 앱으로, AirPods의 클릭 제스처로 음성 입력을 제어한다. 한 번 클릭하면 녹음을 시작하고, 다시 클릭하면 중지하고 텍스트를 확인한 뒤 자동으로 전송하며, 전 과정에서 키보드를 건드릴 필요가 없다. 현재 정식 버전은 1.0이다. ## 주요 기능 - AirPods를 한 번 클릭하면 음성 입력을 시작하고, 다시 클릭하면 중지 후 자동 전송한다. - 연속 여러 회 사용을 지원하며, 매 회 종료 후 다시 시작할 수 있는 유휴 상태로 돌아간다. - 내장 마이크와 AirPods 마이크를 모두 지원하며, 앱 설정을 수정할 필요가 없다. - 기본적으로 `Fn` 길게 누르기를 시뮬레이션하며, Control, Option, Command, Shift 또는 F1–F12로 설정할 수도 있다. - 메뉴 막대와 제어 창에서 실행 상태, 시작, 중지, 사용 설명 및 종료를 제공한다. - 앱을 열 때마다 제어 창을 표시하며, 닫아도 메뉴 막대에서 계속 실행된다. - 실제 키보드 입력이 감지되면 종료되지 않은 음성 키 입력을 자동으로 중단하여, 보조 키가 터미널이나 할 일 앱에 영향을 주지 않도록 한다. - Dock을 차지하지 않으며, BetterTouchTool 등 서드파티 자동화 소프트웨어에 의존하지 않는다. - Apple Silicon과 Intel Mac을 지원하며, 최소 요구 사항은 macOS 13이다. ## 사용 전제 조건 사용하는 음성 입력기에서 음성 입력 단축키를 「Fn 길게 누르기」로 설정해야 한다. README에 따르면 1.0은 豆包 입력기로 실제 AirPods 다회 검수를 완료했으며, 다른 입력기는 「단축키를 누르고 있는 동안 녹음, 떼면 종료」 동작을 지원해야 한다. 앱 실행 중에는 AirPods의 재생/일시정지 클릭을 점유하므로, 이때는 클릭으로 음악을 제어할 수 없다. 앱을 중지하거나 종료하면 미디어 제어가 복구된다. ## 설치 및 권한 GitHub Releases에서 PKG 설치 패키지를 다운로드하여 `/Applications/AirPods Voice 输入法.app`에 설치한다. 설치 프로그램은 이전 테스트 버전을 자동으로 중지하고 제거하여 두 버전이 동시에 AirPods를 점유하는 것을 방지한다. 현재 설치 패키지는 ad-hoc 서명을 사용하므로, macOS가 차단하면 Finder에서 우클릭 후 「열기」를 선택하면 된다. 앱은 음성 키 길게 누르기를 시뮬레이션하고 엔터를 전송하기 위해 macOS 「손쉬운 사용」 권한을 반드시 받아야 한다. 권한 부여 대상은 앱 자체이며, 터미널이나 개발 도구에 권한을 줄 필요가 없고 전체 디스크 접근도 필요하지 않다. 앱 자체는 마이크를 수집하지 않으며, 마이크 권한은 사용자가 선택한 음성 입력기가 관리한다. ## 작동 원리(README 설명) 앱은 `MPRemoteCommandCenter`를 통해 Now Playing 세션을 보유하여 AirPods 클릭을 수신하며, 소스가 `com.apple.bluetoothd` 또는 `com.apple.cloudpaird`인 미디어 이벤트만 허용한다. 키보드 재생 키 등 다른 소스는 음성 입력을 시작하지 않는다. AirPods 마이크가 통화 오디오 모드로 전환되면, 두 번째 클릭은 `bluetoothd`에 의해 Software Mute로 보고되며, 앱은 자신이 시작한 음성 세션에서만 이를 중지 및 전송 신호로 사용한다. IOHID 감시는 예비 채널로 사용되며, 동일한 실제 조작은 350ms 창으로 중복 제거된다. 첫 번째 클릭은 `IOHIDPostEvent`를 통해 Fn을 한 번 전송하여 활성화한다. 두 번째 클릭은 녹음 세션을 종료하고 엔터를 두 번 연속 전송하는데, 첫 번째는 입력기의 조합 문자를 확인하고 두 번째는 메시지를 전송한다. 전역 보조 키가 단축키에 민감한 앱에 영향을 주지 않도록, 1.0에는 세 겹의 보호가 추가되었다. 시작 시 과거에 남은 Fn을 정리하고, 음성 중 실제 키보드 입력이 감지되면 먼저 음성 보조 키를 제거하고 즉시 음성 입력을 종료하며, 앱이 비정상 종료되면 독립 데몬 프로세스가 Fn을 해제한다. 정상 중지, 포그라운드 앱 전환, 5분 안전 타임아웃 또는 앱 종료 시에는 키만 해제하고 잘못 전송하지 않는다. ## 설정 및 로그 기본 설정 파일은 `config/voice-key`이며 내용은 `fn`이다. control, option, command, shift 또는 f1–f12로 변경할 수 있고, 수정 후에는 스크립트를 재시작해야 한다. 소스 실행 시에는 환경 변수로 임시 지정할 수도 있다. 로그는 `/tmp/airpods-voice-input-method/` 아래의 app.log, app.stdout.log 및 app.stderr.log에 위치한다. `pgrep -fl airpods-voice-input-method`로 프로세스를 확인하고, `./scripts/stop.sh`로 안전하게 중지하고 음성 키를 해제할 수 있다. ## 빌드 및 테스트 `scripts/build.sh`로 유니버설 앱을 빌드하고, `scripts/package-release.sh`로 PKG를 생성하며, Developer ID 인증서 지정도 지원한다. 테스트 스크립트는 4회 음성 상호작용, Fn 소비, 키보드 안전, 크래시 복구 등 회귀 시나리오를 다루며, 별도로 `tests/hitl-two-cycle.sh`는 실제 AirPods 수동 검수에 사용된다. ## 라이선스 소스 코드는 PolyForm Noncommercial 1.0.0 라이선스를 사용하며, OSI가 정의한 오픈 소스 라이선스가 아닌 source-available이다. 개인 학습, 연구 및 비상업적 사용은 허용되며, 상업적 사용은 별도로 허가를 받아야 한다.