sponsored links

爆肝一週!利用Python打造了一個語音合成系統,竟然這麼NB

前言

當前,各種雲計算、雲服務迅速發展,各大公司提供了豐富的資源,大大降低了人工智慧開發的門檻,不需要懂語音合成的原理,只需不到半天時間,竟然可以這麼快速開發出一個語音合成工具出來!

爆肝一週!利用Python打造了一個語音合成系統,竟然這麼NB

語音合成系統

其實就是一個基於語音合成的工具,但是這個東西由於很多廠家都提供了API的形式,因此開發難度大大降低,只需要呼叫幾個API即可實現屬於自己的語音合成工具。麻雀雖小,五臟俱全,一個小工具而已。往大了說,這就是一個小型的語音合成系統。

準備工作

首先我們電腦上需要安裝

  • Anaconda
  • Python 3.7
  • visual studio code

步驟

這裡我們選用訊飛開放平臺的WebAPI介面

https://www.xfyun.cn/doc/tts/online_tts/API.html

首先我們到控制檯建立一個應用:

爆肝一週!利用Python打造了一個語音合成系統,竟然這麼NB

建立好了之後,點選該應用進入,有該應用的詳細欄目。(我這裡建立了一個名為myaibot的應用)點選左側的語音合成,再到下一級線上語音合成(流式版)

爆肝一週!利用Python打造了一個語音合成系統,竟然這麼NB

在右上側,能夠看到我們需要拿到3個東西:

  • APPID
  • APISecret
  • APIKey

有了這3個關鍵資訊,我們就可以開始使用訊飛線上語音合成來打造我們的系統了。

程式碼實現

接下來終於到了程式碼實現環節了。首先安裝我們需要的兩個庫

pip install websocket-client
pip install playsound

接下來我們定義一個類TtsPlay,包含4個函式

class TtsPlay:
def __init__(self): #初始化函式
def play_sound(self):#播放音訊函式
def select_vcn(self,*arg):#選擇下拉框設定發音人
def xfyun_tts(self):#進行語音合成

大家需要填上剛才從訊飛開放平臺控制檯獲取到的appid、apikey以及apisecret。另外想要Python人工智慧學習資料的小夥伴可私信我“666”哦!

def __init__(self):
    self.vcn = 'xiaoyan'
    self.APP_ID = 'xxx'# 請填上自己的appid
    self.API_KEY = 'xxx'# 請填上自己的appkey
    self.SECRET_KEY = 'xxx' # 請填上自己的appsecret

    self.fname = ""

    self.root = tk.Tk()  # 初始化視窗
    self.root.title("語音合成系統")  # 視窗名稱
    self.root.geometry("600x550")  # 設定視窗大小
    self.root.resizable(0, 0)   # 為了方便固定視窗大小
    self.tk_lb = tk.Label(self.root, text='請選擇語音發音人')  # 標籤
    self.tk_text = tk.Text(self.root, width=77, height=30)  # 多行文字框
    self.tk_cb_vcn = ttk.Combobox(self.root, width=12)  # 下拉列表框
    # 設定下拉列表框的內容
    self.tk_cb_vcn['values'] = ("甜美女聲-小燕", "親切男聲-許久", "知性女聲-小萍", "可愛童聲-許小寶", "親切女聲-小婧")
    self.tk_cb_vcn.current(0)  # 將當前選擇狀態置為0,也就是第一項
    self.tk_cb_vcn.bind("<<ComboboxSelected>>", self.select_vcn)
    self.tk_tts_file = tk.Label(self.root, text='生成檔名')
    self.b1 = tk.Button(self.root, text='進行語音合成', width=10, height=1, command=self.xfyun_tts)  # 按鈕
    self.tk_play = tk.Button(self.root, text='播放', width=10, height=1, command=self.play_sound)  # 按鈕
    # 各個元件的位置
    self.tk_tts_file.place(x=30, y=500)
    self.b1.place(x=300, y=500)
    self.tk_play.place(x=400, y=500)
    self.tk_lb.place(x=30, y=30)
    self.tk_cb_vcn.place(x=154, y=30)

    self.tk_text.place(x=30, y=60)
    self.root.mainloop()

當選擇了下拉列表,設定對應的發音人

def select_vcn(self, *args):
        if self.tk_cb_vcn.get() == '甜美女聲-小燕':
            self.vcn = "xiaoyan"
        elif self.tk_cb_vcn.get() == '親切男聲-許久':
            self.vcn = "aisjiuxu"
        elif self.tk_cb_vcn.get() == '知性女聲-小萍':
            self.vcn = "aisxping"
        elif self.tk_cb_vcn.get() == '可愛童聲-許小寶':
            self.vcn = "aisbabyxu"
        elif self.tk_cb_vcn.get() == '親切女聲-小婧':
            self.vcn = "aisjinger

接下來我們來魔改訊飛自帶的Python demo;

# -*- coding:utf-8 -*-
#
#   author: iflytek
#
#  本demo測試時執行的環境為:Windows + Python3.7
#  本demo測試成功執行時所安裝的第三方庫及其版本如下:
#   cffi==1.12.3
#   gevent==1.4.0
#   greenlet==0.4.15
#   pycparser==2.19
#   six==1.12.0
#   websocket==0.2.1
#   websocket-client==0.56.0
#   合成小語種需要傳輸小語種文字、使用小語種發音人vcn、tte=unicode以及修改文字編碼方式
#  錯誤碼連結:https://www.xfyun.cn/document/error-code (code返回錯誤碼時必看)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
import websocket
import datetime
import hashlib
import base64
import hmac
import json
from urllib.parse import urlencode
import ssl
from wsgiref.handlers import format_date_time
from datetime import datetime
from time import mktime
import _thread as thread
import os
import wave

STATUS_FIRST_FRAME = 0  # 第一幀的標識
STATUS_CONTINUE_FRAME = 1  # 中間幀標識
STATUS_LAST_FRAME = 2  # 最後一幀的標識

PCM_PATH = "./demo.pcm"

class Ws_Param(object):
    # 初始化
    def __init__(self):
        self.tts_vcn = ""
        self.tts_business_args = ""
        self.tts_common_args = ""
        self.tts_text_data = ""
        self.APPID = ""
        self.APIKey = ""
        self.APISecret = ""

    def set_tts_params(self, text, vcn):
        self.tts_vcn = vcn
        # 業務引數(business),更多個性化引數可在官網檢視
        self.tts_business_args = {"aue": "raw", "auf": "audio/L16;rate=16000", "vcn": self.tts_vcn, "tte": "utf8"}
        # 使用小語種須使用以下方式,此處的unicode指的是 utf16小端的編碼方式,即"UTF-16LE"”
        # self.tts_text_data = {"status": 2, "text": str(base64.b64encode(self.Text.encode('utf-16')), "UTF8")}
        self.tts_text_data = {"status": 2, "text": str(base64.b64encode(text.encode('utf-8')), "UTF8")}

    def set_params(self, appid, api_seccret, api_key):
        if appid != "":
            self.APPID = appid
            # 公共引數(common)
            self.tts_common_args = {"app_id": self.APPID}

        if api_key != "":
            self.APIKey = api_key

        if api_seccret != "":
            self.APISecret = api_seccret
    # 生成url
    def create_url(self):
        url = 'wss://tts-api.xfyun.cn/v2/tts'
        # 生成RFC1123格式的時間戳
        now = datetime.now()
        date = format_date_time(mktime(now.timetuple()))
        # 拼接字串
        signature_origin = "host: " + "ws-api.xfyun.cn" + "\n"
        signature_origin += "date: " + date + "\n"
        signature_origin += "GET " + "/v2/tts " + "HTTP/1.1"
        # 進行hmac-sha256進行加密
        signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
                                 digestmod=hashlib.sha256).digest()
        signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8')

        authorization_origin = "api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"" % (
            self.APIKey, "hmac-sha256", "host date request-line", signature_sha)
        authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
        # 將請求的鑑權引數組合為字典
        v = {
            "authorization": authorization,
            "date": date,
            "host": "ws-api.xfyun.cn"
        }

        url = url + '?' + urlencode(v)

        return url

def on_message(ws, message):
    try:
        message = json.loads(message)
        code = message["code"]
        sid = message["sid"]
        audio = message["data"]["audio"]
        audio = base64.b64decode(audio)
        status = message["data"]["status"]
        print(code, sid, status)
        if status == 2:
            print("ws is closed")
            ws.close()
        if code != 0:
            err_msg = message["message"]
            print("sid:%s call error:%s code is:%s" % (sid, err_msg, code))
        else:
            with open(PCM_PATH, 'ab') as f:
                f.write(audio)

    except Exception as e:
        print("receive msg,but parse exception:", e)

# 收到websocket錯誤的處理
def on_error(ws, error):
    print("### error:", error)

# 收到websocket關閉的處理
def on_close(ws):
    print("### closed ###")

# 收到websocket連線建立的處理
def on_open(ws):
    def run(*args):
        d = {"common": wsParam.tts_common_args,
             "business": wsParam.tts_business_args,
             "data": wsParam.tts_text_data,
             }
        d = json.dumps(d)
        print("------>開始傳送文字資料")
        ws.send(d)
        if os.path.exists(PCM_PATH):
            os.remove(PCM_PATH)

    thread.start_new_thread(run, ())

def text2wav(appid, api_secret, api_key, text, vcn, fname):
    wsParam.set_params(appid, api_secret, api_key)
    wsParam.set_tts_params(text, vcn)
    websocket.enableTrace(False)
    ws_url = wsParam.create_url()
    ws = websocket.WebSocketApp(ws_url, on_message=on_message, on_error=on_error, on_close=on_close)
    ws.on_open = on_open
    ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})

    pcm2wav(PCM_PATH, fname)

def pcm2wav(fname, dstname):
    with open(fname, 'rb') as pcmfile:
        pcmdata = pcmfile.read()
        print(len(pcmdata))
    with wave.open(dstname, "wb") as wavfile:
        wavfile.setparams((1, 2, 16000, 0, 'NONE', 'NONE'))
        wavfile.writeframes(pcmdata)

wsParam = Ws_Param()

# 注意一下需要填入自己的appid、api_secret、api_key
if __name__ == "__main__":
    text2wav(appid='xxx',
             api_secret='xxx',
             api_key='xxx',
             text="這是一個測試",
             vcn="xiaoyan",
             fname="./demo.wav")

程式碼寫好了,我們把Python程式碼run起來,最終一個語音合成系統就這樣實現了!效果可以參考下圖

爆肝一週!利用Python打造了一個語音合成系統,竟然這麼NB

免責宣告:本文內容來源於網路,文章版權歸原作者所有

分類: 健康
時間: 2022-02-13

相關文章

什麼是肺鱗癌?相比肺腺癌是隱蔽性極強,傷害性極大的肺癌

什麼是肺鱗癌?相比肺腺癌是隱蔽性極強,傷害性極大的肺癌
大家都知道大部分磨玻璃結節都屬於早期肺癌,病理型別大都屬於腺癌的一種,那麼我們今天和大家科普和了解一下,這種傷害性極大的肺癌-鱗癌. 先簡單的看一下肺癌的常見病理型別有哪些呢?相對專業,可以做一個瞭解 ...

肺腺癌IB期,真實生存率有多少?醫生告訴你

肺腺癌IB期,真實生存率有多少?醫生告訴你
最近有個網友在網上平臺諮詢,這個病人肺腺癌IB期,腔鏡手術治療已經2年了,術後沒有進行任何治療.現在病人聽說IB期的肺腺癌需要基因檢測,需要靶向治療,否則容易復發轉移.這個病人一再的詢問肺腺癌IB期, ...

多個分子靶向治療藥物待開發,將為晚期HER2陰性胃癌治療開啟新局面

多個分子靶向治療藥物待開發,將為晚期HER2陰性胃癌治療開啟新局面
作者:武漢大學人民醫院腫瘤中心 李嵐 分子靶向治療是胃癌領域的研究熱點.HER2靶基因的發現及相關靶向治療已在臨床廣泛應用並展示出良好的治療效果,然而,我國胃癌患者HER2陽性突變率低.在精準醫學時代 ...

恆瑞醫藥:創新藥吡咯替尼HER2陽性乳腺癌新適應症上市申請獲受理
據"恆瑞醫藥"微信公眾號訊息,近日,恆瑞醫藥自主研發的創新藥馬來酸吡咯替尼片上市許可申請獲國家藥品監督管理局受理,擬定適應症為:吡咯替尼聯合曲妥珠單抗及多西他賽,適用於治療表皮生長 ...

肺腺癌轉移快嗎?相比較肺鱗癌,的確更容易發生遠處轉移

肺腺癌轉移快嗎?相比較肺鱗癌,的確更容易發生遠處轉移
一個網友幫母親諮詢,他的母親常規體檢胸部CT查出肺部結節,病灶才2cm,穿刺活檢提示腺癌,中-低分化.就在全家慶幸病灶不大準備手術時,做腦部磁共振檢查發現腦部轉移了.這個結果令他無法接受,一再的追問, ...

早期肺腺癌中關鍵驅動基因及抑癌基因的研究進展

早期肺腺癌中關鍵驅動基因及抑癌基因的研究進展
早期肺腺癌中關鍵驅動基因及抑癌基因的研究進展 楊榮,廖曉陽,雷弋 *,原萌藝 [摘要] 肺癌在惡性腫瘤中具有極高的發病率及致死率,給全球造成了沉重的社會經濟負擔,而肺腺癌是肺癌的主要型別.儘管肺腺癌患 ...

恆瑞醫藥(600276.SH):馬來酸吡咯替尼片藥品上市許可申請獲藥監局受理
智通財經APP訊,恆瑞醫藥(600276.SH)公告,近日,公司收到國家藥品監督管理局("藥監局")下發的<受理通知書>,公司提交的馬來酸吡咯替尼片藥品上市許可申請獲藥 ...

ADC藥物顯神通!打擊面廣、還抗耐藥,後線治療療效確切

ADC藥物顯神通!打擊面廣、還抗耐藥,後線治療療效確切
Dato-DXd是靶向TROP2的抗體耦聯藥物(ADC),據WCLC 2021和ESMO 2021報道Dato-DXd治療經治的非小細胞肺癌及驅動基因異常的NSCLC的客觀緩解率達30%左右,血液學毒 ...

「健康科普」肺腺癌患者如何護理?

「健康科普」肺腺癌患者如何護理?
1.褥瘡預防:肺癌晚期病人營養狀況一般較差,有時合併全身水腫,極易產生褥瘡,且迅速擴充套件,難以治癒,預防褥瘡發生尤為重要.減輕區域性壓力,按時更換體位,身體易受壓部位用氣圈.軟枕等墊起,避免長期受壓 ...

多線治療後復發的PD-L1陰性晚期肺鱗癌,替雷利珠單抗聯合化療帶來有效緩解

多線治療後復發的PD-L1陰性晚期肺鱗癌,替雷利珠單抗聯合化療帶來有效緩解
*僅供醫學專業人士閱讀參考 2021CSCO年會基層專場暨百"例"挑一經典病例秀SHOW肺癌專場,吉林市第二人民醫院齊雪醫生分享的肺鱗癌治療病例榮獲一等獎. 百"例&qu ...

有敏感基因突變的晚期肺癌病人,靶向治療耐藥後能用免疫治療嗎?

有敏感基因突變的晚期肺癌病人,靶向治療耐藥後能用免疫治療嗎?
孫先生是個晚期肺癌病人,肺腺癌骨轉移,有EGFR 19外顯子突變,2017年開始吃易瑞沙,吃了兩年多耐藥,換三代奧西替尼,上個月複查CT,發現病情進展,主要是骨轉移病灶增多,腎上腺發現新增結節.總體評 ...

肺結節看診(13):肺小結節全身廣泛轉移2例,PET分期:晚期

肺結節看診(13):肺小結節全身廣泛轉移2例,PET分期:晚期
今天和大家分享的兩個病例都是小病灶大轉移,肺結節只有1cm多,但是腫瘤分期已經到了最晚期(ⅣB期).這兩個人都是沒有定期體檢,要發現早期肺癌,定期的體檢和腫瘤篩查很重要,另外PET/CT對確診為浸潤性 ...

殷詠梅教授:DS8201重新定義HER2陽性乳腺癌二線治療標準

殷詠梅教授:DS8201重新定義HER2陽性乳腺癌二線治療標準
*僅供醫學專業人士閱讀參考 DESTINY-Breast03研究帶來的思考和啟示有哪些,且聽大咖的真知灼見. 前 言 當前,抗體藥物偶聯物(ADC)在腫瘤治療領域的重要價值和應用前景不言而喻,DEST ...

肺癌基因檢測做過一次,無突變,放化療效果差,還有再做必要嗎?

肺癌基因檢測做過一次,無突變,放化療效果差,還有再做必要嗎?
昨天一位肺癌患者家屬諮詢我,其父親是一個肺癌晚期患者,3月前支氣管活檢術後行病理提示腺癌,並行基因檢測無基因突變,隨後行規範的放化療治療,效果差.他聽說靶向治療是瞄準腫瘤細胞上特有的靶點進行治療.相比 ...

緩解率達50%!HER2兩款新藥勝利在望

緩解率達50%!HER2兩款新藥勝利在望
HER2突變在非小細胞肺癌中屬於罕見突變,以前的一些泛EGFR TKI和HER2單抗,乃至靶向HER2的ADC藥物(T-DM1)治療HER2 NSCLC效果都不好.好在近年新型藥物不斷湧現,ESMO ...

晚期胃癌全身轉移沒治了?日本專家給出救命新方案

晚期胃癌全身轉移沒治了?日本專家給出救命新方案
當國內的治療方案几乎用盡,晚期胃癌患者還有救嗎? 標準治療方案無效無效!晚期胃癌全身轉移面臨絕境 29歲,國內一流院校畢業,光明燦爛的人生剛剛開啟,沒有人相信,這個陽光帥氣的男孩卻被診斷為晚期胃癌. ...

醫生也會錯:有關肺結節幾個需要澄清的關鍵問題

醫生也會錯:有關肺結節幾個需要澄清的關鍵問題
前言:肺結節為表現的早期肺癌相對傳統肺癌有許多不同,也有許多問題即使是醫生也會一知半解或者尚無定論.如果沒有定論的需要我們醫務人員與科研工作者不斷努力去探知.去了解,然後寫進規範與指南,指導臨床實踐. ...

真知灼見,前沿論道HER2低表達——國創ADC臨床科學轉化論壇(二)

真知灼見,前沿論道HER2低表達——國創ADC臨床科學轉化論壇(二)
自ADC誕生並在HER2 IHC 2+/ISH陰性或IHC 1+乳腺癌患者中獲得可觀療效以來,傳統定義下的HER2陽性(IHC 3+或IHC 2+/ISH+)分型也正在面臨史無前例的重大沖擊,各國學者 ...

2021 ESMO | 晚期乳腺癌亮點研究彙總(一)

2021 ESMO | 晚期乳腺癌亮點研究彙總(一)
編者按 2021年9月16日至21日,2021年歐洲腫瘤內科學會(ESMO)年會採用線上會議的方式舉行.作為全球最具影響力的腫瘤學術平臺之一,ESMO年會每年都會匯聚全球腫瘤專業人士,共同分享腫瘤領域 ...

MSS型晚期結直腸癌治療困境與希望——看“冷腫瘤”如何“長生存”
*僅供醫學專業人士閱讀參考 MSS型晚期結直腸癌(CRC)的綜合治療,一直是下消化道腫瘤診療領域研究的熱點與難點.張蘇展教授.劉雲鵬教授為您解讀MSS型晚期CRC治療如何實現"長生存&quo ...