Python人工智能之路 - 第三篇 : PyAudio 實現錄音 自動化交互實現問答

Python 很強大其緣由就是由於它龐大的三方庫 , 資源是很是的豐富 , 固然也不會缺乏關於音頻的庫windows

關於音頻, PyAudio 這個庫, 能夠實現開啓麥克風錄音, 能夠播放音頻文件等等,此刻咱們不去了解其餘的功能,只瞭解一下它如何實現錄音的app

首先要先 pip 一個 PyAudio函數

pip install pyaudio工具

一.PyAudio 實現麥克風錄音學習

而後創建一個py文件,複製以下代碼spa

import pyaudio
import wave

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 16000
RECORD_SECONDS = 2
WAVE_OUTPUT_FILENAME = "Oldboy.wav"

p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

print("開始錄音,請說話......")

frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)

print("錄音結束,請閉嘴!")

stream.stop_stream()
stream.close()
p.terminate()

wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()

嘗試一下,在目錄中出現了一個 Oldboy.wav 文件 , 聽一聽,仍是很清晰的嘛3d

接下來,咱們將這段錄音代碼,寫在一個函數裏面,若是要錄音的話就調用code

創建一個文件 pyrec.py 並將錄音代碼和函數寫在內orm

# pyrec.py 文件內容
import pyaudio
import wave

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 16000
RECORD_SECONDS = 2

def rec(file_name):
    p = pyaudio.PyAudio()

    stream = p.open(format=FORMAT,
                    channels=CHANNELS,
                    rate=RATE,
                    input=True,
                    frames_per_buffer=CHUNK)

    print("開始錄音,請說話......")

    frames = []

    for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
        data = stream.read(CHUNK)
        frames.append(data)

    print("錄音結束,請閉嘴!")

    stream.stop_stream()
    stream.close()
    p.terminate()

    wf = wave.open(file_name, 'wb')
    wf.setnchannels(CHANNELS)
    wf.setsampwidth(p.get_sample_size(FORMAT))
    wf.setframerate(RATE)
    wf.writeframes(b''.join(frames))
    wf.close()

rec 函數就是咱們調用的錄音函數,而且給他一個文件名,他就會自動將聲音寫入到文件中了blog

 

二.實現音頻格式自動轉換 並 調用語音識別

錄音的問題解決了,趕快和百度語音識別接在一塊兒使用一下:

無論你的錄音有多麼多麼清晰,你發現百度給你返回的永遠是:

{'err_msg': 'speech quality error.', 'err_no': 3301, 'sn': '6397933501529645284'} # 音質不清晰

其實不是沒聽清,而是百度支持的音頻格式PCM搞的鬼

因此,咱們要將錄製的wav音頻文件轉換爲pcm文件

寫一個文件 wav2pcm.py 這個文件裏面的函數是專門爲咱們轉換wav文件的

使用 os 模塊中的 os.system()方法 這個方法是執行系統命令用的, 在windows系統中的命令就是 cmd 裏面寫的東西,dir , cd 這類的命令

# wav2pcm.py 文件內容
import os

def wav_to_pcm(wav_file):
    # 假設 wav_file = "音頻文件.wav"
    # wav_file.split(".") 獲得["音頻文件","wav"] 拿出第一個結果"音頻文件"  與 ".pcm" 拼接 等到結果 "音頻文件.pcm"
    pcm_file = "%s.pcm" %(wav_file.split(".")[0])

    # 就是此前咱們在cmd窗口中輸入命令,這裏面就是在讓Python幫咱們在cmd中執行命令
    os.system("ffmpeg -y  -i %s  -acodec pcm_s16le -f s16le -ac 1 -ar 16000 %s"%(wav_file,pcm_file))

    return pcm_file

這樣咱們就有了把wav轉爲pcm的函數了 , 再從新構建一次我們的代碼

此次的返回結果還挺讓人滿意的嘛

{'corpus_no': '6569869134617218414', 'err_msg': 'success.', 'err_no': 0, 'result': ['老男孩教育'], 'sn': '8116162981529666859'}

拿到語音識別的字符串了,接下來用這段字符串 語音合成, 學習我們說出來的話

 

三.語音合成 與 FFmpeg 播放mp3 文件

拿到字符串了,直接調用synthesis方法去合成吧

這段代碼銜接上一段代碼,成功得到了 synth.mp3 音頻文件,而且肯定了實在學習咱們說的話

接下來就是讓咱們的程序自動將 synth.mp3 音頻文件播放了 其實PyAudio 有播放的功能,可是操做有點複雜

因此咱們仍是選擇用簡單的方式解決複雜的問題,就是這麼簡單粗暴,是否還記得FFmpeg 呢?

FFmpeg 這個系統工具中,有一個 ffplay 的工具用來打開並播放音頻文件的,使用方法大概是: ffplay 音頻文件.mp3

創建一個playmp3.py文件, 寫一個 play_mp3 的函數用來播放已經合成的語音

# playmp3.py 文件內容
import os

def play_mp3(file_name):
    os.system("ffplay  %s"%(file_name))

回到主文件,調用playmp3.py文件中的 play_mp3 函數

執行代碼,當你看到 : 開始錄音,請說話......

請大聲的說出: 學IT 找老男孩教育

而後你就會聽到,一個嬌滴滴聲音重複你說的話

 

四.簡單問答

首先咱們要把代碼從新梳理一下:

把語音合成 語音識別部分的代碼獨立成函數放到baidu_ai.py文件中

# baidu_ai.py 文件內容
from aip import AipSpeech

# 這裏的三個參數,對應在百度語音建立的應用中的三個參數
APP_ID = "xxxxx"
API_KEY = "xxxxxxx"
SECRET_KEY = "xxxxxxxx"

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)


def audio_to_text(pcm_file):
    # 讀取文件 , 終於獲得了PCM文件
    with open(pcm_file, 'rb') as fp:
        file_context = fp.read()

    # 識別本地文件
    res = client.asr(file_context, 'pcm', 16000, {
        'dev_pid': 1536,
    })

    # 從字典裏面獲取"result"的value 列表中第1個元素,就是識別出來的字符串"老男孩教育"
    res_str = res.get("result")[0]

    return res_str


def text_to_audio(res_str):
    synth_file = "synth.mp3"
    synth_context = client.synthesis(res_str, "zh", 1, {
        "vol": 5,
        "spd": 4,
        "pit": 9,
        "per": 4
    })

    with open(synth_file, "wb") as f:
        f.write(synth_context)

    return synth_file

而後把咱們的主文件進行一下修改

import pyrec  # 錄音函數文件
import wav2pcm  # wav轉換pcm 函數文件
import baidu_ai  # 語音合成函數,語音識別函數 文件
import playmp3  # 播放mp3 函數 文件

pyrec.rec("1.wav")  # 錄音並生成wav文件,使用方式傳入文件名

pcm_file = wav2pcm.wav_to_pcm("1.wav")  # 將wav文件 轉換成pcm文件 返回 pcm的文件名

res_str = baidu_ai.audio_to_text(pcm_file) # 將轉換後的pcm音頻文件識別成 文字 res_str

synth_file = baidu_ai.text_to_audio(res_str) # 將res_str 字符串 合成語音 返回文件名 synth_file

playmp3.play_mp3(synth_file) # 播放 synth_file

 

而後就是大展宏圖的時候了,展開大家的想象力:

res_str 是字符串,若是字符串等於"你叫什麼名字"的時候,咱們就要給他一個回答:個人名字叫老男孩教育

新建一個FAQ.py的文件而後創建一個函數faq:

# FAQ.py 文件內容
def faq(Q):
    if Q == "你叫什麼名字": # 問題
        return "個人名字是老男孩教育" # 答案

  return "我不知道你在說什麼" #問題沒有答案時返

在主文件中導入這個函數,並將語音識別後的字符串傳入函數中

如今來嘗試一下:"你叫什麼名字","你今年幾歲了"

成功了,如今你能夠對 FAQ.py 這個文件進行更多的問題匹配了

仍是那句話,別玩兒壞了

思考題:

1.如何實現一直問答不用問一次停一次?

2.問題那麼多,是否是要寫這麼多問題呢?

3.若是我問你是誰,是否是要重複也一次 個人名字叫老男孩教育 的答案呢?

相關文章
相關標籤/搜索