feat: support `--danmaku-only`, `--metadata-only`, `--subtitle-only` (#105)

This commit is contained in:
Nyakku Shigure 2023-02-03 23:46:46 +08:00 committed by GitHub
parent 407a8a43d3
commit c16385d9a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 302 additions and 215 deletions

103
README.md
View File

@ -211,20 +211,6 @@ yutto 支持一些基础参数,无论是批量下载还是单视频下载都
详情同视频编码。 详情同视频编码。
#### 仅下载视频流
- 参数 `--video-only`
- 默认值 `False`
#### 仅下载音频流
- 参数 `--audio-only`
- 默认值 `False`
仅下载其中的音频流,保存为 `.aac` 文件。
值得注意的是,在不选择视频流时,嵌入字幕、弹幕功能将无法工作。
#### 弹幕格式选择 #### 弹幕格式选择
- 参数 `-df``--danmaku-format` - 参数 `-df``--danmaku-format`
@ -265,6 +251,31 @@ B 站提供了 `xml` 与 `protobuf` 两种弹幕数据接口yutto 会自动
- 参数 `--tmp-dir` - 参数 `--tmp-dir`
- 默认值是“存放根目录”即 `-d, --dir` 的值 - 默认值是“存放根目录”即 `-d, --dir` 的值
#### Cookies 设置
- 参数 `-c``--sessdata`
- 默认值 `""`
设置 Cookies 后你才可以下载更高清晰度以及更多的剧集,当你传入你的大会员 `SESSDATA` 时(当然前提是你是大会员),你就可以下载大会员可访问的资源咯。
<details><summary> SESSDATA 获取方式 </summary>
这里用 Chrome 作为示例,其它浏览器请尝试类似方法。
首先,用你的帐号登录 B 站,然后随便打开一个 B 站网页,比如[首页](https://www.bilibili.com/)。
按 F12 打开开发者工具,切换到 Network 栏,刷新页面,此时第一个加载的资源应该就是当前页面的 html选中该资源在右侧 「Request Headers」 中找到 「cookie」在其中找到类似于 `SESSDATA=d8bc7493%2C2843925707%2C08c3e*81;` 的一串字符串,复制这里的 `d8bc7493%2C2843925707%2C08c3e*81`,这就是你需要的 `SESSDATA`
</details>
另外,由于 SESSDATA 中可能有特殊符号,所以传入时你可能需要使用双引号来包裹
```bash
yutto <url> -c "d8bc7493%2C2843925707%2C08c3e*81"
```
当然,示例里的 SESSDATA 是无效的,请使用自己的 SESSDATA。
#### 存放子路径模板 #### 存放子路径模板
- 参数 `-tp``--subpath-template` - 参数 `-tp``--subpath-template`
@ -316,41 +327,56 @@ yutto rimuru1 --batch --alias-file='~/.yutto_alias'
cat ~/.yutto_alias | yutto rimuru-nikki --batch --alias-file - cat ~/.yutto_alias | yutto rimuru-nikki --batch --alias-file -
``` ```
#### Cookies 设置 #### 仅下载视频流
- 参数 `-c` 或 `--sessdata` - 参数 `--video-only`
- 默认值 `""` - 默认值 `False`
设置 Cookies 后你才可以下载更高清晰度以及更多的剧集,当你传入你的大会员 `SESSDATA` 时(当然前提是你是大会员),你就可以下载大会员可访问的资源咯。 > **Note**
>
> 这里「仅下载视频流」是指视频中音视频流仅选择视频流,而不是仅仅下载视频而不下载弹幕字幕等资源,如果需要取消字幕等资源下载,请额外使用 `--no-danmaku` 等参数。
>
> 「仅下载音频流」也是同样的。
<details><summary> SESSDATA 获取方式 </summary> #### 仅下载音频流
这里用 Chrome 作为示例,其它浏览器请尝试类似方法。 - 参数 `--audio-only`
- 默认值 `False`
首先,用你的帐号登录 B 站,然后随便打开一个 B 站网页,比如[首页](https://www.bilibili.com/) 仅下载其中的音频流,保存为 `.aac` 文件
按 F12 打开开发者工具,切换到 Network 栏,刷新页面,此时第一个加载的资源应该就是当前页面的 html选中该资源在右侧 「Request Headers」 中找到 「cookie」在其中找到类似于 `SESSDATA=d8bc7493%2C2843925707%2C08c3e*81;` 的一串字符串,复制这里的 `d8bc7493%2C2843925707%2C08c3e*81`,这就是你需要的 `SESSDATA` #### 不生成弹幕文件
</details>
另外,由于 SESSDATA 中可能有特殊符号,所以传入时你可能需要使用双引号来包裹
```bash
yutto <url> -c "d8bc7493%2C2843925707%2C08c3e*81"
```
当然,示例里的 SESSDATA 是无效的,请使用自己的 SESSDATA。
#### 不下载弹幕
- 参数 `--no-danmaku` - 参数 `--no-danmaku`
- 默认值 `False` - 默认值 `False`
#### 不下载字幕 #### 仅生成弹幕文件
- 参数 `--danmaku-only`
- 默认值 `False`
#### 不生成字幕文件
- 参数 `--no-subtitle` - 参数 `--no-subtitle`
- 默认值 `False` - 默认值 `False`
#### 仅生成字幕文件
- 参数 `--subtitle-only`
- 默认值 `False`
#### 生成媒体元数据文件
- 参数 `--with-metadata`
- 默认值 `False`
目前媒体元数据生成尚在试验阶段,可能提取出的信息并不完整。
#### 仅生成媒体元数据文件
- 参数 `--metadata-only`
- 默认值 `False`
#### 不显示颜色 #### 不显示颜色
- 参数 `--no-color` - 参数 `--no-color`
@ -366,13 +392,6 @@ yutto <url> -c "d8bc7493%2C2843925707%2C08c3e*81"
- 参数 `--debug` - 参数 `--debug`
- 默认值 `False` - 默认值 `False`
#### 生成媒体元数据文件
- 参数 `--with-metadata`
- 默认值 `False`
目前媒体元数据生成尚在试验阶段,可能提取出的信息并不完整。
</details> </details>
### 批量参数 ### 批量参数

247
poetry.lock generated
View File

@ -150,21 +150,22 @@ files = [
[[package]] [[package]]
name = "attrs" name = "attrs"
version = "22.1.0" version = "22.2.0"
description = "Classes Without Boilerplate" description = "Classes Without Boilerplate"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.5" python-versions = ">=3.6"
files = [ files = [
{file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"},
{file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"},
] ]
[package.extras] [package.extras]
dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"]
docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] dev = ["attrs[docs,tests]"]
tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"]
tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] tests = ["attrs[tests-no-zope]", "zope.interface"]
tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"]
[[package]] [[package]]
name = "biliass" name = "biliass"
@ -261,26 +262,26 @@ files = [
[[package]] [[package]]
name = "dicttoxml" name = "dicttoxml"
version = "1.7.15" version = "1.7.16"
description = "Converts a Python dictionary or other native data type into a valid XML string." description = "Converts a Python dictionary or other native data type into a valid XML string."
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.6"
files = [ files = [
{file = "dicttoxml-1.7.15-py3-none-any.whl", hash = "sha256:e6c43f7dc8ff9fbeb3ef5bf9d3bd75f5aaed37dcedf80dd429d27957d17d4c73"}, {file = "dicttoxml-1.7.16-py3-none-any.whl", hash = "sha256:8677671496d0d38e66c7179f82a7e9059f94887777955dc71b0ac602ee637c26"},
{file = "dicttoxml-1.7.15.tar.gz", hash = "sha256:5540fe7dfde2d2ed9467e67fcc981cbd2e164dc3120c862bdb7333202ac48838"}, {file = "dicttoxml-1.7.16.tar.gz", hash = "sha256:6f36ce644881db5cd8940bee9b7cb3f3f6b7b327ba8a67d83d3e2caa0538bf9d"},
] ]
[[package]] [[package]]
name = "exceptiongroup" name = "exceptiongroup"
version = "1.0.4" version = "1.1.0"
description = "Backport of PEP 654 (exception groups)" description = "Backport of PEP 654 (exception groups)"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "exceptiongroup-1.0.4-py3-none-any.whl", hash = "sha256:542adf9dea4055530d6e1279602fa5cb11dab2395fa650b8674eaec35fc4a828"}, {file = "exceptiongroup-1.1.0-py3-none-any.whl", hash = "sha256:327cbda3da756e2de031a3107b81ab7b3770a602c4d16ca618298c526f4bec1e"},
{file = "exceptiongroup-1.0.4.tar.gz", hash = "sha256:bd14967b79cd9bdb54d97323216f8fdf533e278df937aa2a90089e7d6e06e5ec"}, {file = "exceptiongroup-1.1.0.tar.gz", hash = "sha256:bcb67d800a4497e1b404c2dd44fca47d3b7a5e5433dbab67f96c1a685cdfdf23"},
] ]
[package.extras] [package.extras]
@ -384,116 +385,116 @@ files = [
[[package]] [[package]]
name = "iniconfig" name = "iniconfig"
version = "1.1.1" version = "2.0.0"
description = "iniconfig: brain-dead simple config-ini parsing" description = "brain-dead simple config-ini parsing"
category = "dev" category = "dev"
optional = false optional = false
python-versions = "*" python-versions = ">=3.7"
files = [ files = [
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
] ]
[[package]] [[package]]
name = "isort" name = "isort"
version = "5.11.3" version = "5.12.0"
description = "A Python utility / library to sort Python imports." description = "A Python utility / library to sort Python imports."
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7.0" python-versions = ">=3.8.0"
files = [ files = [
{file = "isort-5.11.3-py3-none-any.whl", hash = "sha256:83155ffa936239d986b0f190347a3f2285f42a9b9e1725c89d865b27dd0627e5"}, {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"},
{file = "isort-5.11.3.tar.gz", hash = "sha256:a8ca25fbfad0f7d5d8447a4314837298d9f6b23aed8618584c894574f626b64b"}, {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"},
] ]
[package.extras] [package.extras]
colors = ["colorama (>=0.4.3,<0.5.0)"] colors = ["colorama (>=0.4.3)"]
pipfile-deprecated-finder = ["pipreqs", "requirementslib"] pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"]
plugins = ["setuptools"] plugins = ["setuptools"]
requirements-deprecated-finder = ["pip-api", "pipreqs"] requirements-deprecated-finder = ["pip-api", "pipreqs"]
[[package]] [[package]]
name = "multidict" name = "multidict"
version = "6.0.3" version = "6.0.4"
description = "multidict implementation" description = "multidict implementation"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "multidict-6.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:73009ea04205966d47e16d98686ac5c438af23a1bb30b48a2c5da3423ec9ce37"}, {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"},
{file = "multidict-6.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8b92a9f3ab904397a33b193000dc4de7318ea175c4c460a1e154c415f9008e3d"}, {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"},
{file = "multidict-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:578bfcb16f4b8675ef71b960c00f174b0426e0eeb796bab6737389d8288eb827"}, {file = "multidict-6.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7"},
{file = "multidict-6.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1650ea41c408755da5eed52ac6ccbc8938ccc3e698d81e6f6a1be02ff2a0945"}, {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b"},
{file = "multidict-6.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d52442e7c951e4c9ee591d6047706e66923d248d83958bbf99b8b19515fffaef"}, {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547"},
{file = "multidict-6.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad7d66422b9cc51125509229693d27e18c08f2dea3ac9de408d821932b1b3759"}, {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569"},
{file = "multidict-6.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cd14e61f0da2a2cfb9fe05bfced2a1ed7063ce46a7a8cd473be4973de9a7f91"}, {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93"},
{file = "multidict-6.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:190626ced82d4cc567a09e7346340d380154a493bac6905e0095d8158cdf1e38"}, {file = "multidict-6.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98"},
{file = "multidict-6.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:791458a1f7d1b4ab3bd9e93e0dcd1d59ef7ee9aa051dcd1ea030e62e49b923fd"}, {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0"},
{file = "multidict-6.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b46e79a9f4db53897d17bc64a39d1c7c2be3e3d4f8dba6d6730a2b13ddf0f986"}, {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988"},
{file = "multidict-6.0.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e4a095e18847c12ec20e55326ab8782d9c2d599400a3a2f174fab4796875d0e2"}, {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc"},
{file = "multidict-6.0.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:fb6c3dc3d65014d2c782f5acf0b3ba14e639c6c33d3ed8932ead76b9080b3544"}, {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0"},
{file = "multidict-6.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3541882266247c7cd3dba78d6ef28dbe704774df60c9e4231edaa4493522e614"}, {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5"},
{file = "multidict-6.0.3-cp310-cp310-win32.whl", hash = "sha256:67090b17a0a5be5704fd109f231ee73cefb1b3802d41288d6378b5df46ae89ba"}, {file = "multidict-6.0.4-cp310-cp310-win32.whl", hash = "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8"},
{file = "multidict-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:36df958b15639e40472adaa4f0c2c7828fe680f894a6b48c4ce229f59a6a798b"}, {file = "multidict-6.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc"},
{file = "multidict-6.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5b51969503709415a35754954c2763f536a70b8bf7360322b2edb0c0a44391f6"}, {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03"},
{file = "multidict-6.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:24e8d513bfcaadc1f8b0ebece3ff50961951c54b07d5a775008a882966102418"}, {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3"},
{file = "multidict-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d325d61cac602976a5d47b19eaa7d04e3daf4efce2164c630219885087234102"}, {file = "multidict-6.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba"},
{file = "multidict-6.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26fbbe17f8a7211b623502d2bf41022a51da3025142401417c765bf9a56fed4c"}, {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9"},
{file = "multidict-6.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4fb3fe591956d8841882c463f934c9f7485cfd5f763a08c0d467b513dc18ef89"}, {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982"},
{file = "multidict-6.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1925f78a543b94c3d46274c66a366fee8a263747060220ed0188e5f3eeea1c0"}, {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe"},
{file = "multidict-6.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21e1ce0b187c4e93112304dcde2aa18922fdbe8fb4f13d8aa72a5657bce0563a"}, {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710"},
{file = "multidict-6.0.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e07c24018986fb00d6e7eafca8fcd6e05095649e17fcf0e33a592caaa62a78b9"}, {file = "multidict-6.0.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c"},
{file = "multidict-6.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:114a4ab3e5cfbc56c4b6697686ecb92376c7e8c56893ef20547921552f8bdf57"}, {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4"},
{file = "multidict-6.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4ccf55f28066b4f08666764a957c2b7c241c7547b0921d69c7ceab5f74fe1a45"}, {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a"},
{file = "multidict-6.0.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:9d359b0a962e052b713647ac1f13eabf2263167b149ed1e27d5c579f5c8c7d2c"}, {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c"},
{file = "multidict-6.0.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:df7b4cee3ff31b3335aba602f8d70dbc641e5b7164b1e9565570c9d3c536a438"}, {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed"},
{file = "multidict-6.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ee9b1cae9a6c5d023e5a150f6f6b9dbb3c3bbc7887d6ee07d4c0ecb49a473734"}, {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461"},
{file = "multidict-6.0.3-cp311-cp311-win32.whl", hash = "sha256:960ce1b790952916e682093788696ef7e33ac6a97482f9b983abdc293091b531"}, {file = "multidict-6.0.4-cp311-cp311-win32.whl", hash = "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636"},
{file = "multidict-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:2b66d61966b12e6bba500e5cbb2c721a35e119c30ee02495c5629bd0e91eea30"}, {file = "multidict-6.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0"},
{file = "multidict-6.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:526f8397fc124674b8f39748680a0ff673bd6a715fecb4866716d36e380f015f"}, {file = "multidict-6.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78"},
{file = "multidict-6.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f5d5129a937af4e3c4a1d6c139f4051b7d17d43276cefdd8d442a7031f7eef2"}, {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f"},
{file = "multidict-6.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38d394814b39be1c36ac709006d39d50d72a884f9551acd9c8cc1ffae3fc8c4e"}, {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603"},
{file = "multidict-6.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99341ca1f1db9e7f47914cb2461305665a662383765ced6f843712564766956d"}, {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac"},
{file = "multidict-6.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5790cc603456b6dcf8a9a4765f666895a6afddc88b3d3ba7b53dea2b6e23116"}, {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9"},
{file = "multidict-6.0.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce8e51774eb03844588d3c279adb94efcd0edeccd2f97516623292445bcc01f9"}, {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2"},
{file = "multidict-6.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:baa96a3418e27d723064854143b2f414a422c84cc87285a71558722049bebc5a"}, {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde"},
{file = "multidict-6.0.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:cb4a08f0aaaa869f189ffea0e17b86ad0237b51116d494da15ef7991ee6ad2d7"}, {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe"},
{file = "multidict-6.0.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:62db44727d0befea68e8ad2881bb87a9cfb6b87d45dd78609009627167f37b69"}, {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067"},
{file = "multidict-6.0.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:4cc5c8cd205a9810d16a5cd428cd81bac554ad1477cb87f4ad722b10992e794d"}, {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87"},
{file = "multidict-6.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:f76109387e1ec8d8e2137c94c437b89fe002f29e0881aae8ae45529bdff92000"}, {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d"},
{file = "multidict-6.0.3-cp37-cp37m-win32.whl", hash = "sha256:f8a728511c977df6f3d8af388fcb157e49f11db4a6637dd60131b8b6e40b0253"}, {file = "multidict-6.0.4-cp37-cp37m-win32.whl", hash = "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775"},
{file = "multidict-6.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c2a1168e5aa7c72499fb03c850e0f03f624fa4a5c8d2e215c518d0a73872eb64"}, {file = "multidict-6.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e"},
{file = "multidict-6.0.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:eddf604a3de2ace3d9a4e4d491be7562a1ac095a0a1c95a9ec5781ef0273ef11"}, {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c"},
{file = "multidict-6.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d09daf5c6ce7fc6ed444c9339bbde5ea84e2534d1ca1cd37b60f365c77f00dea"}, {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161"},
{file = "multidict-6.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:12e0d396faa6dc55ff5379eee54d1df3b508243ff15bfc8295a6ec7a4483a335"}, {file = "multidict-6.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11"},
{file = "multidict-6.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70740c2bc9ab1c99f7cdcb104f27d16c63860c56d51c5bf0ef82fc1d892a2131"}, {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e"},
{file = "multidict-6.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e322c94596054352f5a02771eec71563c018b15699b961aba14d6dd943367022"}, {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d"},
{file = "multidict-6.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4159fc1ec9ede8ab93382e0d6ba9b1b3d23c72da39a834db7a116986605c7ab4"}, {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2"},
{file = "multidict-6.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47defc0218682281a52fb1f6346ebb8b68b17538163a89ea24dfe4da37a8a9a3"}, {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258"},
{file = "multidict-6.0.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f9511e48bde6b995825e8d35e434fc96296cf07a25f4aae24ff9162be7eaa46"}, {file = "multidict-6.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52"},
{file = "multidict-6.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e0bce9f7c30e7e3a9e683f670314c0144e8d34be6b7019e40604763bd278d84f"}, {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660"},
{file = "multidict-6.0.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:01b456046a05ff7cceefb0e1d2a9d32f05efcb1c7e0d152446304e11557639ce"}, {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951"},
{file = "multidict-6.0.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:8230a39bae6c2e8a09e4da6bace5064693b00590a4a213e38f9a9366da10e7dd"}, {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60"},
{file = "multidict-6.0.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:445c0851a1cbc1f2ec3b40bc22f9c4a235edb3c9a0906122a9df6ea8d51f886c"}, {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d"},
{file = "multidict-6.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9aac6881454a750554ed4b280a839dcf9e2133a9d12ab4d417d673fb102289b7"}, {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1"},
{file = "multidict-6.0.3-cp38-cp38-win32.whl", hash = "sha256:81c3d597591b0940e04949e4e4f79359b2d2e542a686ba0da5e25de33fec13e0"}, {file = "multidict-6.0.4-cp38-cp38-win32.whl", hash = "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779"},
{file = "multidict-6.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:dc4cfef5d899f5f1a15f3d2ac49f71107a01a5a2745b4dd53fa0cede1419385a"}, {file = "multidict-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480"},
{file = "multidict-6.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d408172519049e36fb6d29672f060dc8461fc7174eba9883c7026041ef9bfb38"}, {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664"},
{file = "multidict-6.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e068dfeadbce63072b2d8096486713d04db4946aad0a0f849bd4fc300799d0d3"}, {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35"},
{file = "multidict-6.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8b817d4ed68fd568ec5e45dd75ddf30cc72a47a6b41b74d5bb211374c296f5e"}, {file = "multidict-6.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60"},
{file = "multidict-6.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cf5d19e12eff855aa198259c0b02fd3f5d07e1291fbd20279c37b3b0e6c9852"}, {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706"},
{file = "multidict-6.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e5a811aab1b4aea0b4be669363c19847a8c547510f0e18fb632956369fdbdf67"}, {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d"},
{file = "multidict-6.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2cfda34b7cb99eacada2072e0f69c0ad3285cb6f8e480b11f2b6d6c1c6f92718"}, {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca"},
{file = "multidict-6.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:beeca903e4270b4afcd114f371a9602240dc143f9e944edfea00f8d4ad56c40d"}, {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1"},
{file = "multidict-6.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd5771e8ea325f85cbb361ddbdeb9ae424a68e5dfb6eea786afdcd22e68a7d5d"}, {file = "multidict-6.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449"},
{file = "multidict-6.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9dbab2a7e9c073bc9538824a01f5ed689194db7f55f2b8102766873e906a6c1a"}, {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf"},
{file = "multidict-6.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f2c0957b3e8c66c10d27272709a5299ab3670a0f187c9428f3b90d267119aedb"}, {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063"},
{file = "multidict-6.0.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:94cbe5535ef150546b8321aebea22862a3284da51e7b55f6f95b7d73e96d90ee"}, {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a"},
{file = "multidict-6.0.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:d0e798b072cf2aab9daceb43d97c9c527a0c7593e67a7846ad4cc6051de1e303"}, {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176"},
{file = "multidict-6.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a27b029caa3b555a4f3da54bc1e718eb55fcf1a11fda8bf0132147b476cf4c08"}, {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95"},
{file = "multidict-6.0.3-cp39-cp39-win32.whl", hash = "sha256:018c8e3be7f161a12b3e41741b6721f9baeb2210f4ab25a6359b7d76c1017dce"}, {file = "multidict-6.0.4-cp39-cp39-win32.whl", hash = "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313"},
{file = "multidict-6.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:5e58ec0375803526d395f6f7e730ecc45d06e15f68f7b9cdbf644a2918324e51"}, {file = "multidict-6.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2"},
{file = "multidict-6.0.3.tar.gz", hash = "sha256:2523a29006c034687eccd3ee70093a697129a3ffe8732535d3b2df6a4ecc279d"}, {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"},
] ]
[[package]] [[package]]
@ -525,43 +526,43 @@ setuptools = "*"
[[package]] [[package]]
name = "packaging" name = "packaging"
version = "22.0" version = "23.0"
description = "Core utilities for Python packages" description = "Core utilities for Python packages"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "packaging-22.0-py3-none-any.whl", hash = "sha256:957e2148ba0e1a3b282772e791ef1d8083648bc131c8ab0c1feba110ce1146c3"}, {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"},
{file = "packaging-22.0.tar.gz", hash = "sha256:2198ec20bd4c017b8f9717e00f0c8714076fc2fd93816750ab48e2c41de2cfd3"}, {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"},
] ]
[[package]] [[package]]
name = "pathspec" name = "pathspec"
version = "0.10.3" version = "0.11.0"
description = "Utility library for gitignore style pattern matching of file paths." description = "Utility library for gitignore style pattern matching of file paths."
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "pathspec-0.10.3-py3-none-any.whl", hash = "sha256:3c95343af8b756205e2aba76e843ba9520a24dd84f68c22b9f93251507509dd6"}, {file = "pathspec-0.11.0-py3-none-any.whl", hash = "sha256:3a66eb970cbac598f9e5ccb5b2cf58930cd8e3ed86d393d541eaf2d8b1705229"},
{file = "pathspec-0.10.3.tar.gz", hash = "sha256:56200de4077d9d0791465aa9095a01d421861e405b5096955051deefd697d6f6"}, {file = "pathspec-0.11.0.tar.gz", hash = "sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc"},
] ]
[[package]] [[package]]
name = "platformdirs" name = "platformdirs"
version = "2.6.0" version = "2.6.2"
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "platformdirs-2.6.0-py3-none-any.whl", hash = "sha256:1a89a12377800c81983db6be069ec068eee989748799b946cce2a6e80dcc54ca"}, {file = "platformdirs-2.6.2-py3-none-any.whl", hash = "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490"},
{file = "platformdirs-2.6.0.tar.gz", hash = "sha256:b46ffafa316e6b83b47489d240ce17173f123a9b9c83282141c3daf26ad9ac2e"}, {file = "platformdirs-2.6.2.tar.gz", hash = "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2"},
] ]
[package.extras] [package.extras]
docs = ["furo (>=2022.9.29)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.4)"] docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"]
test = ["appdirs (==1.4.4)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
[[package]] [[package]]
name = "pluggy" name = "pluggy"
@ -605,14 +606,14 @@ files = [
[[package]] [[package]]
name = "pyright" name = "pyright"
version = "1.1.284" version = "1.1.292"
description = "Command line wrapper for pyright" description = "Command line wrapper for pyright"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "pyright-1.1.284-py3-none-any.whl", hash = "sha256:e3bfbd33c20af48eed9d20138767265161ba8a4b55c740476a36ce822bd482d1"}, {file = "pyright-1.1.292-py3-none-any.whl", hash = "sha256:23d1f14b15afe38bb7a7117b9861ad0546aff078da312d294e60a727445c23ff"},
{file = "pyright-1.1.284.tar.gz", hash = "sha256:ef7c0e46e38be95687f5a0633e55c5171ca166048b9560558168a976162e287c"}, {file = "pyright-1.1.292.tar.gz", hash = "sha256:035ea1af6fabfdcc80c0afb545f677bd377114157d69779cce2a642ff894e51c"},
] ]
[package.dependencies] [package.dependencies]
@ -624,14 +625,14 @@ dev = ["twine (>=3.4.1)"]
[[package]] [[package]]
name = "pytest" name = "pytest"
version = "7.2.0" version = "7.2.1"
description = "pytest: simple powerful testing with Python" description = "pytest: simple powerful testing with Python"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "pytest-7.2.0-py3-none-any.whl", hash = "sha256:892f933d339f068883b6fd5a459f03d85bfcb355e4981e146d2c7616c21fef71"}, {file = "pytest-7.2.1-py3-none-any.whl", hash = "sha256:c7c6ca206e93355074ae32f7403e8ea12163b1163c976fee7d4d84027c162be5"},
{file = "pytest-7.2.0.tar.gz", hash = "sha256:c4014eb40e10f11f355ad4e3c2fb2c6c6d1919c73f3b5a433de4708202cade59"}, {file = "pytest-7.2.1.tar.gz", hash = "sha256:d45e0952f3727241918b8fd0f376f5ff6b301cc0777c6f9a556935c92d8a7d42"},
] ]
[package.dependencies] [package.dependencies]
@ -664,18 +665,18 @@ pytest = ">=5.3"
[[package]] [[package]]
name = "setuptools" name = "setuptools"
version = "65.6.3" version = "67.1.0"
description = "Easily download, build, install, upgrade, and uninstall Python packages" description = "Easily download, build, install, upgrade, and uninstall Python packages"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "setuptools-65.6.3-py3-none-any.whl", hash = "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54"}, {file = "setuptools-67.1.0-py3-none-any.whl", hash = "sha256:a7687c12b444eaac951ea87a9627c4f904ac757e7abdc5aac32833234af90378"},
{file = "setuptools-65.6.3.tar.gz", hash = "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75"}, {file = "setuptools-67.1.0.tar.gz", hash = "sha256:e261cdf010c11a41cb5cb5f1bf3338a7433832029f559a6a7614bd42a967c300"},
] ]
[package.extras] [package.extras]
docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
@ -695,7 +696,7 @@ files = [
name = "typing-extensions" name = "typing-extensions"
version = "4.4.0" version = "4.4.0"
description = "Backported and Experimental Type Hints for Python 3.7+" description = "Backported and Experimental Type Hints for Python 3.7+"
category = "dev" category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
@ -842,4 +843,4 @@ uvloop = ["uvloop"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.9.0" python-versions = "^3.9.0"
content-hash = "412a18bfbb9a9abfbca2b68a75a7876087fa3633ea5d1821ff554c90d9f9bfdb" content-hash = "6003de93985e26bf0e7b4e7ca64c6b685a69759ad8c9ce1f15d7c7667bc70560"

View File

@ -29,6 +29,7 @@ biliass = "1.3.7"
uvloop = { version = "0.17.0", optional = true } uvloop = { version = "0.17.0", optional = true }
dicttoxml = "^1.7.15" dicttoxml = "^1.7.15"
colorama = { version = "^0.4.6", markers = "sys_platform == 'win32'" } colorama = { version = "^0.4.6", markers = "sys_platform == 'win32'" }
typing-extensions = "^4.4.0"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
pytest = "^7.2" pytest = "^7.2"

View File

@ -4,9 +4,12 @@ import argparse
import copy import copy
import re import re
import sys import sys
from collections.abc import Sequence
from pathlib import Path from pathlib import Path
from typing import Any, Literal
import aiohttp import aiohttp
from typing_extensions import TypeAlias
from yutto.__version__ import VERSION as yutto_version from yutto.__version__ import VERSION as yutto_version
from yutto.bilibili_typing.quality import ( from yutto.bilibili_typing.quality import (
@ -36,6 +39,9 @@ from yutto.validator import (
validate_batch_argments, validate_batch_argments,
) )
DownloadResourceType: TypeAlias = Literal["video", "audio", "subtitle", "metadata", "danmaku"]
DOWNLOAD_RESOURCE_TYPES: list[DownloadResourceType] = ["video", "audio", "subtitle", "metadata", "danmaku"]
def main(): def main():
parser = cli() parser = cli()
@ -79,8 +85,6 @@ def cli() -> argparse.ArgumentParser:
group_common.add_argument( group_common.add_argument(
"--acodec", default="mp4a:copy", metavar="DOWNLOAD_ACODEC:SAVE_ACODEC", help="音频编码格式(<下载格式>:<生成格式>" "--acodec", default="mp4a:copy", metavar="DOWNLOAD_ACODEC:SAVE_ACODEC", help="音频编码格式(<下载格式>:<生成格式>"
) )
group_common.add_argument("--video-only", dest="require_audio", action="store_false", help="只下载视频")
group_common.add_argument("--audio-only", dest="require_video", action="store_false", help="只下载音频")
group_common.add_argument("-df", "--danmaku-format", default="ass", choices=["xml", "ass", "protobuf"], help="弹幕类型") group_common.add_argument("-df", "--danmaku-format", default="ass", choices=["xml", "ass", "protobuf"], help="弹幕类型")
group_common.add_argument("-bs", "--block-size", default=0.5, type=float, help="分块下载时各块大小,单位为 MiB默认为 0.5MiB") group_common.add_argument("-bs", "--block-size", default=0.5, type=float, help="分块下载时各块大小,单位为 MiB默认为 0.5MiB")
group_common.add_argument("-w", "--overwrite", action="store_true", help="强制覆盖已下载内容") group_common.add_argument("-w", "--overwrite", action="store_true", help="强制覆盖已下载内容")
@ -92,9 +96,59 @@ def cli() -> argparse.ArgumentParser:
group_common.add_argument( group_common.add_argument(
"-af", "--alias-file", type=argparse.FileType("r", encoding="utf-8"), help="设置 url 别名文件路径" "-af", "--alias-file", type=argparse.FileType("r", encoding="utf-8"), help="设置 url 别名文件路径"
) )
group_common.add_argument("--no-danmaku", action="store_true", help="不生成弹幕文件")
group_common.add_argument("--no-subtitle", action="store_true", help="不生成字幕文件") # 资源选择
group_common.add_argument("--with-metadata", action="store_true", help="生成元数据文件") group_common.add_argument(
"--video-only",
dest="require_audio",
action=create_select_required_action(deselect=["audio"]),
help="仅下载视频流",
)
group_common.add_argument(
"--audio-only",
dest="require_video",
action=create_select_required_action(deselect=["video"]),
help="仅下载音频流",
) # 视频和音频是反选对方,而不是其余反选所有的
group_common.add_argument(
"--no-danmaku",
dest="require_danmaku",
action=create_select_required_action(deselect=["danmaku"]),
help="不生成弹幕文件",
)
group_common.add_argument(
"--danmaku-only",
dest="require_danmaku",
action=create_select_required_action(select=["danmaku"], deselect=invert_selection(["danmaku"])),
help="仅生成弹幕文件",
)
group_common.add_argument(
"--no-subtitle",
dest="require_subtitle",
action=create_select_required_action(deselect=["subtitle"]),
help="不生成字幕文件",
)
group_common.add_argument(
"--subtitle-only",
dest="require_subtitle",
action=create_select_required_action(select=["subtitle"], deselect=invert_selection(["subtitle"])),
help="仅生成字幕文件",
)
group_common.add_argument(
"--with-metadata",
dest="require_metadata",
action=create_select_required_action(select=["metadata"]),
help="生成元数据文件",
)
group_common.add_argument(
"--metadata-only",
dest="require_metadata",
action=create_select_required_action(select=["metadata"], deselect=invert_selection(["metadata"])),
help="仅生成元数据文件",
)
group_common.set_defaults(
require_video=True, require_audio=True, require_subtitle=True, require_metadata=False, require_danmaku=True
)
group_common.add_argument("--metadata-format", default="nfo", choices=["nfo"], help="(待实现)元数据文件类型,目前仅支持 nfo") group_common.add_argument("--metadata-format", default="nfo", choices=["nfo"], help="(待实现)元数据文件类型,目前仅支持 nfo")
group_common.add_argument("--embed-danmaku", action="store_true", help="(待实现)将弹幕文件嵌入到视频中") group_common.add_argument("--embed-danmaku", action="store_true", help="(待实现)将弹幕文件嵌入到视频中")
group_common.add_argument("--embed-subtitle", default=None, help="(待实现)将字幕文件嵌入到视频中(需输入语言代码)") group_common.add_argument("--embed-subtitle", default=None, help="(待实现)将字幕文件嵌入到视频中(需输入语言代码)")
@ -237,5 +291,31 @@ def flatten_args(args: argparse.Namespace, parser: argparse.ArgumentParser) -> l
return [args] return [args]
def create_select_required_action(select: list[DownloadResourceType] = [], deselect: list[DownloadResourceType] = []):
class SelectRequiredAction(argparse.Action):
def __init__(self, option_strings: str, dest: str, nargs: int | str | None = None, **kwargs: dict[str, Any]):
if nargs is not None:
raise ValueError("nargs not allowed")
super().__init__(option_strings, dest, nargs=0, **kwargs)
def __call__(
self,
parser: argparse.ArgumentParser,
namespace: argparse.Namespace,
values: str | Sequence[str] | None,
option_string: str | None = None,
):
for select_item in select:
setattr(namespace, f"require_{select_item}", True)
for deselect_item in deselect:
setattr(namespace, f"require_{deselect_item}", False)
return SelectRequiredAction
def invert_selection(select: list[DownloadResourceType]) -> list[DownloadResourceType]:
return [tp for tp in DOWNLOAD_RESOURCE_TYPES if tp not in select]
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -47,9 +47,9 @@ async def extract_bangumi_data(
name = bangumi_info["name"] name = bangumi_info["name"]
id = bangumi_info["id"] id = bangumi_info["id"]
videos, audios = await get_bangumi_playurl(session, avid, episode_id, cid) videos, audios = await get_bangumi_playurl(session, avid, episode_id, cid)
subtitles = await get_bangumi_subtitles(session, avid, cid) if not args.no_subtitle else [] subtitles = await get_bangumi_subtitles(session, avid, cid) if args.require_subtitle else []
danmaku = await get_danmaku(session, cid, args.danmaku_format) if not args.no_danmaku else EmptyDanmakuData danmaku = await get_danmaku(session, cid, args.danmaku_format) if args.require_danmaku else EmptyDanmakuData
metadata = bangumi_info["metadata"] if args.with_metadata else None metadata = bangumi_info["metadata"] if args.require_metadata else None
subpath_variables_base: PathTemplateVariableDict = { subpath_variables_base: PathTemplateVariableDict = {
"id": id, "id": id,
"name": name, "name": name,
@ -90,9 +90,9 @@ async def extract_ugc_video_data(
name = ugc_video_info["name"] name = ugc_video_info["name"]
id = ugc_video_info["id"] id = ugc_video_info["id"]
videos, audios = await get_ugc_video_playurl(session, avid, cid) videos, audios = await get_ugc_video_playurl(session, avid, cid)
subtitles = await get_ugc_video_subtitles(session, avid, cid) if not args.no_subtitle else [] subtitles = await get_ugc_video_subtitles(session, avid, cid) if args.require_subtitle else []
danmaku = await get_danmaku(session, cid, args.danmaku_format) if not args.no_danmaku else EmptyDanmakuData danmaku = await get_danmaku(session, cid, args.danmaku_format) if args.require_danmaku else EmptyDanmakuData
metadata = ugc_video_info["metadata"] if args.with_metadata else None metadata = ugc_video_info["metadata"] if args.require_metadata else None
subpath_variables_base: PathTemplateVariableDict = { subpath_variables_base: PathTemplateVariableDict = {
"id": id, "id": id,
"name": name, "name": name,

View File

@ -187,14 +187,18 @@ async def start_downloader(
output_dir = Path(episode_data["output_dir"]) output_dir = Path(episode_data["output_dir"])
tmp_dir = Path(episode_data["tmp_dir"]) tmp_dir = Path(episode_data["tmp_dir"])
filename = episode_data["filename"] filename = episode_data["filename"]
require_video = options["require_video"]
require_audio = options["require_audio"]
Logger.info(f"开始处理视频 {filename}") Logger.info(f"开始处理视频 {filename}")
tmp_dir.mkdir(parents=True, exist_ok=True) tmp_dir.mkdir(parents=True, exist_ok=True)
video_path = tmp_dir.joinpath(filename + "_video.m4s") video_path = tmp_dir.joinpath(filename + "_video.m4s")
audio_path = tmp_dir.joinpath(filename + "_audio.m4s") audio_path = tmp_dir.joinpath(filename + "_audio.m4s")
video = select_video(videos, options["require_video"], options["video_quality"], options["video_download_codec"]) video = select_video(videos, options["video_quality"], options["video_download_codec"])
audio = select_audio(audios, options["require_audio"], options["audio_quality"], options["audio_download_codec"]) audio = select_audio(audios, options["audio_quality"], options["audio_download_codec"])
will_download_video = video is not None and require_video
will_download_audio = audio is not None and require_audio
# 显示音视频详细信息 # 显示音视频详细信息
show_videos_info(videos, videos.index(video) if video is not None else -1) show_videos_info(videos, videos.index(video) if video is not None else -1)
@ -202,27 +206,16 @@ async def start_downloader(
output_dir.mkdir(parents=True, exist_ok=True) output_dir.mkdir(parents=True, exist_ok=True)
output_format = ".mp4" output_format = ".mp4"
if video is None: if not will_download_video:
if audio is not None and audio["codec"] == "fLaC": if will_download_audio and audio["codec"] == "fLaC": # type: ignore
output_format = ".flac" output_format = ".flac"
else: else:
output_format = ".aac" output_format = ".aac"
else: else:
if audio is not None and audio["codec"] == "fLaC": if will_download_audio and audio["codec"] == "fLaC": # type: ignore
output_format = ".mkv" # MP4 does not support FLAC audio output_format = ".mkv" # MP4 does not support FLAC audio
output_path = output_dir.joinpath(filename + output_format) output_path = output_dir.joinpath(filename + output_format)
if output_path.exists():
if not options["overwrite"]:
Logger.info(f"文件 {filename} 已存在")
return
else:
Logger.info("文件已存在,因启用 overwrite 选项强制删除……")
output_path.unlink()
if video is None and audio is None:
Logger.warning("没有音视频需要下载")
return
# 保存字幕 # 保存字幕
if subtitles: if subtitles:
@ -238,8 +231,8 @@ async def start_downloader(
write_danmaku( write_danmaku(
danmaku, danmaku,
str(output_path), str(output_path),
video["height"] if video is not None else 0, video["height"] if video is not None else 1080, # 未下载视频时自动按照 1920x1080 处理
video["width"] if video is not None else 0, video["width"] if video is not None else 1920,
) )
Logger.custom("{} 弹幕已生成".format(danmaku["save_type"]).upper(), badge=Badge("弹幕", fore="black", back="cyan")) Logger.custom("{} 弹幕已生成".format(danmaku["save_type"]).upper(), badge=Badge("弹幕", fore="black", back="cyan"))
@ -248,6 +241,18 @@ async def start_downloader(
write_metadata(metadata, str(output_path)) write_metadata(metadata, str(output_path))
Logger.custom("NFO 媒体描述文件已生成", badge=Badge("描述文件", fore="black", back="cyan")) Logger.custom("NFO 媒体描述文件已生成", badge=Badge("描述文件", fore="black", back="cyan"))
if output_path.exists():
if not options["overwrite"]:
Logger.info(f"文件 {filename} 已存在")
return
else:
Logger.info("文件已存在,因启用 overwrite 选项强制删除……")
output_path.unlink()
if not (will_download_audio or will_download_video):
Logger.warning("没有音视频需要下载")
return
# 下载视频 / 音频 # 下载视频 / 音频
await download_video_and_audio(session, video, video_path, audio, audio_path, options) await download_video_and_audio(session, video, video_path, audio, audio_path, options)

View File

@ -49,7 +49,6 @@ class ProgressBar:
async def show_progress(file_buffers: list[AsyncFileBuffer], total_size: int): async def show_progress(file_buffers: list[AsyncFileBuffer], total_size: int):
file_buffers = list(filter(lambda x: x is not None, file_buffers))
t = time.time() t = time.time()
size = sum([file_buffer.written_size for file_buffer in file_buffers]) size = sum([file_buffer.written_size for file_buffer in file_buffers])
progress_bar = ProgressBar("╸━", "") progress_bar = ProgressBar("╸━", "")

View File

@ -23,13 +23,9 @@ from yutto.utils.console.logger import Logger
def select_video( def select_video(
videos: list[VideoUrlMeta], videos: list[VideoUrlMeta],
require_video: bool = True,
video_quality: VideoQuality = 127, video_quality: VideoQuality = 127,
video_codec: VideoCodec = "hevc", video_codec: VideoCodec = "hevc",
) -> Optional[VideoUrlMeta]: ) -> Optional[VideoUrlMeta]:
if not require_video:
return None
video_quality_priority = gen_video_quality_priority(video_quality) video_quality_priority = gen_video_quality_priority(video_quality)
video_codec_priority = gen_vcodec_priority(video_codec) video_codec_priority = gen_vcodec_priority(video_codec)
@ -51,13 +47,9 @@ def select_video(
def select_audio( def select_audio(
audios: list[AudioUrlMeta], audios: list[AudioUrlMeta],
require_audio: bool = True,
audio_quality: AudioQuality = 30280, audio_quality: AudioQuality = 30280,
audio_codec: AudioCodec = "mp4a", audio_codec: AudioCodec = "mp4a",
) -> Optional[AudioUrlMeta]: ) -> Optional[AudioUrlMeta]:
if not require_audio:
return None
audio_quality_priority = gen_audio_quality_priority(audio_quality) audio_quality_priority = gen_audio_quality_priority(audio_quality)
audio_codec_priority = gen_acodec_priority(audio_codec) audio_codec_priority = gen_acodec_priority(audio_codec)

View File

@ -107,11 +107,6 @@ def validate_basic_arguments(args: argparse.Namespace):
) )
sys.exit(ErrorCode.WRONG_ARGUMENT_ERROR.value) sys.exit(ErrorCode.WRONG_ARGUMENT_ERROR.value)
# video_only 和 audio_only 不能同时设置
if not args.require_video and not args.require_audio:
Logger.error("video_only 和 audio_only 不能同时设置呀!")
sys.exit(ErrorCode.WRONG_ARGUMENT_ERROR.value)
# 不下载视频无法嵌入字幕 # 不下载视频无法嵌入字幕
if not args.require_video and args.embed_subtitle: if not args.require_video and args.embed_subtitle:
Logger.error("不下载视频时无法嵌入字幕的哦!") Logger.error("不下载视频时无法嵌入字幕的哦!")
@ -122,18 +117,13 @@ def validate_basic_arguments(args: argparse.Namespace):
Logger.error("不下载视频时无法嵌入弹幕的哦!") Logger.error("不下载视频时无法嵌入弹幕的哦!")
sys.exit(ErrorCode.WRONG_ARGUMENT_ERROR.value) sys.exit(ErrorCode.WRONG_ARGUMENT_ERROR.value)
# 不下载视频无法生成 ASS 弹幕ASS 弹幕生成计算依赖于视频分辨率大小)
if not args.require_video and not args.no_danmaku and args.danmaku_format == "ass":
Logger.error("不下载视频无法生成 ASS 弹幕呀!")
sys.exit(ErrorCode.WRONG_ARGUMENT_ERROR.value)
# 生成字幕才可以嵌入字幕 # 生成字幕才可以嵌入字幕
if args.embed_subtitle and args.no_subtitle: if args.embed_subtitle and not args.require_subtitle:
Logger.error("生成字幕才可以嵌入字幕喔!") Logger.error("生成字幕才可以嵌入字幕喔!")
sys.exit(ErrorCode.WRONG_ARGUMENT_ERROR.value) sys.exit(ErrorCode.WRONG_ARGUMENT_ERROR.value)
# 生成 ASS 弹幕才可以嵌入弹幕 # 生成 ASS 弹幕才可以嵌入弹幕
if args.embed_danmaku and args.no_danmaku: if args.embed_danmaku and not args.require_danmaku:
Logger.error("生成 ASS 弹幕才可以嵌入弹幕喔!") Logger.error("生成 ASS 弹幕才可以嵌入弹幕喔!")
sys.exit(ErrorCode.WRONG_ARGUMENT_ERROR.value) sys.exit(ErrorCode.WRONG_ARGUMENT_ERROR.value)