99from typing import Optional , Callable , Union , TYPE_CHECKING
1010import logging
1111
12+ import websockets
13+
1214from ...utils import verboselogs
1315from .constants import LOGGING , CHANNELS , RATE , CHUNK , TIMEOUT
1416
@@ -24,22 +26,22 @@ class Speaker: # pylint: disable=too-many-instance-attributes
2426 _logger : verboselogs .VerboseLogger
2527
2628 _audio : "pyaudio.PyAudio"
27- _stream : "pyaudio.Stream"
29+ _stream : Optional [ "pyaudio.Stream" ] = None
2830
2931 _chunk : int
3032 _rate : int
3133 _channels : int
32- _output_device_index : Optional [int ]
34+ _output_device_index : Optional [int ] = None
3335
3436 _queue : queue .Queue
3537 _exit : threading .Event
3638
37- _thread : threading .Thread
39+ _thread : Optional [ threading .Thread ] = None
3840 # _asyncio_loop: asyncio.AbstractEventLoop
3941 # _asyncio_thread: threading.Thread
40- _receiver_thread : threading .Thread
42+ _receiver_thread : Optional [ threading .Thread ] = None
4143
42- _loop : asyncio .AbstractEventLoop
44+ _loop : Optional [ asyncio .AbstractEventLoop ] = None
4345
4446 _push_callback_org : Optional [Callable ] = None
4547 _push_callback : Optional [Callable ] = None
@@ -217,6 +219,17 @@ async def _start_asyncio_receiver(self):
217219 elif isinstance (message , bytes ):
218220 self ._logger .verbose ("Received audio data..." )
219221 self .add_audio_to_queue (message )
222+ except websockets .exceptions .ConnectionClosedOK as e :
223+ self ._logger .debug ("send() exiting gracefully: %d" , e .code )
224+ except websockets .exceptions .ConnectionClosed as e :
225+ if e .code in [1000 , 1001 ]:
226+ self ._logger .debug ("send() exiting gracefully: %d" , e .code )
227+ return
228+ self ._logger .error ("_start_asyncio_receiver - ConnectionClosed: %s" , str (e ))
229+ except websockets .exceptions .WebSocketException as e :
230+ self ._logger .error (
231+ "_start_asyncio_receiver- WebSocketException: %s" , str (e )
232+ )
220233 except Exception as e : # pylint: disable=broad-except
221234 self ._logger .error ("_start_asyncio_receiver exception: %s" , str (e ))
222235
@@ -266,23 +279,26 @@ def finish(self) -> bool:
266279 self ._logger .notice ("stopping stream..." )
267280 self ._stream .stop_stream ()
268281 self ._stream .close ()
269- self ._stream = None # type: ignore
282+ self ._stream = None
270283 self ._logger .notice ("stream stopped" )
271284
272- self ._thread .join ()
273- self ._thread = None # type: ignore
285+ if self ._thread is not None :
286+ self ._logger .notice ("joining thread..." )
287+ self ._thread .join ()
288+ self ._thread = None
289+ self ._logger .notice ("thread stopped" )
274290
275291 # if self._asyncio_thread is not None:
276292 # self._logger.notice("stopping asyncio loop...")
277293 # self._asyncio_loop.call_soon_threadsafe(self._asyncio_loop.stop)
278294 # self._asyncio_thread.join()
279- # self._asyncio_thread = None # type: ignore
295+ # self._asyncio_thread = None
280296 # self._logger.notice("_asyncio_thread joined")
281297
282298 if self ._receiver_thread is not None :
283299 self ._logger .notice ("stopping asyncio loop..." )
284300 self ._receiver_thread .join ()
285- self ._receiver_thread = None # type: ignore
301+ self ._receiver_thread = None
286302 self ._logger .notice ("_receiver_thread joined" )
287303
288304 self ._queue = None # type: ignore
0 commit comments