From 84bae4ad2aab9270bc51afeb033ac9f94c3a3f99 Mon Sep 17 00:00:00 2001 From: taizan-hokuto <55448286+taizan-hokuto@users.noreply.github.com> Date: Sat, 18 Apr 2020 00:55:56 +0900 Subject: [PATCH] Modify bytes combination --- pytchat/paramgen/arcparam.py | 68 +++++++++--------- pytchat/paramgen/liveparam.py | 127 +++++++++++++++++----------------- 2 files changed, 101 insertions(+), 94 deletions(-) diff --git a/pytchat/paramgen/arcparam.py b/pytchat/paramgen/arcparam.py index 2cd1829..f62cb40 100644 --- a/pytchat/paramgen/arcparam.py +++ b/pytchat/paramgen/arcparam.py @@ -12,6 +12,7 @@ Author: taizan-hokuto (2019) @taizan205 ver 0.0.1 2019.10.05 ''' + def _gen_vid(video_id): """generate video_id parameter. Parameter @@ -23,7 +24,7 @@ def _gen_vid(video_id): bytes : base64 encoded video_id parameter. """ 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_terminator = b'\x20\x01' @@ -40,42 +41,46 @@ def _gen_vid(video_id): b64enc(reduce(lambda x, y: x+y, item)).decode() ).encode() + def _nval(val): """convert value to byte array""" - if val<0: raise ValueError + if val < 0: + raise ValueError buf = b'' while val >> 7: m = val & 0xFF | 0x80 - buf += m.to_bytes(1,'big') + buf += m.to_bytes(1, 'big') val >>= 7 - buf += val.to_bytes(1,'big') + buf += val.to_bytes(1, 'big') return buf + def _build(video_id, seektime, topchat_only): switch_01 = b'\x04' if topchat_only else b'\x01' if seektime < 0: - times =_nval(0) - switch = b'\x04' - elif seektime == 0: - times =_nval(1) - switch = b'\x03' + times = _nval(0) + switch = b'\x04' + elif seektime == 0: + times = _nval(1) + switch = b'\x03' else: - times =_nval(int(seektime*1000000)) + times = _nval(int(seektime*1000000)) switch = b'\x03' parity = b'\x00' - header_magic= b'\xA2\x9D\xB0\xD3\x04' - sep_0 = b'\x1A' - vid = _gen_vid(video_id) - time_tag = b'\x28' - timestamp1 = times - sep_1 = b'\x30\x00\x38\x00\x40\x00\x48' - 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' - sep_3 = b'\x00\x58\x03\x60' - sep_4 = b'\x68' + parity + b'\x72\x04\x08' - sep_5 = b'\x10' + parity + b'\x78\x00' - body = [ + header_magic = b'\xA2\x9D\xB0\xD3\x04' + sep_0 = b'\x1A' + vid = _gen_vid(video_id) + time_tag = b'\x28' + timestamp1 = times + sep_1 = b'\x30\x00\x38\x00\x40\x00\x48' + 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' + sep_3 = b'\x00\x58\x03\x60' + sep_4 = b'\x68' + parity + b'\x72\x04\x08' + sep_5 = b'\x10' + parity + b'\x78\x00' + + body = b''.join([ sep_0, _nval(len(vid)), vid, @@ -90,18 +95,17 @@ def _build(video_id, seektime, topchat_only): sep_4, switch_01, 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 --------- diff --git a/pytchat/paramgen/liveparam.py b/pytchat/paramgen/liveparam.py index a091b11..09d8273 100644 --- a/pytchat/paramgen/liveparam.py +++ b/pytchat/paramgen/liveparam.py @@ -11,6 +11,8 @@ Author: taizan-hokuto (2019) @taizan205 ver 0.0.1 2019.10.05 ''' + + def _gen_vid(video_id): """generate video_id parameter. Parameter @@ -22,11 +24,11 @@ def _gen_vid(video_id): byte[] : base64 encoded video_id parameter. """ 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_2 = b'\x43\xAA\xB9\xC1\xBD\x01\x3D\x0A' 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' item = [ @@ -44,62 +46,66 @@ def _gen_vid(video_id): b64enc(reduce(lambda x, y: x+y, item)).decode() ).encode() -def _tzparity(video_id,times): - t=0 - for i,s in enumerate(video_id): + +def _tzparity(video_id, times): + t = 0 + for i, s in enumerate(video_id): ss = ord(s) if(ss % 2 == 0): t += ss*(12-i) else: t ^= ss*i - return ((times^t) % 2).to_bytes(1,'big') + return ((times ^ t) % 2).to_bytes(1, 'big') + def _nval(val): """convert value to byte array""" - if val<0: raise ValueError + if val < 0: + raise ValueError buf = b'' while val >> 7: m = val & 0xFF | 0x80 - buf += m.to_bytes(1,'big') + buf += m.to_bytes(1, 'big') val >>= 7 - buf += val.to_bytes(1,'big') + buf += val.to_bytes(1, 'big') return buf + 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' - 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' - sep_0 = b'\x1A' - vid = _gen_vid(video_id) - time_tag = b'\x28' - timestamp1 = _nval(_ts1) - sep_1 = b'\x30\x00\x38\x00\x40\x02\x4A' - un_len = b'\x2B' - 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' - sep_3 = b'\x3A\x00\x40\x00\x4A' - sep_4_len = b'\x02' - sep_4 = b'\x08\x01' - ts_2_start = b'\x50' - timestamp2 = _nval(_ts2) - ts_2_end = b'\x58' - sep_5 = b'\x03' - ts_3_start = b'\x50' - timestamp3 = _nval(_ts3) - ts_3_end = b'\x58' - timestamp4 = _nval(_ts4) - sep_6 = b'\x68' - #switch - sep_7 = b'\x82\x01\x04\x08' - #switch - sep_8 = b'\x10\x00' - sep_9 = b'\x88\x01\x00\xA0\x01' - timestamp5 = _nval(_ts5) + header_magic = b'\xD2\x87\xCC\xC8\x03' + sep_0 = b'\x1A' + vid = _gen_vid(video_id) + time_tag = b'\x28' + timestamp1 = _nval(_ts1) + sep_1 = b'\x30\x00\x38\x00\x40\x02\x4A' + un_len = b'\x2B' + 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' + sep_3 = b'\x3A\x00\x40\x00\x4A' + sep_4_len = b'\x02' + sep_4 = b'\x08\x01' + ts_2_start = b'\x50' + timestamp2 = _nval(_ts2) + ts_2_end = b'\x58' + sep_5 = b'\x03' + ts_3_start = b'\x50' + timestamp3 = _nval(_ts3) + ts_3_end = b'\x58' + timestamp4 = _nval(_ts4) + sep_6 = b'\x68' + # switch + sep_7 = b'\x82\x01\x04\x08' + # switch + sep_8 = b'\x10\x00' + sep_9 = b'\x88\x01\x00\xA0\x01' + timestamp5 = _nval(_ts5) - body = [ + body = b''.join([ sep_0, _nval(len(vid)), vid, @@ -121,37 +127,35 @@ def _build(video_id, _ts1, _ts2, _ts3, _ts4, _ts5, topchat_only): ts_3_end, timestamp4, sep_6, - switch_01,# + switch_01, sep_7, - switch_01,# + switch_01, sep_8, sep_9, timestamp5 - ] + ]) + + return urllib.parse.quote( + b64enc(header_magic + + _nval(len(body)) + + body + ).decode() + ) - body = reduce(lambda x, y: x+y, body) - - return urllib.parse.quote( - b64enc( header_magic + - _nval(len(body)) + - body - ).decode() - ) - def _times(past_sec): - + n = int(time.time()) - - _ts1= n - random.uniform(0,1*3) - _ts2= n - random.uniform(0.01,0.99) - _ts3= n - past_sec + random.uniform(0,1) - _ts4= n - random.uniform(10*60,60*60) - _ts5= n - random.uniform(0.01,0.99) - return list(map(lambda x:int(x*1000000),[_ts1,_ts2,_ts3,_ts4,_ts5])) + + _ts1 = n - random.uniform(0, 1*3) + _ts2 = n - random.uniform(0.01, 0.99) + _ts3 = n - past_sec + random.uniform(0, 1) + _ts4 = n - random.uniform(10*60, 60*60) + _ts5 = n - random.uniform(0.01, 0.99) + 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 --------- @@ -160,5 +164,4 @@ def getparam(video_id, past_sec = 0, topchat_only = False): topchat_only : bool if True, fetch only 'top chat' ''' - return _build(video_id,*_times(past_sec),topchat_only) - + return _build(video_id, *_times(past_sec), topchat_only)