基于edge-tts的剪贴板文本自动朗读

查看 42|回复 1
作者:linjian648   
程序主要功能:监控剪贴板内容的变化,并将变化的文本内容转为语音播放。
功能列表
发音人选择:用户可以选择不同的发音人来进行文本转语音。
语速设置:用户可以设置语速/
快捷键监控:用户可以选择是否启用快捷键监控功能,并指定快捷键组合。
只转换英文内容:用户可以选择是否只转换英文内容,忽略其他语言的文本。
配置管理:程序启动时检查是否有配置文件 jtb.ini,存在则读取配置;不存在则让用户设置并保存配置。
安装依赖库
您可以使用以下命令通过 pip 安装以上所需的库:
pip install pyperclip edge-tts pygame keyboard configparser
[Python] 纯文本查看 复制代码# -*- coding: utf-8 -*-
import pyperclip
import time
import edge_tts
import os
import asyncio
import pygame
import keyboard  # 用于检测全局快捷键
import configparser
# 初始化 pygame
pygame.mixer.init()
# 发音人列表
voices = {
    1: 'zh-CN-XiaoxiaoNeural',
    2: 'zh-CN-XiaoyiNeural',
    3: 'zh-CN-YunjianNeural',
    4: 'zh-CN-YunxiNeural',
    5: 'zh-CN-YunxiaNeural',
    6: 'zh-CN-YunyangNeural'
}
config = configparser.ConfigParser()
if os.path.exists("jtb.ini"):
    config.read("jtb.ini")
    saved_settings = config["SETTINGS"]
    rate_input = saved_settings.get("rate", "1.0").strip()
    voice_choice = int(saved_settings.get("voice_choice", "1"))
    use_hotkey = saved_settings.get("use_hotkey", "n") == 'y'
    hotkey = saved_settings.get("hotkey", "")
    convert_english_only = saved_settings.get("convert_english_only", "n") == 'y'
else:
    rate_input = input("请输入语速(例如 '1.0' 表示正常速度,'1.5' 表示1.5倍速度,默认是 '1.0'): ").strip()
    try:
        rate = float(rate_input)
        rate_percent = f"+{int((rate - 1) * 100)}%"
    except ValueError:
        rate_percent = "+0%"  # 默认语速
    # 打印发音人选项
    print("请选择发音人:")
    for key, value in voices.items():
        print(f"{key}: {value}")
    voice_choice = int(input("请输入发音人编号: "))
    selected_voice = voices.get(voice_choice, 'zh-CN-XiaoxiaoNeural')  # 默认使用 XiaoXiao
    use_hotkey = input("是否启用快捷键监控功能?(y/n): ").strip().lower() == 'y'
    # 如果启用快捷键监控功能,用户定义一个快捷键组合
    if use_hotkey:
        print("请按下要监控的快捷键组合...")
        hotkey = keyboard.read_hotkey()
        print(f"您选择的快捷键组合是: {hotkey}")
    else:
        hotkey = ""
    convert_english_only = input("是否只转换英文内容?(y/n): ").strip().lower() == 'y'
    config["SETTINGS"] = {
        "rate": rate_input,
        "voice_choice": voice_choice,
        "use_hotkey": 'y' if use_hotkey else 'n',
        "hotkey": hotkey,
        "convert_english_only": 'y' if convert_english_only else 'n'
    }
    with open("jtb.ini", "w") as configfile:
        config.write(configfile)
# 用户配置已读取或设置,现在初始化其他变量
try:
    # 使用读取到或输入的 rate_input 进行语速设置
    rate = float(rate_input)
    rate_percent = f"+{int((rate - 1) * 100)}%"
except ValueError:
    rate_percent = "+0%"  # 默认语速
selected_voice = voices.get(voice_choice, 'zh-CN-XiaoxiaoNeural')  # 默认使用 XiaoXiao
# 初始化变量
previous_clipboard_content = ""
async def text_to_speech(text, output_file="output.mp3"):
    # 将发音人设定为用户选择的发音人,并设置语速
    communicator = edge_tts.Communicate(text, voice=selected_voice, rate=rate_percent)
    await communicator.save(output_file)
def play_audio_file(file_path):
    pygame.mixer.music.load(file_path)
    pygame.mixer.music.play()
    while pygame.mixer.music.get_busy():
        pygame.time.Clock().tick(10)
   
    # 等待播放完毕后卸载音频文件
    pygame.mixer.music.unload()
def safe_remove(file_path, retries=3, delay=1):
    """
    安全删除文件的方法
    :param file_path: 要删除的文件路径
    :param retries: 最大重试次数
    :param delay: 每次重试之间的延迟(秒)
    """
    for i in range(retries):
        try:
            os.remove(file_path)
            print(f"文件 {file_path} 已成功删除。")
            break
        except PermissionError as e:
            print(f"删除文件失败,重试 {i+1}/{retries}...")
            time.sleep(delay)
        except Exception as e:
            print(f"发生意外错误: {e}")
            break
def is_english(text):
    try:
        # 检查文本是否只包含英文字符和常用标点符号
        return all(ord(c)  0
    except:
        return False
def process_clipboard_text():
    global previous_clipboard_content
    try:
        current_clipboard_content = pyperclip.paste()
        # 仅在剪贴板内容是有效文本且与上次不同的时候处理
        if is_valid_text(current_clipboard_content) and current_clipboard_content != previous_clipboard_content:
            previous_clipboard_content = current_clipboard_content
            
            # 根据用户设置只处理英文内容
            if not convert_english_only or is_english(current_clipboard_content):
                print(f"内容改变: {current_clipboard_content}")
                # 使用 edge-tts 合成语音并播放
                output_file = "output.mp3"
                asyncio.run(text_to_speech(current_clipboard_content, output_file))
               
                # 检查音频文件是否成功生成且有效
                if os.path.exists(output_file) and os.path.getsize(output_file) > 0:
                    play_audio_file(output_file)
               
                # 播放完毕后删除音频文件
                safe_remove(output_file)
    except pyperclip.PyperclipException as e:
        print(f"读取剪贴板内容时出现错误: {e}")
def monitor_clipboard():
    global previous_clipboard_content
    if use_hotkey:
        print(f"按下组合键 '{hotkey}' 进行文本读取...")
        keyboard.add_hotkey(hotkey, process_clipboard_text)
        keyboard.wait()  # 等待快捷键被触发
    else:
        while True:
            process_clipboard_text()
            # 每隔一秒检测一次
            time.sleep(1)
if __name__ == "__main__":
    try:
        monitor_clipboard()
    except KeyboardInterrupt:
        pygame.mixer.quit()  # 程序退出时清理 pygame
        print("程序已退出")

快捷键, 语速

WXJYXLWMH   

感谢发布原创作品 辛苦了
您需要登录后才可以回帖 登录 | 立即注册

返回顶部