mirror of https://github.com/yutto-dev/yutto
✨ feat: support acg_video
This commit is contained in:
parent
19d4144d05
commit
61e14ee053
|
@ -28,3 +28,8 @@ yutto -q 64 get https://www.bilibili.com/bangumi/play/ep395211
|
|||
## TODO List
|
||||
|
||||
- [ ] 好多,不知道该写些啥,等剩余任务较少时候再来写吧……
|
||||
|
||||
## References
|
||||
|
||||
- https://github.com/SigureMo/bilili
|
||||
- https://github.com/changmenseng/AsyncBilibiliDownloader
|
||||
|
|
|
@ -32,12 +32,13 @@ def main():
|
|||
parser.add_argument("--only-video", dest="require_audio", action="store_false", help="只下载视频")
|
||||
parser.add_argument("--only-audio", dest="require_video", action="store_false", help="只下载音频")
|
||||
parser.add_argument("--danmaku", default="xml", choices=["xml", "ass", "no"], help="弹幕类型,no 为不生成弹幕")
|
||||
parser.add_argument("-b", "--block-size", default=1.0, type=float, help="分块下载时各块大小,单位为 MiB,默认为 1MiB")
|
||||
parser.add_argument("-b", "--block-size", default=0.5, type=float, help="分块下载时各块大小,单位为 MiB,默认为 0.5MiB")
|
||||
parser.add_argument("-w", "--overwrite", action="store_true", help="强制覆盖已下载内容")
|
||||
parser.add_argument("-x", "--proxy", default="auto", help="设置代理(auto 为系统代理、no 为不使用代理、当然也可以设置代理值)")
|
||||
parser.add_argument("-d", "--dir", default="", help="下载目录")
|
||||
parser.add_argument("-c", "--sessdata", default="", help="Cookies 中的 SESSDATA 字段")
|
||||
parser.add_argument("--path-pattern", default="{auto}", help="多级目录的存储路径 Pattern")
|
||||
parser.add_argument("--no-subtitle", action="store_true", help="不生成字幕文件")
|
||||
parser.add_argument("--no-color", action="store_true", help="不使用颜色")
|
||||
parser.add_argument("--debug", action="store_true", help="启用 debug 模式")
|
||||
parser.set_defaults(action=run)
|
||||
|
|
|
@ -1,16 +1,25 @@
|
|||
import argparse
|
||||
import aiohttp
|
||||
from yutto.processor.crawler import gen_cookies, gen_headers
|
||||
from yutto.utils.functiontools.sync import sync
|
||||
import os
|
||||
import sys
|
||||
|
||||
import aiohttp
|
||||
|
||||
from yutto.api.acg_video import get_acg_video_playurl, get_acg_video_title, get_acg_video_list
|
||||
from yutto.api.bangumi import get_bangumi_list, get_bangumi_playurl, get_bangumi_title, get_season_id_by_episode_id
|
||||
from yutto.api.types import AId, AvId, BvId, CId, EpisodeId, MediaId, SeasonId
|
||||
from yutto.processor.crawler import gen_cookies, gen_headers
|
||||
from yutto.processor.downloader import download_video
|
||||
from yutto.api.bangumi import get_bangumi_playurl, get_bangumi_title, get_season_id_by_episode_id, get_bangumi_list
|
||||
from yutto.api.acg_video import get_acg_video_title, get_acg_video_playurl
|
||||
from yutto.api.types import AvId, AId, BvId, EpisodeId, MediaId, SeasonId, CId
|
||||
from yutto.processor.urlparser import regexp_bangumi_ep
|
||||
from yutto.utils.console.logger import Logger
|
||||
from yutto.processor.urlparser import (
|
||||
regexp_acg_video_av,
|
||||
regexp_acg_video_av_short,
|
||||
regexp_acg_video_bv,
|
||||
regexp_acg_video_bv_short,
|
||||
regexp_bangumi_ep,
|
||||
regexp_bangumi_ep_short,
|
||||
)
|
||||
from yutto.utils.console.formatter import repair_filename
|
||||
from yutto.utils.console.logger import Badge, Logger
|
||||
from yutto.utils.functiontools.sync import sync
|
||||
|
||||
|
||||
def add_get_arguments(parser: argparse.ArgumentParser):
|
||||
|
@ -20,10 +29,17 @@ def add_get_arguments(parser: argparse.ArgumentParser):
|
|||
|
||||
@sync
|
||||
async def run(args: argparse.Namespace):
|
||||
# args.sessdata = "0a7f9758%2C1629361847%2Ca86ac*21"
|
||||
# # args.sessdata = ""
|
||||
# sessdata = "0a7f9758%2C1629361847%2Ca86ac*21"
|
||||
# # sessdata = "dfasdlfsa"
|
||||
async with aiohttp.ClientSession(
|
||||
headers=gen_headers(), cookies=gen_cookies(args.sessdata), timeout=aiohttp.ClientTimeout(total=5)
|
||||
headers=gen_headers(),
|
||||
cookies=gen_cookies(args.sessdata),
|
||||
cookie_jar=aiohttp.DummyCookieJar(),
|
||||
timeout=aiohttp.ClientTimeout(total=5),
|
||||
) as session:
|
||||
if match_obj := regexp_bangumi_ep.match(args.url):
|
||||
if (match_obj := regexp_bangumi_ep.match(args.url)) or (match_obj := regexp_bangumi_ep_short.match(args.url)):
|
||||
episode_id = EpisodeId(match_obj.group("episode_id"))
|
||||
season_id = await get_season_id_by_episode_id(session, episode_id)
|
||||
bangumi_list = await get_bangumi_list(session, season_id)
|
||||
|
@ -37,7 +53,27 @@ async def run(args: argparse.Namespace):
|
|||
Logger.error("在列表中未找到该剧集")
|
||||
sys.exit(1)
|
||||
videos, audios = await get_bangumi_playurl(session, avid, episode_id, cid)
|
||||
# title = await get_bangumi_title(session, season_id)
|
||||
title = await get_bangumi_title(session, season_id)
|
||||
Logger.custom(title, Badge("番剧", fore="black", back="cyan"))
|
||||
elif (
|
||||
(match_obj := regexp_acg_video_av.match(args.url))
|
||||
or (match_obj := regexp_acg_video_av_short.match(args.url))
|
||||
or (match_obj := regexp_acg_video_bv.match(args.url))
|
||||
or (match_obj := regexp_acg_video_bv_short.match(args.url))
|
||||
):
|
||||
page: int = 1
|
||||
if "aid" in match_obj.groupdict().keys():
|
||||
avid = AId(match_obj.group("aid"))
|
||||
else:
|
||||
avid = BvId(match_obj.group("bvid"))
|
||||
if match_obj.group("page") is not None:
|
||||
page = int(match_obj.group("page"))
|
||||
acg_video_list = await get_acg_video_list(session, avid)
|
||||
cid = acg_video_list[page - 1]["cid"]
|
||||
filename = acg_video_list[page - 1]["name"]
|
||||
videos, audios = await get_acg_video_playurl(session, avid, cid)
|
||||
title = await get_acg_video_title(session, avid)
|
||||
Logger.custom(title, Badge("投稿视频", fore="black", back="cyan"))
|
||||
else:
|
||||
Logger.error("url 不正确~")
|
||||
sys.exit(1)
|
||||
|
|
|
@ -61,7 +61,7 @@ async def download_video(
|
|||
):
|
||||
video_path = os.path.join(output_dir, file_name + "_video.m4s")
|
||||
audio_path = os.path.join(output_dir, file_name + "_audio.m4s")
|
||||
output_path = os.path.join(output_dir, file_name + "{output_format}")
|
||||
output_path_template = os.path.join(output_dir, file_name + "{output_format}")
|
||||
ffmpeg = FFmpeg()
|
||||
|
||||
# TODO: 显示全部 Videos、Audios 信息
|
||||
|
@ -69,6 +69,12 @@ async def download_video(
|
|||
audio = select_audio(audios, options["require_audio"], options["audio_quality"], options["audio_download_codec"])
|
||||
# TODO: 显示被选中的 Video、Audio 信息
|
||||
|
||||
output_format = ".mp4" if video is not None else ".aac"
|
||||
output_path = output_path_template.format(output_format=output_format)
|
||||
if not options["overwrite"] and os.path.exists(output_path):
|
||||
Logger.info("文件 {} 已存在".format(file_name))
|
||||
return
|
||||
|
||||
# idx_video = -1
|
||||
# if video is not None:
|
||||
# idx_video = videos.index(video)
|
||||
|
@ -146,8 +152,8 @@ async def download_video(
|
|||
"-acodec", options["audio_save_codec"],
|
||||
])
|
||||
args.extend(["-y"])
|
||||
output_format = ".mp4" if video is not None else ".aac"
|
||||
args.append(output_path.format(output_format=output_format))
|
||||
|
||||
args.append(output_path)
|
||||
Logger.debug("FFmpeg > ffmpeg {}".format(" ".join(args)))
|
||||
ffmpeg.exec(args)
|
||||
# fmt: on
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import re
|
||||
|
||||
# avid
|
||||
regexp_acg_video_av = re.compile(r"https?://(www\.|m\.)?bilibili\.com/video/av(?P<avid>\d+)")
|
||||
regexp_acg_video_av_short = re.compile(r"https?://b23\.tv/av(?P<avid>\d+)")
|
||||
regexp_acg_video_av = re.compile(r"https?://(www\.|m\.)?bilibili\.com/video/av(?P<aid>\d+)(\?p=(?P<page>\d+))?")
|
||||
regexp_acg_video_av_short = re.compile(r"https?://b23\.tv/av(?P<aid>\d+)(\?p=(?P<page>\d+))?")
|
||||
|
||||
# bvid
|
||||
regexp_acg_video_bv = re.compile(r"https?://(www\.|m\.)?bilibili\.com/video/(?P<bvid>(bv|BV)\w+)")
|
||||
regexp_acg_video_bv_short = re.compile(r"https?://b23\.tv/(?P<bvid>(bv|BV)\w+)")
|
||||
regexp_acg_video_bv = re.compile(r"https?://(www\.|m\.)?bilibili\.com/video/(?P<bvid>(bv|BV)\w+)(\?p=(?P<page>\d+))?")
|
||||
regexp_acg_video_bv_short = re.compile(r"https?://b23\.tv/(?P<bvid>(bv|BV)\w+)(\?p=(?P<page>\d+))?")
|
||||
|
||||
# media id
|
||||
regexp_bangumi_md = re.compile(r"https?://(www\.|m\.)?bilibili\.com/bangumi/media/md(?P<media_id>\d+)")
|
||||
|
|
Loading…
Reference in New Issue