在线文本转语音工具的实现

文章目录

  • 文章最下面有工具链接!
  • 前言
  • edge-tts库
    • 1.首先使用pip安装这个库
    • 2.写一段示例代码
    • 3.多线程
  • pydub库
    • 1.介绍
    • 2.示例
  • 将他们整合起来
  • 我把他们部署到了我的服务器上,可以在线使用
  • 点我使用工具

文章最下面有工具链接!

前言

最近有文字转语音功能的需求,虽然也有一些免费工具,不过并没有找到好用的在线的文本转语音工具,因此便有了这篇文章。

edge-tts库

这是一个基于微软edge浏览器大声朗读功能的python库,作者将其进行封装,因此我们可以借由它来实现文字转语音功能,那么首先我先介绍一下这个库。edge-tts的github地址

1.首先使用pip安装这个库

pip3 install edge_tts 

2.写一段示例代码

import asyncio
import edge_tts

Content = "注意看,这是一段文字转语音的测试"
voiceName = "zh-TW-YunJheNeural"
output = "sound.mp3"
rate = '+5%'
volume = '+0%'
pitch = '+0Hz'

async def main():
    communicate = edge_tts.Communicate(text = Content, voice=voiceName ,rate=rate, volume=volume,pitch=pitch)
    await communicate.save(output)
  
asyncio.run(main()) 

asyncio.run 是 Python 标准库中 asyncio 模块提供的一个函数,用于运行一个异步函数直到它完成。它通常用于简化异步代码的执行,特别是在运行一个完整的异步应用程序时,而edge_tts所需要的就是这么一个异步执行,使用edge_tts.Communicate来生成音频内容,然后使用communicate.save来将文件保存到本地路径,其中text为所需要的文本,voice为所需要的音色,这个一会介绍,rate为语速,volume为音量,默认0就是满的,pitch为音调,后三个所接收的数据需要带上 正负号 数字 百分比的形式,其中pitch需要 正负号 数字 Hz的形式。

voice为音色参数,对于音色的获取,需要在安装完库之后在cmd里输入

edge-tts --list-voices

来查询,我列举一下这个库所支持的中文音色:

           { "Value": "zh-CN-XiaoxiaoNeural", "text": "晓晓" },
            { "Value": "zh-CN-XiaoyiNeural", "text": "小艺" },
            { "Value": "zh-CN-YunjianNeural", "text": "云建" },
            { "Value": "zh-CN-YunxiNeural", "text": "云溪" },
            { "Value": "zh-CN-YunxiaNeural", "text": "云霞" },
            { "Value": "zh-CN-YunyangNeural", "text": "云阳" },
            { "Value": "zh-CN-liaoning-XiaobeiNeural", "text": "东北小贝" },
            { "Value": "zh-CN-shaanxi-XiaoniNeural", "text": "山西小妮" },
            { "Value": "zh-HK-HiuGaaiNeural", "text": "粤语小妹" },
            { "Value": "zh-HK-HiuMaanNeural", "text": "粤语小妹2" },
            { "Value": "zh-HK-WanLungNeural", "text": "粤语小哥" },
            { "Value": "zh-TW-HsiaoChenNeural", "text": "台湾小妹" },
            { "Value": "zh-TW-HsiaoYuNeural", "text": "台湾小妹2" },
            { "Value": "zh-TW-YunJheNeural", "text": "台湾小哥" }

3.多线程

如果你跟着教程做了下来,你可以尝试使用一段超过5000字的长文本,你会发现生成速度明显慢了下来,我们可以使用多线程来同时生成多段文本,然后再把他们拼接到一起,这样速度便会有明显的提升
下面是一段多线程同步生成文件的测试,我们需要在项目目录下创建texts的文件夹,里面放上我们想要生成的文本:

import asyncio
import time
import edge_tts
import os

async def convert(text, file_name) -> None:
    start_time = time.time()
    communicate = edge_tts.Communicate(text, "zh-CN-XiaoxiaoNeural")
    await communicate.save(f"sounds/{file_name}.mp3")
    print(f"{file_name}用时:{int(time.time() - start_time)}秒")
async def main():
    # 创建输出文件夹
    if not os.path.exists("sounds"):
        os.makedirs("sounds")
    tasks = []
    # 遍历输入文件夹
    for root, dirs, files in os.walk("texts"):
        for file in files:
            # 将文件中的文本读出来
            with open(os.path.join(root, file), "r", encoding='utf-8') as text_file:
                text = text_file.read()
                # 获取文件名
                file_name, ext = os.path.splitext(file)
                # 加入任务列表
                tasks.append(convert(text, file_name))
    # 等待所有任务完成
    await asyncio.gather(*tasks)


asyncio.run(main())

可以看到这几篇文章都在同步下载,那么如果我们有一段很长的长文本,那么就可以按照这种方式来快速生成了。

pydub库

1.介绍

pydub 是一个用于处理音频文件的 Python 库,对音频进行各种操作变得更加容易。以下是一些 pydub 的主要功能:

音频格式转换: pydub 支持多种音频格式之间的转换,例如将 MP3 转换为 WAV 或反之。

音频剪辑和拼接: 你可以使用 pydub 对音频进行剪辑或拼接,合并多个音频文件。

音频格式调整: 调整音频的采样率、声道数、比特率等属性。

音频切片: 从音频文件中提取特定时间范围的片段。

音频效果: 提供一些简单的音频效果,例如增加音量、降低音量、应用均衡器等

我们只需要用到其中的音频拼接功能就可以,需要注意的是,使用这个库需要用到ffmpeg,对于ffmpeg的安装方法请移步至此:ffmpeg官网

2.示例

使用它来拼接音频是十分简单的,这是一段示例代码:

from pydub import AudioSegment
#读取音频文件
audio1 = AudioSegment.from_file("file1.wav")
audio2 = AudioSegment.from_file("file2.wav")
#拼接音频文件
merged_audio0=audio1+audio2
#保存拼接后的音频文件
merged_audio.export("merged.wav", format="wav")

将他们整合起来

需要texts,cache,download三个文件夹,其中texts里为你的文章,然后pwd需要设置为项目运行路径

import asyncio
import edge_tts
import time
from pydub import AudioSegment
import hashlib

pwd = "/var/www/html/sound"

rate = '+0%'
volume = '+0%'
pitch = '+0Hz'
def calculate_8_digit_md5(input_string):
    md5 = hashlib.md5()
    md5.update(input_string.encode('utf-8'))
    md5_hash = md5.hexdigest()[:8]
    return md5_hash
def get_current_time():
    current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    return current_time


async def convert(text, file_name, count,voice_name) -> None:
    global result
    start_time = time.time()
    communicate = edge_tts.Communicate(text=text,voice=voice_name,rate=rate,volume=volume,pitch=pitch)
    await communicate.save(pwd+f"/cache/{file_name}{count}.mp3")
    print(f"{file_name}用时:{int(time.time() - start_time)}秒")
    
def split_and_terminate(input_string, chunk_size=3000):
    res = []
    start = 0
    while start < len(input_string):
        # 截取指定大小的片段
        chunk = input_string[start:start + chunk_size]
        if start + chunk_size < len(input_string):
            last_comma = chunk.rfind(',')
            last_period = chunk.rfind('。')
            last_punctuation = max(last_comma, last_period)
            if last_punctuation != -1:
                chunk = chunk[:last_punctuation + 1]
        res.append(chunk)
        start += len(chunk)
    return res

async def main():
    print("md5:"+md5)
    result = split_and_terminate(text)
    tasks = []
    for index, chunk in enumerate(result):
        tasks.append(convert(chunk, md5,str(index+1),"zh-CN-XiaoxiaoNeural"))
    await asyncio.gather(*tasks)

def save_string_to_file(data, file_path):
    try:
        with open(file_path, 'w', encoding='utf-8') as file:
            file.write(data)
        print(f"字符串已成功保存到文件: {file_path}")
    except Exception as e:
        print(f"保存文件时发生错误: {e}")

if __name__ == "__main__":
    global text,md5
    with open(pwd+"/texts/测试.txt", "r", encoding='utf-8') as text_file:
        text = text_file.read()
        md5 = calculate_8_digit_md5(text + str(time.time()))
    asyncio.run(main())
    print('音频下载完成')
    result = AudioSegment.from_file(pwd+"/cache/" + md5 + "1.mp3")
    print('第1段合成完成')
    count = len(split_and_terminate(text))
    for i in range(2,count+1):
        result += AudioSegment.from_file(pwd+"/cache/" + md5 + str(i) + ".mp3")
        print('第' + str(i) + '段合成完成')
    result.export(pwd+"/download/"+md5+".mp3", format="mp3")
    print(md5+".mp3生成成功")




我把他们部署到了我的服务器上,可以在线使用

点我使用工具

在这里插入图片描述
这个网站还有进度条功能和日志显示功能,他们都是用原生html实现的,如果有人感兴趣,评论区说下,我再出期文章!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/305847.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Halcon3D篇-3D预处理,滤波,点云筛选

前言 由于3D相机采集到的数据通常通过Tiff格式的深度图进行显示或者保存。 深度图与模型的互转可以访问另一篇博客&#xff1a;https://blog.csdn.net/m0_51559565/article/details/135362674 关于3D相机的数据采集&#xff0c;可以访问我们另一篇关于LMI3D相机SDK的二次开发…

Redis主从复制哨兵及集群

目录 一.主从复制 主从复制的工作原理如下&#xff1a; 主从复制的作用&#xff1a; 搭建Redis 主从复制 每台服务器配置&#xff1a; ​编辑进行编译安装&#xff1a; 定义systemd服务管理脚本&#xff1a; 开启服务&#xff0c;报错看下内容&#xff1a; 修改 Redis…

Hyperledger Fabric 二进制安装部署 Peer 节点

规划网络拓扑 3 个 orderer 节点&#xff1b;组织 org1 , org1 下有两个 peer 节点&#xff0c; peer0 和 peer1; 组织 org2 , org2 下有两个 peer 节点&#xff0c; peer0 和 peer1; 节点宿主机 IPhosts端口cli192.168.1.66N/AN/Aorderer0192.168.1.66orderer0.example.com70…

深入浅出:原生态App封装的艺术

一、原生态App封装的优势 性能的极致&#xff1a;原生App直接调用设备的硬件资源&#xff0c;减少了中间层的干扰&#xff0c;从而实现更快的运行速度和更流畅的动画效果。 2. 用户体验的完美&#xff1a;原生App可以访问并遵循特定平台的设计指南&#xff0c;提供与操作系统无…

C#: Label、TextBox 鼠标停留时显示提示信息

说明&#xff1a;记录在 Label、TextBox 控件上 鼠标停留时显示提示信息的方法。 1.效果图 2.具体实现步骤 1. 在Form 窗口中先创建 Label 并取名&#xff1a;KEY_label &#xff0c;或 TextBox 取名&#xff1a;KEY_textBox 2. lable控件的 tips 实现方法1 &#xff1a;代码…

519基于单片机的自动切割流程控制系统

基于单片机的自动切割流程控制系统[proteus仿真] 自动切割流程控制系统这个题目算是课程设计和毕业设计中常见的题目了&#xff0c;本期是一个基于单片机的自动切割流程控制系统 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】&#xff0c;赞赏任意文章 2&…

Centos7 手动更改系统时间

文章目录 1.更改系统时间2.写入系统时间3.查看是否写入成功 1.更改系统时间 date -s "2017-12-18 09:40:00"2.写入系统时间 hwclock -w3.查看是否写入成功 timedatectl

MongoDB重写

可重写操作 当与数据库网络出现连接问题或在数据库集群主节点切换时不能找到一个正在工作的主节点时&#xff0c;可重试写允许数据库连接驱动再进行一次数据库写入操作。 前置条件 需要复制集或分片集&#xff0c;不支持单节点数据库可重试写需要存储引擎支持文档级别锁定&a…

deeplabv3模型的关键点

spp空间金字塔&#xff1a;可以避免图片固定输入&#xff0c;resize之后又减少了语义信息。这样任意大小的图片都可以输入&#xff0c;就保存了完整的信息。 空洞卷积&#xff1a;卷积的升级&#xff0c;多个尺寸的卷积核&#xff0c;增大了感受野&#xff0c;语义信息更加丰…

接口自动化测试要做什么?

作者&#xff1a;不辣的皮皮 链接&#xff1a;https://www.zhihu.com/question/384727359/answer/1124441469 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 可以分为四个步骤/阶段。 原理 》 业务逻辑》 工具》 …

【LeetCode】2626. 数组归约运算

数组归约运算 题目题解 题目 给定一个整数数组 nums、一个 reducer 函数 fn 和一个初始值 init&#xff0c;返回通过依次对数组的每个元素执行 fn 函数得到的最终结果。 通过以下操作实现这个结果&#xff1a;val fn(init, nums[0])&#xff0c;val fn(val, nums[1])&#…

机器学习-线性回归实践

目标&#xff1a;使用Sklearn、numpy模块实现展现数据预处理、线性拟合、得到拟合模型&#xff0c;展现预测值与目标值&#xff0c;展现梯度下降&#xff1b; 一、导入模块 import numpy as np np.set_printoptions(precision2) from sklearn.linear_model import LinearRegr…

JavaWeb的Filter详解

一、Filter过滤器简介 1、基本概念 JavaWeb的三大组件之一&#xff0c;三大组件为&#xff1a;Servlet、Filter、Listener。 过滤器相当于浏览器与Web资源之间的一道过滤网&#xff0c;在访问资源之前通过一系列的过滤器对请求 进行修改、判断以及拦截等&#xff0c;也可以对…

CMake入门教程【核心篇】导入外部库Opencv

😈「CSDN主页」:传送门 😈「Bilibil首页」:传送门 😈「动动你的小手」:点赞👍收藏⭐️评论📝 文章目录 环境准备示例:在Windows上配置OpenCV路径示例:在Linux上配置OpenCV路径环境准备 首先确保你的系统中安装了CMake。可以通过以下命令安装: Windows: 下载并…

Transformer从菜鸟到新手(五)

引言 上篇文章我们在单卡上完成了完整的训练过程。 从本文开始介绍模型训练/推理上的一些优化技巧&#xff0c;本文主要介绍多卡并行训练。 下篇文章将介绍大模型推理常用的缓存技术。 多卡训练 第一个要介绍的是利用多GPU优化&#xff0c;因为在单卡上训练实在是太慢。这…

Camunda ServiceTask

一&#xff1a;Java class Java class实现JavaDelegate接口&#xff0c;只需要配置类的全限定名即可&#xff0c;不需要被Spring容器管理。 public class JavaClassServiceTask implements JavaDelegate {Overridepublic void execute(DelegateExecution execution) throws …

【mars3d】批量关闭矢量数据的startFlicker()闪烁或者全部关闭startFlicker()

问题 1.graphic/entity/billboard怎么能够批量关闭startFlicker()闪烁或者 全部关闭startFlicker()呢&#xff1f; 相关链接 1.http://mars3d.cn/editor-vue.html?idgraphic/entity/billboard 2.http://mars3d.cn/apidoc.html#FlickerEntity 期望效果 1.graphic.stopFlic…

【软考】二叉树的存储

目录 一、基本概念二、二叉树的顺序存储2.1 说明2.2 图示 三、二叉树的链表存储3.1 说明3.2 图示 一、基本概念 1.满二叉树&#xff1a;最深一层都没有子节点&#xff0c;其它层都有左右两个节点 2.完全二叉树&#xff1a;是满二叉树的子集&#xff0c;在完全二叉树中最深一层的…

微信小程序实战-02翻页时钟-2

微信小程序实战系列 《微信小程序实战-01翻页时钟-1》 文章目录 微信小程序实战系列前言计时功能实现clock.wxmlclock.wxssclock.js 运行效果总结 前言 接着《微信小程序实战-01翻页时钟-1》&#xff0c;继续完成“6个页面的静态渲染和计时”功能。 计时功能实现 clock.wxm…

shp格式样本转微软COCO格式样本标注

在做影像识别时&#xff0c;需要大量的样本&#xff0c;对于从事GIS和遥感专业的人员来说&#xff0c;可能使用ArcGIS对着影像&#xff0c;绘制样本效率更高。但是很多框架和开源的代码都是基于PASCAL VOC格式和微软COCO格式的样本。这里我分享一下如何将栅格和shp数据转换微软…