@@ -29,9 +29,13 @@ class PytchatCore:
2929
3030 processor : ChatProcessor
3131
32+ client : httpx.Client
33+ The client for connecting youtube.
34+ You can specify any customized httpx client (e.g. coolies, user agent).
35+
3236 interruptable : bool
3337 Allows keyboard interrupts.
34- Set this parameter to False if your own threading program causes
38+ Set this parameter to False if your own multi- threading program causes
3539 the problem.
3640
3741 force_replay : bool
@@ -57,13 +61,15 @@ class PytchatCore:
5761 def __init__ (self , video_id ,
5862 seektime = - 1 ,
5963 processor = DefaultProcessor (),
64+ client = httpx .Client (http2 = True ),
6065 interruptable = True ,
6166 force_replay = False ,
6267 topchat_only = False ,
6368 hold_exception = True ,
6469 logger = config .logger (__name__ ),
6570 replay_continuation = None
6671 ):
72+ self ._client = client
6773 self ._video_id = util .extract_video_id (video_id )
6874 self .seektime = seektime
6975 if isinstance (processor , tuple ):
@@ -97,7 +103,7 @@ def _setup(self):
97103 """
98104 self .continuation = liveparam .getparam (
99105 self ._video_id ,
100- channel_id = util .get_channelid (httpx . Client ( http2 = True ) , self ._video_id ),
106+ channel_id = util .get_channelid (self . _client , self ._video_id ),
101107 past_sec = 3 )
102108
103109 def _get_chat_component (self ):
@@ -110,19 +116,18 @@ def _get_chat_component(self):
110116 parameter for next chat data
111117 '''
112118 try :
113- with httpx .Client (http2 = True ) as client :
114- if self .continuation and self ._is_alive :
115- contents = self ._get_contents (self .continuation , client , headers )
116- metadata , chatdata = self ._parser .parse (contents )
117- timeout = metadata ['timeoutMs' ] / 1000
118- chat_component = {
119- "video_id" : self ._video_id ,
120- "timeout" : timeout ,
121- "chatdata" : chatdata
122- }
123- self .continuation = metadata .get ('continuation' )
124- self ._last_offset_ms = metadata .get ('last_offset_ms' , 0 )
125- return chat_component
119+ if self .continuation and self ._is_alive :
120+ contents = self ._get_contents (self .continuation , self ._client , headers )
121+ metadata , chatdata = self ._parser .parse (contents )
122+ timeout = metadata ['timeoutMs' ] / 1000
123+ chat_component = {
124+ "video_id" : self ._video_id ,
125+ "timeout" : timeout ,
126+ "chatdata" : chatdata
127+ }
128+ self .continuation = metadata .get ('continuation' )
129+ self ._last_offset_ms = metadata .get ('last_offset_ms' , 0 )
130+ return chat_component
126131 except exceptions .ChatParseException as e :
127132 self ._logger .debug (f"[{ self ._video_id } ]{ str (e )} " )
128133 self ._raise_exception (e )
@@ -139,9 +144,8 @@ def _get_contents(self, continuation, client, headers):
139144 -------
140145 'continuationContents' which includes metadata & chat data.
141146 '''
142- livechat_json = (
143- self ._get_livechat_json (continuation , client , replay = self ._is_replay , offset_ms = self ._last_offset_ms )
144- )
147+ livechat_json = self ._get_livechat_json (
148+ continuation , client , replay = self ._is_replay , offset_ms = self ._last_offset_ms )
145149 contents , dat = self ._parser .get_contents (livechat_json )
146150 if self ._dat == '' and dat :
147151 self ._dat = dat
@@ -152,7 +156,8 @@ def _get_contents(self, continuation, client, headers):
152156 self ._fetch_url = config ._smr
153157 continuation = arcparam .getparam (
154158 self ._video_id , self .seektime , self ._topchat_only , util .get_channelid (client , self ._video_id ))
155- livechat_json = self ._get_livechat_json (continuation , client , replay = True , offset_ms = self .seektime * 1000 )
159+ livechat_json = self ._get_livechat_json (
160+ continuation , client , replay = True , offset_ms = self .seektime * 1000 )
156161 reload_continuation = self ._parser .reload_continuation (
157162 self ._parser .get_contents (livechat_json )[0 ])
158163 if reload_continuation :
@@ -173,15 +178,14 @@ def _get_livechat_json(self, continuation, client, replay: bool, offset_ms: int
173178 offset_ms = 0
174179 param = util .get_param (continuation , dat = self ._dat , replay = replay , offsetms = offset_ms )
175180 for _ in range (MAX_RETRY + 1 ):
176- with httpx .Client (http2 = True ) as client :
177- try :
178- response = client .post (self ._fetch_url , json = param )
179- livechat_json = json .loads (response .text )
180- break
181- except (json .JSONDecodeError , httpx .ConnectTimeout , httpx .ReadTimeout , httpx .ConnectError ) as e :
182- err = e
183- time .sleep (2 )
184- continue
181+ try :
182+ response = client .post (self ._fetch_url , json = param )
183+ livechat_json = response .json ()
184+ break
185+ except (json .JSONDecodeError , httpx .ConnectTimeout , httpx .ReadTimeout , httpx .ConnectError ) as e :
186+ err = e
187+ time .sleep (2 )
188+ continue
185189 else :
186190 self ._logger .error (f"[{ self ._video_id } ]"
187191 f"Exceeded retry count. Last error: { str (err )} " )
@@ -202,6 +206,8 @@ def is_alive(self):
202206 return self ._is_alive
203207
204208 def terminate (self ):
209+ if not self .is_alive ():
210+ return
205211 self ._is_alive = False
206212 self .processor .finalize ()
207213
0 commit comments