Listen to Content

一个面向 macOS 的本地语音审听工具。它调用阿里云百炼 DashScope 生成语音, 使用 afplay 播放,并允许 AI 代理通过确定性的命令完成暂停、继续、停止、 缓存清理和最终音频保存。

项目由两层组成:

  • listen-to-content CLI:独立处理供应商调用、音频、播放器和缓存。
  • skills/listen-to-content:供 Codex 和 OpenCode 自动调用 CLI 的 Skill 适配层。

环境要求

  • macOS 13 或更新版本
  • Python 3.11 或更新版本
  • 阿里云百炼北京地域的 DashScope API Key

运行时只使用 Python 标准库和 macOS 自带的 afplayafconvert

安装

git clone https://github.com/zjczg/listen-to-content.git
cd listen-to-content
python3 -m venv .venv
.venv/bin/pip install .
./scripts/install-skill --target auto

安装目标支持:

目标 安装位置 行为
auto 自动检测 默认值,安装到当前机器已有的受支持客户端
codex ${CODEX_HOME:-$HOME/.codex}/skills/ 仅安装 Codex Skill
opencode ${XDG_CONFIG_HOME:-$HOME/.config}/opencode/skills/ 仅安装 OpenCode Skill
all 上述两个位置 同时安装 Codex 和 OpenCode Skill

同时使用两个客户端时执行:

./scripts/install-skill --target all

安装器将同一份 Skill 和 launcher 复制到每个客户端,两个 launcher 都调用 同一个 CLI,并共享 Keychain 配置与音频缓存。更新项目后重新运行安装命令即可 更新 Skill。安装或更新后需要重新启动已打开的客户端。

将 Key 安全保存到 macOS Keychain:

.venv/bin/listen-to-content setup
.venv/bin/listen-to-content doctor

也可以只在当前进程环境中设置 DASHSCOPE_API_KEY。不要把真实 Key 写入 .env.example、Skill 或 Git 仓库。

使用

调用前检查文本分段、有效字符数和预估费用,不会访问云端:

.venv/bin/listen-to-content synthesize \
  --file "/absolute/path/document.md" \
  --dry-run

明确确认上传后生成并播放:

.venv/bin/listen-to-content synthesize \
  --file "/absolute/path/document.md" \
  --confirm-cloud \
  --play

控制播放与查看资源:

.venv/bin/listen-to-content pause
.venv/bin/listen-to-content resume
.venv/bin/listen-to-content stop
.venv/bin/listen-to-content status
.venv/bin/listen-to-content list
.venv/bin/listen-to-content info

Markdown 中独占一行的 [面试官][候选人][旁白],以及英文 [interviewer][candidate][narrator] 会自动使用不同音色。 普通 .txt.md.docx 文件使用旁白音色。

验证 OpenCode 已发现 Skill:

opencode debug skill

输出中应包含名称为 listen-to-content 的条目。能被发现只代表 Skill 格式与 安装位置正确;完整验证还需要通过客户端调用一次 synthesize --dry-run

缓存和定稿

临时资源默认位于:

~/Library/Caches/io.github.zjczg.listen-to-content/
├── segments/   # 按文本、模型、音色和参数寻址的 WAV
├── sessions/   # 合并后的 M4A 和清单
├── logs/       # afplay 的本地错误日志
└── player.json # 受控播放器状态

相同内容和参数会复用单段缓存,不会重复调用 API。clean 命令默认清理 30 天前的资源,并将缓存限制在约 2 GB:

.venv/bin/listen-to-content clean --dry-run
.venv/bin/listen-to-content clean

确认音频后固定到用户指定目录:

.venv/bin/listen-to-content pin \
  --destination "/absolute/path/final-audio" \
  --confirmed

同名正式音频默认不会被覆盖;确认替换时额外传入 --replace

隐私与费用

  • 只有缺少本地缓存且带有 --confirm-cloud 时,文本才会发送给 DashScope。
  • API Key 优先保存在 macOS Keychain,不写入日志或缓存清单。
  • 费用估算默认按 qwen-audio-3.0-tts-plus 北京地域 1.4 元/万有效字符计算。价格可能变化,最终以阿里云账单为准。
  • 当前版本先完成文件式生成和可靠播放控制,不提供真正的流式播放。

开发验证

python3 -m venv .venv
.venv/bin/pip install -e '.[dev]'
.venv/bin/ruff check .
.venv/bin/pytest
./scripts/validate-skill

自动化测试不会调用真实 DashScope,也不会播放声音。真实 API 与扬声器测试是 发布前的手工检查。安装器测试使用隔离的临时 Codex、OpenCode 目录,不会修改 开发者的全局配置。

卸载

./scripts/uninstall-skill --target all
rm -rf .venv

卸载脚本也支持 autocodexopencodeall。它只删除能够识别为 listen-to-content 的 Skill 目录。

缓存不会自动删除。如需删除,先执行 listen-to-content stop,再删除 ~/Library/Caches/io.github.zjczg.listen-to-content/