skill
goodnotes-attachment-extractor
从 GoodNotes 导出的 .goodnotes 文件中提取音频、图片和 PDF 附件;附带 Agent Skill,可被 Claude Code / Codex / Cursor 直接调用。
Set up
Skills are installed by placing their folder where your agent loads skills.
The download comes from github.com/ou0826/goodnotes-attachment-extractor itself, not from our server, so what you get is exactly what its author published.
Install instructions come from the README
README
synced Oct 26, 2026非官方工具声明:本项目是独立的第三方工具,与 GoodNotes 的开发者 Time Base Technology Limited 没有任何关联、赞助或背书。GoodNotes 是其所有者的 注册商标。本项目只处理你本人拥有或已获授权的文件,不包含、不破解 GoodNotes 的任何专有代码或资源。
✨ 功能
🧩 Agent Skill
仓库里附带一个 Agent Skill,可以直接装进 Claude Code、Codex、Cursor:
npx skills add ou0826/goodnotes-attachment-extractor
也可以手动复制 skills/goodnotes-attachment-extractor/ 到
/.claude/skills/(DSH 用 /.dsh/skills/)。
装好后直接对代理说"把这个 .goodnotes 里的录音和图片导出来"。 详见 skills/README.md。
🎯 它解决什么问题
GoodNotes 导出的 .goodnotes 是一个 ZIP 容器,附件在 attachments/ 下, 文件名通常是一串 UUID。直接解压后,你很难知道哪个文件是录音、哪个是图片。
| 直接解压 .goodnotes | 使用本工具之后 |
|---|---|
| attachments/4F2A9C...(无扩展名) | 音频/录音_11m26s.m4a |
| attachments/A08519...(无扩展名) | 图片/图片_2048x1536.png |
| attachments/D34B78...(无扩展名) | 文档/文档_D34B7852.pdf |
工具会读取文件头识别真实类型,解析 MP4 / JPEG / PNG / PDF 元数据, 再生成人类可读的文件名,并按类型分文件夹存放。
🚀 快速开始
方式一:下载可执行文件(推荐,免安装)
- 打开 Releases;
- 按用途下载:
| 文件 | 用途 |
|---|---|
| GoodNotes-Attachment-Extractor-vX.Y.Z-win64-GUI.exe | 图形界面版,双击直接打开,无控制台窗口(推荐) |
| GoodNotes-Attachment-Extractor-vX.Y.Z-win64.exe | 命令行版,适合批量处理和脚本调用 |
- 命令行版要打开界面时,执行 GoodNotes-Attachment-Extractor-vX.Y.Z-win64.exe --gui。
发布版 exe 没有购买代码签名证书,SmartScreen 可能拦截。 点击「更多信息 → 仍要运行」即可。如果不放心,可以从源码运行或自行构建。
方式二:从源码安装
git clone https://github.com/ou0826/goodnotes-attachment-extractor.git
cd goodnotes-attachment-extractor
python -m pip install -e .
安装后得到两个命令:
gn-extract # 命令行
gn-extract-gui # 图形界面
不安装也能运行:
# Windows PowerShell
$env:PYTHONPATH="src"; python -m goodnotes_extractor --gui
# macOS / Linux
PYTHONPATH=src python -m goodnotes_extractor --gui
python -m pip install -e ".[dev]"
python scripts/build_exe.py
产物:dist/GoodNotes-Attachment-Extractor.exe。
🖥️ 使用
图形界面
Windows 用户可以直接双击下载的 ...-win64-GUI.exe;源码安装用户执行:
gn-extract-gui
- 点击「选择文件」加载 .goodnotes,或点击「选择目录(批量)」递归扫描文件夹;
- 在左侧勾选要提取的类型(音频 / 图片 / PDF);
- 点击「开始提取」,右侧表格显示结果,底部显示进度和日志;
- 勾选「完成后打开输出目录」可在结束后自动打开文件夹。
命令行
gn-extract <文件.goodnotes> [输出目录] # 提取单个文件
gn-extract --gui # 启动图形界面
gn-extract --batch <目录> [输出目录] # 批量提取
gn-extract --info <文件.goodnotes> # 仅查看元数据
| 选项 | 说明 |
|---|---|
| --gui | 启动图形界面 |
| --batch <目录> | 批量处理目录中所有 .goodnotes |
| --info <文件> | 显示元数据,不导出附件 |
| --no-audio / --no-image / --no-pdf | 跳过对应类型 |
| --no-organize | 不按类型分文件夹 |
| -v, --version | 显示版本号 |
| -h, --help | 显示帮助 |
# 提取到默认目录(源文件同级的「笔记名_提取」)
gn-extract 汽车工艺学复习.goodnotes
# 指定输出目录,只导出音频
gn-extract 笔记.goodnotes D:导出 --no-image --no-pdf
# 批量处理整个文件夹
gn-extract --batch D:GoodNotes备份
# 查看一个文件里都有什么
gn-extract --info 笔记.goodnotes
输出结构
笔记名_提取/
├── 音频/
│ └── 录音_11m26s.m4a
├── 图片/
│ └── 图片_2048x1536.png
└── 文档/
└── 文档_A08519D7.pdf
- 音频:录音_<时长>.m4a
- 图片:图片_<宽>x<高>.<扩展名>
- PDF:文档_<原附件 UUID 前 8 位>.pdf
- 同名文件自动追加 _1、_2,不会覆盖已有文件。
图形界面指定了输出目录时,会再加一层笔记名: <输出目录>/<笔记名>/音频/...
🔍 工作原理
flowchart LR
A[".goodnotes<br/>ZIP 容器"] --> B["读取 attachments/"]
B --> C{"魔术字节识别"}
C -->|M4A / AAC| D["音频/录音_11m26s.m4a"]
C -->|JPEG / PNG| E["图片/图片_2048x1536.png"]
C -->|PDF| F["文档/文档_D34B7852.pdf"]
D --> G["按类型归档"]
E --> G
F --> G
- 只用 Python 标准库,不依赖第三方二进制解析库;
- 不做解密,也不绕过任何技术保护措施,只读取未加密的 ZIP 容器;
- 详细模块说明见 docs/design.md。
❓ 常见问题
请确认导出时勾选了"包括录音和音频"(或类似选项),并检查界面左侧是否勾选了音频类型。
部分录音的 moov 原子位于文件尾部,个别播放器兼容性较差。可以用 VLC 播放, 或使用 ffmpeg 转成 WAV/MP3:
ffmpeg -i 录音_11m26s.m4a 录音.wav
不会。程序以只读方式打开 ZIP 容器,只在输出目录中新建文件。
不会。程序没有任何网络请求、没有遥测、没有账号系统,所有处理都在本机完成。
主要针对 GoodNotes 5 导出的 .goodnotes 格式开发与测试。其他版本如遇问题, 欢迎提交 Issue 并附上(脱敏后的)目录结构,不要上传包含个人内容的原始笔记。
示例文件会包含真实笔记与个人信息,因此不随仓库分发。测试请使用你自己的文件。
🔒 隐私
- 无网络请求、无遥测、无账号系统;
- 配置文件:~/.goodnotes-extractor/config.json
- 日志文件:~/.goodnotes-extractor/logs/(自动轮转,最多保留 10 个)
提交 Issue 前请删除日志中的个人路径、文件名等信息。
🗂️ 项目结构
.
├── src/goodnotes_extractor/
│ ├── __init__.py 版本与包元信息
│ ├── __main__.py python -m goodnotes_extractor 入口
│ ├── cli.py 命令行入口、单文件提取
│ ├── gui.py Tkinter 图形界面
│ ├── parser.py MP4/JPEG/PNG/PDF 二进制解析
│ ├── classifier.py 魔术字节类型识别
│ ├── metadata.py Protobuf 索引解码
│ ├── batch.py 批量处理与去重
│ ├── converter.py 可选格式转换(库 API)
│ ├── config.py 配置管理
│ └── logger.py 日志管理
├── tests/ 74 个单元测试(unittest / pytest)
├── docs/ 使用说明、架构文档、发布指南
├── skills/ Agent Skill(npx skills add)
├── scripts/build_exe.py PyInstaller 构建脚本
└── .github/workflows/ CI 与自动发布
🛠️ 开发与测试
python -m pip install -e ".[dev]"
pytest # 或
python -m unittest discover -s tests -v
python scripts/build_exe.py # 构建 Windows exe
提交 PR 前请确保测试全部通过。详细规范见 CONTRIBUTING.md。
🤝 参与贡献
欢迎提交 Issue 和 Pull Request:
- Bug:使用 Bug Report 模板,附上系统版本、复现步骤和脱敏后的日志;
- 功能建议:使用 Feature Request 模板,说明使用场景;
- 安全问题:请勿公开提交,按 SECURITY.md 私下联系。
参与本项目即表示你同意遵守 CODE_OF_CONDUCT.md。
📄 许可证
本项目采用 MIT License 开源。你可以自由使用、修改、分发, 包括商业用途,但需保留版权声明和许可证文本。
本项目已申请软件著作权。
第三方组件与商标声明见 NOTICE。
⚠️ 免责声明
本软件按"原样"提供,不附带任何明示或暗示的担保。使用本软件造成的任何数据丢失、 文件损坏或其他损失,作者不承担责任。请在使用前备份重要笔记。
本项目与 Time Base Technology Limited 无任何关联。GoodNotes 是其注册商标。