mirror of
https://github.com/amtoaer/bili-sync.git
synced 2026-05-11 10:00:18 +08:00
feat: 实现基本的下载功能
This commit is contained in:
6
constants.py
Normal file
6
constants.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
DEFAULT_CONFIG_PATH = Path(__file__).parent / "config.json"
|
||||
|
||||
FFMPEG_COMMAND = "ffmpeg"
|
||||
8
main.py
8
main.py
@@ -1,12 +1,10 @@
|
||||
import asyncio
|
||||
|
||||
from bilibili_api import favorite_list
|
||||
from processor import process
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
result = await favorite_list.get_video_favorite_list(9183758)
|
||||
print(result)
|
||||
await process()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.get_event_loop().run_until_complete(main())
|
||||
asyncio.run(main())
|
||||
|
||||
93
processor.py
Normal file
93
processor.py
Normal file
@@ -0,0 +1,93 @@
|
||||
from constants import FFMPEG_COMMAND
|
||||
from settings import settings
|
||||
from credential import credential
|
||||
from bilibili_api import favorite_list, video, HEADERS
|
||||
from pathlib import Path
|
||||
import httpx
|
||||
from asyncio import create_subprocess_exec
|
||||
from asyncio.subprocess import DEVNULL
|
||||
from loguru import logger
|
||||
|
||||
|
||||
async def download_content(url: str, path: Path):
|
||||
async with httpx.AsyncClient(headers=HEADERS) as sess:
|
||||
resp = await sess.get(url)
|
||||
with path.open("wb") as f:
|
||||
for chunk in resp.iter_bytes(1024):
|
||||
if not chunk:
|
||||
break
|
||||
f.write(chunk)
|
||||
|
||||
|
||||
async def process():
|
||||
for favorite_id in settings.favorite_ids:
|
||||
if favorite_id not in settings.path_mapper:
|
||||
logger.warning(f"Favorite {favorite_id} not in path mapper, ignored.")
|
||||
continue
|
||||
try:
|
||||
save_path = Path(settings.path_mapper[favorite_id])
|
||||
save_path.mkdir(parents=True, exist_ok=True)
|
||||
favorite_video_list = await favorite_list.get_video_favorite_list_content(
|
||||
favorite_id, credential=credential
|
||||
)
|
||||
logger.info(
|
||||
"start to process favorite {}", favorite_video_list["info"]["title"]
|
||||
)
|
||||
# TODO:
|
||||
# 1. 添加进度条
|
||||
# 2. 翻页以下载全部内容
|
||||
# 3. 对接数据库
|
||||
# 4. 构建 nfo
|
||||
for media in favorite_video_list["medias"][:8]:
|
||||
title = media["title"]
|
||||
final_path = save_path / f"{title}.mp4"
|
||||
if final_path.exists():
|
||||
logger.info(f"{final_path} already exists, skipped.")
|
||||
continue
|
||||
v = video.Video(media["bvid"], credential=credential)
|
||||
detector = video.VideoDownloadURLDataDetecter(
|
||||
await v.get_download_url(page_index=0)
|
||||
)
|
||||
streams = detector.detect_best_streams()
|
||||
if detector.check_flv_stream():
|
||||
tmp_path = save_path / f"{title}.flv"
|
||||
await download_content(streams[0].url, tmp_path)
|
||||
process = await create_subprocess_exec(
|
||||
FFMPEG_COMMAND,
|
||||
"-i",
|
||||
str(tmp_path),
|
||||
str(final_path),
|
||||
stdout=DEVNULL,
|
||||
stderr=DEVNULL,
|
||||
)
|
||||
await process.communicate()
|
||||
tmp_path.unlink()
|
||||
else:
|
||||
tmp_video_path, tmp_audio_path = (
|
||||
save_path / f"{title}_video.m4s",
|
||||
save_path / f"{title}_audio.m4s",
|
||||
)
|
||||
await download_content(streams[0].url, tmp_video_path)
|
||||
await download_content(streams[1].url, tmp_audio_path)
|
||||
# 混流
|
||||
process = await create_subprocess_exec(
|
||||
FFMPEG_COMMAND,
|
||||
"-i",
|
||||
str(tmp_video_path),
|
||||
"-i",
|
||||
str(tmp_audio_path),
|
||||
"-c",
|
||||
"copy",
|
||||
str(final_path),
|
||||
stdout=DEVNULL,
|
||||
stderr=DEVNULL,
|
||||
)
|
||||
await process.communicate()
|
||||
tmp_video_path.unlink()
|
||||
tmp_audio_path.unlink()
|
||||
|
||||
logger.info(f"{final_path} downloaded successfully.")
|
||||
|
||||
except Exception:
|
||||
logger.exception(f"Failed to process favorite {favorite_id}")
|
||||
continue
|
||||
Reference in New Issue
Block a user