使用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()