Files
GetDanMu/sites/qq.py
2020-01-11 17:57:51 +08:00

164 lines
5.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3.7
# coding=utf-8
'''
# 作者: weimo
# 创建日期: 2020-01-04 19:14:37
# 上次编辑时间 : 2020-01-11 17:25:34
# 一个人的命运啊,当然要靠自我奋斗,但是...
'''
import os
import sys
import json
import requests
from basic.vars import qqlive
from pfunc.dump_to_ass import check_file, write_one_video_subtitles
from pfunc.request_info import get_all_vids_by_cid as get_vids
from pfunc.request_info import get_danmu_target_id_by_vid as get_target_id
def get_video_info_by_vid(vids: list):
idlist = ",".join(vids)
api_url = "http://union.video.qq.com/fcgi-bin/data"
params = {
"tid":"98",
"appid":"10001005",
"appkey":"0d1a9ddd94de871b",
"idlist":f"{idlist}",
"otype":"json"
}
try:
r = requests.get(api_url, params=params, headers=qqlive).content.decode("utf-8")
except Exception as e:
print("error info -->", e)
return
data = json.loads(r.lstrip("QZOutputJson=").rstrip(";"))
if not data.get("results"):
return
subkey = ["title", "episode", "langue", "duration"]
vinfos = []
for index, item in enumerate(data["results"]):
vid = [vids[index]]
values = [str(item["fields"][key]) for key in subkey if item["fields"].get(key) is not None]
name = "_".join(values)
if item["fields"].get("duration"):
duration = int(item["fields"]["duration"])
else:
duration = 0
# target_id = item["fields"]["targetid"] # 这个target_id一般不是弹幕用的
target_id = get_target_id(vid)
if target_id is None:
continue
vinfos.append([vid, name, duration, target_id])
# print(vinfos)
return vinfos
def get_danmu_by_target_id(vid: str, duration: int, target_id, font="微软雅黑", font_size=25):
# timestamp间隔30s 默认从15开始
api_url = "https://mfm.video.qq.com/danmu"
params = {
"otype":"json",
"target_id":"{}&vid={}".format(target_id, vid),
"session_key":"0,0,0",
"timestamp":15
}
# subtitle = ASS(file_path, font=font, font_size=font_size)
comments = []
while params["timestamp"] < duration:
try:
r = requests.get(api_url, params=params, headers=qqlive).content.decode("utf-8")
except Exception as e:
print("error info -->", e)
continue
try:
danmu = json.loads(r)
except Exception as e:
danmu = json.loads(r, strict=False)
if danmu.get("count") is None:
# timestamp不变 再试一次
continue
danmu_count = danmu["count"]
for comment in danmu["comments"]:
if comment["content_style"]:
style = json.loads(comment["content_style"])
if style.get("gradient_colors"):
color = style["gradient_colors"]
elif style.get("color"):
color = style["color"]
else:
color = ["ffffff"]
else:
color = ["ffffff"]
comments.append([comment["content"], color, comment["timepoint"]])
print("已下载{:.2f}%".format(params["timestamp"]*100/duration))
params["timestamp"] += 30
comments = sorted(comments, key=lambda _: _[-1])
return comments
def get_one_subtitle_by_vinfo(vinfo, font="微软雅黑", font_size=25, skip=False):
vid, name, duration, target_id = vinfo
print(name, "开始下载...")
flag, file_path = check_file(name, skip=skip)
if flag is False:
print("跳过{}".format(name))
return
comments = get_danmu_by_target_id(vid, duration, target_id, font=font, font_size=font_size)
# print("{}弹幕下载完成!".format(name))
return comments, file_path
def ask_input(url=""):
if url == "":
url = input("请输入vid/coverid/链接输入q退出\n").strip()
if url == "q" or url == "":
sys.exit("已结束")
# https://v.qq.com/x/cover/m441e3rjq9kwpsc/i0025secmkz.html
params = url.replace(".html", "").split("/")
if params[-1].__len__() == 11:
vids = [params[-1]]
elif params[-1].__len__() == 15:
cid = params[-1]
vids = get_vids(cid)
else:
vid = url.split("vid=")[-1]
if len(vid) != 11:
vid = vid.split("&")[0]
if len(vid) != 11:
sys.exit("没找到vid")
vids = [vid]
return vids
def main(args):
vids = []
if args.cid and args.cid.__len__() == 15:
vids += get_vids(args.cid)
if args.vid:
if args.vid.strip().__len__() == 11:
vids += [args.vid.strip()]
elif args.vid.strip().__len__() > 11:
vids += [vid for vid in args.vid.strip().replace(" ", "").split(",") if vid.__len__() == 11]
else:
pass
if args.url:
vids += ask_input(url=args.url)
if args.vid == "" and args.cid == "" and args.url == "":
vids += ask_input()
if vids.__len__() <= 0:
sys.exit("没有任何有效输入")
vinfos = get_video_info_by_vid(vids)
subtitles = {}
for vinfo in vinfos:
infos = get_one_subtitle_by_vinfo(vinfo, args.font, args.font_size, args.y)
if infos is None:
continue
comments, file_path = infos
comments = write_one_video_subtitles(file_path, comments, args)
subtitles.update({file_path:comments})
return subtitles
# if __name__ == "__main__":
# # 打包 --> pyinstaller -F .\qq.py -c -n GetDanMu_qq_1.1
# main()
# # subtitle = ASS()