mirror of https://github.com/yutto-dev/yutto
✨ feat: add new argument `--download-vcode-priority` (#217)
This commit is contained in:
parent
3a196008e5
commit
6a5b99ebdd
22
README.md
22
README.md
|
@ -199,7 +199,7 @@ yutto 支持一些基础参数,无论是批量下载还是单视频下载都
|
|||
|
||||
该参数略微复杂,前半部分表示在下载时**优先**选择哪一种编码的视频流,后半部分则表示在合并时如何编码视频流,两者使用 `:` 分隔。
|
||||
|
||||
值得注意的是,前半的下载编码只是优先下载的编码而已,如果不存在该编码,则仍会像视频清晰度调节机制一样自动选择其余编码。
|
||||
值得注意的是,前半的下载编码只是优先下载的编码而已,如果不存在该编码,则会根据 `--download-vcodec-priority` 自动选择其余编码,如未设置 `--download-vcodec-priority`,则会类似视频清晰度调节机制先降序后升序的方式来选择。
|
||||
|
||||
而后半部分的参数如果设置成非 `copy` 的值则可以确保在下载完成后对其进行重新编码,而且不止支持 `av1`、`hevc` 与 `avc`,只要你的 FFmpeg 支持的视频编码器,它都可以完成。
|
||||
|
||||
|
@ -212,6 +212,26 @@ yutto 支持一些基础参数,无论是批量下载还是单视频下载都
|
|||
|
||||
详情同视频编码。
|
||||
|
||||
#### 指定视频下载编码优先级
|
||||
|
||||
- 参数 `--download-vcodec-priority`
|
||||
- 默认值 `"auto"`
|
||||
- 可选值 `"auto"` 或者使用 `,` 分隔的下载编码列表,如 `"hevc,avc,av1"`
|
||||
|
||||
当使用默认值 `"auto"` 时,yutto 会类似视频清晰度调节机制先降序后升序的方式来选择。
|
||||
|
||||
当使用自定义下载编码列表时,yutto 会严格按照列表中的顺序进行选择,如果不存在则会认为该视频无视频流。
|
||||
|
||||
<!--
|
||||
这里使用 [!Warning] 渲染会出问题,因为 GitHub 尚不支持嵌套在 summary 中,因此暂时回退到 **Warning** 的写法
|
||||
更多讨论见
|
||||
https://github.com/orgs/community/discussions/16925#discussioncomment-7571187
|
||||
-->
|
||||
|
||||
> **Warning**
|
||||
>
|
||||
> 如若设置本参数,请总是将 `--download-vcode-priority` 首选编码作为 `--vcodec` 的前半部分,否则可能会导致下载失败。
|
||||
|
||||
#### 指定输出格式
|
||||
|
||||
- 参数 `--output-format`
|
||||
|
|
|
@ -96,6 +96,11 @@ def cli() -> argparse.ArgumentParser:
|
|||
metavar="DOWNLOAD_ACODEC:SAVE_ACODEC",
|
||||
help="音频编码格式(<下载格式>:<生成格式>)",
|
||||
)
|
||||
group_common.add_argument(
|
||||
"--download-vcodec-priority",
|
||||
default="auto",
|
||||
help="视频编码格式优先级,使用 `,` 分隔,如 `hevc,avc,av1`,默认为 `auto`,即根据 vcodec 中「下载编码」自动推断",
|
||||
)
|
||||
group_common.add_argument(
|
||||
"--output-format", default="infer", choices=["infer", "mp4", "mkv", "mov"], help="输出格式(infer 为自动推断)"
|
||||
)
|
||||
|
@ -305,6 +310,9 @@ async def run(args_list: list[argparse.Namespace]):
|
|||
"video_quality": args.video_quality,
|
||||
"video_download_codec": args.vcodec.split(":")[0],
|
||||
"video_save_codec": args.vcodec.split(":")[1],
|
||||
"video_download_codec_priority": args.download_vcodec_priority.split(",")
|
||||
if args.download_vcodec_priority != "auto"
|
||||
else None,
|
||||
"require_audio": args.require_audio,
|
||||
"audio_quality": args.audio_quality,
|
||||
"audio_download_codec": args.acodec.split(":")[0],
|
||||
|
|
|
@ -175,6 +175,7 @@ class DownloaderOptions(TypedDict):
|
|||
video_quality: VideoQuality
|
||||
video_download_codec: VideoCodec
|
||||
video_save_codec: str
|
||||
video_download_codec_priority: list[VideoCodec] | None
|
||||
require_audio: bool
|
||||
audio_quality: AudioQuality
|
||||
audio_download_codec: AudioCodec
|
||||
|
|
|
@ -217,7 +217,9 @@ async def start_downloader(
|
|||
video_path = tmp_dir.joinpath(filename + "_video.m4s")
|
||||
audio_path = tmp_dir.joinpath(filename + "_audio.m4s")
|
||||
|
||||
video = select_video(videos, options["video_quality"], options["video_download_codec"])
|
||||
video = select_video(
|
||||
videos, options["video_quality"], options["video_download_codec"], options["video_download_codec_priority"]
|
||||
)
|
||||
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
|
||||
|
|
|
@ -24,9 +24,12 @@ def select_video(
|
|||
videos: list[VideoUrlMeta],
|
||||
video_quality: VideoQuality = 127,
|
||||
video_codec: VideoCodec = "hevc",
|
||||
video_download_codec_priority: list[VideoCodec] | None = None,
|
||||
) -> VideoUrlMeta | None:
|
||||
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) if video_download_codec_priority is None else video_download_codec_priority
|
||||
)
|
||||
|
||||
# fmt: off
|
||||
video_combined_priority = [
|
||||
|
|
|
@ -10,10 +10,7 @@ import aiohttp
|
|||
|
||||
from yutto._typing import UserInfo
|
||||
from yutto.api.user_info import get_user_info
|
||||
from yutto.bilibili_typing.codec import (
|
||||
audio_codec_priority_default,
|
||||
video_codec_priority_default,
|
||||
)
|
||||
from yutto.bilibili_typing.codec import VideoCodec, audio_codec_priority_default, video_codec_priority_default
|
||||
from yutto.exceptions import ErrorCode
|
||||
from yutto.processor.selector import validate_episodes_selection
|
||||
from yutto.utils.asynclib import initial_async_policy
|
||||
|
@ -70,19 +67,47 @@ def validate_basic_arguments(args: argparse.Namespace):
|
|||
|
||||
ffmpeg = FFmpeg()
|
||||
|
||||
download_vcodec_priority: list[VideoCodec] = video_codec_priority_default
|
||||
if args.download_vcodec_priority != "auto":
|
||||
user_download_vcodec_priority = args.download_vcodec_priority.split(",")
|
||||
if not user_download_vcodec_priority:
|
||||
Logger.error("download_vcodec_priority 参数值为空哦")
|
||||
sys.exit(ErrorCode.WRONG_ARGUMENT_ERROR.value)
|
||||
for vcodec in user_download_vcodec_priority:
|
||||
if vcodec not in video_codec_priority_default:
|
||||
Logger.error(
|
||||
"download_vcodec_priority 参数值({})不满足要求哦(允许值:{{{}}})".format(
|
||||
vcodec, ", ".join(video_codec_priority_default)
|
||||
)
|
||||
)
|
||||
sys.exit(ErrorCode.WRONG_ARGUMENT_ERROR.value)
|
||||
download_vcodec_priority = user_download_vcodec_priority
|
||||
if len(download_vcodec_priority) < len(video_codec_priority_default):
|
||||
Logger.warning(
|
||||
"download_vcodec_priority({})不包含所有下载视频编码({}),不包含部分将永远不会选择哦".format(
|
||||
args.download_vcodec_priority, ", ".join(video_codec_priority_default)
|
||||
)
|
||||
)
|
||||
|
||||
# vcodec 检查
|
||||
vcodec_splited = args.vcodec.split(":")
|
||||
if len(vcodec_splited) != 2:
|
||||
Logger.error(f"vcodec 参数值({args.vcodec})不满足要求哦(并非使用 : 分隔的值)")
|
||||
sys.exit(ErrorCode.WRONG_ARGUMENT_ERROR.value)
|
||||
video_download_codec, video_save_codec = vcodec_splited
|
||||
if video_download_codec not in video_codec_priority_default:
|
||||
if video_download_codec not in download_vcodec_priority:
|
||||
Logger.error(
|
||||
"download_vcodec 参数值({})不满足要求哦(允许值:{{{}}})".format(
|
||||
video_download_codec, ", ".join(video_codec_priority_default)
|
||||
video_download_codec, ", ".join(download_vcodec_priority)
|
||||
)
|
||||
)
|
||||
sys.exit(ErrorCode.WRONG_ARGUMENT_ERROR.value)
|
||||
if args.download_vcodec_priority != "auto" and download_vcodec_priority[0] != video_download_codec:
|
||||
Logger.warning(
|
||||
"download_vcodec 参数值({})不是优先级最高的编码({}),可能会导致下载失败哦".format(
|
||||
video_download_codec, download_vcodec_priority[0]
|
||||
)
|
||||
)
|
||||
if video_save_codec not in ffmpeg.video_encodecs + ["copy"]:
|
||||
Logger.error(
|
||||
"save_vcodec 参数值({})不满足要求哦(允许值:{{{}}})".format(
|
||||
|
|
Loading…
Reference in New Issue