2024-09-02 00:13:34 +00:00
|
|
|
#encoding = utf8
|
|
|
|
import json
|
|
|
|
import logging
|
2024-09-26 12:28:49 +00:00
|
|
|
import os
|
2024-09-04 16:51:14 +00:00
|
|
|
from logging import handlers
|
2024-09-02 00:13:34 +00:00
|
|
|
import tkinter
|
|
|
|
import tkinter.messagebox
|
|
|
|
import customtkinter
|
2024-09-25 06:37:15 +00:00
|
|
|
import cv2
|
2024-09-02 00:13:34 +00:00
|
|
|
import requests
|
2024-09-26 12:28:49 +00:00
|
|
|
import winsound
|
2024-09-12 00:15:09 +00:00
|
|
|
from PIL import Image, ImageTk
|
2024-09-02 00:13:34 +00:00
|
|
|
|
2024-09-26 12:28:49 +00:00
|
|
|
from playsound import playsound
|
|
|
|
|
2024-09-02 00:13:34 +00:00
|
|
|
from Human import Human
|
|
|
|
from tts.EdgeTTS import EdgeTTS
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
customtkinter.set_appearance_mode("System") # Modes: "System" (standard), "Dark", "Light"
|
|
|
|
customtkinter.set_default_color_theme("green") # Themes: "blue" (standard), "green", "dark-blue"
|
|
|
|
|
|
|
|
|
|
|
|
class App(customtkinter.CTk):
|
|
|
|
def __init__(self):
|
|
|
|
super().__init__()
|
|
|
|
|
|
|
|
self._tts_url = 'http://localhost:8080'
|
|
|
|
|
|
|
|
# configure window
|
2024-09-26 12:28:49 +00:00
|
|
|
self.title("TTS demo")
|
2024-09-02 00:13:34 +00:00
|
|
|
self.geometry(f"{1100}x{580}")
|
|
|
|
|
|
|
|
self.grid_columnconfigure(1, weight=1)
|
|
|
|
self.grid_rowconfigure((0, 1), weight=1)
|
|
|
|
|
|
|
|
self.image_frame = customtkinter.CTkFrame(self, corner_radius=10)
|
|
|
|
self.image_frame.grid(row=0, column=0, rowspan=2, columnspan=3,
|
|
|
|
padx=(20, 20), pady=(20, 0), sticky="nsew")
|
|
|
|
self.image_frame.grid_rowconfigure(0, weight=1)
|
|
|
|
self.logo_label = customtkinter.CTkLabel(self.image_frame, text="CustomTkinter",
|
|
|
|
font=customtkinter.CTkFont(size=20, weight="bold"))
|
|
|
|
# self.logo_label.grid(row=0, column=0, padx=20, pady=(20, 10))
|
|
|
|
|
|
|
|
self.entry = customtkinter.CTkEntry(self, placeholder_text="输入内容")
|
2024-10-03 17:52:49 +00:00
|
|
|
self.entry.insert(0, "你好,我是中国湘西人。")
|
2024-09-02 00:13:34 +00:00
|
|
|
self.entry.grid(row=2, column=0, columnspan=2, padx=(20, 0), pady=(20, 20), sticky="nsew")
|
|
|
|
|
|
|
|
self.main_button_1 = customtkinter.CTkButton(master=self, fg_color="transparent", border_width=2,
|
|
|
|
text_color=("gray10", "#DCE4EE"), text='发送',
|
|
|
|
command=self.request_tts)
|
|
|
|
self.main_button_1.grid(row=2, column=2, padx=(20, 20), pady=(20, 20), sticky="nsew")
|
|
|
|
|
|
|
|
self._init_image_canvas()
|
|
|
|
|
2024-09-26 12:28:49 +00:00
|
|
|
self._is_play_audio = False
|
2024-09-02 00:13:34 +00:00
|
|
|
self._human = Human()
|
2024-09-12 00:15:09 +00:00
|
|
|
self._render()
|
2024-09-26 12:28:49 +00:00
|
|
|
# self.play_audio()
|
2024-09-02 00:13:34 +00:00
|
|
|
|
2024-09-04 16:51:14 +00:00
|
|
|
def on_destroy(self):
|
|
|
|
logger.info('------------App destroy------------')
|
|
|
|
self._human.on_destroy()
|
|
|
|
|
2024-09-26 12:28:49 +00:00
|
|
|
def play_audio(self):
|
2024-09-28 18:47:04 +00:00
|
|
|
return
|
|
|
|
# if self._is_play_audio:
|
|
|
|
# return
|
|
|
|
# self._is_play_audio = True
|
|
|
|
# file = os.path.curdir + '/audio/test1.wav'
|
|
|
|
# print(file)
|
|
|
|
# winsound.PlaySound(file, winsound.SND_ASYNC or winsound.SND_FILENAME)
|
2024-09-26 12:28:49 +00:00
|
|
|
# playsound(file)
|
|
|
|
|
2024-09-02 00:13:34 +00:00
|
|
|
def _init_image_canvas(self):
|
|
|
|
self._canvas = customtkinter.CTkCanvas(self.image_frame)
|
|
|
|
self._canvas.pack(fill=customtkinter.BOTH, expand=customtkinter.YES)
|
|
|
|
|
2024-09-12 00:15:09 +00:00
|
|
|
def _render(self):
|
|
|
|
image = self._human.render()
|
|
|
|
if image is None:
|
|
|
|
self.after(100, self._render)
|
|
|
|
return
|
|
|
|
|
2024-10-03 17:52:49 +00:00
|
|
|
# self.play_audio()
|
2024-09-25 06:37:15 +00:00
|
|
|
iheight, iwidth = image.shape[0], image.shape[1]
|
|
|
|
width = self.winfo_width()
|
|
|
|
height = self.winfo_height()
|
|
|
|
if iheight / iwidth >= width / height:
|
|
|
|
image = cv2.resize(image, (int(width), int(iheight * width / iwidth)))
|
|
|
|
else:
|
|
|
|
image = cv2.resize(image, (int(iwidth * height / iheight), int(height)), interpolation=cv2.INTER_AREA)
|
|
|
|
# image = cv2.resize(image, (int(width), int(height)), interpolation=cv2.INTER_AREA)
|
|
|
|
|
|
|
|
# image = cv2.resize(image, (int(width), int(height)), interpolation=cv2.INTER_AREA)
|
|
|
|
|
2024-09-12 00:15:09 +00:00
|
|
|
img = Image.fromarray(image)
|
2024-09-25 06:37:15 +00:00
|
|
|
|
2024-09-12 00:15:09 +00:00
|
|
|
imgtk = ImageTk.PhotoImage(image=img)
|
|
|
|
|
|
|
|
self._canvas.delete("all")
|
|
|
|
|
|
|
|
self._canvas.imgtk = imgtk
|
|
|
|
width = self.winfo_width() * 0.5
|
|
|
|
height = self.winfo_height() * 0.5
|
|
|
|
self._canvas.create_image(width, height, anchor=customtkinter.CENTER, image=imgtk)
|
|
|
|
self._canvas.update()
|
2024-09-28 18:47:04 +00:00
|
|
|
self.after(40, self._render)
|
2024-09-12 00:15:09 +00:00
|
|
|
|
2024-09-02 00:13:34 +00:00
|
|
|
def request_tts(self):
|
|
|
|
content = self.entry.get()
|
2024-09-28 18:47:04 +00:00
|
|
|
# content = ''
|
2024-09-02 00:13:34 +00:00
|
|
|
print('content:', content)
|
|
|
|
self.entry.delete(0, customtkinter.END)
|
2024-09-04 16:51:14 +00:00
|
|
|
self._human.read(content)
|
|
|
|
# payload = {
|
|
|
|
# 'text': content,
|
|
|
|
# 'voice': 'zh-CN-XiaoyiNeural'
|
|
|
|
# }
|
|
|
|
# resp = requests.get(self._tts_url + '/tts', params=urlencode(payload))
|
|
|
|
# if resp.status_code != 200:
|
|
|
|
# print('tts error', resp.status_code)
|
|
|
|
# return
|
|
|
|
#
|
|
|
|
# print(resp.content)
|
|
|
|
#
|
|
|
|
# resJson = json.loads(resp.text)
|
|
|
|
# url = resJson.get('url')
|
|
|
|
# self.download_tts(url)
|
2024-09-02 00:13:34 +00:00
|
|
|
|
|
|
|
def download_tts(self, url):
|
|
|
|
file_name = url[3:]
|
|
|
|
print(file_name)
|
|
|
|
download_url = self._tts_url + url
|
|
|
|
print('download tts', download_url)
|
|
|
|
resp = requests.get(download_url)
|
|
|
|
with open('./audio/mp3/' + file_name, 'wb') as mp3:
|
|
|
|
mp3.write(resp.content)
|
|
|
|
|
|
|
|
from pydub import AudioSegment
|
|
|
|
sound = AudioSegment.from_mp3('./audio/mp3/' + file_name)
|
|
|
|
sound.export('./audio/wav/' + file_name + '.wav', format="wav")
|
|
|
|
|
|
|
|
# open('./audio/', 'wb') with
|
|
|
|
|
|
|
|
|
2024-09-04 16:51:14 +00:00
|
|
|
def config_logging(file_name: str, console_level: int=logging.INFO, file_level: int=logging.DEBUG):
|
|
|
|
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)
|
2024-09-02 00:13:34 +00:00
|
|
|
|
2024-09-04 16:51:14 +00:00
|
|
|
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)
|
2024-09-09 00:30:15 +00:00
|
|
|
|
2024-09-04 16:51:14 +00:00
|
|
|
logger.info('------------start------------')
|
2024-09-02 00:13:34 +00:00
|
|
|
app = App()
|
|
|
|
app.mainloop()
|
2024-09-04 16:51:14 +00:00
|
|
|
app.on_destroy()
|
|
|
|
# logger.info('------------exit------------')
|