1
0
mirror of https://github.com/wbt5/real-url.git synced 2025-07-29 21:00:30 +08:00

Compare commits

...

4 Commits

Author SHA1 Message Date
乌帮图
cab036f982
🐛修复虎牙一起看 2021-11-07 16:25:27 +08:00
wbt5
b42eefc357
💡 Update README.md 2021-11-07 16:04:01 +08:00
wbt5
2762543baa
Add 咪咕体育 (#273) 2021-11-07 16:01:46 +08:00
YJ1211
ea49dfd3c3 修复虎牙一起看 2021-10-30 16:31:11 +08:00
3 changed files with 162 additions and 55 deletions

View File

@ -10,7 +10,7 @@
目前已实现: 目前已实现:
**58** 个直播平台的直播源获取:斗鱼直播、虎牙直播、哔哩哔哩直播、战旗直播、网易 CC 直播、火猫直播、企鹅电竞、YY 直播、一直播、快手直播、花椒直播、映客直播、西瓜直播、触手直播已倒闭、NOW 直播、抖音直播爱奇艺直播、酷狗直播、龙珠直播、PPS 奇秀直播、六间房、17 直播、来疯直播、优酷轮播台、网易 LOOK 直播、千帆直播、陌陌直播、小米直播、迅雷直播、京东直播、企鹅体育、人人直播、棉花糖直播、九秀直播、羚萌直播、95秀、新浪疯播、红人直播、艾米直播、KK直播、酷我聚星、乐嗨直播、秀色直播、星光直播、我秀直播、热猫直播、艺气山直播、AcFun 直播、猫耳FM、畅秀阁、Twitch、TikTok、央视频、PP体育、zhibotv、腾讯体育直播、爱奇艺体育直播、liveU、bigolive。 **59** 个直播平台的直播源获取:斗鱼直播、虎牙直播、哔哩哔哩直播、战旗直播、网易 CC 直播、火猫直播、企鹅电竞、YY 直播、一直播、快手直播、花椒直播、映客直播、西瓜直播、触手直播已倒闭、NOW 直播、抖音直播爱奇艺直播、酷狗直播、龙珠直播、PPS 奇秀直播、六间房、17 直播、来疯直播、优酷轮播台、网易 LOOK 直播、千帆直播、陌陌直播、小米直播、迅雷直播、京东直播、企鹅体育、人人直播、棉花糖直播、九秀直播、羚萌直播、95秀、新浪疯播、红人直播、艾米直播、KK直播、酷我聚星、乐嗨直播、秀色直播、星光直播、我秀直播、热猫直播、艺气山直播、AcFun 直播、猫耳FM、畅秀阁、Twitch、TikTok、央视频、PP体育、zhibotv、腾讯体育直播、爱奇艺体育直播、liveU、bigolive、咪咕视频体育
**18** 个直播平台的弹幕获取:斗鱼直播、虎牙直播、哔哩哔哩直播、快手直播、火猫直播、企鹅电竞、花椒直播、映客直播、网易 CC 直播、酷狗直播、龙珠直播、PPS 奇秀、搜狐千帆、战旗直播、来疯直播、网易 LOOK 直播、AcFun 直播、艺气山直播。 **18** 个直播平台的弹幕获取:斗鱼直播、虎牙直播、哔哩哔哩直播、快手直播、火猫直播、企鹅电竞、花椒直播、映客直播、网易 CC 直播、酷狗直播、龙珠直播、PPS 奇秀、搜狐千帆、战旗直播、来疯直播、网易 LOOK 直播、AcFun 直播、艺气山直播。
@ -26,6 +26,8 @@
有直播平台失效或新增其他平台解析的,可发 [issue](https://github.com/wbt5/real-url/issues/new)。 有直播平台失效或新增其他平台解析的,可发 [issue](https://github.com/wbt5/real-url/issues/new)。
## 更新 ## 更新
2021.11.7:sparkles:新增咪咕体育。
2021.8.15:sparkles:新增 liveU、bigolive。 2021.8.15:sparkles:新增 liveU、bigolive。
2021.7.4:art:更新哔哩哔哩直播源;:bug:修复Acfun直播弹幕:bug:修复企鹅电竞弹幕。 2021.7.4:art:更新哔哩哔哩直播源;:bug:修复Acfun直播弹幕:bug:修复企鹅电竞弹幕。

98
huya.py
View File

@ -1,5 +1,4 @@
# 获取虎牙直播的真实流媒体地址。 # 获取虎牙直播的真实流媒体地址。
# 虎牙"一起看"频道的直播间可能会卡顿,尝试将返回地址 tx.hls.huya.com 中的 tx 改为 bd、migu-bd。
import requests import requests
import re import re
@ -7,61 +6,52 @@ import base64
import urllib.parse import urllib.parse
import hashlib import hashlib
import time import time
import json
def live(e):
i, b = e.split('?')
r = i.split('/')
s = re.sub(r'.(flv|m3u8)', '', r[-1])
c = b.split('&', 3)
c = [i for i in c if i != '']
n = {i.split('=')[0]: i.split('=')[1] for i in c}
fm = urllib.parse.unquote(n['fm'])
u = base64.b64decode(fm).decode('utf-8')
p = u.split('_')[0]
f = str(int(time.time() * 1e7))
l = n['wsTime']
t = '0'
h = '_'.join([p, t, s, f, l])
m = hashlib.md5(h.encode('utf-8')).hexdigest()
y = c[-1]
url = "{}?wsSecret={}&wsTime={}&u={}&seqid={}&{}".format(i, m, l, t, f, y)
return url
class HuYa: def get_real_url(room_id):
def __init__(self, rid):
self.rid = rid
def get_real_url(self):
try:
room_url = 'https://m.huya.com/' + str(self.rid)
header = {
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 '
'(KHTML, like Gecko) Chrome/75.0.3770.100 Mobile Safari/537.36 '
}
response = requests.get(url=room_url, headers=header).text
info = json.loads(re.findall(r"<script> window.HNF_GLOBAL_INIT = (.*)</script>", response)[0])
if info == {'exceptionType': 0}:
raise Exception('房间不存在')
roomInfo = info["roomInfo"]
real_url = {}
# not live
if roomInfo["eLiveStatus"] == 1:
raise Exception('未开播')
# live
elif roomInfo["eLiveStatus"] == 2:
streamInfos = roomInfo["tLiveInfo"]["tLiveStreamInfo"]["vStreamInfo"]["value"]
for streamInfo in streamInfos:
real_url[streamInfo["sCdnType"].lower() + "_flv"] = streamInfo["sFlvUrl"] + "/" + streamInfo["sStreamName"] + "." + \
streamInfo["sFlvUrlSuffix"] + "?" + streamInfo["sFlvAntiCode"]
real_url[streamInfo["sCdnType"].lower() + "_hls"] = streamInfo["sHlsUrl"] + "/" + streamInfo["sStreamName"] + "." + \
streamInfo["sHlsUrlSuffix"] + "?" + streamInfo["sHlsAntiCode"]
# replay
elif roomInfo["eLiveStatus"] == 3:
real_url["replay"] = roomInfo["tReplayInfo"]["tReplayVideoInfo"]["sUrl"]
else:
raise Exception('未知错误')
except Exception as e:
raise Exception(e)
return real_url
def get_real_url(rid):
try: try:
hy = HuYa(rid) room_url = 'https://m.huya.com/' + str(room_id)
return hy.get_real_url() header = {
except Exception as e: 'Content-Type': 'application/x-www-form-urlencoded',
print('Exception', e) 'User-Agent': 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) '
return False 'Chrome/75.0.3770.100 Mobile Safari/537.36 '
}
response = requests.get(url=room_url, headers=header).text
liveLineUrl = re.findall(r'"liveLineUrl":"([\s\S]*?)",', response)[0]
liveline = base64.b64decode(liveLineUrl).decode('utf-8')
if liveline:
if 'replay' in liveline:
return '直播录像:' + liveline
else:
liveline = live(liveline)
real_url = ("https:" + liveline).replace("hls", "flv").replace("m3u8", "flv")
else:
real_url = '未开播或直播间不存在'
except:
real_url = '未开播或直播间不存在'
return real_url
if __name__ == '__main__': rid = input('输入虎牙直播房间号:\n')
rid = input('输入虎牙直播房间号:\n') real_url = get_real_url(rid)
print(get_real_url(rid)) print('该直播间源地址为:')
print(real_url)

115
migu.py Normal file
View File

@ -0,0 +1,115 @@
# -*- coding: utf-8 -*-
# @Time: 2021/11/6 10:51
# @Project: real-url
# @Author: wbt5
# @Blog: https://wbt5.com
import requests
from urllib import parse
class MiGu:
"""
获取咪咕体育直播的流媒体地址
直播列表:https://www.miguvideo.com/mgs/website/prd/sportMatchDetail.html
直播间地址形式:https://www.miguvideo.com/mgs/website/prd/sportLive.html?mgdbId=120000173758
mgdbId 120000173758即为房间号
"""
def __init__(self, rid, rate=3):
"""
Args:
rate:估计是清晰度默认rate=3是高清
rid:房间号 120000173758
"""
self.rid = rid
self.rate = rate
def get_real_url(self):
"""
先获取contId
Returns:
url
"""
headers = {
'appId': 'miguvideo',
'clientId': '',
'SDKCEId': '',
'terminalId': 'www',
'userId': '',
'userToken': '',
'X-UP-CLIENT-CHANNEL-ID': '',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/95.0.4638.69 Safari/537.36',
'Referer': 'https://www.miguvideo.com/',
}
url = 'https://app-sc.miguvideo.com/vms-match/v3/staticcache/basic/basic-data/{}'.format(self.rid)
with requests.Session() as session:
res = session.get(url, headers=headers).json()
try:
contid = res['body']['pId']
url = f'https://webapi.miguvideo.com/gateway/playurl/v3/play/playurl?contId={contid}&rateType={self.rate}'
res = session.get(url, headers=headers).json()
try:
playurl = res['body']['urlInfo']['url']
real_url = self.calcu(playurl)
return real_url
except KeyError:
return '未获取到url,可能参数错误!'
except KeyError:
return '未获取到contId'
@staticmethod
def calcu(pre_url):
"""
计算ddCalcu原始过程在pcPlayer.js的9432行到9460行
这里直接用python代码还原其实可以简化
Args:
pre_url:playurl请求返回的url用来拼接计算ddCalcu
Returns:
real_url:添加ddCalcu后的播放地址
"""
params = dict(parse.parse_qsl(pre_url.split('?')[-1]))
t = 'eeeeeeeee'
r = str(params['timestamp'])
n = str(params['ProgramID'])
a = params['Channel_ID']
o = params['puData']
# s = '2624'
# js里是遍历s这里直接写死
u = t[2] or 'e'
ll = r[6] or 't'
c = n[2] or "c"
f = a[len(a) - 4] or 'n'
d = o
h = []
for p in range(0, int(len(d) / 2)):
h.append(d[len(d) - p - 1])
if p < len(d) - p - 1:
h.append(o[p])
x = {
1: u,
2: ll,
3: c,
4: f
}
h.append(x[p]) if p in [1, 2, 3, 4] else ''
v = ''.join(h)
real_url = pre_url + '&ddCalcu=' + v
return real_url
def get_real_url(rid):
try:
mg = MiGu(rid)
return mg.get_real_url()
except Exception as e:
print('Exception', e)
return False
if __name__ == '__main__':
rr = input('请输入咪咕直播间号:\n')
print(get_real_url(rr))