Modify bytes combination
This commit is contained in:
@@ -12,6 +12,7 @@ Author: taizan-hokuto (2019) @taizan205
|
|||||||
ver 0.0.1 2019.10.05
|
ver 0.0.1 2019.10.05
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
def _gen_vid(video_id):
|
def _gen_vid(video_id):
|
||||||
"""generate video_id parameter.
|
"""generate video_id parameter.
|
||||||
Parameter
|
Parameter
|
||||||
@@ -23,7 +24,7 @@ def _gen_vid(video_id):
|
|||||||
bytes : base64 encoded video_id parameter.
|
bytes : base64 encoded video_id parameter.
|
||||||
"""
|
"""
|
||||||
header_magic = b'\x0A\x0F\x1A\x0D\x0A'
|
header_magic = b'\x0A\x0F\x1A\x0D\x0A'
|
||||||
header_id = video_id.encode()
|
header_id = video_id.encode()
|
||||||
header_sep_1 = b'\x1A\x13\xEA\xA8\xDD\xB9\x01\x0D\x0A\x0B'
|
header_sep_1 = b'\x1A\x13\xEA\xA8\xDD\xB9\x01\x0D\x0A\x0B'
|
||||||
header_terminator = b'\x20\x01'
|
header_terminator = b'\x20\x01'
|
||||||
|
|
||||||
@@ -40,42 +41,46 @@ def _gen_vid(video_id):
|
|||||||
b64enc(reduce(lambda x, y: x+y, item)).decode()
|
b64enc(reduce(lambda x, y: x+y, item)).decode()
|
||||||
).encode()
|
).encode()
|
||||||
|
|
||||||
|
|
||||||
def _nval(val):
|
def _nval(val):
|
||||||
"""convert value to byte array"""
|
"""convert value to byte array"""
|
||||||
if val<0: raise ValueError
|
if val < 0:
|
||||||
|
raise ValueError
|
||||||
buf = b''
|
buf = b''
|
||||||
while val >> 7:
|
while val >> 7:
|
||||||
m = val & 0xFF | 0x80
|
m = val & 0xFF | 0x80
|
||||||
buf += m.to_bytes(1,'big')
|
buf += m.to_bytes(1, 'big')
|
||||||
val >>= 7
|
val >>= 7
|
||||||
buf += val.to_bytes(1,'big')
|
buf += val.to_bytes(1, 'big')
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
|
|
||||||
def _build(video_id, seektime, topchat_only):
|
def _build(video_id, seektime, topchat_only):
|
||||||
switch_01 = b'\x04' if topchat_only else b'\x01'
|
switch_01 = b'\x04' if topchat_only else b'\x01'
|
||||||
if seektime < 0:
|
if seektime < 0:
|
||||||
times =_nval(0)
|
times = _nval(0)
|
||||||
switch = b'\x04'
|
switch = b'\x04'
|
||||||
elif seektime == 0:
|
elif seektime == 0:
|
||||||
times =_nval(1)
|
times = _nval(1)
|
||||||
switch = b'\x03'
|
switch = b'\x03'
|
||||||
else:
|
else:
|
||||||
times =_nval(int(seektime*1000000))
|
times = _nval(int(seektime*1000000))
|
||||||
switch = b'\x03'
|
switch = b'\x03'
|
||||||
parity = b'\x00'
|
parity = b'\x00'
|
||||||
|
|
||||||
header_magic= b'\xA2\x9D\xB0\xD3\x04'
|
header_magic = b'\xA2\x9D\xB0\xD3\x04'
|
||||||
sep_0 = b'\x1A'
|
sep_0 = b'\x1A'
|
||||||
vid = _gen_vid(video_id)
|
vid = _gen_vid(video_id)
|
||||||
time_tag = b'\x28'
|
time_tag = b'\x28'
|
||||||
timestamp1 = times
|
timestamp1 = times
|
||||||
sep_1 = b'\x30\x00\x38\x00\x40\x00\x48'
|
sep_1 = b'\x30\x00\x38\x00\x40\x00\x48'
|
||||||
sep_2 = b'\x52\x1C\x08\x00\x10\x00\x18\x00\x20\x00'
|
sep_2 = b'\x52\x1C\x08\x00\x10\x00\x18\x00\x20\x00'
|
||||||
chkstr = b'\x2A\x0E\x73\x74\x61\x74\x69\x63\x63\x68\x65\x63\x6B\x73\x75\x6D\x40'
|
chkstr = b'\x2A\x0E\x73\x74\x61\x74\x69\x63\x63\x68\x65\x63\x6B\x73\x75\x6D\x40'
|
||||||
sep_3 = b'\x00\x58\x03\x60'
|
sep_3 = b'\x00\x58\x03\x60'
|
||||||
sep_4 = b'\x68' + parity + b'\x72\x04\x08'
|
sep_4 = b'\x68' + parity + b'\x72\x04\x08'
|
||||||
sep_5 = b'\x10' + parity + b'\x78\x00'
|
sep_5 = b'\x10' + parity + b'\x78\x00'
|
||||||
body = [
|
|
||||||
|
body = b''.join([
|
||||||
sep_0,
|
sep_0,
|
||||||
_nval(len(vid)),
|
_nval(len(vid)),
|
||||||
vid,
|
vid,
|
||||||
@@ -90,18 +95,17 @@ def _build(video_id, seektime, topchat_only):
|
|||||||
sep_4,
|
sep_4,
|
||||||
switch_01,
|
switch_01,
|
||||||
sep_5
|
sep_5
|
||||||
]
|
])
|
||||||
|
|
||||||
body = reduce(lambda x, y: x+y, body)
|
return urllib.parse.quote(
|
||||||
|
b64enc(header_magic +
|
||||||
|
_nval(len(body)) +
|
||||||
|
body
|
||||||
|
).decode()
|
||||||
|
)
|
||||||
|
|
||||||
return urllib.parse.quote(
|
|
||||||
b64enc( header_magic +
|
|
||||||
_nval(len(body)) +
|
|
||||||
body
|
|
||||||
).decode()
|
|
||||||
)
|
|
||||||
|
|
||||||
def getparam(video_id, seektime = 0, topchat_only = False):
|
def getparam(video_id, seektime=0, topchat_only=False):
|
||||||
'''
|
'''
|
||||||
Parameter
|
Parameter
|
||||||
---------
|
---------
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ Author: taizan-hokuto (2019) @taizan205
|
|||||||
|
|
||||||
ver 0.0.1 2019.10.05
|
ver 0.0.1 2019.10.05
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
def _gen_vid(video_id):
|
def _gen_vid(video_id):
|
||||||
"""generate video_id parameter.
|
"""generate video_id parameter.
|
||||||
Parameter
|
Parameter
|
||||||
@@ -22,11 +24,11 @@ def _gen_vid(video_id):
|
|||||||
byte[] : base64 encoded video_id parameter.
|
byte[] : base64 encoded video_id parameter.
|
||||||
"""
|
"""
|
||||||
header_magic = b'\x0A\x0F\x0A\x0D\x0A'
|
header_magic = b'\x0A\x0F\x0A\x0D\x0A'
|
||||||
header_id = video_id.encode()
|
header_id = video_id.encode()
|
||||||
header_sep_1 = b'\x1A'
|
header_sep_1 = b'\x1A'
|
||||||
header_sep_2 = b'\x43\xAA\xB9\xC1\xBD\x01\x3D\x0A'
|
header_sep_2 = b'\x43\xAA\xB9\xC1\xBD\x01\x3D\x0A'
|
||||||
header_suburl = ('https://www.youtube.com/live_chat?v='
|
header_suburl = ('https://www.youtube.com/live_chat?v='
|
||||||
f'{video_id}&is_popout=1').encode()
|
f'{video_id}&is_popout=1').encode()
|
||||||
header_terminator = b'\x20\x02'
|
header_terminator = b'\x20\x02'
|
||||||
|
|
||||||
item = [
|
item = [
|
||||||
@@ -44,62 +46,66 @@ def _gen_vid(video_id):
|
|||||||
b64enc(reduce(lambda x, y: x+y, item)).decode()
|
b64enc(reduce(lambda x, y: x+y, item)).decode()
|
||||||
).encode()
|
).encode()
|
||||||
|
|
||||||
def _tzparity(video_id,times):
|
|
||||||
t=0
|
def _tzparity(video_id, times):
|
||||||
for i,s in enumerate(video_id):
|
t = 0
|
||||||
|
for i, s in enumerate(video_id):
|
||||||
ss = ord(s)
|
ss = ord(s)
|
||||||
if(ss % 2 == 0):
|
if(ss % 2 == 0):
|
||||||
t += ss*(12-i)
|
t += ss*(12-i)
|
||||||
else:
|
else:
|
||||||
t ^= ss*i
|
t ^= ss*i
|
||||||
|
|
||||||
return ((times^t) % 2).to_bytes(1,'big')
|
return ((times ^ t) % 2).to_bytes(1, 'big')
|
||||||
|
|
||||||
|
|
||||||
def _nval(val):
|
def _nval(val):
|
||||||
"""convert value to byte array"""
|
"""convert value to byte array"""
|
||||||
if val<0: raise ValueError
|
if val < 0:
|
||||||
|
raise ValueError
|
||||||
buf = b''
|
buf = b''
|
||||||
while val >> 7:
|
while val >> 7:
|
||||||
m = val & 0xFF | 0x80
|
m = val & 0xFF | 0x80
|
||||||
buf += m.to_bytes(1,'big')
|
buf += m.to_bytes(1, 'big')
|
||||||
val >>= 7
|
val >>= 7
|
||||||
buf += val.to_bytes(1,'big')
|
buf += val.to_bytes(1, 'big')
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
|
|
||||||
def _build(video_id, _ts1, _ts2, _ts3, _ts4, _ts5, topchat_only):
|
def _build(video_id, _ts1, _ts2, _ts3, _ts4, _ts5, topchat_only):
|
||||||
#_short_type2
|
# _short_type2
|
||||||
switch_01 = b'\x04' if topchat_only else b'\x01'
|
switch_01 = b'\x04' if topchat_only else b'\x01'
|
||||||
parity = _tzparity(video_id, _ts1^_ts2^_ts3^_ts4^_ts5)
|
parity = _tzparity(video_id, _ts1 ^ _ts2 ^ _ts3 ^ _ts4 ^ _ts5)
|
||||||
|
|
||||||
header_magic= b'\xD2\x87\xCC\xC8\x03'
|
header_magic = b'\xD2\x87\xCC\xC8\x03'
|
||||||
sep_0 = b'\x1A'
|
sep_0 = b'\x1A'
|
||||||
vid = _gen_vid(video_id)
|
vid = _gen_vid(video_id)
|
||||||
time_tag = b'\x28'
|
time_tag = b'\x28'
|
||||||
timestamp1 = _nval(_ts1)
|
timestamp1 = _nval(_ts1)
|
||||||
sep_1 = b'\x30\x00\x38\x00\x40\x02\x4A'
|
sep_1 = b'\x30\x00\x38\x00\x40\x02\x4A'
|
||||||
un_len = b'\x2B'
|
un_len = b'\x2B'
|
||||||
sep_2 = b'\x08'+parity+b'\x10\x00\x18\x00\x20\x00'
|
sep_2 = b'\x08'+parity+b'\x10\x00\x18\x00\x20\x00'
|
||||||
chkstr = b'\x2A\x0E\x73\x74\x61\x74\x69\x63\x63\x68\x65\x63\x6B\x73\x75\x6D'
|
chkstr = b'\x2A\x0E\x73\x74\x61\x74\x69\x63\x63\x68\x65\x63\x6B\x73\x75\x6D'
|
||||||
sep_3 = b'\x3A\x00\x40\x00\x4A'
|
sep_3 = b'\x3A\x00\x40\x00\x4A'
|
||||||
sep_4_len = b'\x02'
|
sep_4_len = b'\x02'
|
||||||
sep_4 = b'\x08\x01'
|
sep_4 = b'\x08\x01'
|
||||||
ts_2_start = b'\x50'
|
ts_2_start = b'\x50'
|
||||||
timestamp2 = _nval(_ts2)
|
timestamp2 = _nval(_ts2)
|
||||||
ts_2_end = b'\x58'
|
ts_2_end = b'\x58'
|
||||||
sep_5 = b'\x03'
|
sep_5 = b'\x03'
|
||||||
ts_3_start = b'\x50'
|
ts_3_start = b'\x50'
|
||||||
timestamp3 = _nval(_ts3)
|
timestamp3 = _nval(_ts3)
|
||||||
ts_3_end = b'\x58'
|
ts_3_end = b'\x58'
|
||||||
timestamp4 = _nval(_ts4)
|
timestamp4 = _nval(_ts4)
|
||||||
sep_6 = b'\x68'
|
sep_6 = b'\x68'
|
||||||
#switch
|
# switch
|
||||||
sep_7 = b'\x82\x01\x04\x08'
|
sep_7 = b'\x82\x01\x04\x08'
|
||||||
#switch
|
# switch
|
||||||
sep_8 = b'\x10\x00'
|
sep_8 = b'\x10\x00'
|
||||||
sep_9 = b'\x88\x01\x00\xA0\x01'
|
sep_9 = b'\x88\x01\x00\xA0\x01'
|
||||||
timestamp5 = _nval(_ts5)
|
timestamp5 = _nval(_ts5)
|
||||||
|
|
||||||
body = [
|
body = b''.join([
|
||||||
sep_0,
|
sep_0,
|
||||||
_nval(len(vid)),
|
_nval(len(vid)),
|
||||||
vid,
|
vid,
|
||||||
@@ -121,37 +127,35 @@ def _build(video_id, _ts1, _ts2, _ts3, _ts4, _ts5, topchat_only):
|
|||||||
ts_3_end,
|
ts_3_end,
|
||||||
timestamp4,
|
timestamp4,
|
||||||
sep_6,
|
sep_6,
|
||||||
switch_01,#
|
switch_01,
|
||||||
sep_7,
|
sep_7,
|
||||||
switch_01,#
|
switch_01,
|
||||||
sep_8,
|
sep_8,
|
||||||
sep_9,
|
sep_9,
|
||||||
timestamp5
|
timestamp5
|
||||||
]
|
])
|
||||||
|
|
||||||
body = reduce(lambda x, y: x+y, body)
|
return urllib.parse.quote(
|
||||||
|
b64enc(header_magic +
|
||||||
return urllib.parse.quote(
|
_nval(len(body)) +
|
||||||
b64enc( header_magic +
|
body
|
||||||
_nval(len(body)) +
|
).decode()
|
||||||
body
|
)
|
||||||
).decode()
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _times(past_sec):
|
def _times(past_sec):
|
||||||
|
|
||||||
n = int(time.time())
|
n = int(time.time())
|
||||||
|
|
||||||
_ts1= n - random.uniform(0,1*3)
|
_ts1 = n - random.uniform(0, 1*3)
|
||||||
_ts2= n - random.uniform(0.01,0.99)
|
_ts2 = n - random.uniform(0.01, 0.99)
|
||||||
_ts3= n - past_sec + random.uniform(0,1)
|
_ts3 = n - past_sec + random.uniform(0, 1)
|
||||||
_ts4= n - random.uniform(10*60,60*60)
|
_ts4 = n - random.uniform(10*60, 60*60)
|
||||||
_ts5= n - random.uniform(0.01,0.99)
|
_ts5 = n - random.uniform(0.01, 0.99)
|
||||||
return list(map(lambda x:int(x*1000000),[_ts1,_ts2,_ts3,_ts4,_ts5]))
|
return list(map(lambda x: int(x*1000000), [_ts1, _ts2, _ts3, _ts4, _ts5]))
|
||||||
|
|
||||||
|
|
||||||
def getparam(video_id, past_sec = 0, topchat_only = False):
|
def getparam(video_id, past_sec=0, topchat_only=False):
|
||||||
'''
|
'''
|
||||||
Parameter
|
Parameter
|
||||||
---------
|
---------
|
||||||
@@ -160,5 +164,4 @@ def getparam(video_id, past_sec = 0, topchat_only = False):
|
|||||||
topchat_only : bool
|
topchat_only : bool
|
||||||
if True, fetch only 'top chat'
|
if True, fetch only 'top chat'
|
||||||
'''
|
'''
|
||||||
return _build(video_id,*_times(past_sec),topchat_only)
|
return _build(video_id, *_times(past_sec), topchat_only)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user