1
0
mirror of https://github.com/wbt5/real-url.git synced 2025-06-17 08:25:25 +08:00

Compare commits

...

4 Commits

Author SHA1 Message Date
wbt5
7fb5260544 delete 2020-09-26 18:33:21 +08:00
wbt5
7ea00dd4a5 删掉YY 2020-09-26 18:29:57 +08:00
wbt5
c7ff83cfa7 增加bd、migu-bd 2020-09-26 18:28:44 +08:00
wbt5
a992f96d4c 更新 2020-09-26 18:27:46 +08:00
6 changed files with 9 additions and 1422 deletions

View File

@ -25,7 +25,9 @@
## 更新
### 2020.09.12新增斗鱼添加一个从PC网页端获取直播源的方法可选线路和清晰度新增requirements.txt文件更新代码。
### 2020.09.26:更新:虎牙直播源;注释掉未完成的 YY 直播弹幕功能。
2020.09.12新增斗鱼添加一个从PC网页端获取直播源的方法可选线路和清晰度新增requirements.txt文件更新代码。
2020.08.18:更新快手直播源,现在播放链接需要带参数;更新快手直播弹幕,直接用 protobuf 序列化;新增 AcFun、艺气山两个平台的弹幕功能。

View File

@ -1,139 +0,0 @@
syntax = "proto2";
package YiQishanPack;
message CSHead {
optional uint32 command = 1;
optional uint32 subcmd = 2;
optional uint32 seq = 3;
optional bytes uuid = 4;
optional uint32 clientType = 5;
optional uint32 headFlag = 6;
optional uint32 clientVer = 7;
optional bytes signature = 8;
optional uint32 routeKey = 9;
}
message TCPAccessReq {
optional bytes AccessToken = 1;
optional bytes MachineCode = 2;
}
message TcpHelloReq {
optional string uuid = 1;
}
message EnterRoomReq {
optional bytes uuid = 1;
optional bytes roomid = 2;
optional uint32 neednum = 3;
optional bool isfake = 4;
optional bool needbroadcast = 5;
optional bytes nick = 6;
optional bytes clientip = 7;
optional bytes subroomid = 8;
optional uint32 gameid = 10;
}
message RoomHelloReq {
optional bytes uuid = 1;
optional bytes roomid = 2;
optional bytes roomsig = 3;
optional uint32 connsvrip = 4;
optional bool isinternal = 5;
optional bytes subroomid = 6;
}
message Token {
optional string uuid = 1;
optional bytes gtkey = 2;
optional uint32 ip = 3;
optional uint32 expiresstime = 4;
optional uint32 gentime = 5;
}
message PublicChatNotify {
optional bytes roomid = 1;
optional bytes uuid = 2;
optional bytes nick = 3;
optional ChatInfo info = 4;
optional bytes touuid = 5;
optional bytes tonick = 6;
optional uint32 privilege = 7;
optional uint32 rank = 8;
optional uint32 fromgame = 9;
optional bytes gameid = 10;
repeated BadgeType badges = 11;
optional RoomUserInfo userinfo = 12;
optional bool isnoble = 13;
optional uint32 noblelevelid = 14;
optional string noblelevelname = 15;
optional bool isnoblemessage = 16;
}
enum BadgeType {
NOBARRAGE = 0;
FIRST_CHARGE_BADGE = 1;
FIRST_CHARGE_COPPER = 2;
FIRST_CHARGE_SLIVER = 3;
FIRST_CHARGE_GOLD = 4;
}
message ChatInfo {
optional uint32 chattype = 1;
optional bytes textmsg = 2;
}
message RoomUserInfo {
optional bytes uuid = 1;
optional bytes nick = 2;
optional uint32 weekartistconsume = 3;
optional uint32 artisttotalconsume = 4;
optional uint32 totalconsume = 5;
optional uint32 guardendtime = 6;
optional uint32 peerageid = 7;
}
message GiftNotyInfo {
optional bytes roomid = 1;
optional bytes giftid = 2;
optional uint32 giftcnt = 3;
optional bytes fromuuid = 4;
optional bytes fromnick = 5;
optional bytes touuid = 6;
optional bytes tonick = 7;
optional uint32 consume = 8;
optional bytes sessid = 9;
optional uint32 hits = 10;
optional uint32 hitsall = 11;
optional uint32 flag = 12;
optional uint32 fromviplevel = 13;
optional uint32 fanslevel = 14;
optional bool fromisnoble = 15;
optional uint32 fromnoblelevelid = 16;
}
message NotifyFreeGift {
optional bytes uuid = 1;
optional bytes fromnick = 2;
optional bytes touuid = 3;
optional bytes tonick = 4;
optional bytes roomid = 5;
optional uint32 giftid = 6;
optional uint32 giftcnt = 7;
optional uint32 fromviplevel = 8;
optional uint32 fanslevel = 9;
optional bool fromisnoble = 11;
optional uint32 fromnoblelevelid = 12;
}
message SendBroadcastPkg {
optional bytes uuid = 1;
repeated BroadcastMsg broadcastmsg = 2;
message BroadcastMsg {
optional uint32 businesstype = 1;
optional bytes title = 2;
optional bytes content = 3;
optional uint32 msgseq = 4;
}
}

View File

@ -1,137 +0,0 @@
import binascii
import struct
import requests
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad
from . import _173_pb2 as pb
class YiQiShan:
ws_url = 'wss://websocket.173.com/'
def __init__(self, rid):
self.rid = str(rid)
self.key = b'e#>&*m16'
with requests.Session() as se:
res = se.get('http://www.173.com/{}'.format(rid))
try:
self.uuid, _, token, _ = res.cookies.values()
except ValueError:
raise Exception('房间不存在')
self.accesstoken = binascii.a2b_hex(token)
s = YiQiShan.des_decode(self.accesstoken, self.key)
p = pb.Token()
p.ParseFromString(s)
self.gtkey = p.gtkey[:8]
@staticmethod
def des_encode(t, key):
t = pad(t, DES.block_size)
c = DES.new(key, DES.MODE_ECB)
res = c.encrypt(t)
return res
@staticmethod
def des_decode(t, key):
c = DES.new(key, DES.MODE_ECB)
res = c.decrypt(t)
length = len(res)
padding = res[length - 1]
res = res[0:length - padding]
return res
def startup(self):
p = pb.TCPAccessReq()
p.AccessToken = self.accesstoken
return p.SerializeToString()
def tcphelloreq(self):
p = pb.TcpHelloReq()
p.uuid = self.uuid
return p.SerializeToString()
def enterroomreq(self):
p = pb.EnterRoomReq()
p.uuid = self.uuid.encode()
p.roomid = self.rid.encode()
return p.SerializeToString()
def roomhelloreq(self):
p = pb.RoomHelloReq()
p.uuid = self.uuid.encode()
p.roomid = self.rid.encode()
return p.SerializeToString()
def pack(self, paylod_type):
command = {
'startup': 123,
'tcphelloreq': 122,
'enterroomreq': 601,
'roomhelloreq': 600
}
subcmd = {
'startup': 0,
'tcphelloreq': 0,
'enterroomreq': 1,
'roomhelloreq': 1
}
p = pb.CSHead()
p.command = command[paylod_type]
p.subcmd = subcmd[paylod_type]
p.uuid = self.uuid.encode()
p.clientType = 4
p.routeKey = int(self.rid)
n = p.SerializeToString()
key = self.key if paylod_type == 'startup' else self.gtkey
payload = getattr(self, paylod_type)()
s = YiQiShan.des_encode(payload, key)
buf = struct.pack('!HcH', len(n) + len(s) + 8, b'W', len(n))
buf += n
buf += struct.pack('!H', len(s))
buf += s + b'M'
return buf
def unpack(self, data):
msgs = [{'name': '', 'content': '', 'msg_type': 'other'}]
s, = struct.unpack_from('!h', data, 3)
p, = struct.unpack_from('!h', data, 5 + s)
u = data[7 + s:7 + s + p]
a = pb.CSHead()
a.ParseFromString(data[5:5 + s])
cmd = a.command
key = self.key if cmd == 123 else self.gtkey
t = u if cmd == 102 else YiQiShan.des_decode(u, key)
o = cmd
# r = a.subcmd
if o == 102:
p = pb.SendBroadcastPkg()
p.ParseFromString(t)
for i in p.broadcastmsg:
# PublicChatNotify = 1
# BUSINESS_TYPE_FREE_GIFT = 2
# BUSINESS_TYPE_PAY_GIFT = 3
if i.businesstype == 1: # 发言
q = pb.PublicChatNotify()
q.ParseFromString(i.content)
user = q.nick.decode()
content = q.info.textmsg.decode()
# elif i.businesstype == 2: # 免费礼物
# print(i.businesstype)
# q = pb.NotifyFreeGift()
# q.ParseFromString(i.content)
# elif i.businesstype == 3: # 收费礼物
# print(i.businesstype)
# q = pb.GiftNotyInfo()
# q.ParseFromString(i.content)
# else:
# pass
msg = {'name': user, 'content': content, 'msg_type': 'danmaku'}
msgs.append(msg.copy())
return msgs

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,7 @@ from .look import Look
from .pps import QiXiu
from .qf import QF
from .zhanqi import ZhanQi
from .yy import YY
# from .yy import YY
__all__ = ['DanmakuClient']
@ -57,7 +57,7 @@ class DanmakuClient:
'look.163.com': Look,
'acfun.cn': AcFun,
'173.com': YiQiShan,
'yy.com': YY}.items():
'yy.com': ''}.items():
if re.match(r'^(?:http[s]?://)?.*?%s/(.+?)$' % u, url):
self.__site = s
self.__u = u

View File

@ -1,5 +1,5 @@
# 获取虎牙直播的真实流媒体地址。
# 虎牙"一起看"频道的直播间可能会卡顿
# 虎牙"一起看"频道的直播间可能会卡顿,尝试将返回地址 tx.hls.huya.com 中的 tx 改为 bd、migu-bd。
import requests
import re
@ -34,7 +34,9 @@ class HuYa:
b_url = self.live(livelineurl.replace('_2000', ''))
real_url = {
'2000p': "https:" + s_url,
'BD': "https:" + b_url
'tx': "https:" + b_url,
'bd': "https:" + b_url.replace('tx.hls.huya.com', 'bd.hls.huya.com'),
'migu-bd': "https:" + b_url.replace('tx.hls.huya.com', 'migu-bd.hls.huya.com'),
}
else:
raise Exception('未开播或直播间不存在')