yt-dlp-controller 0.1.0__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.
- yt_dlp_controller-0.1.0/PKG-INFO +226 -0
- yt_dlp_controller-0.1.0/README.md +202 -0
- yt_dlp_controller-0.1.0/pyproject.toml +58 -0
- yt_dlp_controller-0.1.0/setup.cfg +4 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller/__init__.py +4 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller/app.py +269 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller/app.tcss +238 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller/config.py +260 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller/main.py +61 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller/queue.py +711 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller/screens/__init__.py +1 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller/screens/home.py +90 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller/screens/modals.py +335 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller/screens/new_download.py +573 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller/screens/queue.py +492 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller/screens/settings.py +418 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller/ui.py +368 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller/widgets.py +988 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller/ytdlp.py +572 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller.egg-info/PKG-INFO +226 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller.egg-info/SOURCES.txt +38 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller.egg-info/dependency_links.txt +1 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller.egg-info/entry_points.txt +2 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller.egg-info/requires.txt +5 -0
- yt_dlp_controller-0.1.0/yt_dlp_controller.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: yt_dlp_controller
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: 基于 Textual 的 yt-dlp 图形化终端界面
|
|
5
|
+
Author-email: Moha-Master <hongkongreporter@outlook.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Moha-Master/yt-dlp-Controller
|
|
8
|
+
Project-URL: Repository, https://github.com/Moha-Master/yt-dlp-Controller.git
|
|
9
|
+
Project-URL: GitHub, https://github.com/Moha-Master/yt-dlp-Controller
|
|
10
|
+
Project-URL: Issues, https://github.com/Moha-Master/yt-dlp-Controller/issues
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
Requires-Dist: textual>=8.0
|
|
21
|
+
Requires-Dist: PyYAML>=6.0
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
24
|
+
|
|
25
|
+
# yt-dlp 控制台工具 (yt-dlp-controller)
|
|
26
|
+
|
|
27
|
+
基于 [Textual](https://textual.textualize.io/) 的 **yt-dlp 图形化终端界面**。
|
|
28
|
+
|
|
29
|
+
## 功能
|
|
30
|
+
|
|
31
|
+
- **新建下载**:粘贴一条或多条链接,解析标题 / 上传者 / 时长;播放列表显式展示条目数与范围(全部 / 仅当前 / 前 N 个),绝不静默合并成一条
|
|
32
|
+
- **格式选择**:10 种预设(最佳 / ≤4K / ≤2K / ≤1080p / ≤720p / ≤480p / 仅音频最佳 / MP3 / M4A / 自定义),可按完整格式表选择任意 `format_id`
|
|
33
|
+
- **任务队列**:实时进度条、速度、剩余时间、大小;暂停 / 继续(POSIX)、取消、重试、移除、详情与日志;顶栏「⚙ 并发」可直接调整同时下载数(1-8,立即生效)
|
|
34
|
+
- **下载历史**:与队列同一张表,按「全部 / 进行中 / 已完成 / 失败」筛选并支持模糊搜索;活跃任务优先排列,已完成 / 失败记录自动沉底
|
|
35
|
+
- **持久化**:配置 `config.yaml` + 队列 `queue.json` 原子写;重启后提示是否续传被中断的任务
|
|
36
|
+
- **后处理**:合并容器、字幕、嵌入元数据 / 封面、SponsorBlock、限速、cookies、代理、并发
|
|
37
|
+
- **网络适配**:自动跟随系统代理(或手动指定 / 强制直连)、使用系统证书库、跳过 HTTPS 证书校验,适配 Steamcommunity302 等中间人代理场景
|
|
38
|
+
- **进程管理**:每个任务独立进程组,取消同时结束 ffmpeg 等子进程;退出前清理全部子进程
|
|
39
|
+
|
|
40
|
+
## 环境要求
|
|
41
|
+
|
|
42
|
+
- Python >= 3.10
|
|
43
|
+
- [`yt-dlp`](https://github.com/yt-dlp/yt-dlp) 在 `PATH` 中(或在设置里填写路径)
|
|
44
|
+
- `ffmpeg` / `ffprobe`(合并音视频、嵌入字幕 / 封面时需要)
|
|
45
|
+
|
|
46
|
+
## 安装
|
|
47
|
+
|
|
48
|
+
使用 pip 进行安装:
|
|
49
|
+
```bash
|
|
50
|
+
pip install yt-dlp-controller
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 启动
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
ytdlpctl # 使用默认配置目录
|
|
57
|
+
ytdlpctl -D /tmp/cfg # 指定配置目录
|
|
58
|
+
ytdlpctl --yt-dlp /path/to/yt-dlp
|
|
59
|
+
ytdlpctl --version
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
配置目录优先级:`-D/--dir` > 环境变量 `YT_DLP_CONTROLLER_CONFIG_DIR` > `~/.config/yt-dlp-controller`。
|
|
63
|
+
首次启动会自动生成 `config.yaml` 与下载目录;配置值非法时回落到默认值并在状态栏提示,不会阻止启动。
|
|
64
|
+
|
|
65
|
+
## 键位
|
|
66
|
+
|
|
67
|
+
### 全局
|
|
68
|
+
|
|
69
|
+
| 键 | 行为 |
|
|
70
|
+
|---|---|
|
|
71
|
+
| `Ctrl+Q` | 任意界面退出(有未完成任务时先确认;确认框默认选中「继续下载」) |
|
|
72
|
+
| `Tab` / `Shift+Tab` | 焦点轮切 |
|
|
73
|
+
|
|
74
|
+
### 主菜单
|
|
75
|
+
|
|
76
|
+
| 键 | 行为 |
|
|
77
|
+
|---|---|
|
|
78
|
+
| `↑` / `↓` | 选择菜单项 |
|
|
79
|
+
| `Enter` | 进入 |
|
|
80
|
+
| `1` ~ `4` | 直达:新建下载 / 任务队列 / 设置 / 退出 |
|
|
81
|
+
| `Esc` / `Ctrl+C` | 退出程序 |
|
|
82
|
+
|
|
83
|
+
### 功能页(新建下载 / 队列 / 设置)
|
|
84
|
+
|
|
85
|
+
| 键 | 行为 |
|
|
86
|
+
|---|---|
|
|
87
|
+
| `Esc` / `Ctrl+C` | 返回上一页(优先关闭浮层与模态) |
|
|
88
|
+
| `Ctrl+R` | 刷新(焦点在输入框时让位给控件原生行为;新建下载页无刷新语义) |
|
|
89
|
+
| `Home` / `End` / `PgUp` / `PgDn` | 页面滚动(输入框聚焦时让位) |
|
|
90
|
+
|
|
91
|
+
### 新建下载
|
|
92
|
+
|
|
93
|
+
| 键 | 行为 |
|
|
94
|
+
|---|---|
|
|
95
|
+
| `Enter`(链接框内) | 解析链接 |
|
|
96
|
+
| `Ctrl+Enter` | 跳过格式选择,用默认预设直接加入队列 |
|
|
97
|
+
| `Ctrl+V` | 终端原生粘贴(输入框内) |
|
|
98
|
+
| 按钮 | 「解析」「加入队列」「查看全部格式…」「高级选项…」「粘贴并解析」 |
|
|
99
|
+
|
|
100
|
+
### 任务队列(含下载历史)
|
|
101
|
+
|
|
102
|
+
| 键 | 行为 |
|
|
103
|
+
|---|---|
|
|
104
|
+
| `↑` / `↓` | 选择任务 |
|
|
105
|
+
| `Enter` / 单击 | 任务详情(日志、完整命令、打开目录、复制、重试) |
|
|
106
|
+
| `Ctrl+N` | 新建下载 |
|
|
107
|
+
| `Ctrl+P` | 暂停 / 继续(仅 POSIX 提供) |
|
|
108
|
+
| `Ctrl+X` | 取消任务(保留记录,可重试) |
|
|
109
|
+
| `Delete` | 移除任务(确认框默认「取消」) |
|
|
110
|
+
| `/` | 聚焦搜索框 |
|
|
111
|
+
| `Ctrl+R` | 刷新 |
|
|
112
|
+
|
|
113
|
+
顶部筛选按钮「全部 / 进行中 / 已完成 / 失败」即历史视图入口;任务按活跃程度排序(下载中 → 后处理 → 暂停 → 等待 → 中断 → 失败 → 完成 / 取消),同组内按创建时间倒序。
|
|
114
|
+
|
|
115
|
+
### 设置
|
|
116
|
+
|
|
117
|
+
| 键 | 行为 |
|
|
118
|
+
|---|---|
|
|
119
|
+
| 点击「编辑」 | 打开对应面板的表单(下载 / 网络与认证 / 后处理与环境) |
|
|
120
|
+
| `Ctrl+R` | 重新读取配置并刷新版本信息 |
|
|
121
|
+
| `PgUp` / `PgDn` | 滚动面板 |
|
|
122
|
+
|
|
123
|
+
### 模态
|
|
124
|
+
|
|
125
|
+
| 键 | 行为 |
|
|
126
|
+
|---|---|
|
|
127
|
+
| `Enter` | 提交表单 / 确认(危险确认框默认聚焦「取消」,需 `Tab` 后确认) |
|
|
128
|
+
| `Esc` / `Ctrl+C` | 取消 / 关闭当前层 |
|
|
129
|
+
| `Tab` / `Shift+Tab` | 表单字段轮切 |
|
|
130
|
+
|
|
131
|
+
## 配置
|
|
132
|
+
|
|
133
|
+
在工作目录下生成 `./config.yaml`,通常无需手动编辑,使用 TUI 内置设置页面即可:
|
|
134
|
+
|
|
135
|
+
```yaml
|
|
136
|
+
download_dir: ~/Downloads/yt-dlp
|
|
137
|
+
filename_template: '%(title)s [%(id)s].%(ext)s'
|
|
138
|
+
default_preset: best # best|2160|1440|1080|720|480|audio_best|audio_mp3|audio_m4a(custom 仅逐任务)
|
|
139
|
+
merge_container: auto # auto|mp4|mkv
|
|
140
|
+
max_concurrent_tasks: 2 # 1-8
|
|
141
|
+
concurrent_fragments: 4 # -N,0=不指定
|
|
142
|
+
rate_limit: '' # 如 5M,空=不限
|
|
143
|
+
retries: 10
|
|
144
|
+
cookies_file: ''
|
|
145
|
+
cookies_from_browser: '' # chrome/firefox/edge/brave/...
|
|
146
|
+
auto_proxy: true # 不传 --proxy,由 yt-dlp 自动读取 HTTPS_PROXY / HTTP_PROXY / ALL_PROXY
|
|
147
|
+
proxy: '' # 仅在 auto_proxy: false 时生效;留空 = --proxy "" 强制直连
|
|
148
|
+
use_system_certs: false # --compat-options no-certifi,改用系统信任库
|
|
149
|
+
no_check_certificates: false # --no-check-certificates,完全不校验 HTTPS 证书
|
|
150
|
+
sub_langs: zh.*,en.*
|
|
151
|
+
embed_subs: false
|
|
152
|
+
embed_metadata: true
|
|
153
|
+
embed_thumbnail: false
|
|
154
|
+
sponsorblock_remove: '' # 如 sponsor
|
|
155
|
+
ytdlp_path: ''
|
|
156
|
+
ffmpeg_path: ''
|
|
157
|
+
ignore_ytdlp_config: true # 加 --ignore-config,避免用户 yt-dlp.conf 干扰
|
|
158
|
+
history_limit: 200 # 保留的已完成 / 已取消记录数
|
|
159
|
+
open_queue_after_add: true
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
- `cookies_file` 与 `cookies_from_browser` 同时存在时**文件优先**。
|
|
163
|
+
- `ignore_ytdlp_config` 默认开启,保证 TUI 参数可预测。
|
|
164
|
+
- 保存设置后立即生效,并发数会热更新;正在运行的任务保持原参数。
|
|
165
|
+
- `ytdlp_path` / `ffmpeg_path` 留空时,启动会用 `PATH` 探测结果自动填入并保存;配置里的路径失效时会自动回退到 `PATH`。
|
|
166
|
+
- 代理:`auto_proxy: true` 时 TUI **不传** `--proxy`,由 yt-dlp 自己读取环境变量(`HTTPS_PROXY` / `HTTP_PROXY` / `ALL_PROXY`,含 `NO_PROXY`),设置页会显示检测到的值;关闭后总是传 `--proxy "<值>"`,留空即 `--proxy ""` 强制直连。
|
|
167
|
+
- 证书:`use_system_certs` 加 `--compat-options no-certifi`,让 yt-dlp 使用系统证书库;`no_check_certificates` 加 `--no-check-certificates` 完全跳过 SSL 校验。
|
|
168
|
+
|
|
169
|
+
## 队列与恢复
|
|
170
|
+
|
|
171
|
+
- 队列文件:`<配置目录>/queue.json`。
|
|
172
|
+
- 退出时若有未完成任务,会要求确认;确认退出会终止进程组,并把这些任务标记为 `interrupted`。
|
|
173
|
+
- 下次启动检测到 `interrupted` 任务时弹窗询问是否继续(保留 `.part` 断点续传)。
|
|
174
|
+
- 取消任务不会删除记录,状态保留为「已取消」,可随时重试。
|
|
175
|
+
|
|
176
|
+
## 常见问题
|
|
177
|
+
|
|
178
|
+
**提示「需要登录 / cookies」**
|
|
179
|
+
在「设置 → 网络与认证」填写 cookies 文件(推荐 Netscape 格式),或指定浏览器 cookies。
|
|
180
|
+
|
|
181
|
+
**403 / 429 被限流**
|
|
182
|
+
降低「并发任务」,或配置代理 / cookies 后重试。
|
|
183
|
+
|
|
184
|
+
**没有声音或没有画面**
|
|
185
|
+
在新建下载页改用「最佳画质(视频+音频)」,或从「查看全部格式…」里选带音频的格式。合并需要 `ffmpeg`。
|
|
186
|
+
|
|
187
|
+
**合并或嵌入封面失败**
|
|
188
|
+
安装 `ffmpeg` / `ffprobe`,或在设置里指定完整路径。
|
|
189
|
+
|
|
190
|
+
**HTTPS 证书校验失败(Steamcommunity302 等中间人代理)**
|
|
191
|
+
先开「设置 → 网络与认证 → 使用系统证书库」(`--compat-options no-certifi`),让 yt-dlp 读取系统信任的 302 根证书;仍失败再临时开启「跳过证书校验」(`--no-check-certificates`)。注意后者不校验任何证书,仅建议在可信网络下使用。
|
|
192
|
+
|
|
193
|
+
**设置里的代理不生效?**
|
|
194
|
+
「自动检测代理」开启时 TUI 不传 `--proxy`,完全以环境变量为准;要使用手填代理,先关闭该开关。关闭后留空代理表示强制直连,而不是「自动」。
|
|
195
|
+
|
|
196
|
+
**Windows 没有暂停按钮?**
|
|
197
|
+
暂停依赖 POSIX 的 `SIGSTOP` / `SIGCONT`,非 POSIX 平台隐藏该按钮与 `Ctrl+P`。
|
|
198
|
+
|
|
199
|
+
**下载目录里出现 `.part` 文件**
|
|
200
|
+
取消或中断后保留的断点文件,重试 / 继续时 yt-dlp 会自动续传。
|
|
201
|
+
|
|
202
|
+
**播放列表只下了一部分?**
|
|
203
|
+
播放列表默认展示条目数与范围;选择「前 N 个…」会写为 `-I 1-N`,选择「仅当前」会加 `--no-playlist`。
|
|
204
|
+
|
|
205
|
+
## 开发
|
|
206
|
+
|
|
207
|
+
目录结构:
|
|
208
|
+
|
|
209
|
+
```text
|
|
210
|
+
yt_dlp_controller/
|
|
211
|
+
├── main.py # CLI:-D / --yt-dlp / --version
|
|
212
|
+
├── app.py # App、状态栏、事件分发、启动恢复、退出保护
|
|
213
|
+
├── config.py # 配置目录 / 默认值 / 校验回落 / 读写
|
|
214
|
+
├── ytdlp.py # 参数构建、probe、行解析、错误归类、格式化
|
|
215
|
+
├── queue.py # Task、QueueManager、进程组、持久化
|
|
216
|
+
├── ui.py # PageScreen、首页 LOGO
|
|
217
|
+
├── widgets.py # 模态、表格、HintBar、加载指示
|
|
218
|
+
├── app.tcss # 全局样式(复用四项目 UI 规范)
|
|
219
|
+
└── screens/ # home / new_download / queue / settings / modals
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
界面规范与 Textual 8.2.8 实测依据见 `docs/textual-dev-guide.md`。
|
|
223
|
+
|
|
224
|
+
## 许可证
|
|
225
|
+
|
|
226
|
+
MIT
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# yt-dlp 控制台工具 (yt-dlp-controller)
|
|
2
|
+
|
|
3
|
+
基于 [Textual](https://textual.textualize.io/) 的 **yt-dlp 图形化终端界面**。
|
|
4
|
+
|
|
5
|
+
## 功能
|
|
6
|
+
|
|
7
|
+
- **新建下载**:粘贴一条或多条链接,解析标题 / 上传者 / 时长;播放列表显式展示条目数与范围(全部 / 仅当前 / 前 N 个),绝不静默合并成一条
|
|
8
|
+
- **格式选择**:10 种预设(最佳 / ≤4K / ≤2K / ≤1080p / ≤720p / ≤480p / 仅音频最佳 / MP3 / M4A / 自定义),可按完整格式表选择任意 `format_id`
|
|
9
|
+
- **任务队列**:实时进度条、速度、剩余时间、大小;暂停 / 继续(POSIX)、取消、重试、移除、详情与日志;顶栏「⚙ 并发」可直接调整同时下载数(1-8,立即生效)
|
|
10
|
+
- **下载历史**:与队列同一张表,按「全部 / 进行中 / 已完成 / 失败」筛选并支持模糊搜索;活跃任务优先排列,已完成 / 失败记录自动沉底
|
|
11
|
+
- **持久化**:配置 `config.yaml` + 队列 `queue.json` 原子写;重启后提示是否续传被中断的任务
|
|
12
|
+
- **后处理**:合并容器、字幕、嵌入元数据 / 封面、SponsorBlock、限速、cookies、代理、并发
|
|
13
|
+
- **网络适配**:自动跟随系统代理(或手动指定 / 强制直连)、使用系统证书库、跳过 HTTPS 证书校验,适配 Steamcommunity302 等中间人代理场景
|
|
14
|
+
- **进程管理**:每个任务独立进程组,取消同时结束 ffmpeg 等子进程;退出前清理全部子进程
|
|
15
|
+
|
|
16
|
+
## 环境要求
|
|
17
|
+
|
|
18
|
+
- Python >= 3.10
|
|
19
|
+
- [`yt-dlp`](https://github.com/yt-dlp/yt-dlp) 在 `PATH` 中(或在设置里填写路径)
|
|
20
|
+
- `ffmpeg` / `ffprobe`(合并音视频、嵌入字幕 / 封面时需要)
|
|
21
|
+
|
|
22
|
+
## 安装
|
|
23
|
+
|
|
24
|
+
使用 pip 进行安装:
|
|
25
|
+
```bash
|
|
26
|
+
pip install yt-dlp-controller
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 启动
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
ytdlpctl # 使用默认配置目录
|
|
33
|
+
ytdlpctl -D /tmp/cfg # 指定配置目录
|
|
34
|
+
ytdlpctl --yt-dlp /path/to/yt-dlp
|
|
35
|
+
ytdlpctl --version
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
配置目录优先级:`-D/--dir` > 环境变量 `YT_DLP_CONTROLLER_CONFIG_DIR` > `~/.config/yt-dlp-controller`。
|
|
39
|
+
首次启动会自动生成 `config.yaml` 与下载目录;配置值非法时回落到默认值并在状态栏提示,不会阻止启动。
|
|
40
|
+
|
|
41
|
+
## 键位
|
|
42
|
+
|
|
43
|
+
### 全局
|
|
44
|
+
|
|
45
|
+
| 键 | 行为 |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `Ctrl+Q` | 任意界面退出(有未完成任务时先确认;确认框默认选中「继续下载」) |
|
|
48
|
+
| `Tab` / `Shift+Tab` | 焦点轮切 |
|
|
49
|
+
|
|
50
|
+
### 主菜单
|
|
51
|
+
|
|
52
|
+
| 键 | 行为 |
|
|
53
|
+
|---|---|
|
|
54
|
+
| `↑` / `↓` | 选择菜单项 |
|
|
55
|
+
| `Enter` | 进入 |
|
|
56
|
+
| `1` ~ `4` | 直达:新建下载 / 任务队列 / 设置 / 退出 |
|
|
57
|
+
| `Esc` / `Ctrl+C` | 退出程序 |
|
|
58
|
+
|
|
59
|
+
### 功能页(新建下载 / 队列 / 设置)
|
|
60
|
+
|
|
61
|
+
| 键 | 行为 |
|
|
62
|
+
|---|---|
|
|
63
|
+
| `Esc` / `Ctrl+C` | 返回上一页(优先关闭浮层与模态) |
|
|
64
|
+
| `Ctrl+R` | 刷新(焦点在输入框时让位给控件原生行为;新建下载页无刷新语义) |
|
|
65
|
+
| `Home` / `End` / `PgUp` / `PgDn` | 页面滚动(输入框聚焦时让位) |
|
|
66
|
+
|
|
67
|
+
### 新建下载
|
|
68
|
+
|
|
69
|
+
| 键 | 行为 |
|
|
70
|
+
|---|---|
|
|
71
|
+
| `Enter`(链接框内) | 解析链接 |
|
|
72
|
+
| `Ctrl+Enter` | 跳过格式选择,用默认预设直接加入队列 |
|
|
73
|
+
| `Ctrl+V` | 终端原生粘贴(输入框内) |
|
|
74
|
+
| 按钮 | 「解析」「加入队列」「查看全部格式…」「高级选项…」「粘贴并解析」 |
|
|
75
|
+
|
|
76
|
+
### 任务队列(含下载历史)
|
|
77
|
+
|
|
78
|
+
| 键 | 行为 |
|
|
79
|
+
|---|---|
|
|
80
|
+
| `↑` / `↓` | 选择任务 |
|
|
81
|
+
| `Enter` / 单击 | 任务详情(日志、完整命令、打开目录、复制、重试) |
|
|
82
|
+
| `Ctrl+N` | 新建下载 |
|
|
83
|
+
| `Ctrl+P` | 暂停 / 继续(仅 POSIX 提供) |
|
|
84
|
+
| `Ctrl+X` | 取消任务(保留记录,可重试) |
|
|
85
|
+
| `Delete` | 移除任务(确认框默认「取消」) |
|
|
86
|
+
| `/` | 聚焦搜索框 |
|
|
87
|
+
| `Ctrl+R` | 刷新 |
|
|
88
|
+
|
|
89
|
+
顶部筛选按钮「全部 / 进行中 / 已完成 / 失败」即历史视图入口;任务按活跃程度排序(下载中 → 后处理 → 暂停 → 等待 → 中断 → 失败 → 完成 / 取消),同组内按创建时间倒序。
|
|
90
|
+
|
|
91
|
+
### 设置
|
|
92
|
+
|
|
93
|
+
| 键 | 行为 |
|
|
94
|
+
|---|---|
|
|
95
|
+
| 点击「编辑」 | 打开对应面板的表单(下载 / 网络与认证 / 后处理与环境) |
|
|
96
|
+
| `Ctrl+R` | 重新读取配置并刷新版本信息 |
|
|
97
|
+
| `PgUp` / `PgDn` | 滚动面板 |
|
|
98
|
+
|
|
99
|
+
### 模态
|
|
100
|
+
|
|
101
|
+
| 键 | 行为 |
|
|
102
|
+
|---|---|
|
|
103
|
+
| `Enter` | 提交表单 / 确认(危险确认框默认聚焦「取消」,需 `Tab` 后确认) |
|
|
104
|
+
| `Esc` / `Ctrl+C` | 取消 / 关闭当前层 |
|
|
105
|
+
| `Tab` / `Shift+Tab` | 表单字段轮切 |
|
|
106
|
+
|
|
107
|
+
## 配置
|
|
108
|
+
|
|
109
|
+
在工作目录下生成 `./config.yaml`,通常无需手动编辑,使用 TUI 内置设置页面即可:
|
|
110
|
+
|
|
111
|
+
```yaml
|
|
112
|
+
download_dir: ~/Downloads/yt-dlp
|
|
113
|
+
filename_template: '%(title)s [%(id)s].%(ext)s'
|
|
114
|
+
default_preset: best # best|2160|1440|1080|720|480|audio_best|audio_mp3|audio_m4a(custom 仅逐任务)
|
|
115
|
+
merge_container: auto # auto|mp4|mkv
|
|
116
|
+
max_concurrent_tasks: 2 # 1-8
|
|
117
|
+
concurrent_fragments: 4 # -N,0=不指定
|
|
118
|
+
rate_limit: '' # 如 5M,空=不限
|
|
119
|
+
retries: 10
|
|
120
|
+
cookies_file: ''
|
|
121
|
+
cookies_from_browser: '' # chrome/firefox/edge/brave/...
|
|
122
|
+
auto_proxy: true # 不传 --proxy,由 yt-dlp 自动读取 HTTPS_PROXY / HTTP_PROXY / ALL_PROXY
|
|
123
|
+
proxy: '' # 仅在 auto_proxy: false 时生效;留空 = --proxy "" 强制直连
|
|
124
|
+
use_system_certs: false # --compat-options no-certifi,改用系统信任库
|
|
125
|
+
no_check_certificates: false # --no-check-certificates,完全不校验 HTTPS 证书
|
|
126
|
+
sub_langs: zh.*,en.*
|
|
127
|
+
embed_subs: false
|
|
128
|
+
embed_metadata: true
|
|
129
|
+
embed_thumbnail: false
|
|
130
|
+
sponsorblock_remove: '' # 如 sponsor
|
|
131
|
+
ytdlp_path: ''
|
|
132
|
+
ffmpeg_path: ''
|
|
133
|
+
ignore_ytdlp_config: true # 加 --ignore-config,避免用户 yt-dlp.conf 干扰
|
|
134
|
+
history_limit: 200 # 保留的已完成 / 已取消记录数
|
|
135
|
+
open_queue_after_add: true
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
- `cookies_file` 与 `cookies_from_browser` 同时存在时**文件优先**。
|
|
139
|
+
- `ignore_ytdlp_config` 默认开启,保证 TUI 参数可预测。
|
|
140
|
+
- 保存设置后立即生效,并发数会热更新;正在运行的任务保持原参数。
|
|
141
|
+
- `ytdlp_path` / `ffmpeg_path` 留空时,启动会用 `PATH` 探测结果自动填入并保存;配置里的路径失效时会自动回退到 `PATH`。
|
|
142
|
+
- 代理:`auto_proxy: true` 时 TUI **不传** `--proxy`,由 yt-dlp 自己读取环境变量(`HTTPS_PROXY` / `HTTP_PROXY` / `ALL_PROXY`,含 `NO_PROXY`),设置页会显示检测到的值;关闭后总是传 `--proxy "<值>"`,留空即 `--proxy ""` 强制直连。
|
|
143
|
+
- 证书:`use_system_certs` 加 `--compat-options no-certifi`,让 yt-dlp 使用系统证书库;`no_check_certificates` 加 `--no-check-certificates` 完全跳过 SSL 校验。
|
|
144
|
+
|
|
145
|
+
## 队列与恢复
|
|
146
|
+
|
|
147
|
+
- 队列文件:`<配置目录>/queue.json`。
|
|
148
|
+
- 退出时若有未完成任务,会要求确认;确认退出会终止进程组,并把这些任务标记为 `interrupted`。
|
|
149
|
+
- 下次启动检测到 `interrupted` 任务时弹窗询问是否继续(保留 `.part` 断点续传)。
|
|
150
|
+
- 取消任务不会删除记录,状态保留为「已取消」,可随时重试。
|
|
151
|
+
|
|
152
|
+
## 常见问题
|
|
153
|
+
|
|
154
|
+
**提示「需要登录 / cookies」**
|
|
155
|
+
在「设置 → 网络与认证」填写 cookies 文件(推荐 Netscape 格式),或指定浏览器 cookies。
|
|
156
|
+
|
|
157
|
+
**403 / 429 被限流**
|
|
158
|
+
降低「并发任务」,或配置代理 / cookies 后重试。
|
|
159
|
+
|
|
160
|
+
**没有声音或没有画面**
|
|
161
|
+
在新建下载页改用「最佳画质(视频+音频)」,或从「查看全部格式…」里选带音频的格式。合并需要 `ffmpeg`。
|
|
162
|
+
|
|
163
|
+
**合并或嵌入封面失败**
|
|
164
|
+
安装 `ffmpeg` / `ffprobe`,或在设置里指定完整路径。
|
|
165
|
+
|
|
166
|
+
**HTTPS 证书校验失败(Steamcommunity302 等中间人代理)**
|
|
167
|
+
先开「设置 → 网络与认证 → 使用系统证书库」(`--compat-options no-certifi`),让 yt-dlp 读取系统信任的 302 根证书;仍失败再临时开启「跳过证书校验」(`--no-check-certificates`)。注意后者不校验任何证书,仅建议在可信网络下使用。
|
|
168
|
+
|
|
169
|
+
**设置里的代理不生效?**
|
|
170
|
+
「自动检测代理」开启时 TUI 不传 `--proxy`,完全以环境变量为准;要使用手填代理,先关闭该开关。关闭后留空代理表示强制直连,而不是「自动」。
|
|
171
|
+
|
|
172
|
+
**Windows 没有暂停按钮?**
|
|
173
|
+
暂停依赖 POSIX 的 `SIGSTOP` / `SIGCONT`,非 POSIX 平台隐藏该按钮与 `Ctrl+P`。
|
|
174
|
+
|
|
175
|
+
**下载目录里出现 `.part` 文件**
|
|
176
|
+
取消或中断后保留的断点文件,重试 / 继续时 yt-dlp 会自动续传。
|
|
177
|
+
|
|
178
|
+
**播放列表只下了一部分?**
|
|
179
|
+
播放列表默认展示条目数与范围;选择「前 N 个…」会写为 `-I 1-N`,选择「仅当前」会加 `--no-playlist`。
|
|
180
|
+
|
|
181
|
+
## 开发
|
|
182
|
+
|
|
183
|
+
目录结构:
|
|
184
|
+
|
|
185
|
+
```text
|
|
186
|
+
yt_dlp_controller/
|
|
187
|
+
├── main.py # CLI:-D / --yt-dlp / --version
|
|
188
|
+
├── app.py # App、状态栏、事件分发、启动恢复、退出保护
|
|
189
|
+
├── config.py # 配置目录 / 默认值 / 校验回落 / 读写
|
|
190
|
+
├── ytdlp.py # 参数构建、probe、行解析、错误归类、格式化
|
|
191
|
+
├── queue.py # Task、QueueManager、进程组、持久化
|
|
192
|
+
├── ui.py # PageScreen、首页 LOGO
|
|
193
|
+
├── widgets.py # 模态、表格、HintBar、加载指示
|
|
194
|
+
├── app.tcss # 全局样式(复用四项目 UI 规范)
|
|
195
|
+
└── screens/ # home / new_download / queue / settings / modals
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
界面规范与 Textual 8.2.8 实测依据见 `docs/textual-dev-guide.md`。
|
|
199
|
+
|
|
200
|
+
## 许可证
|
|
201
|
+
|
|
202
|
+
MIT
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "yt_dlp_controller"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "基于 Textual 的 yt-dlp 图形化终端界面"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
authors = [
|
|
11
|
+
{name = "Moha-Master", email = "hongkongreporter@outlook.com"},
|
|
12
|
+
]
|
|
13
|
+
license = "MIT"
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
]
|
|
23
|
+
requires-python = ">=3.10"
|
|
24
|
+
dependencies = [
|
|
25
|
+
"textual>=8.0",
|
|
26
|
+
"PyYAML>=6.0",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
dev = ["ruff>=0.6"]
|
|
31
|
+
|
|
32
|
+
[project.urls]
|
|
33
|
+
Homepage = "https://github.com/Moha-Master/yt-dlp-Controller"
|
|
34
|
+
Repository = "https://github.com/Moha-Master/yt-dlp-Controller.git"
|
|
35
|
+
GitHub = "https://github.com/Moha-Master/yt-dlp-Controller"
|
|
36
|
+
Issues = "https://github.com/Moha-Master/yt-dlp-Controller/issues"
|
|
37
|
+
|
|
38
|
+
[project.scripts]
|
|
39
|
+
ytdlpctl = "yt_dlp_controller.main:main"
|
|
40
|
+
|
|
41
|
+
[tool.setuptools.packages.find]
|
|
42
|
+
where = ["."]
|
|
43
|
+
include = ["yt_dlp_controller*"]
|
|
44
|
+
exclude = ["tests*", "venv*"]
|
|
45
|
+
|
|
46
|
+
[tool.setuptools.package-dir]
|
|
47
|
+
"" = "."
|
|
48
|
+
|
|
49
|
+
[tool.setuptools.package-data]
|
|
50
|
+
yt_dlp_controller = ["*.tcss"]
|
|
51
|
+
|
|
52
|
+
[tool.ruff]
|
|
53
|
+
line-length = 120
|
|
54
|
+
target-version = "py310"
|
|
55
|
+
|
|
56
|
+
[tool.ruff.lint]
|
|
57
|
+
select = ["E", "F", "W", "I", "UP", "B", "C4"]
|
|
58
|
+
ignore = ["E501"]
|