1. 程式人生 > >使用騰訊ai搭建人機互動play

使用騰訊ai搭建人機互動play

# -*- coding: utf-8 -*-
# coded by 伊瑪目的門徒
import hashlib
import time
import random
import string
from urllib.parse import quote
import pandas as pd
import requests

import os
import pyaudio
import wave
import base64
import time

app_key = '************'
audio = pyaudio.PyAudio()

FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 8000#44100
CHUNK = 1024
RECORD_SECONDS = 3

def curlmd5(src):
    m = hashlib.md5(src.encode('UTF-8'))
    # 將得到的MD5值所有字元轉換成大寫
    return m.hexdigest().upper()

def get_params(plus_item):
    # 請求時間戳(秒級),用於防止請求重放(保證簽名5分鐘有效)
    t = time.time()
    time_stamp=str(int(t))
    # 請求隨機字串,用於保證簽名不可預測
    nonce_str = ''.join(random.sample(string.ascii_letters + string.digits, 10))
    # 應用標誌,這裡修改成自己的id和key
    app_id = '*************'
    app_key = '************'
    params = {'app_id':app_id,
              'question':plus_item,
              'time_stamp':time_stamp,
              'nonce_str':nonce_str,
              'session':'10000'
             }
    sign_before = ''
    # 要對key排序再拼接
    for key in sorted(params):
        # 鍵值拼接過程value部分需要URL編碼,URL編碼演算法用大寫字母,例如%E8。quote預設大寫。
        sign_before += '{}={}&'.format(key,quote(params[key], safe=''))
    # 將應用金鑰以app_key為鍵名,拼接到字串sign_before末尾
    sign_before += 'app_key={}'.format(app_key)
    # 對字串sign_before進行MD5運算,得到介面請求籤名
    sign = curlmd5(sign_before)
    params['sign'] = sign
    return params





def record():




    # start Recording
    stream = audio.open(format=FORMAT, channels=CHANNELS,
                    rate=RATE, input=True,
                    frames_per_buffer=CHUNK)
    print("listening...")
    frames = []
    for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
        data = stream.read(CHUNK)
        frames.append(data)
    # stop Recording
    stream.stop_stream()
    stream.close()

    voice = b''.join(frames)
    b64voice = base64.b64encode(voice)

    url_asr = 'https://api.ai.qq.com/fcgi-bin/aai/aai_asr'
    nonce_str = ''.join(random.sample(string.ascii_letters + string.digits, 16))
    data = {
        'app_id':  '************8',
        'time_stamp': str(int(time.time())),
        'nonce_str': nonce_str,
        'format': '1',
        'speech': b64voice.decode()

    }
    sign_before = ''

    for key in sorted(data):
        # 鍵值拼接過程value部分需要URL編碼,URL編碼演算法用大寫字母,例如%E8。quote預設大寫。
        sign_before += '{}={}&'.format(key,quote(data[key], safe=''))
        #    將應用金鑰以app_key為鍵名,拼接到字串sign_before末尾
    sign_before += 'app_key={}'.format(app_key)
    # 對字串sign_before進行MD5運算,得到介面請求籤名
    #print (sign_before)
    sign = curlmd5(sign_before)
    data['sign'] = sign

    #print (data['sign'])


    r = requests.post(url_asr, data=data)
    #print (r.text)
    question = r.json()['data']['text']
    return question


def get_content(plus_item):
    # 聊天的API地址
    url = "https://api.ai.qq.com/fcgi-bin/nlp/nlp_textchat"
    # 獲取請求引數
    plus_item = plus_item.encode('utf-8')
    #呼叫md5加密後的電子簽名
    payload = get_params(plus_item)
    # r = requests.get(url,params=payload)
    r = requests.post(url,data=payload)
    return r.json()["data"]["answer"]



# In[385]:


def playsound(voice):
    stream = audio.open(
        format = FORMAT,
        channels = CHANNELS,
        rate = RATE,
        output = True)
    stream.write(voice)
    stream.close()


# In[386]:


def speak(text):
    text = text[:50]

    app_id = '************'
    app_key = '*************'
    url_speak = 'https://api.ai.qq.com/fcgi-bin/aai/aai_tts'
    nonce_str = ''.join(random.sample(string.ascii_letters + string.digits, 16))
    data = {
        'app_id': app_id,
        'time_stamp': str(int(time.time())),
        'nonce_str': nonce_str,
        'text': text,
        'speaker': '6',
        'format': '2',
        'volume': '0',
        'speed': '100',
        'aht': '0',
        'apc': '58',
    }

    sign_before = ''

    for key in sorted(data):
        # 鍵值拼接過程value部分需要URL編碼,URL編碼演算法用大寫字母,例如%E8。quote預設大寫。
        sign_before += '{}={}&'.format(key,quote(data[key], safe=''))
        #    將應用金鑰以app_key為鍵名,拼接到字串sign_before末尾
    sign_before += 'app_key={}'.format(app_key)
    # 對字串sign_before進行MD5運算,得到介面請求籤名
    #print (sign_before)
    sign = curlmd5(sign_before)
    data['sign'] = sign


    r = requests.post(url_speak, data=data)
    voice = r.json()['data']['speech']
    voice = base64.b64decode(voice)
    playsound(voice)

df=pd.DataFrame({'And':[......],
                'Or':['0',[......],
                 'result':[......]

})

#print (df)


def judge_index(content):
    for  a in df['And']:

        if str(a) in content:
            pp=df[(df.And==a)].index.values
            pp=pp.tolist()
            #print(pp[0])
            t=pp[0]
            #print  (type(df.ix[t,'Or']))
            for item in df.ix[t,'Or']:
                if item in content:
                    #print (t)
                    return (t)


        else:
            pass
    return -1

def judge(content):
    f=judge_index(content)

    if  f>-1:

        return f
    else:
        return  False






if __name__ == '__main__':
    while True:
        question = record()
        print(question)
        if '結束'in question:
            break
        if judge(question):

            answer = df.ix[judge(question),'result']
        else:
            answer = get_content(question)
        print(answer)
        speak(answer)

結果展示:https://www.bilibili.com/video/av30723860/