首页 > Python > 文章正文

python自制有声小说

更新时间:2020-08-10

最近工作中测试ASR,语音识别系统。人工读太累,想自动化来实现。给一段text,能给我发出正确的声音,然后按住按钮,产品能够录制下来并且正常识别。

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:101677771

可不可以实现呢,万能的python当然是可以的。
搜了一下文字转语音,发现python的库还是很多的。
主要来源于单纯的声音库类,多媒体库类的音频模块,游戏库的音频模块,界面窗口库自带的媒体播放模块
pyaudio
pydub
pyglet
pygame

网页正文识别也不在话下。这里我尝试了 readability、goose3。

1.1 readability

readability 支持 Python3,使用 pip install readability-lxml 安装即可。

readability 使用起来也很方便:

import requests
from readability import Document
 
response = requests.get('http://news.china.com/socialgd/10000169/20180616/32537640_all.html')
doc = Document(response.text)
print(doc.title())

但是 readability 提取到的正文内容不是文本,里面仍包含 HTML 标签。

当然也可以结合其他组件再对 HTML 进行处理,如 html2text,我们这里就不再延伸,有兴趣的可以自行尝试。

1.2 goose3

Goose 本来是一个用 Java 编写的文章提取器,后来就有了 Python 实现版:goose3 。

使用起来也很方便,同时对中文支持也不错。使用 pip install goose3 即可安装。

 from goose3 import Goose
from goose3.text import StopWordsChinese
url  = 'http://news.china.com/socialgd/10000169/20180616/32537640_all.html'
 g = Goose({'stopwords_class': StopWordsChinese})
article = g.extract(url=url)
 print(article.cleaned_text[:150])

可以看出网页正文提取效果还不错,基本满足我们的要求,可以使用!
这样爬取网页内容就很容易了。当然你也可以自己写爬虫。

我还发现一个这样的库:
pyttsx3(Text to Speech)是一个语音转换模块,它可以在离线的环境下工作,支持多个引擎
安装

pip install pyttsx3

尝试

import pyttsx3

teacher = pyttsx3.init()
teacher.say('Hello World!')
teacher.runAndWait()

朗读中文

import pyttsx3

msg = '''盼望着,盼望着,东风来了,春天的脚步...'''
teacher = pyttsx3.init()
teacher.say(msg)
teacher.runAndWait()

调节语速

import pyttsx3

msg = '''盼望着,盼望着,东风来了,春天的脚步...'''
teacher = pyttsx3.init()
rate = teacher.getProperty('rate')
teacher.setProperty('rate', rate + 20)
teacher.say(msg)
teacher.runAndWait()

变换声音

import pyttsx3

msg = '''天行健,君子自强不息'''
teacher = pyttsx3.init()
voices = teacher.getProperty('voices')
for i in voices:
    teacher.setProperty('voice', i.id)
    teacher.say(msg)
teacher.runAndWait()

读英文还好,但是,读不出中文,于是搜了一个答案,说要在windos机器上改个注册表

engine.setProperty("voice","HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Speech\Voices\Tokens\TTS_MS_ZH-CN_HUIHUI_11.0")

尝试了一下,是可以读出中文,但是读出来的太机械,很明显的机器的声音。对于我自动化已经满足,如果要来听书,还是要找个萝莉音更爽。

然后看到说有某度的AI语音识别,需要注册百度的应用开发者账户,

用户可以自行去下面的网站去注册[语音合成-百度AIai.baidu.com,注册百度云之后,去控制台创建应用,过程比较简单。
用python实现起来也比较简单:
步骤如下,

1.1 安装百度AI模块,安装命令“pip install baidu-aip”

1.2 安装pydub,pydub是python的一个音频处理库处理,能对wav格式的音频直接进行处理,安装命令“pip install pydub”

1.3 安装ffmpeg,可以实现对mp3格式的处理,安装命令“sudo apt-get install ffmpeg”

其中的参数如下:
参数 类型 描述 必传
tex String 合成的文本,使用UTF-8编码,请注意文本长度必须小于1024字节 是
lang String 语言选择,填写zh 是
ctp String 客户端类型选择,web端填写1 是
cuid String 用户唯一标识,用来区分用户,填写机器 MAC 地址或 IMEI 码,长度为60以内 否
spd String 语速,取值0-9,默认为5中语速 否
pit String 音调,取值0-9,默认为5中语调 否
vol String 音量,取值0-15,默认为5中音量 否
per String 发音人选择,0为女声,1为男声,3为情感合成-度逍遥,4为情感合成-度丫丫,默认为普通女 否

接口对单次传入的文本进行了限制,合成文本长度必须小于 1024 字节,如果文本长度过长,就需要进行切割处理,采用多次请求的方式,分别转换成语音文件,最后再将多个语音文件合并成一个
写段代码试试看

from aip import AipSpeech
from pydub import AudioSegment
import time
 
#input your own APP_ID/API_KEY/SECRET_KEY
APP_ID = '14891501' 
API_KEY = 'EIm2iXtvDSplvR5cyHU8dAeM' 
SECRET_KEY = '4KkGGzTq2GVrBEYPLXXWEEIoyLL1F6Zt ' 
 
print("baiduVoiceGenerate: V1.0, by Guanagwei_Jiang, 20181121")
str = raw_input("请输入要转成语音的文字:")
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
result = client.synthesis(str, 'zh', 1, { 'vol': 5,'per':4 })
 
if not isinstance(result, dict):
    with open('temp.mp3', 'wb') as f:
        f.write(result)
 
sound = AudioSegment.from_mp3('temp.mp3')
sound.export(time.strftime("%Y%m%d_%H%M%S", time.localtime())+".wav", format="wav")

于是就可以将爬到的文字,转换成语音。听下来效果还可以,可以根据参数换男/女声音,和感情度。

import re
from aip import AipSpeech

app_id = 'id'
api_key = 'APIkey'
secret_key = 'screctkey'

client = AipSpeech(app_id,api_key,secret_key)

with open('read.txt','r') as a:
    text = a.readlines()

for cut in text:
    #以1000个字节的长度进行分割
    text_cut = re.findall('.{1000}', cut)
    text_cut.append(cut[(len(text_cut) * 1000):])
    #在分割后的字符串中间插入"---"
    text_final = '---'.join(text_cut)
#计算文本中有多少个"---"标志
times = text_final.count('---')
for n in range(0,times+1):
    name = text_final.split('---')[n]
    result = client.synthesis(name, 'zh', '1',
                              {"vol": 9,
                               "spd": 4,
                               "pit": 9,
                               "per": 3,
                               })

    with open('test/' + str(n + 1) + '.mp3', "wb") as d:
        print('正在生成第' + str(n + 1) + '段语音......')
        d.write(result)

可以将分段的语音,按照我前文的操作,所有的合并起来,就成了一个整体了。
或者使用pydub和ffmpeg实现wav转mp3格式。这样就实现了文字转声音。

相关文章
相关标签