feat: support acg_video

This commit is contained in:
SigureMo 2021-05-03 04:25:22 +08:00
parent 19d4144d05
commit 61e14ee053
No known key found for this signature in database
GPG Key ID: F99A3CD7BD76B247
5 changed files with 67 additions and 19 deletions

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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+)")