|
4 | 4 | import subprocess |
5 | 5 | import tkinter as tk |
6 | 6 | from tkinter import ttk, filedialog, messagebox |
| 7 | +from datetime import datetime |
7 | 8 |
|
8 | 9 | KOKORO_PATH = r"F:\AI\kokoro-tts\kokoro.bat" |
9 | 10 |
|
@@ -82,12 +83,14 @@ def create_widgets(self): |
82 | 83 | self.lang_dropdown.bind("<<ComboboxSelected>>", self.update_lang_code) |
83 | 84 |
|
84 | 85 | ttk.Label(voice_frame, text="Speed:").grid(row=0, column=4, padx=5, sticky="w") |
85 | | - self.speed_var = tk.DoubleVar(value=1.0) |
86 | | - ttk.Spinbox(voice_frame, from_=0.5, to=2.0, increment=0.1, textvariable=self.speed_var, width=5).grid(row=0, column=5, padx=5) |
| 86 | + self.speed_var = tk.DoubleVar(value=0.8) |
| 87 | + ttk.Spinbox(voice_frame, from_=0.5, to=2.0, increment=0.1, |
| 88 | + textvariable=self.speed_var, width=5).grid(row=0, column=5, padx=5) |
87 | 89 |
|
88 | 90 | ttk.Label(voice_frame, text="Format:").grid(row=0, column=6, padx=5, sticky="w") |
89 | 91 | self.format_var = tk.StringVar(value="wav") |
90 | | - ttk.Combobox(voice_frame, textvariable=self.format_var, values=["wav", "mp3"], width=5, state="readonly").grid(row=0, column=7, padx=5) |
| 92 | + ttk.Combobox(voice_frame, textvariable=self.format_var, values=["wav", "mp3"], |
| 93 | + width=5, state="readonly").grid(row=0, column=7, padx=5) |
91 | 94 |
|
92 | 95 | split_frame = ttk.Frame(main_frame) |
93 | 96 | split_frame.pack(fill=tk.X, pady=5) |
@@ -163,29 +166,76 @@ def process_files(self): |
163 | 166 | messagebox.showerror("Error", "No files selected for processing") |
164 | 167 | return |
165 | 168 |
|
166 | | - # Build base options |
167 | | - cmd_options = [ |
168 | | - "--voice", self.voice_var.get(), |
169 | | - "--lang", self.actual_lang_code, |
170 | | - "--speed", str(self.speed_var.get()), |
171 | | - "--format", self.format_var.get() |
172 | | - ] |
173 | | - |
174 | | - if split_dir := self.split_var.get(): |
175 | | - cmd_options += ["--split-output", split_dir] |
| 169 | + processing_params = { |
| 170 | + "voice": self.voice_var.get(), |
| 171 | + "language": self.actual_lang_code, |
| 172 | + "speed": str(self.speed_var.get()), |
| 173 | + "format": self.format_var.get(), |
| 174 | + "split_dir": self.split_var.get() or "None", |
| 175 | + "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S") |
| 176 | + } |
176 | 177 |
|
177 | 178 | self.root.destroy() |
178 | 179 |
|
179 | 180 | for file_path in self.file_list: |
180 | | - output_file = os.path.splitext(file_path)[0] + f".{self.format_var.get()}" |
181 | | - file_cmd = [KOKORO_PATH, file_path, output_file] + cmd_options |
| 181 | + output_file = os.path.splitext(file_path)[0] + f".{processing_params['format']}" |
| 182 | + log_file = output_file + ".log" |
| 183 | + |
| 184 | + cmd = [ |
| 185 | + KOKORO_PATH, |
| 186 | + file_path, |
| 187 | + output_file, |
| 188 | + "--voice", processing_params["voice"], |
| 189 | + "--lang", processing_params["language"], |
| 190 | + "--speed", processing_params["speed"], |
| 191 | + "--format", processing_params["format"] |
| 192 | + ] |
182 | 193 |
|
183 | | - print(f"\nProcessing: {os.path.basename(file_path)}") |
184 | | - try: |
185 | | - subprocess.run(file_cmd, check=True) |
186 | | - print(f"Successfully created: {output_file}") |
187 | | - except subprocess.CalledProcessError as e: |
188 | | - print(f"Error processing {file_path}: {e}") |
| 194 | + if processing_params["split_dir"] != "None": |
| 195 | + cmd += ["--split-output", processing_params["split_dir"]] |
| 196 | + |
| 197 | + with open(log_file, "w", encoding="utf-8") as log: |
| 198 | + log.write(f"Kokoro TTS Processing Log\n{'='*30}\n") |
| 199 | + log.write(f"Timestamp: {processing_params['timestamp']}\n") |
| 200 | + log.write(f"Input File: {file_path}\n") |
| 201 | + log.write(f"Output File: {output_file}\n") |
| 202 | + log.write(f"Voice: {processing_params['voice']}\n") |
| 203 | + log.write(f"Language: {processing_params['language']}\n") |
| 204 | + log.write(f"Speed: {processing_params['speed']}\n") |
| 205 | + log.write(f"Format: {processing_params['format']}\n") |
| 206 | + log.write(f"Split Directory: {processing_params['split_dir']}\n") |
| 207 | + log.write("\nProcessing Details:\n") |
| 208 | + |
| 209 | + try: |
| 210 | + process = subprocess.Popen( |
| 211 | + cmd, |
| 212 | + stdout=subprocess.PIPE, |
| 213 | + stderr=subprocess.STDOUT, |
| 214 | + text=True, |
| 215 | + encoding='utf-8', |
| 216 | + errors='replace' |
| 217 | + ) |
| 218 | + |
| 219 | + while True: |
| 220 | + output = process.stdout.readline() |
| 221 | + if output == '' and process.poll() is not None: |
| 222 | + break |
| 223 | + if output: |
| 224 | + print(output.strip()) |
| 225 | + log.write(output) |
| 226 | + |
| 227 | + exit_code = process.poll() |
| 228 | + if exit_code == 0: |
| 229 | + log.write("\nSUCCESSFUL PROCESSING\n") |
| 230 | + print(f"\nSuccessfully created: {output_file}") |
| 231 | + print(f"Log file created: {log_file}") |
| 232 | + else: |
| 233 | + log.write(f"\nPROCESSING FAILED (Code: {exit_code})\n") |
| 234 | + print(f"\nError processing {file_path} (Code: {exit_code})") |
| 235 | + |
| 236 | + except Exception as e: |
| 237 | + log.write(f"\nUNEXPECTED ERROR: {str(e)}\n") |
| 238 | + print(f"\nUnexpected error: {e}") |
189 | 239 |
|
190 | 240 | if __name__ == "__main__": |
191 | 241 | initial_files = [] |
|
0 commit comments