Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,6 @@ cd 目录名
python getVideo.py

# 运行成功后,通过GUI操作即可
如果需要使用cookie,在输入框输入以下内容,每一项都可以在F12内找到,替换为自己的:
SESSDATA=; bili_jct=; DedeUserID=; DedeUserID__ckMd5=;
```
75 changes: 67 additions & 8 deletions 13.一键获取B站视频内容并下载(含GUI界面)/getVideo.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import tkinter as tk
from tkinter import ttk, messagebox
import unicodedata
import platform

# 输入cookie以获取更优画质的视频,默认下载最优画质。
headers = {
Expand Down Expand Up @@ -40,11 +41,40 @@ def get_info(html_url):
title = sanitize_filename(title)
else:
title = 'bili_video'
# 提取视频内容
html_data = re.findall('window.__playinfo__=(.*?)</script>', response.text)[0]
json_data = json.loads(html_data)
audio_url = json_data['data']['dash']['audio'][0]['baseUrl']
video_url = json_data['data']['dash']['video'][0]['baseUrl']

# 先尝试普通方式
playinfo_match = re.findall(r'window\.__playinfo__=(\{.*?\})</script>', response.text)
if playinfo_match:
json_data = json.loads(playinfo_match[0])
data = json_data.get("data")
else:
# 检查是不是 bangumi/ep 页面
ep_match = re.search(r'/ep(\d+)', html_url)
if not ep_match:
raise Exception("未找到视频信息,无法解析。")
ep_id = ep_match.group(1)
api_url = f"https://api.bilibili.com/pgc/player/web/playurl?ep_id={ep_id}&qn=80&fnval=4048"
api_response = requests.get(api_url, headers=headers)
json_data = api_response.json()
if json_data.get('code') != 0:
raise Exception("番剧接口返回异常,无法下载。")
# 关键处:番剧接口返回的是 result 字段
data = json_data.get("result")
if not data:
raise Exception("未找到视频流信息。")

# 优先使用 dash 流
if "dash" in data:
dash = data["dash"]
audio_url = dash['audio'][0]['baseUrl']
video_url = dash['video'][0]['baseUrl']
# 兼容部分没有 dash 的番剧(有些接口只返回 durl)
elif "durl" in data:
# 这里只能下载合成流(无独立音频)
video_url = data["durl"][0]["url"]
audio_url = video_url # 没有独立音频
else:
raise Exception("未找到视频流(dash/durl)信息。")
return [title, audio_url, video_url]


Expand Down Expand Up @@ -76,12 +106,34 @@ def save(title, audio_url, video_url, update_progress):

def merge_data(title, update_progress):
os.makedirs("video", exist_ok=True)
command = f'ffmpeg -y -i "{title}_only.mp4" -i "{title}_only.mp3" -c:v copy -c:a aac -strict experimental "./video/{title}.mp4"'
# 检测 ffmpeg 路径
ffmpeg_path = get_ffmpeg_path()
command = f'"{ffmpeg_path}" -y -i "{title}_only.mp4" -i "{title}_only.mp3" -c:v copy -c:a aac -strict experimental "./video/{title}.mp4"'
update_progress("合并音视频...", 90)
subprocess.run(command, shell=True)
# 使用 errors='ignore' 或 errors='replace' 来处理编码错误
result = subprocess.run(command, shell=True, capture_output=True, text=True, encoding='utf-8', errors='replace')
if result.returncode != 0:
error_msg = f"FFmpeg 错误: {result.stderr}"
print(error_msg)
# 在GUI中显示错误
messagebox.showerror("错误", "音视频合并失败")
return False # 返回失败状态
update_progress("完成", 100)
os.remove(f'{title}_only.mp3')
os.remove(f'{title}_only.mp4')
return True # 返回成功状态

def get_ffmpeg_path():
project_dir = os.path.dirname(__file__)
if platform.system() == 'Windows':
ffmpeg_exe = 'ffmpeg.exe'
else:
ffmpeg_exe = 'ffmpeg'

project_ffmpeg = os.path.join(project_dir, 'ffmpeg', 'bin', ffmpeg_exe)
if os.path.exists(project_ffmpeg):
return project_ffmpeg
return ffmpeg_exe


# GUI部分
Expand All @@ -93,6 +145,9 @@ def start_download():

def run():
try:
# 动态设置cookie
headers['cookie'] = cookie_entry.get().strip()

download_button.config(state="disabled")
progress_label.config(text="解析中...")
progress_bar["value"] = 0
Expand All @@ -118,13 +173,17 @@ def update_progress(text, percent):
# 创建窗口
root = tk.Tk()
root.title("B站视频下载器")
root.geometry("400x200")
root.geometry("400x250")

tk.Label(root, text="请输入B站视频URL:").pack(pady=5)

url_entry = tk.Entry(root, width=50)
url_entry.pack(pady=5)

tk.Label(root, text="(可选)请输入B站 Cookie:").pack(pady=5)
cookie_entry = tk.Entry(root, width=50)
cookie_entry.pack(pady=5)

download_button = tk.Button(root, text="下载", command=start_download)
download_button.pack(pady=5)

Expand Down