Python 居然可以读故事了

惊!Python 居然可以读故事了

之前上班很忙,回到家之后只想闭着眼睛好好休息会,不想看屏幕,但是我又想想追之前没看完的小说,然后...我需要一个可以给我讲故事的机器人

虽然浏览器和读书软件里面也能朗读,但是我觉得太僵硬了,本来是很有意思的一段剧情,被念成流水账,听着想睡觉、让人分分钟想着弃坑,然后我就打算用爬虫定时下载新的章节再把文字储存到音频软件,这样不仅可以再选择一个好用的语音合成工具来处理,并且还可以反复听,香香了~

文本整合容易,但是如何将其快速转换成音频呢?难道要自己训练模型 “炼丹” 解决?no no ,费力不讨好,毕竟自己手头这点算法知识非常浅显,而且硬件条件也不允许,本着 “能用就行” 的原则,我决定先使用市面上开放平台的产品来解决。经过对比,发现有道智云的语音合成还不错(此处可体验),决定使用有道智云的语音合成 API 进行开发。

效果先睹为快:

先用朱自清先生的《荷塘月色》的两段进行试验,开发了简单的 demo,搞定了从文本的加载到生成音频文件的逻辑
以下是详细的开发过程

image.png

要转化成语音的文本:

image.png

合成结果(第一段):

合成结果(第二段):

很可惜,这里不能上传 mp3 格式的音乐文件

image.png

调用 API 接口的准备工作

先创建实例和应用,然后绑定它们,获取id和密匙。个人注册的具体过程请见文章分享一次批量文件翻译的开发过程

image.png

开发过程详细介绍

下面介绍具体的代码开发过程。

首先根据文档来分析有道智云的 API 输入输出规范。语音合成 API 调用十分简单,该 API 采用 https 方式通信,所需参数如下表:

字段名 类型 含义 必填 备注
q text 待合成音频文件的文本字符串 True 比如:您好
langType text 合成文本的语言类型 True 支持语言
appKey text 应用 ID True 可在 应用管理 查看
salt text UUID True UUID
sign text True MD5(应用 ID+q+salt + 应用密钥)
voice text 翻译结果发音选择,0 为女声,1 为男声,默认为女声 false 0
format text 目标音频格式,支持 mp3 false mp3
speed text 合成音频的语速 false 比如:"1" 为正常速度
volume text 合成音频的音量 false 正常为 "1.00", 最大为 "5.00", 最小为 "0.50"

简单的概括一下,需要的音频特征,用utf-8编码文本组织好自己的语言,再加上签名等参数就可以得到一份令人满意的合成音频

在接口输出中里,合成成功的话,正常的返回会是二进制的语音文件,但是如果出现了错误,就会返回到json结果,可以用这个来判断运行是否成功

Demo 开发:

这个 demo 使用 python3 开发,包括 maindow.py,synthesis.py,synthesistool.py 三个文件,分别为 demo 的界面、界面逻辑处理和语音合成接口调用工具封装。

  1. 界面部分:

    界面部分代码如下,比较简单。

    root=tk.Tk()
    root.title("youdao speech synthesis test")
    frm = tk.Frame(root)
    frm.grid(padx='50', pady='50')
    
    btn_get_file = tk.Button(frm, text='选择待合成文件', command=get_files)
    btn_get_file.grid(row=0, column=0, ipadx='3', ipady='3', padx='10', pady='20')
    
    text1 = tk.Text(frm, width='40', height='10')
    text1.grid(row=0, column=1)
    
    btn_sure=tk.Button(frm,text="合成",command=synthesis_files)
    btn_sure.grid(row=1,column=1)
    复制代码
    

    其中启动按钮 btn_sure 的绑定事件 synthesis_files() 来收集带所有的文本文件,启动合成,并打印运行结果:

    def synthesis_files():
        if syn_m.file_paths:
            message=syn_m.get_synthesis_result()
            tk.messagebox.showinfo("提示", message)
            os.system('start' + '.\\result')
        else :
            tk.messagebox.showinfo("提示","无文件")
    复制代码
    
  2. synthesis.py

    这里主要是配合界面实现一些文本读取和请求接口处理返回值的逻辑。首先定义一个 Synthesis_model

    class Synthesis_model():
        def __init__(self,file_paths,result_root_path,syn_type):
            self.file_paths=file_paths              
            self.result_root_path=result_root_path  
            self.syn_type=syn_type                  
    复制代码
    

    get_synthesis_result() 方法实现了批量读取文件并调用合成方法、处理返回信息的逻辑:

        def get_synthesis_result(self):
            syn_result=""
            for file_path in self.file_paths:
    
                file_name=os.path.basename(file_path).split('.')[0]
                file_content=open(file_path,encoding='utf-8').read()
    
                result=self.synthesis_use_netease(file_name,file_content)
    
                if result=="1":
                    syn_result=syn_result+file_path+" ok !\n"
                else:
                    syn_result=syn_result+file_path+result
            return syn_result
    复制代码
    

    单独定义了方法 synthesis_use_netease() 具体实现调用 API 的方法,这样增加了 demo 的扩展性,实现了一种合成模块可插拔的松耦合形式:

    def synthesis_use_netease(self,file_name,text):
        result=connect(text,'zh-CHS')
        print(result)
        if result.headers['Content-Type']=="audio/mp3":
            millis = int(round(time.time() * 1000))
            filePath = "./result/" + file_name+"-"+str(millis) + ".mp3"
            fo = open(filePath, 'wb')
            fo.write(result.content)
            fo.close()
            return "1"
        else:
            return "error:"+result.content
    复制代码
    
  3. synthesistool.py
    1. synthesistool.py 中是和请求有道智云 API 直接相关的一些方法,最核心的是 connect() 方法,整合了 API 所要求的各个参数,并调用执行请求的方法 do_request(),并返回 API 处理结果。

      def connect(text,lang_type):
          q = text
      
          data = {}
          data['langType'] = lang_type
          salt = str(uuid.uuid1())
          signStr = APP_KEY + q + salt + APP_SECRET
          sign = encrypt(signStr)
          data['appKey'] = APP_KEY
          data['q'] = q
          data['salt'] = salt
          data['sign'] = sign
      
          response = do_request(data)
          return response
      复制代码
      

    有想试一下的伙伴可以自己去下载一下代码体验一下 : P。项目地址:https://github.com/LemonQH/SpeechSynthesis

    温馨提示: 1、运行 demo 时,需要替换 synthesistool.py 模块中的 APP_KEY 、 APP_SECRET 为你自己生成的 APP_KEY、APP_SECRET 哦 2、你要手动在项目路径下创造./result 文件夹,或者修改成其他的位置

总结

以上就是我的开发过程,有道智云的语音合成 API 文档清晰,调用过程全程无坑,开发体验和合成效果都令人感到舒适。

想学习python的可以关注私信我哦

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,874评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,102评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,676评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,911评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,937评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,935评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,860评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,660评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,113评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,363评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,506评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,238评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,861评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,486评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,674评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,513评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,426评论 2 352

推荐阅读更多精彩内容

  • 理解 HTTP 协议对构建网络应用是一个非常基础的要求,比如爬虫类程序,必须深入理解 Request 和 Reso...
    马六甲的笔记阅读 478评论 0 0
  • 渐变的面目拼图要我怎么拼? 我是疲乏了还是投降了? 不是不允许自己坠落, 我没有滴水不进的保护膜。 就是害怕变得面...
    闷热当乘凉阅读 4,241评论 0 13
  • 夜莺2517阅读 127,718评论 1 9
  • 版本:ios 1.2.1 亮点: 1.app角标可以实时更新天气温度或选择空气质量,建议处女座就不要选了,不然老想...
    我就是沉沉阅读 6,887评论 1 6
  • 我是一名过去式的高三狗,很可悲,在这三年里我没有恋爱,看着同龄的小伙伴们一对儿一对儿的,我的心不好受。怎么说呢,高...
    小娘纸阅读 3,387评论 4 7