mirror of
https://github.com/xhlove/GetDanMu.git
synced 2025-12-18 00:55:57 +08:00
新增芒果TV支持
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
'''
|
'''
|
||||||
# 作者: weimo
|
# 作者: weimo
|
||||||
# 创建日期: 2020-01-04 19:14:39
|
# 创建日期: 2020-01-04 19:14:39
|
||||||
# 上次编辑时间 : 2020-01-16 20:15:52
|
# 上次编辑时间 : 2020-01-28 18:39:00
|
||||||
# 一个人的命运啊,当然要靠自我奋斗,但是...
|
# 一个人的命运啊,当然要靠自我奋斗,但是...
|
||||||
'''
|
'''
|
||||||
|
|
||||||
@@ -15,6 +15,7 @@ from sites.qq import main as qq
|
|||||||
from sites.iqiyi import main as iqiyi
|
from sites.iqiyi import main as iqiyi
|
||||||
from sites.youku import main as youku
|
from sites.youku import main as youku
|
||||||
from sites.sohu import main as sohu
|
from sites.sohu import main as sohu
|
||||||
|
from sites.mgtv import main as mgtv
|
||||||
from pfunc.cfunc import check_url_site
|
from pfunc.cfunc import check_url_site
|
||||||
|
|
||||||
# -------------------------------------------
|
# -------------------------------------------
|
||||||
@@ -32,7 +33,7 @@ def main():
|
|||||||
parser.add_argument("-f", "--font", default="微软雅黑", help="指定输出字幕字体")
|
parser.add_argument("-f", "--font", default="微软雅黑", help="指定输出字幕字体")
|
||||||
parser.add_argument("-fs", "--font-size", default=28, help="指定输出字幕字体大小")
|
parser.add_argument("-fs", "--font-size", default=28, help="指定输出字幕字体大小")
|
||||||
parser.add_argument("-s", "--site", default="", help="指定网站")
|
parser.add_argument("-s", "--site", default="", help="指定网站")
|
||||||
parser.add_argument("-cid", "--cid", default="", help="下载cid对应视频的弹幕(腾讯视频合集)")
|
parser.add_argument("-cid", "--cid", default="", help="下载cid对应视频的弹幕(腾讯 芒果视频合集)")
|
||||||
parser.add_argument("-vid", "--vid", default="", help="下载vid对应视频的弹幕,支持同时多个vid,需要用逗号隔开")
|
parser.add_argument("-vid", "--vid", default="", help="下载vid对应视频的弹幕,支持同时多个vid,需要用逗号隔开")
|
||||||
parser.add_argument("-aid", "--aid", default="", help="下载aid对应视频的弹幕(爱奇艺合集)")
|
parser.add_argument("-aid", "--aid", default="", help="下载aid对应视频的弹幕(爱奇艺合集)")
|
||||||
parser.add_argument("-tvid", "--tvid", default="", help="下载tvid对应视频的弹幕,支持同时多个tvid,需要用逗号隔开")
|
parser.add_argument("-tvid", "--tvid", default="", help="下载tvid对应视频的弹幕,支持同时多个tvid,需要用逗号隔开")
|
||||||
@@ -68,6 +69,8 @@ def main():
|
|||||||
subtitles = youku(args)
|
subtitles = youku(args)
|
||||||
if args.site == "sohu":
|
if args.site == "sohu":
|
||||||
subtitles = sohu(args)
|
subtitles = sohu(args)
|
||||||
|
if args.site == "mgtv":
|
||||||
|
subtitles = mgtv(args)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# 打包 --> pyinstaller GetDanMu.spec
|
# 打包 --> pyinstaller GetDanMu.spec
|
||||||
|
|||||||
16
README.md
16
README.md
@@ -11,6 +11,18 @@
|
|||||||
| **爱奇艺** | <https://www.iqiyi.com/> |✓|✓|✓|
|
| **爱奇艺** | <https://www.iqiyi.com/> |✓|✓|✓|
|
||||||
| **优酷** | <https://v.youku.com/> |✓|✓|✓|
|
| **优酷** | <https://v.youku.com/> |✓|✓|✓|
|
||||||
| **搜狐视频** | <https://tv.sohu.com/> |✓|✓||
|
| **搜狐视频** | <https://tv.sohu.com/> |✓|✓||
|
||||||
|
| **芒果TV** | <https://www.mgtv.com/> |✓|✓|✓|
|
||||||
|
|
||||||
|
# 使用示例
|
||||||
|
- 命令(建议)
|
||||||
|
|
||||||
|
> GetDanMu.exe -u https://www.mgtv.com/b/334727/7452407.html
|
||||||
|
|
||||||
|
- 双击运行
|
||||||
|
> 提示逻辑有待完善
|
||||||
|
|
||||||
|
# 效果示意(字幕与视频不相关)
|
||||||
|

|
||||||
|
|
||||||
## 可能存在的问题
|
## 可能存在的问题
|
||||||
- 下载进度接近100%时暂时没有反应
|
- 下载进度接近100%时暂时没有反应
|
||||||
@@ -22,6 +34,10 @@
|
|||||||
|
|
||||||
# 更新日志
|
# 更新日志
|
||||||
|
|
||||||
|
## 2020/1/28
|
||||||
|
- 增加芒果TV的支持(支持综艺合集、支持series命令)
|
||||||
|
- 爱奇艺bug修复
|
||||||
|
|
||||||
## 2020/1/16
|
## 2020/1/16
|
||||||
- 增加搜狐视频的支持(剧集)
|
- 增加搜狐视频的支持(剧集)
|
||||||
- 改进输入提示(双击运行时)
|
- 改进输入提示(双击运行时)
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
'''
|
'''
|
||||||
# 作者: weimo
|
# 作者: weimo
|
||||||
# 创建日期: 2020-01-04 19:14:35
|
# 创建日期: 2020-01-04 19:14:35
|
||||||
# 上次编辑时间 : 2020-01-16 19:10:06
|
# 上次编辑时间 : 2020-01-28 17:43:44
|
||||||
# 一个人的命运啊,当然要靠自我奋斗,但是...
|
# 一个人的命运啊,当然要靠自我奋斗,但是...
|
||||||
'''
|
'''
|
||||||
|
|
||||||
ALLOW_SITES = ["qq", "iqiyi", "youku", "sohu"]
|
ALLOW_SITES = ["qq", "iqiyi", "youku", "sohu", "mgtv"]
|
||||||
|
|
||||||
qqlive = {
|
qqlive = {
|
||||||
"User-Agent":"qqlive"
|
"User-Agent":"qqlive"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
'''
|
'''
|
||||||
# 作者: weimo
|
# 作者: weimo
|
||||||
# 创建日期: 2020-01-04 19:14:43
|
# 创建日期: 2020-01-04 19:14:43
|
||||||
# 上次编辑时间 : 2020-01-21 12:36:47
|
# 上次编辑时间 : 2020-01-28 18:38:32
|
||||||
# 一个人的命运啊,当然要靠自我奋斗,但是...
|
# 一个人的命运啊,当然要靠自我奋斗,但是...
|
||||||
'''
|
'''
|
||||||
import re
|
import re
|
||||||
@@ -113,7 +113,7 @@ def matchit(patterns, text):
|
|||||||
break
|
break
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def duration_to_sec(duration):
|
def duration_to_sec(duration: str):
|
||||||
return sum(x * int(t) for x, t in zip([3600, 60, 1][2 - duration.count(":"):], duration.split(":")))
|
return sum(x * int(t) for x, t in zip([3600, 60, 1][2 - duration.count(":"):], duration.split(":")))
|
||||||
|
|
||||||
def get_year_range(aid, locale="zh_cn"):
|
def get_year_range(aid, locale="zh_cn"):
|
||||||
|
|||||||
207
sites/mgtv.py
Normal file
207
sites/mgtv.py
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
#!/usr/bin/env python3.7
|
||||||
|
# coding=utf-8
|
||||||
|
'''
|
||||||
|
# 作者: weimo
|
||||||
|
# 创建日期: 2020-01-28 15:55:22
|
||||||
|
# 上次编辑时间 : 2020-01-28 19:57:57
|
||||||
|
# 一个人的命运啊,当然要靠自我奋斗,但是...
|
||||||
|
'''
|
||||||
|
import re
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import base64
|
||||||
|
import requests
|
||||||
|
from uuid import uuid4
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
from basic.vars import chrome
|
||||||
|
from pfunc.request_info import duration_to_sec
|
||||||
|
from pfunc.dump_to_ass import check_file, write_one_video_subtitles
|
||||||
|
|
||||||
|
pno_params = {
|
||||||
|
"pad":"1121",
|
||||||
|
"ipad":"1030"
|
||||||
|
}
|
||||||
|
type_params = {
|
||||||
|
"h5flash":"h5flash",
|
||||||
|
"padh5":"padh5",
|
||||||
|
"pch5":"pch5"
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_danmu_by_vid(vid: str, cid: str, duration: int):
|
||||||
|
api_url = "https://galaxy.bz.mgtv.com/rdbarrage"
|
||||||
|
params = OrderedDict({
|
||||||
|
"version": "2.0.0",
|
||||||
|
"vid": vid,
|
||||||
|
"abroad": "0",
|
||||||
|
"pid": "",
|
||||||
|
"os": "",
|
||||||
|
"uuid": "",
|
||||||
|
"deviceid": "",
|
||||||
|
"cid": cid,
|
||||||
|
"ticket": "",
|
||||||
|
"time": "0",
|
||||||
|
"mac": "",
|
||||||
|
"platform": "0",
|
||||||
|
"callback": ""
|
||||||
|
})
|
||||||
|
comments = []
|
||||||
|
index = 0
|
||||||
|
max_index = duration // 60 + 1
|
||||||
|
while index < max_index:
|
||||||
|
params["time"] = str(index * 60 * 1000)
|
||||||
|
try:
|
||||||
|
r = requests.get(api_url, params=params, headers=chrome, timeout=3).content.decode("utf-8")
|
||||||
|
except Exception as e:
|
||||||
|
continue
|
||||||
|
items = json.loads(r)["data"]["items"]
|
||||||
|
index += 1
|
||||||
|
if items is None:
|
||||||
|
continue
|
||||||
|
for item in items:
|
||||||
|
comments.append([item["content"], ["ffffff"], int(item["time"] / 1000)])
|
||||||
|
print("已下载{:.2f}%".format(index / max_index * 100))
|
||||||
|
return comments
|
||||||
|
|
||||||
|
def get_tk2(did):
|
||||||
|
pno = pno_params["ipad"]
|
||||||
|
ts = str(int(time.time()))
|
||||||
|
text = f"did={did}|pno={pno}|ver=0.3.0301|clit={ts}"
|
||||||
|
tk2 = base64.b64encode(text.encode("utf-8")).decode("utf-8").replace("+", "_").replace("/", "~").replace("=", "-")
|
||||||
|
return tk2[::-1]
|
||||||
|
|
||||||
|
def get_vinfos_by_cid_or_vid(xid: str, flag="vid"):
|
||||||
|
api_url = "https://pcweb.api.mgtv.com/episode/list"
|
||||||
|
params = {
|
||||||
|
"video_id": xid,
|
||||||
|
"page": "0",
|
||||||
|
"size": "25",
|
||||||
|
"cxid": "",
|
||||||
|
"version": "5.5.35",
|
||||||
|
"callback": "",
|
||||||
|
"_support": "10000000",
|
||||||
|
"_": str(int(time.time() * 1000))
|
||||||
|
}
|
||||||
|
if flag == "cid":
|
||||||
|
_ = params.pop("video_id")
|
||||||
|
params["collection_id"] = xid
|
||||||
|
page = 1
|
||||||
|
vinfos = []
|
||||||
|
while True:
|
||||||
|
params["page"] = page
|
||||||
|
try:
|
||||||
|
r = requests.get(api_url, params=params, headers=chrome, timeout=3).content.decode("utf-8")
|
||||||
|
except Exception as e:
|
||||||
|
continue
|
||||||
|
data = json.loads(r)["data"]
|
||||||
|
for ep in data["list"]:
|
||||||
|
if re.match("\d\d\d\d-\d\d-\d\d", ep["t4"]):
|
||||||
|
# 综艺的加上日期
|
||||||
|
name = "{t4}_{t3}_{t2}".format(**ep).replace(" ", "")
|
||||||
|
else:
|
||||||
|
name = "{t3}_{t2}".format(**ep).replace(" ", "")
|
||||||
|
duration = duration_to_sec(ep["time"])
|
||||||
|
vinfos.append([name, duration, ep["video_id"], ep["clip_id"]])
|
||||||
|
if page < data["count"] // 25 + 1:
|
||||||
|
page += 1
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
return vinfos
|
||||||
|
|
||||||
|
def get_vinfo_by_vid(vid: str):
|
||||||
|
api_url = "https://pcweb.api.mgtv.com/player/video"
|
||||||
|
type_ = type_params["pch5"]
|
||||||
|
did = uuid4().__str__()
|
||||||
|
suuid = uuid4().__str__()
|
||||||
|
params = OrderedDict({
|
||||||
|
"did": did,
|
||||||
|
"suuid": suuid,
|
||||||
|
"cxid": "",
|
||||||
|
"tk2": get_tk2(did),
|
||||||
|
"video_id": vid,
|
||||||
|
"type": type_,
|
||||||
|
"_support": "10000000",
|
||||||
|
"auth_mode": "1",
|
||||||
|
"callback": ""
|
||||||
|
})
|
||||||
|
try:
|
||||||
|
r = requests.get(api_url, params=params, headers=chrome, timeout=3).content.decode("utf-8")
|
||||||
|
except Exception as e:
|
||||||
|
return
|
||||||
|
info = json.loads(r)["data"]["info"]
|
||||||
|
name = "{title}_{series}_{desc}".format(**info).replace(" ", "")
|
||||||
|
duration = int(info["duration"])
|
||||||
|
cid = info["collection_id"]
|
||||||
|
return [name, duration, vid, cid]
|
||||||
|
|
||||||
|
def get_vinfos_by_url(url: str, isall: bool):
|
||||||
|
vinfos = []
|
||||||
|
# url = https://www.mgtv.com/b/323323/4458375.html
|
||||||
|
ids = re.match("[\s\S]+?mgtv.com/b/(\d+)/(\d+)\.html", url)
|
||||||
|
# url = "https://www.mgtv.com/h/333999.html?fpa=se"
|
||||||
|
cid_v1 = re.match("[\s\S]+?mgtv.com/h/(\d+)\.html", url)
|
||||||
|
# url = "https://m.mgtv.com/h/333999/0.html"
|
||||||
|
cid_v2 = re.match("[\s\S]+?mgtv.com/h/(\d+)/\d\.html", url)
|
||||||
|
if ids is None and cid_v1 is None and cid_v2 is None:
|
||||||
|
return
|
||||||
|
if ids and ids.groups().__len__() == 2:
|
||||||
|
cid, vid = ids.groups()
|
||||||
|
if isall:
|
||||||
|
vi = get_vinfos_by_cid_or_vid(vid)
|
||||||
|
if vi:
|
||||||
|
vinfos += vi
|
||||||
|
else:
|
||||||
|
vinfo = get_vinfo_by_vid(vid)
|
||||||
|
if vinfo is None:
|
||||||
|
return
|
||||||
|
vinfos.append(vinfo)
|
||||||
|
print("ccc", cid_v1)
|
||||||
|
if cid_v1 or cid_v2:
|
||||||
|
if cid_v2 is None:
|
||||||
|
cid = cid_v1.group(1)
|
||||||
|
else:
|
||||||
|
cid = cid_v2.group(1)
|
||||||
|
vi = get_vinfos_by_cid_or_vid(cid, flag="cid")
|
||||||
|
if vi:
|
||||||
|
vinfos += vi
|
||||||
|
return vinfos
|
||||||
|
|
||||||
|
def main(args):
|
||||||
|
vinfos = []
|
||||||
|
isall = False
|
||||||
|
if args.series:
|
||||||
|
isall = True
|
||||||
|
if args.url:
|
||||||
|
vi = get_vinfos_by_url(args.url, isall)
|
||||||
|
if vi:
|
||||||
|
vinfos += vi
|
||||||
|
if args.vid:
|
||||||
|
if isall:
|
||||||
|
vi = get_vinfos_by_cid_or_vid(args.vid)
|
||||||
|
if vi:
|
||||||
|
vinfos += vi
|
||||||
|
else:
|
||||||
|
vi = get_vinfo_by_vid(args.vid)
|
||||||
|
if vi:
|
||||||
|
vinfos.append(vi)
|
||||||
|
if args.cid:
|
||||||
|
vi = get_vinfos_by_cid_or_vid(args.cid)
|
||||||
|
if vi:
|
||||||
|
vinfos += vi
|
||||||
|
subtitles = {}
|
||||||
|
for name, duration, vid, cid in vinfos:
|
||||||
|
print(name, "开始下载...")
|
||||||
|
flag, file_path = check_file(name, args)
|
||||||
|
if flag is False:
|
||||||
|
print("跳过{}".format(name))
|
||||||
|
continue
|
||||||
|
comments = get_danmu_by_vid(vid, cid, duration)
|
||||||
|
write_one_video_subtitles(file_path, comments, args)
|
||||||
|
subtitles.update({file_path:comments})
|
||||||
|
print(name, "下载完成!")
|
||||||
|
return subtitles
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
args = object()
|
||||||
|
args.url = "https://www.mgtv.com/h/333999.html?fpa=se"
|
||||||
|
main(args)
|
||||||
Reference in New Issue
Block a user