TDN-M commited on
Commit
b7935b6
·
verified ·
1 Parent(s): 93ff1fe

Update tts.py

Browse files
Files changed (1) hide show
  1. tts.py +125 -104
tts.py CHANGED
@@ -1,116 +1,137 @@
 
 
1
  import os
2
- import re
3
- import torch
4
- import torchaudio
5
- from huggingface_hub import snapshot_download, hf_hub_download
6
- from TTS.tts.configs.xtts_config import XttsConfig
7
- from TTS.tts.models.xtts import Xtts
8
- from vinorm import TTSnorm
9
-
10
- # Cấu hình đường dẫn tải hình
11
- checkpoint_dir = "model/"
12
- repo_id = "capleaf/viXTTS"
13
- use_deepspeed = False
14
-
15
- # Tạo thư mục nếu chưa tồn tại
16
- os.makedirs(checkpoint_dir, exist_ok=True)
17
-
18
- # Kiểm tra và tải các file cần thiết
19
- required_files = ["model.pth", "config.json", "vocab.json", "speakers_xtts.pth"]
20
- files_in_dir = os.listdir(checkpoint_dir)
21
- if not all(file in files_in_dir for file in required_files):
22
- snapshot_download(
23
- repo_id=repo_id,
24
- repo_type="model",
25
- local_dir=checkpoint_dir,
26
- )
27
- hf_hub_download(
28
- repo_id="coqui/XTTS-v2",
29
- filename="speakers_xtts.pth",
30
- local_dir=checkpoint_dir,
31
- )
32
-
33
- # Tải cấu hình và mô hình
34
- xtts_config = os.path.join(checkpoint_dir, "config.json")
35
- config = XttsConfig()
36
- config.load_json(xtts_config)
37
- MODEL = Xtts.init_from_config(config)
38
- MODEL.load_checkpoint(config, checkpoint_dir=checkpoint_dir, use_deepspeed=use_deepspeed)
39
-
40
- # Sử dụng GPU nếu có
41
- if torch.cuda.is_available():
42
- MODEL.cuda()
43
-
44
- # Danh sách ngôn ngữ được hỗ trợ (chỉ tiếng Việt và tiếng Anh)
45
- supported_languages = ["vi", "en"]
46
-
47
-
48
- def normalize_vietnamese_text(text):
49
  """
50
- Chuẩn hóa văn bản tiếng Việt.
51
  """
52
- text = (
53
- TTSnorm(text, unknown=False, lower=False, rule=True)
54
- .replace("..", ".")
55
- .replace("!.", "!")
56
- .replace("?.", "?")
57
- .replace(" .", ".")
58
- .replace(" ,", ",")
59
- .replace('"', "")
60
- .replace("'", "")
61
- .replace("AI", "Ây Ai")
62
- .replace("A.I", "Ây Ai")
63
- )
64
- return text
65
-
66
 
67
- def generate_speech(text, language="vi", speaker_wav=None, normalize_text=True):
68
  """
69
- Tạo giọng nói từ văn bản.
70
  """
71
- if language not in supported_languages:
72
- raise ValueError(f"Ngôn ngữ {language} không được hỗ trợ. Chỉ hỗ trợ tiếng Việt (vi) và tiếng Anh (en).")
 
 
 
73
 
74
- if len(text) < 2:
75
- raise ValueError("Văn bản quá ngắn. Vui lòng nhập văn bản dài hơn.")
 
 
 
 
 
 
 
76
 
 
 
 
 
77
  try:
78
- # Chuẩn hóa văn bản nếu cần
79
- if normalize_text and language == "vi":
80
- text = normalize_vietnamese_text(text)
81
-
82
- # Lấy latent và embedding từ file âm thanh mẫu
83
- gpt_cond_latent, speaker_embedding = MODEL.get_conditioning_latents(
84
- audio_path=speaker_wav,
85
- gpt_cond_len=30,
86
- gpt_cond_chunk_len=4,
87
- max_ref_length=60,
88
- )
89
-
90
- # Tạo giọng nói
91
- out = MODEL.inference(
92
- text,
93
- language,
94
- gpt_cond_latent,
95
- speaker_embedding,
96
- repetition_penalty=5.0,
97
- temperature=0.75,
98
- enable_text_splitting=True,
99
- )
100
-
101
- # Lưu file âm thanh
102
- output_file = "output.wav"
103
- torchaudio.save(output_file, torch.tensor(out["wav"]).unsqueeze(0), 24000)
104
-
105
- return output_file
106
-
107
  except Exception as e:
108
- raise RuntimeError(f"Lỗi khi tạo giọng nói: {str(e)}")
109
-
110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  if __name__ == "__main__":
112
- # dụ sử dụng
113
- text = "Xin chào, đây là một đoạn văn bản được chuyển thành giọng nói."
114
- speaker_wav = "voices/sample_voice.wav" # Đường dẫn đến file âm thanh mẫu trong thư mục /voices
115
- output_audio = generate_speech(text, language="vi", speaker_wav=speaker_wav)
116
- print(f"File âm thanh đã được tạo: {output_audio}")
 
1
+ import asyncio
2
+ import mimetypes
3
  import os
4
+ import tempfile
5
+ import glob
6
+ import fitz # PyMuPDF
7
+ import random
8
+ import gradio as gr
9
+ from docx import Document
10
+ from content_generation import create_content, CONTENT_TYPES
11
+ from openai import OpenAI
12
+ from gradio_client import Client, handle_file # Thêm thư viện để gọi API
13
+ from tts import generate_speech
14
+
15
+ # Khởi tạo client OpenAI với API key từ biến môi trường
16
+ client = OpenAI(api_key=os.environ.get('OPENAI_API_KEY'))
17
+
18
+ # Đường dẫn đến thư mục chứa các file âm thanh
19
+ VOICES_DIR = "voices"
20
+
21
+ def create_docx(content, output_path):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  """
23
+ Tạo file docx từ nội dung.
24
  """
25
+ doc = Document()
26
+ doc.add_paragraph(content)
27
+ doc.save(output_path)
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ def process_pdf(file_path):
30
  """
31
+ Xử file PDF trích xuất nội dung.
32
  """
33
+ doc = fitz.open(file_path)
34
+ text = ""
35
+ for page in doc:
36
+ text += page.get_text()
37
+ return text
38
 
39
+ def process_docx(file_path):
40
+ """
41
+ Xử lý file DOCX và trích xuất nội dung.
42
+ """
43
+ doc = Document(file_path)
44
+ text = ""
45
+ for para in doc.paragraphs:
46
+ text += para.text
47
+ return text
48
 
49
+ def text_to_speech(content, voice_file):
50
+ """
51
+ Chuyển đổi nội dung thành giọng nói bằng hàm generate_speech từ tts.py.
52
+ """
53
  try:
54
+ # Gọi hàm generate_speech để tạo file âm thanh
55
+ output_audio = generate_speech(content, language="vi", speaker_wav=voice_file)
56
+ return output_audio
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  except Exception as e:
58
+ return f"Lỗi khi chuyển đổi văn bản thành giọng nói: {str(e)}"
 
59
 
60
+ def convert_content_to_speech(content, voice_file):
61
+ """
62
+ Chuyển đổi nội dung thành giọng nói.
63
+ """
64
+ return text_to_speech(content, voice_file)
65
+
66
+
67
+ def interface():
68
+ with gr.Blocks() as app:
69
+ gr.Markdown("# Ứng dụng Tạo Nội dung và Video")
70
+
71
+ with gr.Tab("Tạo Nội dung"):
72
+ with gr.Row():
73
+ with gr.Column():
74
+ prompt = gr.Textbox(label="Nhập yêu cầu nội dung")
75
+ file_upload = gr.File(label="Tải lên file kèm theo", type="filepath")
76
+ content_type = gr.Radio(label="Chọn loại nội dung",
77
+ choices=CONTENT_TYPES,
78
+ value=None) # Giá trị mặc định là không có gì được chọn
79
+ voice_files = [os.path.join(VOICES_DIR, f) for f in os.listdir(VOICES_DIR) if f.endswith(".wav")]
80
+ voice_selector = gr.Dropdown(label="Chọn giọng đọc", choices=voice_files) # Dropdown để chọn file âm thanh
81
+ content_button = gr.Button("Tạo Nội dung")
82
+
83
+ with gr.Column():
84
+ content_output = gr.Textbox(label="Nội dung tạo ra", interactive=True)
85
+ confirm_button = gr.Button("Xác nhận nội dung")
86
+ download_docx = gr.File(label="Tải xuống file DOCX", interactive=False)
87
+ status_message = gr.Label(label="Trạng thái")
88
+ convert_to_speech_button = gr.Button("Chuyển đổi thành giọng nói")
89
+ audio_output = gr.Audio(label="Synthesised Audio", autoplay=True) # Phát tự động
90
+
91
+ def generate_content(prompt, file, content_type):
92
+ try:
93
+ status = "Đang xử lý..."
94
+ if file and os.path.exists(file):
95
+ mime_type, _ = mimetypes.guess_type(file)
96
+ if mime_type == "application/pdf":
97
+ file_content = process_pdf(file)
98
+ prompt = f"{prompt}\n\nDưới đây là nội dung của file tài liệu:\n\n{file_content}"
99
+ elif mime_type in (
100
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
101
+ "application/msword"):
102
+ file_content = process_docx(file)
103
+ prompt = f"{prompt}\n\nDưới đây là nội dung của file tài liệu:\n\n{file_content}"
104
+ else:
105
+ raise ValueError("Định dạng file không được hỗ trợ.")
106
+
107
+ if not content_type:
108
+ raise ValueError("Vui lòng chọn một loại nội dung")
109
+
110
+ script_content = create_content(prompt, content_type, "Tiếng Việt")
111
+ docx_path = "script.docx"
112
+ create_docx(script_content, docx_path)
113
+
114
+ status = "Đã tạo nội dung thành công!"
115
+ return script_content, docx_path, status
116
+ except Exception as e:
117
+ status = f"Đã xảy ra lỗi: {str(e)}"
118
+ return "", None, status
119
+
120
+ async def confirm_content(content):
121
+ docx_path = "script.docx"
122
+ create_docx(content, docx_path)
123
+
124
+ content_button.click(generate_content,
125
+ inputs=[prompt, file_upload, content_type],
126
+ outputs=[content_output, download_docx, status_message])
127
+
128
+ convert_to_speech_button.click(convert_content_to_speech,
129
+ inputs=[content_output, voice_selector],
130
+ outputs=[audio_output])
131
+
132
+ return app
133
+
134
+ # Khởi chạy ứng dụng
135
  if __name__ == "__main__":
136
+ app = interface()
137
+ app.launch(share=True)