Skip to content

Latest commit

 

History

History
106 lines (77 loc) · 10.6 KB

README.org

File metadata and controls

106 lines (77 loc) · 10.6 KB

debuff

macOS 原生菜单栏小工具(Swift),三合一:

  • **久坐计时**:超过阈值弹出仿魔兽 debuff 浮窗(外框 + 图标 + 计时)。
  • **微信 / 飞书未读**:读取 Dock 角标,未读达到阈值时同样弹出 debuff 浮窗。
  • **语音输入**:全局快捷键唤起麦克风录音,本地 STT 服务实时转写并粘贴到光标处,带实时波形指示条。

软件说明

菜单栏图标常驻;点击后出现设置菜单,可调整久坐阈值、自定义图标、语音输入各项参数。

语音输入

通过菜单「语音输入 → 开始语音输入」或全局快捷键(默认 =⌥D=)开启麦克风后,进入**常驻监听**模式:麦克风开启后会一直保持,直到用菜单「停止语音输入」关停。麦克风打开期间,控件分两种**语音状态**:

  • **激活(绿)**:说的话停顿达设定时间(默认 1 秒)或单段超最大时长(默认 60 秒)自动切段,每段由本地 STT 服务转写后实时粘贴到**当前光标位置**(「边说边粘」,默认开启),可连续说多句。
  • **非激活(灰)**:控件不消失,音柱变灰并随声音实时跳动;此时麦克风只驱动波形跳动,**不做语音切段/转写与指令识别**(待命期几乎零性能消耗),重新激活仅靠快捷键。

**状态切换(仅在激活状态识别;「over/删除/清空」需整句命中,「发送」允许贴在句子末尾)**:

  • 说「over」:激活 → 非激活
  • 说「发送」,或所说句子的最后两字为「发送」(转写自动加的尾随句号会被忽略):「发送」视为指令而非正文,只把前面的正文粘贴上去并敲一次回车(发送),随后把控件切回**非激活待命**——不再退出/隐藏控件
  • 快捷键 =⌥D=:在激活/非激活间切换(引擎未开启时先开启并进入激活);非激活 → 激活已取消语音唤醒,只能按快捷键
  • **波形指示条**:一个圆角边框悬浮小窗;激活时绿色实时跳动,非激活待命时灰色实时跳动,可用鼠标拖拽移动、拖右缘调宽,位置/宽度自动保存。麦克风完全关停(菜单「停止语音输入」)后控件隐藏。
  • **波形敏感度**:菜单「语音输入 → 设置 → 波形敏感度」提供 0.1~1 的滑块,默认 0.5。0.5 为标准(与旧版观感一致,增益 1 倍);0.5→1 为增强区间,最多约 10 倍,越靠近 1 越小的声音也能把音柱顶满;0.5→0.1 为减弱区间,需要更大声音柱才会撑高。拖动即时生效并自动保存。
  • **转写 loading**:只要有在途转写,整段波形就被三个从左到右依次闪动的绿点覆盖,转写全部返回即恢复波形。VAD 停顿切段与收尾段同样会触发,借此可确认切片时机并观察每段转写耗时。按键提交时,转写结果先出现在光波下方文本区,随后整段粘贴到当前输入框并清空下方文本区。
  • **切段倒计时**:最大切段上限已延长到 60 秒(旧设置自动提升);当前片段距最大切段还剩 5 秒时,波形右缘显示倒计时数字(5→1)。该处不绘制音柱、数字直接落在面板底板上,因此背景与整块 UI 一致、不额外引入颜色,也不挤压波形;切段转写开始后倒计时消失。
  • **快捷键**:默认 =⌥D=,可在菜单「语音输入 → 设置 → 快捷键」中更换。
  • **锁屏自动停麦**:屏幕锁定后麦克风自动切到关闭状态(控件隐藏、录音点消失);解锁后自动恢复到锁屏前的状态(激活/非激活)。
  • **麦克风选择**:菜单「语音输入 → 设置 → 麦克风」可指定输入设备,默认「跟随系统默认」。macOS 只允许应用采系统默认输入,因此所选设备仅在录音期间被临时接管为系统默认输入(录音里系统其它依赖默认麦克风的应用也会暂时跟到该设备),停止语音输入 / 锁屏 / 退出应用时自动还原;所选设备中途拔出会自动回退到系统默认并续麦。
  • **STT 服务地址**:默认 http://127.0.0.1:8001/v1/audio/transcriptions=,OpenAI 兼容接口(multipart =file 字段,返回 ={“text”: “…”}=),可在菜单中自定义。菜单「测试服务连接」可检测连通性。
  • **粘贴方式**:默认「实时(边说边粘)」,可改为「结束后统一粘贴」。
  • **激活状态透明度**:可在菜单中设置(0.50 / 0.65 / 0.80 / 1.00)。

语音日记(只记激活语音 + 节省时间统计)

激活状态下说出的内容在转写上屏时,同一份文本(不重复转写)逐条以 [日期 时:分:秒] 开头追加到 =~/Desktop/语音日记/yyyy-MM-dd.txt=(日期为说话当天,跨天自动换文件)。同时把当天转写的字数与折算的「节约时间」永久累计,展示在菜单「语音输入」区域。

  • **只记激活语音**:非激活待命(灰)不录音、不做后台切段/转写,环境杂音不会进日记;停麦/锁屏等收尾段的激活语音照常入日记。
  • **指令词过滤**:纯指令(「over/删除/清空」等)不入日记;「发送」指令前带的正文本会照常入日记。
  • **节省时间统计**:按 100 字/分钟的打字速度估算(转写 N 字 ≈ 节约 N/100 分钟),菜单栏显示「今日语音输入 N 字」「累计节约 X 天 X 小时 X 分钟」,历史字符与折算时间跨天永久累计(今日字数每天清零重计)。统计跟随激活语音输入,与是否写入桌面文件无关。
  • **启停**:由菜单「语音输入 → 语音日记:记录激活语音到桌面」控制是否写入桌面文件(默认开启);「打开语音日记目录…」直达当天文件。

环境要求

  • macOS 13 或更高版本
  • Swift 5.9+(随 Xcode 或 Command Line Tools 安装)
  • 本地 STT 服务(funasr-llamacpp + FSMN-VAD,:persistent: 常驻),示例见 ~/Desktop/foucs/funasr-llamacpp/ 的 README / start-funasr-server.sh

权限要求

使用 scripts/package-macos-app.sh 打包成 .app 后运行(直接用 swift run 跑裸可执行文件时权限提示可能无法正常弹出)。

  • **麦克风**:语音输入录音用,首次使用系统弹窗授权。
  • **辅助功能**:读取输入光标位置 + 模拟 ⌘V 粘贴。未授权时录音前会弹出醒目提示并引导到系统设置。

编译与运行

cd /path/to/debuff
swift build -c release
./.build/release/SedentaryDebuff

打包成标准 =.app=(可拖入「应用程序」):

./scripts/package-macos-app.sh   # 产物 dist/debuff.app
cp -R dist/debuff.app /Applications/

用 Xcode 打开 Package.swift 亦可直接编译运行。

配置持久化

久坐阈值、图标路径、语音输入各参数(STT 地址、快捷键、粘贴模式、停顿/最大切段、激活透明度、波形位置、波形敏感度)均保存在本机 UserDefaults 中。

目录结构

  • Sources/SedentaryDebuff/ 主代码
    • SedentaryDebuffApp.swift / SedentaryDebuffAppDelegate.swift 应用入口
    • SedentaryMonitor.swift 久坐计时
    • WeChatDebuffMonitor.swift / FeishuDebuffMonitor.swift 未读监控
    • DebuffStatusBarController.swift 菜单栏与设置菜单
    • Dictation/ 语音输入模块(快捷键、录音、分段、STT 上传、粘贴、波形面板、光标定位)
    • CrashLog.swift 崩溃日志(写入 =~/Library/Logs/SedentaryDebuff_crash.log=)
  • scripts/package-macos-app.sh 打包脚本
  • App/ 打包用的 =Info.plist=、图标与资源

版本记录

  • v1.0:久坐 debuff 浮窗
  • 语音输入:全局快捷键录音 → 本地 STT 转写 → 粘贴到光标;波形指示条(可拖拽、激活绿色/待命灰色实时跳动)
  • 语音状态:常驻监听,激活/非激活切换(说「over」待命、「发送」回车并待命、快捷键切换)
  • 性能优化:取消「说 输入/激活」的语音唤醒;非激活待命只驱动波形、不再后台转写与识别指令
  • 锁屏/唤醒、设备重连自愈:解锁或系统默认麦克风重新连接后,若引擎「开着却录不进声音」(start 时设备未就绪、或 start 成功却无输入缓冲回调),周期健康检查会自动重建引擎续麦;全新开启失败也按退避自动重试,录音在麦克风就绪后自动恢复,快捷键无需反复重按
  • 停顿切段改相对判停:停顿不再依赖绝对电平门限,而是相对本句说话音量(跌到约 1/5 以下即算停顿),安静房间里麦克风残留电平偏高导致「停顿了却不切段、拖到最长时长才转写」的问题已修复;菜单新增 0.4 秒停顿档
  • 语音输入可指定麦克风:菜单「语音输入 → 设置 → 麦克风」可选「跟随系统默认」或某具体输入设备;选定时录音期间接管系统默认输入并等设备真正 running 后才开麦,停止/锁屏/退出自动还原,设备拔出自动回退跟随系统默认
  • 语音日记(只记激活语音):取消非激活待命的后台切段/转写(杂音不再进日记),只把激活转写上屏的内容追加到 ~/Desktop/语音日记/当天日期.txt;新增节省时间统计——今日转写字数按 100 字/分钟打字速度折算节约时间并永久累计,菜单栏显示「今日语音输入 N 字」「累计节约 X 天 X 小时 X 分钟」
  • 停顿判定档位上限从 2.0 秒延长到 5 秒(新增 3.0 / 4.0 / 5.0 档);光波下方缓冲文本区支持鼠标滚轮上下滚动(hover 即可滚);文本区右下方新增「清除 / 粘贴」两个按钮,左键清空尚未提交的缓冲,右键把缓冲整段粘贴到当前光标并待命(等同于提交快捷键),按钮右侧显示当前提交快捷键;缓冲文字区改为毛玻璃背景(Material 模糊 + 深色蒙层)以保证叠字下的可读性
  • iPhone 麦克风等互联设备的安全唤醒:这类设备只有成为「系统默认输入」才会被系统唤醒(直接绑 AudioUnit 不触发互联握手,start 只会反复报 coreaudio ‘stop’),而旧的「切走再切回」抖动又容易把它带进「已连接却全是零电平」的坏状态。现改为:只做一次真实的默认切换,然后轮询设备是否真正 running(必要时显式 AudioDeviceStart 催促),就绪后才开麦,不再来回抖动
  • 配置变化通知防抖:互联设备握手时系统会连发多条 =AVAudioEngineConfigurationChange=,逐条重建会互相触发形成风暴(引擎反复 start/stop、设备始终出不了电平)。现在冷却窗口内只处理最后一条,并忽略由自身 start/stop 触发的回声通知