Skip to content

Instantly share code, notes, and snippets.

@zhongfly
Last active November 10, 2021 11:51
Show Gist options
  • Save zhongfly/c6b419312da5fafc9afdf809b257137b to your computer and use it in GitHub Desktop.
Save zhongfly/c6b419312da5fafc9afdf809b257137b to your computer and use it in GitHub Desktop.
B站国际版简中字幕下载
# -*- encoding: utf-8 -*-
# python3.6
import json
import os
import requests
th_api = "https://api.biliintl.com"
BangumiInfoUrl = th_api + "/intl/gateway/web/view/ogv_collection"
SubInfoUrl = th_api + "/intl/gateway/v2/app/subtitle"
th_api_proxy = "https://api.global.bilibili.com" # 可用漫游代理https://github.com/yujincheng08/BiliRoaming/wiki/
BangumiInfoUrl_proxy = th_api_proxy + "/intl/gateway/v2/ogv/view/app/season"
def download(url, path):
r = requests.get(url, stream=True)
r.raise_for_status()
f = open(path, "wb")
for chunk in r.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
f.close()
def getBangumiInfo(season_id):
r = requests.get(
BangumiInfoUrl,
params={"season_id": int(season_id), "s_locale": "zh_Hans"},
).json()
if r["code"] == 0:
return r["data"]["episodes"]
else:
raise Exception(f'Warn: getBangumiInfo for {season_id} message:{r["message"]}')
def getSubUrl(ep_id):
r = requests.get(
SubInfoUrl,
params={"ep_id": int(ep_id), "s_locale": "zh_Hans"},
).json()
if r["code"] == 0:
if r["data"]["suggest_key"] == "zh-Hans":
return r["data"]["subtitles"][0]["url"]
else:
raise Exception(f"Warn: getSubUrl for {ep_id} message:无中文简体字幕")
else:
raise Exception(f'Warn: getSubUrl for {ep_id} message:{r["message"]}')
def printBangumiInfo(episodesData):
for (ord, episode) in enumerate(episodesData, start=1):
print(
f"{ord:<3} 剧集id:{episode['ep_id']},剧集名:{episode['title']} {episode['long_title']}"
)
def downloadSub(season_id):
episodesData = getBangumiInfo(season_id=season_id)
printBangumiInfo(episodesData)
ep_ord = int(input("请输入需要下载的剧集对应的序号:")) - 1
ep = episodesData[ep_ord]
url = getSubUrl(ep["ep_id"])
path = f"{ep['title']} {ep['long_title']}.json"
download(url, path)
return path
def getBangumiInfo_proxy(season_id):
r = requests.get(
BangumiInfoUrl_proxy,
params={
"area": "th",
"s_locale": "zh_SG",
"access_key": "2021",
"season_id": season_id,
"mobi_app": "bstar_a",
"build": "1080003",
},
headers={"http_x_from_biliroaming": "*"},
)
result = r.json()
if result["code"] == 0:
return result["result"]["modules"][0]["data"]["episodes"]
else:
raise Exception(
f'Warn: getSubUrl_proxy for {season_id} message:{result["message"]}'
)
def printBangumiInfo_proxy(episodesData):
for (ord, episode) in enumerate(episodesData, start=1):
sub_keys = ""
for sub in episode["subtitles"]:
sub_keys +=f"{sub['key']} "
print(f"{ord:<3} 剧集id:{episode['id']},剧集名:{episode['long_title_display']},语言:{sub_keys.rstrip()}")
def downloadSub_proxy(season_id):
episodesData = getBangumiInfo_proxy(season_id)
printBangumiInfo_proxy(episodesData)
ep_ord = int(input("请输入需要下载的剧集对应的序号:")) - 1
ep = episodesData[ep_ord]
for sub in ep["subtitles"]:
if sub["key"] == "zh-Hans":
url = sub["url"]
path = f"{ep['long_title_display']}.json"
download(url, path)
return path
sub_keys = ""
for sub in ep["subtitles"]:
sub_keys +=f"{sub['key']} "
print(f"Warn: downloadSub_proxy for {season_id} message:无中文简体字幕,有以下语言:{sub_keys.rstrip()}")
# 以下代码来自https://github.com/y2361547758/bcc2ass/blob/master/bcc2ass.py
def sec2time(sec, type=""):
h = int(sec) // 3600
m = int(sec) // 60 % 60
s = sec % 60
f = int(sec * 1000) % 1000
if type == "srt":
return "%02d:%02d:%02d,%03d" % (h, m, int(s), f)
elif type == "ass":
return "%d:%02d:%02d.%02d" % (h, m, s, f // 10)
elif type == "lrc":
return "%02d:%02d.%02d" % (int(sec) // 60, s, f // 10)
return "%02d:%02d:%02.2f" % (h, m, s)
def color2asscolor(color, alpha=0):
return ("&H%02X" % alpha) + color[1:]
def bcc2ass(bcc_file, type):
font_size_ratio = 50
with open(bcc_file, encoding="utf-8") as f:
bcc = json.load(f)
output = f"{os.path.splitext(bcc_file)[0]}.{type}"
with open(output, "w", encoding="utf-8") as f:
count = 1
if type == "ass":
print("[V4+ Styles]", file=f)
print(
"Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding",
file=f,
)
location = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0}
Alignment = 2
for i in bcc["body"]:
location[i["location"]] += 1
if location[Alignment] < location[i["location"]]:
Alignment = i["location"]
print(
"Style: Default",
"Arial",
"%d" % (bcc["font_size"] * font_size_ratio),
color2asscolor(bcc["font_color"]),
"&H000000FF",
color2asscolor(
bcc["background_color"], int(bcc["background_alpha"] * 0xFF)
),
"&H00000000,0,0,0,0,100,100,0,0,1,2,2,%d,10,10,10,1" % Alignment,
sep=",",
file=f,
)
print(file=f)
print("[Events]", file=f)
print(
"Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text",
file=f,
)
for i in bcc["body"]:
if type == "srt":
print(count, file=f)
print(
sec2time(i["from"], type) + " --> " + sec2time(i["to"], type),
file=f,
)
print(i["content"], file=f)
print(file=f)
count += 1
elif type == "ass":
align = "" if i["location"] == Alignment else "{\\a%d}" % i["location"]
print(
"Dialogue: 0,"
+ sec2time(i["from"], type)
+ ","
+ sec2time(i["to"], type)
+ ",Default,,0,0,0,,"
+ align
+ i["content"].replace("\n", r"\N"),
file=f,
)
if __name__ == "__main__":
while True:
try:
# season_id = 1010919
season_id = int(input("请输入番剧season_id:"))
# bcc_file = downloadSub(season_id)
bcc_file = downloadSub_proxy(season_id)
bcc2ass(bcc_file, "srt")
except Exception as e:
print(e)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment