human/ui.py

168 lines
5.7 KiB
Python
Raw Normal View History

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-10-17 00:25:53 +00:00
import queue
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
2024-10-17 00:25:53 +00:00
from queue import Queue
2024-09-02 00:13:34 +00:00
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-10-17 00:25:53 +00:00
from human import HumanContext
2024-10-31 18:31:59 +00:00
from utils import config_logging, read_image
2024-10-17 15:26:21 +00:00
2024-10-17 00:25:53 +00:00
# from tts.EdgeTTS import EdgeTTS
2024-09-02 00:13:34 +00:00
logger = logging.getLogger(__name__)
2024-10-31 18:31:59 +00:00
current_file_path = os.path.dirname(os.path.abspath(__file__))
2024-09-02 00:13:34 +00:00
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-10-18 00:15:48 +00:00
self.geometry(f"{1150}x{580}")
2024-09-02 00:13:34 +00:00
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))
2024-10-31 18:31:59 +00:00
# self.entry = customtkinter.CTkEntry(self, placeholder_text="输入内容")
# self.entry.insert(0, "大家好,测试虚拟数字人。")
# 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")
background = os.path.join(current_file_path, 'data', 'background', 'background.webp')
logger.info(f'background: {background}')
2024-11-01 12:38:57 +00:00
# self._background = ImageTk.PhotoImage(read_image(background))
2024-09-02 00:13:34 +00:00
self._init_image_canvas()
2024-10-17 00:25:53 +00:00
# self._human = Human()
self._queue = Queue()
self._human_context = HumanContext()
self._human_context.build()
render = self._human_context.render_handler
render.set_image_render(self)
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-10-04 10:10:03 +00:00
def destroy(self):
self.on_destroy()
super().destroy()
2024-09-04 16:51:14 +00:00
def on_destroy(self):
logger.info('------------App destroy------------')
2024-10-17 00:25:53 +00:00
# self._human.on_destroy()
def render_image(self, image):
self._queue.put(image)
2024-09-26 12:28:49 +00:00
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):
2024-10-18 00:15:48 +00:00
after_time = 24
2024-10-17 00:25:53 +00:00
try:
2024-10-17 15:26:21 +00:00
image = self._queue.get(block=True, timeout=0.003)
2024-10-17 00:25:53 +00:00
if image is None:
2024-10-17 15:26:21 +00:00
self.after(after_time, self._render)
2024-10-17 00:25:53 +00:00
return
except queue.Empty:
2024-10-17 15:26:21 +00:00
self.after(after_time, self._render)
2024-09-12 00:15:09 +00:00
return
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)
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
2024-10-31 18:31:59 +00:00
2024-09-12 00:15:09 +00:00
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-10-17 15:26:21 +00:00
self.after(after_time, 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-10-04 08:44:06 +00:00
self._human.pause_talk()
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")
2024-10-17 15:26:21 +00:00
def on_render(self, image):
self._queue.put(image)
2024-09-04 16:51:14 +00:00
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-10-04 10:10:03 +00:00
# app.on_destroy()
logger.info('------------exit------------')