使用python调用系统的tts功能进行朗读
import pyttsx3 import threading import tkinter as tk from tkinter import messagebox import time # 小说的txt文件路径 NOVEL_FILE = '仙逆.txt' # 读取位置的文件路径 POSITION_FILE = 'reading_position.txt' # 播放语音的线程和标志 voice_thread = None playing = False exitStatus = False engine = pyttsx3.init() def save_position(line_number): """保存当前阅读位置到文件""" with open(POSITION_FILE, 'w') as f: f.write(str(line_number)) def load_position(): """从文件加载上次的阅读位置""" try: with open(POSITION_FILE, 'r') as f: return int(f.read().strip()) except FileNotFoundError: return 0 # 如果没有找到文件,则返回0,表示从头开始读 def read_line(line_number): """读取并朗读单行文本""" with open(NOVEL_FILE, 'r', encoding='utf-8') as f: f.seek(0) for idx, line in enumerate(f): if idx == line_number: text_widget.delete(1.0, tk.END) # 清空Text组件内容 text_widget.insert(tk.END, f"{line_number}. {line.strip()}") engine.say(line.strip()) engine.runAndWait() break def play_voice(start_line): """从指定行开始播放语音""" global playing global exitStatus playing = True exitStatus = False lines_read = 0 try: with open(NOVEL_FILE, 'r', encoding='utf-8') as f: f.seek(0) for line_number, line in enumerate(f, start=start_line): read_line(line_number) if exitStatus: playing = False print('将退出', playing) break lines_read += 1 if lines_read == 2: save_position(line_number + 1) if not playing: break lines_read = 0 except Exception as e: messagebox.showerror("Error", str(e)) finally: playing = False def play_audio(): """播放语音""" global voice_thread, playing start_line = load_position() if voice_thread is None or not voice_thread.is_alive(): voice_thread = threading.Thread(target=play_voice, args=(start_line,)) voice_thread.start() else: messagebox.showinfo("Info", "播放中") def pause_audio(): """暂停语音""" global playing playing = False messagebox.showinfo("Info", "暂停阅读") def resume_audio(): """恢复语音""" global playing playing = True messagebox.showinfo("Info", "恢复阅读") def exit_program(): """退出程序,保存当前位置""" global playing, voice_thread playing = False try: # 尝试等待voice_thread线程结束 if voice_thread is not None and voice_thread.is_alive(): voice_thread.join() except Exception as e: # 如果join()调用引发异常,打印错误信息 print(f"An error occurred while waiting for the voice thread to finish: {e}") finally: # 无论是否发生异常,都确保销毁Tkinter窗口 root.destroy() exit def exitSoft(): global exitStatus global playing if playing: #exitStatus = True messagebox.showinfo("Info", "请先暂停等待读完再退出") else: exit_program() # 创建GUI窗口 root = tk.Tk() root.title("Text to Speech Reader") # 播放按钮 play_button = tk.Button(root, text="Play", command=play_audio) play_button.pack(side=tk.LEFT, padx=10, pady=10) # 暂停/恢复按钮 pause_resume_button = tk.Button(root, text="Pause", command=pause_audio) pause_resume_button.pack(side=tk.LEFT, padx=10, pady=10) # 退出按钮 play_button_exit = tk.Button(root, text="Exit", command=exitSoft) play_button_exit.pack(side=tk.LEFT, padx=10, pady=10) # 创建一个Text组件来显示文本内容 text_widget = tk.Text(root, height=10, width=50) text_widget.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) # 当关闭窗口时结束所有后台线程 root.protocol("WM_DELETE_WINDOW", lambda: exit_program()) # 运行GUI窗口 root.mainloop()