当前位置 博文首页 > LY的博客:使用腾讯ai搭建人机交互play

    LY的博客:使用腾讯ai搭建人机交互play

    作者:[db:作者] 时间:2021-08-09 22:09

    # -*- 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/

    cs