add logger & cleanup
This commit is contained in:
+31
-36
@@ -5,7 +5,10 @@ import threading
|
|||||||
import os
|
import os
|
||||||
import wave
|
import wave
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
logging.basicConfig(level = logging.INFO)
|
||||||
|
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
@@ -16,24 +19,14 @@ from websockets.sync.server import serve
|
|||||||
from transcriber import WhisperModel
|
from transcriber import WhisperModel
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
|
||||||
class Constants:
|
|
||||||
AUDIO_OVER = b"audio_data_over"
|
|
||||||
ACK = b"acknowledged"
|
|
||||||
SENDING_FILE = b"sending_audio_file"
|
|
||||||
FILE_SENT = b"audio_file_sent"
|
|
||||||
|
|
||||||
|
|
||||||
RATE = 16000
|
|
||||||
clients = {}
|
clients = {}
|
||||||
client_ids = {}
|
|
||||||
|
|
||||||
|
|
||||||
def recv_audio(websocket):
|
def recv_audio(websocket):
|
||||||
"""
|
"""
|
||||||
Receive audio chunks from client in an infinite loop.
|
Receive audio chunks from client in an infinite loop.
|
||||||
"""
|
"""
|
||||||
client = ServeClient(websocket=websocket)
|
global clients
|
||||||
|
client = ServeClient(websocket)
|
||||||
clients[websocket] = client
|
clients[websocket] = client
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
@@ -45,17 +38,20 @@ def recv_audio(websocket):
|
|||||||
clients[websocket].add_frames(frame_np)
|
clients[websocket].add_frames(frame_np)
|
||||||
|
|
||||||
except websockets.ConnectionClosedOK:
|
except websockets.ConnectionClosedOK:
|
||||||
|
clients[websocket].cleanup()
|
||||||
|
clients.pop(websocket)
|
||||||
|
print(clients)
|
||||||
logging.info("Connection Closed.")
|
logging.info("Connection Closed.")
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
class ServeClient:
|
class ServeClient:
|
||||||
RATE = 16000
|
RATE = 16000
|
||||||
def __init__(self, websocket=None, topic=None, device=None, verbose=True):
|
def __init__(self, websocket, topic=None, device=None):
|
||||||
self.payload_size = struct.calcsize("Q")
|
self.payload_size = struct.calcsize("Q")
|
||||||
self.data = b""
|
self.data = b""
|
||||||
self.frames = b""
|
self.frames = b""
|
||||||
self.transcriber = WhisperModel("small.en", compute_type="float16")
|
self.transcriber = WhisperModel("small.en", compute_type="float16", local_files_only=False)
|
||||||
self.timestamp_offset = 0.0
|
self.timestamp_offset = 0.0
|
||||||
self.frames_np = None
|
self.frames_np = None
|
||||||
self.frames_offset = 0.0
|
self.frames_offset = 0.0
|
||||||
@@ -63,7 +59,6 @@ class ServeClient:
|
|||||||
self.current_out = ''
|
self.current_out = ''
|
||||||
self.prev_out = ''
|
self.prev_out = ''
|
||||||
self.t_start=None
|
self.t_start=None
|
||||||
self.verbose = verbose
|
|
||||||
self.exit = False
|
self.exit = False
|
||||||
self.same_output_threshold = 0
|
self.same_output_threshold = 0
|
||||||
self.show_prev_out_thresh = 5 # if pause(no output from whisper) show previous output for 5 seconds
|
self.show_prev_out_thresh = 5 # if pause(no output from whisper) show previous output for 5 seconds
|
||||||
@@ -83,14 +78,6 @@ class ServeClient:
|
|||||||
self.trans_thread = threading.Thread(target=self.speech_to_text)
|
self.trans_thread = threading.Thread(target=self.speech_to_text)
|
||||||
self.trans_thread.start()
|
self.trans_thread.start()
|
||||||
|
|
||||||
def send_response_to_client(self, message):
|
|
||||||
"""
|
|
||||||
Send serialized response to client.
|
|
||||||
"""
|
|
||||||
a = pickle.dumps(message)
|
|
||||||
message = struct.pack("Q",len(a))+a
|
|
||||||
self.client_socket.sendall(message)
|
|
||||||
|
|
||||||
def fill_output(self, output):
|
def fill_output(self, output):
|
||||||
"""
|
"""
|
||||||
Format output with current and previous complete segments
|
Format output with current and previous complete segments
|
||||||
@@ -114,9 +101,9 @@ class ServeClient:
|
|||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
def add_frames(self, frame_np):
|
def add_frames(self, frame_np):
|
||||||
if self.frames_np is not None and self.frames_np.shape[0] > 45*RATE:
|
if self.frames_np is not None and self.frames_np.shape[0] > 45*self.RATE:
|
||||||
self.frames_offset += 45.0
|
self.frames_offset += 45.0
|
||||||
self.frames_np = self.frames_np[int(30*RATE):]
|
self.frames_np = self.frames_np[int(30*self.RATE):]
|
||||||
if self.frames_np is None:
|
if self.frames_np is None:
|
||||||
self.frames_np = frame_np.copy()
|
self.frames_np = frame_np.copy()
|
||||||
else:
|
else:
|
||||||
@@ -127,15 +114,12 @@ class ServeClient:
|
|||||||
Process audio stream in an infinite loop.
|
Process audio stream in an infinite loop.
|
||||||
"""
|
"""
|
||||||
while True:
|
while True:
|
||||||
if self.exit:
|
if self.exit:
|
||||||
self.transcriber.destroy()
|
logging.info("Exiting speech to text thread")
|
||||||
break
|
break
|
||||||
if self.frames_np is None:
|
|
||||||
logging.info("No frames to process.")
|
|
||||||
continue
|
|
||||||
|
|
||||||
if self.websocket is None:
|
if self.frames_np is None:
|
||||||
logging.info("Websocket is None.")
|
continue
|
||||||
|
|
||||||
# clip audio if the current chunk exceeds 30 seconds, this basically implies that
|
# clip audio if the current chunk exceeds 30 seconds, this basically implies that
|
||||||
# no valid segment for the last 30 seconds from whisper
|
# no valid segment for the last 30 seconds from whisper
|
||||||
@@ -171,8 +155,10 @@ class ServeClient:
|
|||||||
'text': output,
|
'text': output,
|
||||||
'segments': segments
|
'segments': segments
|
||||||
}
|
}
|
||||||
|
try:
|
||||||
self.websocket.send(str(out_dict))
|
self.websocket.send(str(out_dict))
|
||||||
|
except Exception as e:
|
||||||
|
logging.info(f"[ERROR]: {e}")
|
||||||
else:
|
else:
|
||||||
# show previous output if there is pause i.e. no output from whisper
|
# show previous output if there is pause i.e. no output from whisper
|
||||||
output = ''
|
output = ''
|
||||||
@@ -194,9 +180,12 @@ class ServeClient:
|
|||||||
'segments': segments
|
'segments': segments
|
||||||
}
|
}
|
||||||
|
|
||||||
self.websocket.send(str(out_dict))
|
try:
|
||||||
|
self.websocket.send(str(out_dict))
|
||||||
|
except Exception as e:
|
||||||
|
logging.info(f"[INFO]: {e}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if self.verbose: logging.error(f"[ERROR]: {e}")
|
logging.info(f"[INFO]: {e}")
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
|
|
||||||
def update_segments(self, segments, duration):
|
def update_segments(self, segments, duration):
|
||||||
@@ -269,6 +258,12 @@ class ServeClient:
|
|||||||
output = self.current_out
|
output = self.current_out
|
||||||
return self.fill_output(output), last_segment
|
return self.fill_output(output), last_segment
|
||||||
|
|
||||||
|
def cleanup(self):
|
||||||
|
logging.info("Cleaning up.")
|
||||||
|
self.exit = True
|
||||||
|
self.transcriber.destroy()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
with serve(recv_audio, "127.0.0.1", 9090) as server:
|
with serve(recv_audio, "127.0.0.1", 9090) as server:
|
||||||
|
|||||||
Reference in New Issue
Block a user