添加chunk处理

This commit is contained in:
jiegeaiai 2024-09-05 00:51:14 +08:00
parent 9569009f32
commit b0753a5220
5 changed files with 112 additions and 19 deletions

View File

@ -1,14 +1,50 @@
#encoding = utf8 #encoding = utf8
import logging
import queue
from queue import Queue from queue import Queue
import numpy as np
from tts.Chunk2Mal import Chunk2Mal
logger = logging.getLogger(__name__)
class Human: class Human:
def __init__(self): def __init__(self):
self._tts = None self._tts = None
self._audio_chunk_queue = Queue() self._fps = 25 # 20 ms per frame
self._sample_rate = 16000
self._chunk = self._sample_rate // self._fps # 320 samples per chunk (20ms * 16000 / 1000)
self._chunk_2_mal = Chunk2Mal()
def on_destroy(self):
if self._tts is not None:
self._tts.stop()
logger.info('human destroy')
def set_tts(self, tts): def set_tts(self, tts):
if self._tts == tts:
return
self._tts = tts self._tts = tts
self._tts.start()
def read(self, txt):
if self._tts is None:
logger.warning('tts is none')
return
self._tts.push_txt(txt)
def push_audio_chunk(self, chunk): def push_audio_chunk(self, chunk):
pass self._chunk_2_mal.push_chunk(chunk)
self._audio_chunk_queue.put(chunk)
def pull_audio_chunk(self):
try:
chunk = self._audio_chunk_queue.get(block=True, timeout=1.0)
type = 1
except queue.Empty:
chunk = np.zeros(self._chunk, dtype=np.float32)
type = 0
return chunk, type

View File

@ -2,7 +2,7 @@ librosa~=0.10.2.post1
numpy~=1.26.3 numpy~=1.26.3
opencv-contrib-python opencv-contrib-python
opencv-python~=4.10.0.84 opencv-python~=4.10.0.84
torch~=2.4.0+cu118 torch
torchvision torchvision
tqdm~=4.66.5 tqdm~=4.66.5
numba numba

11
tts/Chunk2Mal.py Normal file
View File

@ -0,0 +1,11 @@
#encoding = utf8
from queue import Queue
class Chunk2Mal:
def __init__(self):
self._audio_chunk_queue = Queue()
def push_chunk(self, chunk):
self._audio_chunk_queue.put(chunk)

View File

@ -1,4 +1,5 @@
#encoding = utf8 #encoding = utf8
import logging
import queue import queue
from io import BytesIO from io import BytesIO
from queue import Queue from queue import Queue
@ -17,12 +18,14 @@ class TTSBase:
self._chunk = self._sample_rate // self._fps self._chunk = self._sample_rate // self._fps
def _on_run(self): def _on_run(self):
logging.info('tts run')
while not self._exit_event.is_set(): while not self._exit_event.is_set():
try: try:
txt = self._queue.get(block=True, timeout=1) txt = self._queue.get(block=True, timeout=1)
except queue.Empty: except queue.Empty:
continue continue
self._request(txt) self._request(txt)
logging.info('tts exit')
def _request(self, txt): def _request(self, txt):
pass pass
@ -33,6 +36,7 @@ class TTSBase:
self._exit_event = Event() self._exit_event = Event()
self._thread = Thread(target=self._on_run) self._thread = Thread(target=self._on_run)
self._thread.start() self._thread.start()
logging.info('tts start')
def stop(self): def stop(self):
if self._exit_event is None: if self._exit_event is None:
@ -40,6 +44,7 @@ class TTSBase:
self._exit_event.set() self._exit_event.set()
self._thread.join() self._thread.join()
logging.info('tts stop')
def clear(self): def clear(self):
self._queue.queue.clear() self._queue.queue.clear()

73
ui.py
View File

@ -1,6 +1,7 @@
#encoding = utf8 #encoding = utf8
import json import json
import logging import logging
from logging import handlers
import tkinter import tkinter
import tkinter.messagebox import tkinter.messagebox
import customtkinter import customtkinter
@ -52,6 +53,10 @@ class App(customtkinter.CTk):
tts = EdgeTTS(self._human) tts = EdgeTTS(self._human)
self._human.set_tts(tts) self._human.set_tts(tts)
def on_destroy(self):
logger.info('------------App destroy------------')
self._human.on_destroy()
def _init_image_canvas(self): def _init_image_canvas(self):
self._canvas = customtkinter.CTkCanvas(self.image_frame) self._canvas = customtkinter.CTkCanvas(self.image_frame)
self._canvas.pack(fill=customtkinter.BOTH, expand=customtkinter.YES) self._canvas.pack(fill=customtkinter.BOTH, expand=customtkinter.YES)
@ -60,20 +65,21 @@ class App(customtkinter.CTk):
content = self.entry.get() content = self.entry.get()
print('content:', content) print('content:', content)
self.entry.delete(0, customtkinter.END) self.entry.delete(0, customtkinter.END)
payload = { self._human.read(content)
'text': content, # payload = {
'voice': 'zh-CN-XiaoyiNeural' # 'text': content,
} # 'voice': 'zh-CN-XiaoyiNeural'
resp = requests.get(self._tts_url + '/tts', params=urlencode(payload)) # }
if resp.status_code != 200: # resp = requests.get(self._tts_url + '/tts', params=urlencode(payload))
print('tts error', resp.status_code) # if resp.status_code != 200:
return # print('tts error', resp.status_code)
# return
print(resp.content) #
# print(resp.content)
resJson = json.loads(resp.text) #
url = resJson.get('url') # resJson = json.loads(resp.text)
self.download_tts(url) # url = resJson.get('url')
# self.download_tts(url)
def download_tts(self, url): def download_tts(self, url):
file_name = url[3:] file_name = url[3:]
@ -91,8 +97,43 @@ class App(customtkinter.CTk):
# open('./audio/', 'wb') with # open('./audio/', 'wb') with
if __name__ == "__main__": def config_logging(file_name: str, console_level: int=logging.INFO, file_level: int=logging.DEBUG):
logging.basicConfig(filename='./logs/info.log', level=logging.INFO) file_handler = logging.FileHandler(file_name, mode='a', encoding="utf8")
file_handler.setFormatter(logging.Formatter(
'%(asctime)s [%(levelname)s] %(module)s.%(lineno)d %(name)s:\t%(message)s'
))
file_handler.setLevel(file_level)
console_handler = logging.StreamHandler()
console_handler.setFormatter(logging.Formatter(
'[%(asctime)s %(levelname)s] %(message)s',
datefmt="%Y/%m/%d %H:%M:%S"
))
console_handler.setLevel(console_level)
logging.basicConfig(
level=min(console_level, file_level),
handlers=[file_handler, console_handler],
)
if __name__ == "__main__":
# logging.basicConfig(filename='./logs/info.log', level=logging.INFO)
config_logging('./logs/info.log', logging.INFO, logging.INFO)
# logger = logging.getLogger('manager')
# # 输出到控制台, 级别为DEBUG
# console = logging.StreamHandler()
# console.setLevel(logging.DEBUG)
# logger.addHandler(console)
#
# # 输出到文件, 级别为INFO, 文件按大小切分
# filelog = logging.handlers.RotatingFileHandler(filename='./logs/info.log', level=logging.INFO,
# maxBytes=1024 * 1024, backupCount=5)
# filelog.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
# logger.setLevel(logging.INFO)
# logger.addHandler(filelog)
logger.info('------------start------------')
app = App() app = App()
app.mainloop() app.mainloop()
app.on_destroy()
# logger.info('------------exit------------')