mirror of
https://github.com/wbt5/real-url.git
synced 2025-07-28 12:15:52 +08:00
Compare commits
6 Commits
a183f53730
...
183d14aff8
Author | SHA1 | Date | |
---|---|---|---|
|
183d14aff8 | ||
|
dc957e6abb | ||
|
b0b8edeb49 | ||
|
ca1da4aeb7 | ||
|
17a1f788cb | ||
|
9f594bd1d9 |
@ -6,9 +6,9 @@
|
||||
|
||||
目前已实现:
|
||||
|
||||
**26** 个直播平台的直播源获取:斗鱼直播、虎牙直播、哔哩哔哩直播、战旗直播、网易 CC 直播、火猫直播、企鹅电竞、YY 直播、一直播、快手直播、花椒直播、映客直播、西瓜直播、触手直播、NOW 直播、抖音直播,爱奇艺直播、酷狗直播、龙珠直播、PPS 奇秀直播、六间房、17 直播、来疯直播、优酷轮播台、网易 look 直播、千帆直播。
|
||||
**27** 个直播平台的直播源获取:斗鱼直播、虎牙直播、哔哩哔哩直播、战旗直播、网易 CC 直播、火猫直播、企鹅电竞、YY 直播、一直播、快手直播、花椒直播、映客直播、西瓜直播、触手直播、NOW 直播、抖音直播,爱奇艺直播、酷狗直播、龙珠直播、PPS 奇秀直播、六间房、17 直播、来疯直播、优酷轮播台、网易 LOOK 直播、千帆直播、陌陌直播。
|
||||
|
||||
**15** 个直播平台的弹幕获取:斗鱼直播、虎牙直播、哔哩哔哩直播、快手直播、火猫直播、企鹅电竞、花椒直播、映客直播、网易CC直播、酷狗直播、龙珠直播、PPS奇秀、搜狐千帆、战旗直播、来疯直播。
|
||||
**16** 个直播平台的弹幕获取:斗鱼直播、虎牙直播、哔哩哔哩直播、快手直播、火猫直播、企鹅电竞、花椒直播、映客直播、网易 CC 直播、酷狗直播、龙珠直播、PPS 奇秀、搜狐千帆、战旗直播、来疯直播、网易 LOOK 直播。
|
||||
|
||||
## 运行
|
||||
|
||||
@ -23,7 +23,9 @@
|
||||
|
||||
## 更新
|
||||
|
||||
### 2020.07.19:新增来疯直播弹幕获取
|
||||
### 2020.07.25:新增网易 LOOK 直播弹幕获取;修复斗鱼直播源;新增陌陌直播源。
|
||||
|
||||
2020.07.19:新增来疯直播弹幕获取
|
||||
|
||||
2020.07.18:新增酷狗、龙珠、PPS奇秀、搜狐千帆、战旗直播等5个平台的弹幕获取
|
||||
|
||||
|
@ -17,6 +17,7 @@ from .longzhu import LongZhu
|
||||
from .pps import QiXiu
|
||||
from .qf import QF
|
||||
from .laifeng import LaiFeng
|
||||
from .look import Look
|
||||
|
||||
__all__ = ['DanmakuClient']
|
||||
|
||||
@ -48,7 +49,8 @@ class DanmakuClient:
|
||||
'longzhu.com': LongZhu,
|
||||
'pps.tv': QiXiu,
|
||||
'qf.56.com': QF,
|
||||
'laifeng.com': LaiFeng}.items():
|
||||
'laifeng.com': LaiFeng,
|
||||
'look.163.com': Look}.items():
|
||||
if re.match(r'^(?:http[s]?://)?.*?%s/(.+?)$' % u, url):
|
||||
self.__site = s
|
||||
self.__u = u
|
||||
@ -63,7 +65,7 @@ class DanmakuClient:
|
||||
self.__ws = await self.__hs.ws_connect(ws_url)
|
||||
if reg_datas:
|
||||
for reg_data in reg_datas:
|
||||
if self.__u == 'qf.56.com' or self.__u == 'laifeng.com':
|
||||
if self.__u == 'qf.56.com' or self.__u == 'laifeng.com' or self.__u == 'look.163.com':
|
||||
await self.__ws.send_str(reg_data)
|
||||
else:
|
||||
await self.__ws.send_bytes(reg_data)
|
||||
@ -72,7 +74,7 @@ class DanmakuClient:
|
||||
while not self.__stop and self.__site.heartbeat:
|
||||
await asyncio.sleep(self.__site.heartbeatInterval)
|
||||
try:
|
||||
if self.__u == 'qf.56.com' or self.__u == 'laifeng.com':
|
||||
if self.__u == 'qf.56.com' or self.__u == 'laifeng.com' or self.__u == 'look.163.com':
|
||||
await self.__ws.send_str(self.__site.heartbeat)
|
||||
else:
|
||||
await self.__ws.send_bytes(self.__site.heartbeat)
|
||||
|
112
danmu/danmaku/look.py
Normal file
112
danmu/danmaku/look.py
Normal file
@ -0,0 +1,112 @@
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Util.Padding import pad
|
||||
import aiohttp
|
||||
import json
|
||||
import base64
|
||||
|
||||
|
||||
class Look:
|
||||
heartbeat = '2::'
|
||||
heartbeatInterval = 30
|
||||
|
||||
@staticmethod
|
||||
def aes_(t, key):
|
||||
t = t.encode('utf-8')
|
||||
t = pad(t, AES.block_size)
|
||||
key = key.encode()
|
||||
iv = b'0102030405060708'
|
||||
mode = AES.MODE_CBC
|
||||
c = AES.new(key, mode, iv)
|
||||
res = c.encrypt(t)
|
||||
return base64.b64encode(res).decode('utf-8')
|
||||
|
||||
@staticmethod
|
||||
async def get_ws_info(url):
|
||||
rid = url.split('=')[-1]
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get('https://weblink10.netease.im/socket.io/1/') as resp:
|
||||
res = await resp.text()
|
||||
sessid = res.split(':')[0]
|
||||
ws_url = 'wss://weblink10.netease.im/socket.io/1/websocket/' + sessid
|
||||
room = {
|
||||
'liveRoomNo': rid
|
||||
}
|
||||
c = json.dumps(room, separators=(',', ':'))
|
||||
data = {
|
||||
'params': Look.aes_(Look.aes_(c, '0CoJUm6Qyw8W8jud'), 'dV00kZnm4Au69cp2'),
|
||||
'encSecKey': 'e08bda29630b9a9bbf9552a1e5f889972aedfe6bc4e695b60d566294043431c60e42487153c6e0df42df0aa9d40c739552d8d8ee58d9acbcab8f4ae0df997a787eefcc56bdcd12fd2f1e41bdb5f9db240b3e10b6bd762fd207853af4c78dddf8254cf6ff83599120bd041c3e7dfb3faea1cd2886bd2c40de0981a11ae2af2a33 '
|
||||
}
|
||||
async with session.post('https://api.look.163.com/weapi/livestream/room/get/v3', data=data) as resp:
|
||||
res = await resp.json()
|
||||
roomid = res['data']['roomInfo']['roomId']
|
||||
|
||||
args = {
|
||||
'SID': 13,
|
||||
'CID': 2,
|
||||
'SER': 1,
|
||||
'Q': [{
|
||||
't': 'byte',
|
||||
'v': 1
|
||||
}, {
|
||||
't': 'Property',
|
||||
'v': {
|
||||
'1': '3a6a3e48f6854dfa4e4464f3bdaec3b4',
|
||||
'2': '',
|
||||
'3': '1713a7e3e1e4d7b99fe5bcff2fe7e178',
|
||||
'5': roomid,
|
||||
'8': 0,
|
||||
'20': '',
|
||||
'21': ' ',
|
||||
'26': '',
|
||||
'38': 1
|
||||
}
|
||||
}, {
|
||||
't': 'Property',
|
||||
'v': {
|
||||
'4': '',
|
||||
'6': '47',
|
||||
'8': 1,
|
||||
'9': 1,
|
||||
'13': '1713a7e3e1e4d7b99fe5bcff2fe7e178',
|
||||
'18': '3a6a3e48f6854dfa4e4464f3bdaec3b4',
|
||||
'19': '',
|
||||
'24': '',
|
||||
'26': '',
|
||||
'1000': ''
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
reg_data = '3:::' + json.dumps(args, separators=(',', ':'))
|
||||
|
||||
return ws_url, [reg_data]
|
||||
|
||||
@staticmethod
|
||||
def decode_msg(message):
|
||||
type_ = message[0]
|
||||
msgs = []
|
||||
msg = {'name': '', 'content': '', 'msg_type': 'other'}
|
||||
if type_ == '3':
|
||||
data = json.loads(message[4:])
|
||||
if data['cid'] == 10:
|
||||
body = data['r'][1]['body']
|
||||
body = body[0]
|
||||
if body['2'] == '100':
|
||||
info = json.loads(body['4'])
|
||||
if info['type'] == 114: # 入场信息
|
||||
msg['name'] = info['content']['user']['nickName']
|
||||
msg['content'] = ' 进入了直播间'
|
||||
msg['msg_type'] = 'danmaku'
|
||||
elif info['type'] == 102: # 礼物
|
||||
msg['name'] = info['content']['user']['nickName']
|
||||
number = info['content']['number']
|
||||
giftname = info['content']['giftName']
|
||||
msg['content'] = ' 送了{}{}个'.format(giftname, number)
|
||||
msg['msg_type'] = 'danmaku'
|
||||
elif body['2'] == '0': # 发言
|
||||
info = json.loads(body['4'])
|
||||
msg['name'] = info['content']['user']['nickname']
|
||||
msg['content'] = body['3']
|
||||
msg['msg_type'] = 'danmaku'
|
||||
msgs.append(msg.copy())
|
||||
return msgs
|
@ -31,10 +31,11 @@ asyncio.run(main(a))
|
||||
# 企鹅电竞:https://egame.qq.com/383204988
|
||||
# 花椒直播:https://www.huajiao.com/l/303344861?qd=hu
|
||||
# 映客直播:https://www.inke.cn/liveroom/index.html?uid=87493223&id=1593906372018299
|
||||
# CC直播:https://cc.163.com/363936598/a
|
||||
# CC直播:https://cc.163.com/363936598/
|
||||
# 酷狗直播:https://fanxing.kugou.com/1676290
|
||||
# 战旗直播
|
||||
# 龙珠直播:http://star.longzhu.com/wsde135864219
|
||||
# PPS奇秀直播:https://x.pps.tv/room/208337
|
||||
# 搜狐千帆直播:https://qf.56.com/520208a
|
||||
# 来疯直播:https://v.laifeng.com/656428
|
||||
# LOOK直播:https://look.163.com/live?id=196257915
|
||||
|
4
douyu.py
4
douyu.py
@ -101,8 +101,8 @@ def get_sign_url(post_v, rid, tt, ub9):
|
||||
if 'mix=1' in real_url:
|
||||
result1 = mix_room(rid)
|
||||
else:
|
||||
pattern1 = r'live/(\d{1,8}[0-9a-zA-Z]+)_?[\d]{0,4}/playlist'
|
||||
result1 = re.findall(pattern1, real_url, re.I)[0]
|
||||
pattern = r'/(\d{1,8}[0-9a-zA-Z]+)_?[\d]{0,4}.m3u8'
|
||||
result1 = re.search(pattern, real_url).group(1)
|
||||
else:
|
||||
result1 = 0
|
||||
return result1
|
||||
|
31
immomo.py
Normal file
31
immomo.py
Normal file
@ -0,0 +1,31 @@
|
||||
import requests
|
||||
|
||||
|
||||
def immomo(rid):
|
||||
url = 'https://web.immomo.com/webmomo/api/scene/profile/roominfos'
|
||||
data = {
|
||||
'stid': rid,
|
||||
'src': 'url'
|
||||
}
|
||||
|
||||
with requests.Session() as s:
|
||||
s.get('https://web.immomo.com')
|
||||
res = s.post(url, data=data).json()
|
||||
|
||||
ec = res.get('ec', 0)
|
||||
if ec != 200:
|
||||
raise Exception('请求参数错误')
|
||||
else:
|
||||
live = res['data']['live']
|
||||
if live:
|
||||
real_url = res['data']['url']
|
||||
return real_url
|
||||
else:
|
||||
raise Exception('未开播')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
r = input('输入陌陌直播房间号:\n')
|
||||
print(immomo(r))
|
||||
|
||||
# https://web.immomo.com/live/337033339
|
Loading…
x
Reference in New Issue
Block a user