现在位置: 首页  >  编程技术  >  Python
小说朗读器,使用windows系统自带的tts功能进行朗读
0 90

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


下一篇:没有了~
 评论
 站内搜索