bilinote-cli 0.1.0__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/.gitignore +2 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/BiliNote.shortcut +0 -0
- bilinote_cli-0.1.2/CHANGELOG.md +8 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/PKG-INFO +43 -25
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/README.md +42 -24
- bilinote_cli-0.1.2/publish.command +72 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/pyproject.toml +4 -1
- bilinote_cli-0.1.2/src/app/gpt/provider/OpenAI_compatible_provider.py +35 -0
- bilinote_cli-0.1.2/src/app/models/process_config.py +52 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/services/note.py +5 -40
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/services/pipeline/ai_processor.py +1 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/services/pipeline/preparer.py +27 -33
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/cli.py +311 -193
- bilinote_cli-0.1.0/TODO.md +0 -42
- bilinote_cli-0.1.0/publish.sh +0 -4
- bilinote_cli-0.1.0/skills/357/274/210/346/226/275/345/267/245/344/270/255 unfinished/357/274/211/bilinote/SKILL.md" +0 -190
- bilinote_cli-0.1.0/skills/357/274/210/346/226/275/345/267/245/344/270/255 unfinished/357/274/211/bilinote/evals/evals.json" +0 -35
- bilinote_cli-0.1.0/src/app/gpt/provider/OpenAI_compatible_provider.py +0 -31
- bilinote_cli-0.1.0/tests/__init__.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/.github/ISSUE_TEMPLATE//346/226/260/345/242/236/345/212/237/350/203/275/345/273/272/350/256/256.md" +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/.github/workflows/docker-build.yml +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/.github/workflows/main.yml +0 -0
- /bilinote_cli-0.1.0/skills/357/274/210/346/226/275/345/267/245/344/270/255 unfinished/357/274/211/bilinote/memory.md" → /bilinote_cli-0.1.2/CHANGELOG.md.tmp +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/CLAUDE.md +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/LICENSE +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/README.en.md +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/dev-docs//345/216/206/345/217/262/350/256/260/345/275/225/345/222/214/351/207/215/350/257/225/346/234/215/345/212/241/350/256/276/350/256/241.md" +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/dev-docs//345/217/221/345/270/203/345/210/260 githubTODO.md" +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/dev-docs//345/221/275/345/220/215/346/226/271/345/274/217.md" +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/__init__.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/config_manager.py +0 -0
- {bilinote_cli-0.1.0/src/app/core → bilinote_cli-0.1.2/src/app/decorators}/__init__.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/decorators/timeit.py +0 -0
- {bilinote_cli-0.1.0/src/app/decorators → bilinote_cli-0.1.2/src/app/downloaders}/__init__.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/downloaders/base.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/downloaders/bilibili_downloader.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/downloaders/common.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/downloaders/douyin_downloader.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/downloaders/douyin_helper/abogus.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/downloaders/kuaishou_downloader.py +0 -0
- {bilinote_cli-0.1.0/src/app/downloaders → bilinote_cli-0.1.2/src/app/downloaders/kuaishou_helper}/__init__.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/downloaders/kuaishou_helper/kuaishou.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/downloaders/local_downloader.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/downloaders/xiaoyuzhoufm_download.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/downloaders/youtube_downloader.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/downloaders/youtube_subtitle.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/enmus/exception.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/enmus/note_enums.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/enmus/task_status_enums.py +0 -0
- {bilinote_cli-0.1.0/src/app/downloaders/kuaishou_helper → bilinote_cli-0.1.2/src/app/exceptions}/__init__.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/exceptions/biz_exception.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/exceptions/note.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/exceptions/provider.py +0 -0
- {bilinote_cli-0.1.0/src/app/exceptions → bilinote_cli-0.1.2/src/app/gpt}/__init__.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/gpt/base.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/gpt/gpt_factory.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/gpt/prompt.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/gpt/prompt_builder.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/gpt/request_chunker.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/gpt/universal_gpt.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/gpt/utils.py +0 -0
- {bilinote_cli-0.1.0/src/app/gpt → bilinote_cli-0.1.2/src/app/models}/__init__.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/models/audio_model.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/models/gpt_model.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/models/model_config.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/models/notes_model.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/models/pipeline_model.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/models/provide_model.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/models/transcriber_model.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/models/video_record.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/secret_manager.py +0 -0
- {bilinote_cli-0.1.0/src/app/models → bilinote_cli-0.1.2/src/app/services}/__init__.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/services/batch_processor.py +0 -0
- {bilinote_cli-0.1.0/src/app/services → bilinote_cli-0.1.2/src/app/services/cache}/__init__.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/services/cache/task_cache.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/services/constant.py +0 -0
- {bilinote_cli-0.1.0/src/app/services/cache → bilinote_cli-0.1.2/src/app/services/pipeline}/__init__.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/services/postprocessing.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/services/searcher.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/services/serial_executor.py +0 -0
- {bilinote_cli-0.1.0/src/app/services/pipeline → bilinote_cli-0.1.2/src/app/transcriber}/__init__.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/transcriber/base.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/transcriber/bcut.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/transcriber/groq.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/transcriber/kuaishou.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/transcriber/transcriber_provider.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/transcriber/whisper_cpp.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/utils/cookie_helper.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/utils/env_checker.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/utils/file_cleanup.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/utils/logger.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/utils/note_helper.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/utils/path_helper.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/utils/screenshot_marker.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/utils/status_code.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/utils/url_parser.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/utils/video_helper.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/utils/video_reader.py +0 -0
- {bilinote_cli-0.1.0/src/app/transcriber → bilinote_cli-0.1.2/src/app/validators}/__init__.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/app/validators/video_url_validator.py +0 -0
- {bilinote_cli-0.1.0/src/app/validators → bilinote_cli-0.1.2/src/config}/__init__.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/config/config.yaml.example +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/config/dev_config.json +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/config/model_config_manager.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/config/models.json +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/config/transcriber.json +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/src/ffmpeg_helper.py +0 -0
- {bilinote_cli-0.1.0/src/config → bilinote_cli-0.1.2/tests}/__init__.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/conftest.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/integration/test_transcriber_integration.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/unit/downloaders/test_bilibili_downloader.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/unit/downloaders/test_cookie_helper.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/unit/downloaders/test_douyin_downloader.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/unit/downloaders/test_kuaishou_downloader.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/unit/gpt/test_request_chunker.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/unit/gpt/test_universal_gpt_checkpoint.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/unit/services/test_searcher.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/unit/services/test_task_serial_executor.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/unit/transcriber/test_transcriber_fallback.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/unit/utils/test_note_helper.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/unit/utils/test_path_helper.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/unit/utils/test_screenshot_marker.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/unit/utils/test_url_parser.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/unit/utils/test_video_helper.py +0 -0
- {bilinote_cli-0.1.0 → bilinote_cli-0.1.2}/tests/unit/utils/test_video_reader_dedupe.py +0 -0
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bilinote-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: AI 视频笔记生成 CLI 工具
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Python: >=3.12
|
|
@@ -25,7 +25,7 @@ Description-Content-Type: text/markdown
|
|
|
25
25
|
AI 视频笔记生成工具 - 让 AI 为你的视频做笔记
|
|
26
26
|
|
|
27
27
|
> **项目说明**:本项目基于 [BiliNote](https://github.com/JefferyHcool/BiliNote) fork 并进行大量重构。
|
|
28
|
-
>
|
|
28
|
+
> 感谢原作者 Jeffery Huang 的杰出工作。
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
## 功能
|
|
@@ -40,8 +40,7 @@ AI 视频笔记生成工具 - 让 AI 为你的视频做笔记
|
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
42
|
# 安装 CLI
|
|
43
|
-
|
|
44
|
-
uv tool install .
|
|
43
|
+
uv tool install bilinote-cli
|
|
45
44
|
|
|
46
45
|
# 安装 FFmpeg(必需)
|
|
47
46
|
brew install ffmpeg # macOS
|
|
@@ -63,21 +62,14 @@ bilinote config list
|
|
|
63
62
|
```
|
|
64
63
|
|
|
65
64
|
|
|
66
|
-
|
|
65
|
+
其他配置在 `~/.bilinote/config.yaml`:
|
|
66
|
+
- windows: `C:\Users\<user_name>\.bilinote\config.yaml`
|
|
67
67
|
```yaml
|
|
68
68
|
transcriber:
|
|
69
69
|
default_type: "bcut" # 默认音频转写器
|
|
70
70
|
whisper_model_size: "base"
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
### 【教程】提取 Safari Cookie
|
|
74
|
-
|
|
75
|
-
1. 打开 Safari 的开发者模式。
|
|
76
|
-
2. 在浏览器中打开目标网站,按 F12(或 Cmd + Opt + I)打开开发者工具。
|
|
77
|
-
3. 切换到 **Network (网络)** 标签页。
|
|
78
|
-
4. 刷新页面,随便找一个请求,**右键**点击该请求。
|
|
79
|
-
5. 选择 **Copy** -> **Copy as cURL**。
|
|
80
|
-
6. 在你的剪贴板里,你会看到一串完整的命令,其中 `-H 'cookie: ...'` 后面就是该网站的所有 Cookie。
|
|
81
73
|
|
|
82
74
|
## 使用
|
|
83
75
|
|
|
@@ -85,6 +77,9 @@ transcriber:
|
|
|
85
77
|
# 基础用法
|
|
86
78
|
bilinote process "https://www.bilibili.com/video/BV1mQ9jBcEf4"
|
|
87
79
|
|
|
80
|
+
# 批量处理
|
|
81
|
+
bilinote process "<url1>" "<url2>"
|
|
82
|
+
|
|
88
83
|
# 带截图和链接
|
|
89
84
|
bilinote process "<url>" --screenshot --link --style 学术风
|
|
90
85
|
|
|
@@ -100,6 +95,21 @@ bilinote search "Python 教程" --platform bilibili
|
|
|
100
95
|
# 其他命令
|
|
101
96
|
bilinote model-list # 列出可用模型
|
|
102
97
|
bilinote model-set-default deepseek # 设置默认模型
|
|
98
|
+
bilinote check # 检查环境(ffmpeg、LLM可用性)
|
|
99
|
+
bilinote install-shortcut # 安装 macOS 快捷指令(推荐)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 目录结构
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
~/.bilinote/ #windows: C:\Users\<user_name>\.bilinote\
|
|
106
|
+
├── data/
|
|
107
|
+
│ ├── downloads/ # 下载的音频
|
|
108
|
+
│ ├── cache/ # 转写缓存
|
|
109
|
+
│ ├── output/notes/ # 生成的笔记★
|
|
110
|
+
│ └── state/ # 任务状态
|
|
111
|
+
├── config.yaml # 用户配置★
|
|
112
|
+
└── logs/
|
|
103
113
|
```
|
|
104
114
|
|
|
105
115
|
## 命令说明
|
|
@@ -112,6 +122,8 @@ bilinote model-set-default deepseek # 设置默认模型
|
|
|
112
122
|
| `model-set-default <model>` | 设置默认模型 |
|
|
113
123
|
| `config set <key> <value>` | 设置密钥 |
|
|
114
124
|
| `config list` | 查看配置状态 |
|
|
125
|
+
| `install-shortcut` | 安装快捷指令(仅限 macOS) |
|
|
126
|
+
| `check` | 环境检查 |
|
|
115
127
|
|
|
116
128
|
### process 参数
|
|
117
129
|
|
|
@@ -123,20 +135,26 @@ bilinote model-set-default deepseek # 设置默认模型
|
|
|
123
135
|
| `--link` | 插入视频跳转链接 |
|
|
124
136
|
| `--style` | 笔记风格:学术风、口语风等 |
|
|
125
137
|
| `--video-understanding` | 启用多模态理解 |
|
|
126
|
-
| `--output` |
|
|
138
|
+
| `--output-dir` | 输出目录路径 |
|
|
127
139
|
|
|
128
|
-
##
|
|
140
|
+
## 【指南】提取 Safari Cookie
|
|
141
|
+
|
|
142
|
+
1. 打开 Safari 的开发者模式。
|
|
143
|
+
2. 在浏览器中打开目标网站,按 F12(或 Cmd + Opt + I)打开开发者工具。
|
|
144
|
+
3. 切换到 **Network (网络)** 标签页。
|
|
145
|
+
4. 刷新页面,随便找一个请求,**右键**点击该请求。
|
|
146
|
+
5. 选择 **Copy** -> **Copy as cURL**。
|
|
147
|
+
6. 在你的剪贴板里,你会看到一串完整的命令,其中 `-H 'cookie: ...'` 后面就是该网站的所有 Cookie。
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
## 【指南】使用快捷指令一键运行(仅限 macOS)
|
|
151
|
+
**安装快捷指令**:终端运行 `bilinote install-shortcut`
|
|
152
|
+
|
|
153
|
+
**使用方式**:
|
|
154
|
+
1. 浏览器内点击网址栏,选择到 B 站视频链接的网址文本。
|
|
155
|
+
2. 点击菜单栏(屏幕左上角)的浏览器 App 名称(如“Safari”)。
|
|
156
|
+
3. 点击【服务】 -> 【BiliNote】
|
|
129
157
|
|
|
130
|
-
```bash
|
|
131
|
-
~/.bilinote/ #windows: C:\Users\<user_name>\.bilinote\
|
|
132
|
-
├── data/
|
|
133
|
-
│ ├── downloads/ # 下载的音频
|
|
134
|
-
│ ├── cache/ # 转写缓存
|
|
135
|
-
│ ├── output/notes/ # 生成的笔记★
|
|
136
|
-
│ └── state/ # 任务状态
|
|
137
|
-
├── config.yaml # 用户配置★
|
|
138
|
-
└── logs/
|
|
139
|
-
```
|
|
140
158
|
|
|
141
159
|
## 【指南】配置 whisper-cpp 作为本地音频转写器
|
|
142
160
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
AI 视频笔记生成工具 - 让 AI 为你的视频做笔记
|
|
5
5
|
|
|
6
6
|
> **项目说明**:本项目基于 [BiliNote](https://github.com/JefferyHcool/BiliNote) fork 并进行大量重构。
|
|
7
|
-
>
|
|
7
|
+
> 感谢原作者 Jeffery Huang 的杰出工作。
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
## 功能
|
|
@@ -19,8 +19,7 @@ AI 视频笔记生成工具 - 让 AI 为你的视频做笔记
|
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
# 安装 CLI
|
|
22
|
-
|
|
23
|
-
uv tool install .
|
|
22
|
+
uv tool install bilinote-cli
|
|
24
23
|
|
|
25
24
|
# 安装 FFmpeg(必需)
|
|
26
25
|
brew install ffmpeg # macOS
|
|
@@ -42,21 +41,14 @@ bilinote config list
|
|
|
42
41
|
```
|
|
43
42
|
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
其他配置在 `~/.bilinote/config.yaml`:
|
|
45
|
+
- windows: `C:\Users\<user_name>\.bilinote\config.yaml`
|
|
46
46
|
```yaml
|
|
47
47
|
transcriber:
|
|
48
48
|
default_type: "bcut" # 默认音频转写器
|
|
49
49
|
whisper_model_size: "base"
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
### 【教程】提取 Safari Cookie
|
|
53
|
-
|
|
54
|
-
1. 打开 Safari 的开发者模式。
|
|
55
|
-
2. 在浏览器中打开目标网站,按 F12(或 Cmd + Opt + I)打开开发者工具。
|
|
56
|
-
3. 切换到 **Network (网络)** 标签页。
|
|
57
|
-
4. 刷新页面,随便找一个请求,**右键**点击该请求。
|
|
58
|
-
5. 选择 **Copy** -> **Copy as cURL**。
|
|
59
|
-
6. 在你的剪贴板里,你会看到一串完整的命令,其中 `-H 'cookie: ...'` 后面就是该网站的所有 Cookie。
|
|
60
52
|
|
|
61
53
|
## 使用
|
|
62
54
|
|
|
@@ -64,6 +56,9 @@ transcriber:
|
|
|
64
56
|
# 基础用法
|
|
65
57
|
bilinote process "https://www.bilibili.com/video/BV1mQ9jBcEf4"
|
|
66
58
|
|
|
59
|
+
# 批量处理
|
|
60
|
+
bilinote process "<url1>" "<url2>"
|
|
61
|
+
|
|
67
62
|
# 带截图和链接
|
|
68
63
|
bilinote process "<url>" --screenshot --link --style 学术风
|
|
69
64
|
|
|
@@ -79,6 +74,21 @@ bilinote search "Python 教程" --platform bilibili
|
|
|
79
74
|
# 其他命令
|
|
80
75
|
bilinote model-list # 列出可用模型
|
|
81
76
|
bilinote model-set-default deepseek # 设置默认模型
|
|
77
|
+
bilinote check # 检查环境(ffmpeg、LLM可用性)
|
|
78
|
+
bilinote install-shortcut # 安装 macOS 快捷指令(推荐)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## 目录结构
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
~/.bilinote/ #windows: C:\Users\<user_name>\.bilinote\
|
|
85
|
+
├── data/
|
|
86
|
+
│ ├── downloads/ # 下载的音频
|
|
87
|
+
│ ├── cache/ # 转写缓存
|
|
88
|
+
│ ├── output/notes/ # 生成的笔记★
|
|
89
|
+
│ └── state/ # 任务状态
|
|
90
|
+
├── config.yaml # 用户配置★
|
|
91
|
+
└── logs/
|
|
82
92
|
```
|
|
83
93
|
|
|
84
94
|
## 命令说明
|
|
@@ -91,6 +101,8 @@ bilinote model-set-default deepseek # 设置默认模型
|
|
|
91
101
|
| `model-set-default <model>` | 设置默认模型 |
|
|
92
102
|
| `config set <key> <value>` | 设置密钥 |
|
|
93
103
|
| `config list` | 查看配置状态 |
|
|
104
|
+
| `install-shortcut` | 安装快捷指令(仅限 macOS) |
|
|
105
|
+
| `check` | 环境检查 |
|
|
94
106
|
|
|
95
107
|
### process 参数
|
|
96
108
|
|
|
@@ -102,20 +114,26 @@ bilinote model-set-default deepseek # 设置默认模型
|
|
|
102
114
|
| `--link` | 插入视频跳转链接 |
|
|
103
115
|
| `--style` | 笔记风格:学术风、口语风等 |
|
|
104
116
|
| `--video-understanding` | 启用多模态理解 |
|
|
105
|
-
| `--output` |
|
|
117
|
+
| `--output-dir` | 输出目录路径 |
|
|
106
118
|
|
|
107
|
-
##
|
|
119
|
+
## 【指南】提取 Safari Cookie
|
|
120
|
+
|
|
121
|
+
1. 打开 Safari 的开发者模式。
|
|
122
|
+
2. 在浏览器中打开目标网站,按 F12(或 Cmd + Opt + I)打开开发者工具。
|
|
123
|
+
3. 切换到 **Network (网络)** 标签页。
|
|
124
|
+
4. 刷新页面,随便找一个请求,**右键**点击该请求。
|
|
125
|
+
5. 选择 **Copy** -> **Copy as cURL**。
|
|
126
|
+
6. 在你的剪贴板里,你会看到一串完整的命令,其中 `-H 'cookie: ...'` 后面就是该网站的所有 Cookie。
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
## 【指南】使用快捷指令一键运行(仅限 macOS)
|
|
130
|
+
**安装快捷指令**:终端运行 `bilinote install-shortcut`
|
|
131
|
+
|
|
132
|
+
**使用方式**:
|
|
133
|
+
1. 浏览器内点击网址栏,选择到 B 站视频链接的网址文本。
|
|
134
|
+
2. 点击菜单栏(屏幕左上角)的浏览器 App 名称(如“Safari”)。
|
|
135
|
+
3. 点击【服务】 -> 【BiliNote】
|
|
108
136
|
|
|
109
|
-
```bash
|
|
110
|
-
~/.bilinote/ #windows: C:\Users\<user_name>\.bilinote\
|
|
111
|
-
├── data/
|
|
112
|
-
│ ├── downloads/ # 下载的音频
|
|
113
|
-
│ ├── cache/ # 转写缓存
|
|
114
|
-
│ ├── output/notes/ # 生成的笔记★
|
|
115
|
-
│ └── state/ # 任务状态
|
|
116
|
-
├── config.yaml # 用户配置★
|
|
117
|
-
└── logs/
|
|
118
|
-
```
|
|
119
137
|
|
|
120
138
|
## 【指南】配置 whisper-cpp 作为本地音频转写器
|
|
121
139
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
set -e
|
|
2
|
+
|
|
3
|
+
# ---------- 用户配置 ----------
|
|
4
|
+
VERSION="0.1.2"
|
|
5
|
+
|
|
6
|
+
# CHANGELOG 分类包括:Added Changed Removed Fixed Security
|
|
7
|
+
|
|
8
|
+
CHANGELOG="### Changed
|
|
9
|
+
- search 指令后的批量记笔记功能,支持并行处理
|
|
10
|
+
"
|
|
11
|
+
|
|
12
|
+
cd "$(dirname "$0")"
|
|
13
|
+
|
|
14
|
+
# 检查 CHANGELOG 和版本是否已存在
|
|
15
|
+
if [ -f CHANGELOG.md ]; then
|
|
16
|
+
if grep -q "^## \[${VERSION}\]" CHANGELOG.md; then
|
|
17
|
+
echo "版本已存在,跳过"
|
|
18
|
+
exit 0
|
|
19
|
+
fi
|
|
20
|
+
else
|
|
21
|
+
echo "# Changelog" > CHANGELOG.md
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# ---------- 自动修改 pyproject.toml ----------
|
|
26
|
+
if [ ! -f pyproject.toml ]; then
|
|
27
|
+
echo "错误:当前目录没有 pyproject.toml"
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# 替换 version 字段
|
|
32
|
+
grep -q "^version" pyproject.toml || { echo "Error: 'version' line not found in pyproject.toml" >&2; exit 1; }
|
|
33
|
+
sed -i.bak -E "s/^version.*/version = \"${VERSION}\"/" pyproject.toml
|
|
34
|
+
|
|
35
|
+
rm -f pyproject.toml.bak # 删除备份文件
|
|
36
|
+
|
|
37
|
+
echo "✓ pyproject.toml 版本号已更新为 ${VERSION}"
|
|
38
|
+
|
|
39
|
+
# ---------- 自动更新 CHANGELOG.md ----------
|
|
40
|
+
DATE=$(date +%Y-%m-%d)
|
|
41
|
+
NEW_ENTRY="## [${VERSION}] - ${DATE}"$'\n'"${CHANGELOG}"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# 使用 awk 在第一个 "## [数字" 行之前插入新条目(前后空行)
|
|
45
|
+
awk -v new_entry="$NEW_ENTRY" '
|
|
46
|
+
BEGIN { inserted = 0 }
|
|
47
|
+
/^## \[[0-9]/ && !inserted {
|
|
48
|
+
# 在匹配行之前先打印新条目(前后加空行)
|
|
49
|
+
print ""
|
|
50
|
+
print new_entry
|
|
51
|
+
print ""
|
|
52
|
+
inserted = 1
|
|
53
|
+
}
|
|
54
|
+
{ print }
|
|
55
|
+
END {
|
|
56
|
+
# 如果没有匹配到任何版本标题,则在末尾追加新条目
|
|
57
|
+
if (!inserted) {
|
|
58
|
+
print ""
|
|
59
|
+
print new_entry
|
|
60
|
+
print ""
|
|
61
|
+
}
|
|
62
|
+
}' CHANGELOG.md > CHANGELOG.md.tmp && mv CHANGELOG.md.tmp CHANGELOG.md
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
echo "✓ CHANGELOG.md 已添加 ${VERSION} 版本的更新记录"
|
|
66
|
+
|
|
67
|
+
# ---------- 原有发布流程 ----------
|
|
68
|
+
rm -rf dist/
|
|
69
|
+
uv build
|
|
70
|
+
ls dist/
|
|
71
|
+
export UV_PUBLISH_TOKEN="pypi-AgEIcHlwaS5vcmcCJGM1M2U5NThjLWQ4NTctNDBlNy04NDFhLTUzMTM4NTk0OTU2NwACFFsxLFsiYmlsaW5vdGUtY2xpIl1dAAIsWzIsWyJmN2Y4MzczOC1lMzlkLTQyOTgtODMyMS1mMTkxM2JhMDQxZDYiXV0AAAYg4oFE7cnbCFM5fV6HOB10sNzaBk84MYhbnZ6MWaT7Cu8"
|
|
72
|
+
uv publish
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "bilinote-cli"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.2"
|
|
8
8
|
description = "AI 视频笔记生成 CLI 工具"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
@@ -30,6 +30,9 @@ bilinote = "src.cli:main"
|
|
|
30
30
|
[tool.hatch.build.targets.wheel]
|
|
31
31
|
packages = ["src"]
|
|
32
32
|
|
|
33
|
+
[tool.hatch.build.targets.wheel.force-include]
|
|
34
|
+
"BiliNote.shortcut" = "src/BiliNote.shortcut"
|
|
35
|
+
|
|
33
36
|
[dependency-groups]
|
|
34
37
|
dev = [
|
|
35
38
|
"deptry>=0.25.1",
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from typing import Optional, Union
|
|
2
|
+
|
|
3
|
+
from openai import OpenAI
|
|
4
|
+
|
|
5
|
+
from app.utils.logger import get_logger
|
|
6
|
+
|
|
7
|
+
logging= get_logger(__name__)
|
|
8
|
+
class OpenAICompatibleProvider:
|
|
9
|
+
def __init__(self, api_key: str, base_url: str, model: Union[str, None]=None):
|
|
10
|
+
self.client = OpenAI(api_key=api_key, base_url=base_url)
|
|
11
|
+
self.model = model
|
|
12
|
+
|
|
13
|
+
@property
|
|
14
|
+
def get_client(self):
|
|
15
|
+
return self.client
|
|
16
|
+
|
|
17
|
+
@staticmethod
|
|
18
|
+
def test_connection(api_key: str, base_url: str, model_name: str) -> tuple[bool, str]:
|
|
19
|
+
"""
|
|
20
|
+
轻量级连通性测试:发送一条最小 chat 请求验证 Key/服务/模型名是否有效。
|
|
21
|
+
返回 (是否成功, 错误描述)。
|
|
22
|
+
"""
|
|
23
|
+
try:
|
|
24
|
+
client = OpenAI(api_key=api_key, base_url=base_url)
|
|
25
|
+
client.chat.completions.create(
|
|
26
|
+
model=model_name,
|
|
27
|
+
messages=[{"role": "user", "content": "ok"}],
|
|
28
|
+
max_tokens=1,
|
|
29
|
+
)
|
|
30
|
+
logging.info("连通性测试成功")
|
|
31
|
+
return True, ""
|
|
32
|
+
except Exception as e:
|
|
33
|
+
error_str = str(e)
|
|
34
|
+
logging.info(f"连通性测试失败:{error_str}")
|
|
35
|
+
return False, error_str
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""ProcessConfig - CLI 处理参数配置,统一替代手工参数拆解"""
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator
|
|
4
|
+
|
|
5
|
+
from app.enmus.note_enums import DownloadQuality
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ProcessConfig(BaseModel):
|
|
9
|
+
"""处理参数配置包。
|
|
10
|
+
|
|
11
|
+
收拢 CLI ``process`` / ``search`` 子命令的所有共享参数,
|
|
12
|
+
通过 ``ProcessConfig(**vars(args))`` 一键从 argparse namespace 转换。
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
model_config = ConfigDict(extra="ignore")
|
|
16
|
+
|
|
17
|
+
quality: DownloadQuality = Field(default=DownloadQuality.medium)
|
|
18
|
+
screenshot: bool = False
|
|
19
|
+
link: bool = False
|
|
20
|
+
style: str | None = None
|
|
21
|
+
format: list[str] = Field(default_factory=list)
|
|
22
|
+
video_understanding: bool = False
|
|
23
|
+
video_interval: int = 0
|
|
24
|
+
grid_size: list[int] | None = None
|
|
25
|
+
no_subtitle: bool = False
|
|
26
|
+
extras: str | None = None
|
|
27
|
+
|
|
28
|
+
@field_validator("quality", mode="before")
|
|
29
|
+
@classmethod
|
|
30
|
+
def parse_quality(cls, v: object) -> DownloadQuality:
|
|
31
|
+
if isinstance(v, DownloadQuality):
|
|
32
|
+
return v
|
|
33
|
+
if isinstance(v, str):
|
|
34
|
+
mapping = {
|
|
35
|
+
"fast": DownloadQuality.fast,
|
|
36
|
+
"medium": DownloadQuality.medium,
|
|
37
|
+
"slow": DownloadQuality.slow,
|
|
38
|
+
}
|
|
39
|
+
if v in mapping:
|
|
40
|
+
return mapping[v]
|
|
41
|
+
return DownloadQuality.medium
|
|
42
|
+
|
|
43
|
+
@model_validator(mode="after")
|
|
44
|
+
def sync_format_from_flags(self):
|
|
45
|
+
"""将 screenshot/link 布尔标志同步到 format 列表"""
|
|
46
|
+
fmt = list(self.format) if self.format else []
|
|
47
|
+
if self.screenshot and "screenshot" not in fmt:
|
|
48
|
+
fmt.append("screenshot")
|
|
49
|
+
if self.link and "link" not in fmt:
|
|
50
|
+
fmt.append("link")
|
|
51
|
+
self.format = fmt
|
|
52
|
+
return self
|
|
@@ -7,6 +7,7 @@ from app.enmus.note_enums import DownloadQuality
|
|
|
7
7
|
from app.enmus.task_status_enums import TaskStatus
|
|
8
8
|
from app.models.notes_model import NoteResult
|
|
9
9
|
from app.models.pipeline_model import PreparedTask
|
|
10
|
+
from app.models.process_config import ProcessConfig
|
|
10
11
|
from app.services.cache.task_cache import TaskCache
|
|
11
12
|
from app.services.pipeline.ai_processor import AIProcessor
|
|
12
13
|
from app.services.pipeline.preparer import TaskPreparer
|
|
@@ -42,19 +43,10 @@ class NoteGenerator:
|
|
|
42
43
|
self,
|
|
43
44
|
video_url: Union[str, HttpUrl],
|
|
44
45
|
platform: str,
|
|
45
|
-
|
|
46
|
+
cfg: ProcessConfig,
|
|
46
47
|
task_id: Optional[str] = None,
|
|
47
48
|
model_name: Optional[str] = None,
|
|
48
|
-
link: bool = False,
|
|
49
|
-
screenshot: bool = False,
|
|
50
|
-
_format: Optional[List[str]] = None,
|
|
51
|
-
style: Optional[str] = None,
|
|
52
|
-
extras: Optional[str] = None,
|
|
53
49
|
output_path: Optional[str] = None,
|
|
54
|
-
video_understanding: bool = False,
|
|
55
|
-
video_interval: int = 0,
|
|
56
|
-
grid_size: Optional[List[int]] = None,
|
|
57
|
-
no_subtitle: bool = False,
|
|
58
50
|
) -> Optional[NoteResult]:
|
|
59
51
|
"""
|
|
60
52
|
主流程:按步骤依次下载、转写、GPT 总结、截图/链接处理、存库、返回 NoteResult。
|
|
@@ -63,18 +55,9 @@ class NoteGenerator:
|
|
|
63
55
|
prepared = self.prepare(
|
|
64
56
|
video_url=video_url,
|
|
65
57
|
platform=platform,
|
|
66
|
-
|
|
58
|
+
cfg=cfg,
|
|
67
59
|
task_id=task_id,
|
|
68
|
-
link=link,
|
|
69
|
-
screenshot=screenshot,
|
|
70
|
-
_format=_format,
|
|
71
|
-
style=style,
|
|
72
|
-
extras=extras,
|
|
73
60
|
output_path=output_path,
|
|
74
|
-
video_understanding=video_understanding,
|
|
75
|
-
video_interval=video_interval,
|
|
76
|
-
grid_size=grid_size,
|
|
77
|
-
no_subtitle=no_subtitle,
|
|
78
61
|
)
|
|
79
62
|
if prepared is None:
|
|
80
63
|
return None
|
|
@@ -88,18 +71,9 @@ class NoteGenerator:
|
|
|
88
71
|
self,
|
|
89
72
|
video_url: Union[str, HttpUrl],
|
|
90
73
|
platform: str,
|
|
91
|
-
|
|
74
|
+
cfg: ProcessConfig,
|
|
92
75
|
task_id: Optional[str] = None,
|
|
93
|
-
link: bool = False,
|
|
94
|
-
screenshot: bool = False,
|
|
95
|
-
_format: Optional[List[str]] = None,
|
|
96
|
-
style: Optional[str] = None,
|
|
97
|
-
extras: Optional[str] = None,
|
|
98
76
|
output_path: Optional[str] = None,
|
|
99
|
-
video_understanding: bool = False,
|
|
100
|
-
video_interval: int = 0,
|
|
101
|
-
grid_size: Optional[List[int]] = None,
|
|
102
|
-
no_subtitle: bool = False,
|
|
103
77
|
) -> Optional[PreparedTask]:
|
|
104
78
|
"""
|
|
105
79
|
同步准备阶段:下载、转写、构建 GPTSource。
|
|
@@ -108,18 +82,9 @@ class NoteGenerator:
|
|
|
108
82
|
return self.preparer.prepare(
|
|
109
83
|
video_url=video_url,
|
|
110
84
|
platform=platform,
|
|
111
|
-
|
|
85
|
+
cfg=cfg,
|
|
112
86
|
task_id=task_id,
|
|
113
|
-
link=link,
|
|
114
|
-
screenshot=screenshot,
|
|
115
|
-
_format=_format,
|
|
116
|
-
style=style,
|
|
117
|
-
extras=extras,
|
|
118
87
|
output_path=output_path,
|
|
119
|
-
video_understanding=video_understanding,
|
|
120
|
-
video_interval=video_interval,
|
|
121
|
-
grid_size=grid_size,
|
|
122
|
-
no_subtitle=no_subtitle,
|
|
123
88
|
)
|
|
124
89
|
|
|
125
90
|
def summarize_and_save(
|