flask 智能图灵机器人

语音文字相互转换

汉字转化为语音

from aip import AipSpeech

""" 你的 APPID AK SK """
APP_ID = '15420891'
API_KEY = 'clBfcG0eTy4GGHzpynHAUp8E'
SECRET_KEY = 'IaVWwTW7aKamjHVBv84pmTf8nKPrv2WX'

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
result = client.synthesis('北国风光,千里冰封,万里雪飘。', 'zh', 1,
                          {
                            'vol': 5,
                            'spd': 3,
                            'pit': 9,
                            'per': 4
                            })


# 识别正确返回语音二进制 错误则返回dict 参照下面错误码
if not isinstance(result, dict):
    with open('audio.mp3', 'wb') as f:
        f.write(result)
参数 类型 描述 是否必须
tex String 合成的文本,使用UTF-8编码, 请注意文本长度必须小于1024字节
cuid String 用户唯一标识,用来区分用户, 填写机器 MAC 地址或 IMEI 码,长度为60以内
spd String 语速,取值0-9,默认为5中语速
pit String 音调,取值0-9,默认为5中语调
vol String 音量,取值0-15,默认为5中音量
per String 发音人选择, 0为女声,1为男声, 3为情感合成-度逍遥,4为情感合成-度丫丫,默认为普通女

语音转化为汉字

from aip import AipSpeech
import os


""" 你的 APPID AK SK """
APP_ID = '15420336'
API_KEY = 'VwSGcqqwsCl282LGKnFwHDIA'
SECRET_KEY = 'h4oL6Y9yRuvmD0oSdQGQZchNcix4TF5P'

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)


# 读取文件
def get_file_content(filePath):
    os.system(f"ffmpeg -y  -i {filePath} -acodec pcm_s16le -f s16le -ac 1 -ar 16000 {filePath}.pcm")
    with open(f"{filePath}.pcm", 'rb') as fp:
        return fp.read()

# 识别本地文件
res = client.asr(get_file_content('wyn.wma'), 'pcm', 16000, {
    'dev_pid': 1536,
})

print(res.get("result")[0])
# 结果可能是一个列表取其中最相似的即可
参数 类型 描述 是否必须
speech Buffer 建立包含语音内容的Buffer对象, 语音文件的格式,pcm 或者 wav 或者 amr。不区分大小写
format String 语音文件的格式,pcm 或者 wav 或者 amr。不区分大小写。推荐pcm文件
rate int 采样率,16000,固定值
cuid String 用户唯一标识,用来区分用户,填写机器 MAC 地址或 IMEI 码,长度为60以内
dev_pid Int 不填写lan参数生效,都不填写,默认1537(普通话 输入法模型),dev_pid参数见本节开头的表格
lan(已废弃) String 历史兼容参数,请使用dev_pid。如果dev_pid填写,该参数会被覆盖。语种选择,输入法模型,默认中文(zh)。 中文=zh、粤语=ct、英文=en,不区分大小写。

dev_pid 参数列表

dev_pid 语言 模型 是否有标点 备注
1536 普通话(支持简单的英文识别) 搜索模型 无标点 支持自定义词库
1537 普通话(纯中文识别) 输入法模型 有标点 不支持自定义词库
1737 英语 有标点 不支持自定义词库
1637 粤语 有标点 不支持自定义词库
1837 四川话 有标点 不支持自定义词库
1936 普通话远场 远场模型 有标点 不支持

返回样例:

// 成功返回
{
    "err_no": 0,
    "err_msg": "success.",
    "corpus_no": "15984125203285346378",
    "sn": "481D633F-73BA-726F-49EF-8659ACCC2F3D",
    "result": ["北京天气"]
}

// 失败返回
{
    "err_no": 2000,
    "err_msg": "data empty.",
    "sn": null
}

错误返回格式

若请求错误,服务器将返回的JSON文本包含以下参数:

  • error_code:错误码。
  • error_msg:错误描述信息,帮助理解和解决发生的错误。

错误码

错误码 用户输入/服务端 含义 一般解决方法
3300 用户输入错误 输入参数不正确 请仔细核对文档及参照demo,核对输入参数
3301 用户输入错误 音频质量过差 请上传清晰的音频
3302 用户输入错误 鉴权失败 token字段校验失败。请使用正确的API_KEY 和 SECRET_KEY生成
3303 服务端问题 语音服务器后端问题 请将api返回结果反馈至论坛或者QQ群
3304 用户请求超限 用户的请求QPS超限 请降低识别api请求频率 (qps以appId计算,移动端如果共用则累计)
3305 用户请求超限 用户的日pv(日请求量)超限 请“申请提高配额”,如果暂未通过,请降低日请求量
3307 服务端问题 语音服务器后端识别出错问题 目前请确保16000的采样率音频时长低于30s,8000的采样率音频时长低于60s。如果仍有问题,请将api返回结果反馈至论坛或者QQ群
3308 用户输入错误 音频过长 音频时长不超过60s,请将音频时长截取为60s以下
3309 用户输入错误 音频数据问题 服务端无法将音频转为pcm格式,可能是长度问题,音频格式问题等。 请将输入的音频时长截取为60s以下,并核对下音频的编码,是否是8K或者16K, 16bits,单声道。
3310 用户输入错误 输入的音频文件过大 语音文件共有3种输入方式: json 里的speech 参数(base64后); 直接post 二进制数据,及callback参数里url。 分别对应三种情况:json超过10M;直接post的语音文件超过10M;callback里回调url的音频文件超过10M
3311 用户输入错误 采样率rate参数不在选项里 目前rate参数仅提供8000,16000两种,填写4000即会有此错误
3312 用户输入错误 音频格式format参数不在选项里 目前格式仅仅支持pcm,wav或amr,如填写mp3即会有此错误

错误码常见问题及具体分析

3300 错误

语音识别api使用的是HTTP POST方法, BODY里直接放置json, Content-Type头部为 application/json。 并非常见的浏览器表单请求(application/x-www-form-urlencoded或者multipart/x-www-form-urlencoded)。

必填字段:format rate channel cuid token cuid token cuid token cuid token,请勿漏填。此外 (speech, len) 及 (url, callback) 这两组参数必须二选一,如果都填,默认处理第一组。 channel cuid token,请勿漏填。此外 (speech, len) 及 (url, callback) 这两组参数必须二选一,如果都填,默认处理第一种。 channel cuid token,请勿漏填。此外 (speech, len) 及 (url, callback) 这两组参数必须二选一,如果都填,默认处理第一种。

必填字段如format rate channel cuid token,请勿漏填。此外 (speech, len) 及 (url, callback) 这两组参数必须二选一,如果都填,默认处理第一种,并确认 音频时长截取为60s以下。

3309错误

wav和amr的音频,服务端会自动转为pcm,这个过程中导致转码出错。请确认下format及rate参数与音频一致,并确认音频时长截取为60s以下。

3301 错误

识别结果实际为空。可能是音频质量过差,不清晰,或者是空白音频。 有时也可能是pcm填错采样率。如16K采样率的pcm文件,填写的rate参数为8000。

语音识别相互转换

""" 你的 APPID AK SK """
APP_ID = '15420336'
API_KEY = 'VwSGcqqwsCl282LGKnFwHDIA'
SECRET_KEY = 'h4oL6Y9yRuvmD0oSdQGQZchNcix4TF5P'

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

# 读取文件
def get_file_content(filePath):
    os.system(f"ffmpeg -y  -i {filePath} -acodec pcm_s16le -f s16le -ac 1 -ar 16000 {filePath}.pcm")
    with open(f"{filePath}.pcm", 'rb') as fp:
        return fp.read()

def audio2text(filepath):
    # 识别本地文件
    res = client.asr(get_file_content(filepath), 'pcm', 16000, {
        'dev_pid': 1536,
    })

    print(res.get("result")[0])

    return res.get("result")[0]

def text2audio(text):
    filename = f"{time.time()}.mp3"
    result = client.synthesis(text, 'zh', 1, {
        'vol': 5,
        "spd": 3,
        "pit": 7,
        "per": 4
    })

    # 识别正确返回语音二进制 错误则返回dict 参照下面错误码
    if not isinstance(result, dict):
        with open(filename, 'wb') as f:
            f.write(result)

    return filename


text = audio2text("wyn.wma")
filename = text2audio(text)

os.system(filename)

图灵机器人

import requests
args = {
    "reqType": 0,
    "perception": {
        "inputText": {
            "text": "北京天气怎么样"
        },
        "inputImage": {
            "url": "imageUrl"
        },
        "selfInfo": {
            "location": {
                "city": "北京",
                "province": "北京",
                "street": "信息路"
            }
        }
    },
    "userInfo": {
            "apiKey": "47dead7dcee74a1da3bcc980d147598c",
            "userId": "zzy"
    }
}
url = 'http://openapi.tuling123.com/openapi/api/v2'
res = requests.post(url=url, json=args)
text = res.json().get('results')[0].get('values').get('text')
print(text)

参数说明

参数 类型 是否必须 取值范围 说明
reqType int N - 输入类型:0-文本(默认)、1-图片、2-音频
perception - Y - 输入信息
userInfo - Y - 用户参数

perception

参数 类型 是否必须 取值范围 说明
inputText - N - 文本信息
inputImage - N - 图片信息
inputMedia - N - 音频信息
selfInfo - N - 客户端属性

注意:输入参数必须包含inputText或inputImage或inputMedia!

扫描二维码关注公众号,回复: 4929874 查看本文章

*inputText*

参数 类型 是否必须 取值范围 说明
text String Y 1-128字符 直接输入文本

*inputImage*

参数 类型 是否必须 取值范围 说明
url String Y 图片地址

*inputText*

参数 类型 是否必须 取值范围 说明
text String Y 1-128字符 直接输入文本

*inputImage*

参数 类型 是否必须 取值范围 说明
url String Y 图片地址

*inputMedia*

参数 类型 是否必须 取值范围 说明
url String Y 音频地址

*selfInfo*

参数 类型 是否必须 取值范围 说明
location - N - 地理位置信息

*location*

参数 类型 是否必须 取值范围 说明
city String Y - 所在城市
province String N - 省份
street String N - 街道

userInfo

参数 类型 是否必须 取值范围 说明
apiKey String Y 32位 机器人标识
userId String Y 长度小于等于32位 用户唯一标识
groupId String N 长度小于等于64位 群聊唯一标识
userIdName String N 长度小于等于64位 群内用户昵称

输出参数

输出示例:

  {
    "intent": {
        "code": 10005,
        "intentName": "",
        "actionName": "",
        "parameters": {
            "nearby_place": "酒店"
        }
    },
    "results": [
        {
            "groupType": 1,
            "resultType": "url",
            "values": {
                "url": "http://m.elong.com/hotel/0101/nlist/#indate=2016-12-10&outdate=2016-12-11&keywords=%E4%BF%A1%E6%81%AF%E8%B7%AF"
            }
        },
        {
            "groupType": 1,
            "resultType": "text",
            "values": {
                "text": "亲,已帮你找到相关酒店信息"
            }
        }
    ]
}

参数说明

参数 类型 是否必须 取值范围 说明
intent - Y - 请求意图
results - N - 输出结果集

intent

参数 类型 是否包含 取值范围 说明
code int Y - 输出功能code
intentName String N - 意图名称
actionName String N - 意图动作名称
parameters Map N - 功能相关参数

results

参数 类型 是否包含 取值范围 说明
resultType String Y 文本(text);连接(url);音频(voice);视频(video);图片(image);图文(news) 输出类型
values - Y - 输出值
groupType int Y - ‘组’编号:0为独立输出,大于0时可能包含同组相关内容 (如:音频与文本为一组时说明内容一致)

异常返回码

异常返回格式
{
    'intent':
        {
            'code':5000
        }
}
异常返回说明
异常码 说明
5000 无解析结果
6000 暂不支持该功能
4000 请求参数格式错误
4001 加密方式错误
4002 无功能权限
4003 该apikey没有可用请求次数
4005 无功能权限
4007 apikey不合法
4100 userid获取失败
4200 上传格式错误
4300 批量操作超过限制
4400 没有上传合法userid
4500 userid申请个数超过限制
4600 输入内容为空
4602 输入文本内容超长(上限150)
7002 上传信息失败
8008 服务器错误
0 上传成功

图灵结合语音

from aip import AipSpeech,AipNlp
import time,os

""" 你的 APPID AK SK """
APP_ID = '15420336'
API_KEY = 'VwSGcqqwsCl282LGKnFwHDIA'
SECRET_KEY = 'h4oL6Y9yRuvmD0oSdQGQZchNcix4TF5P'

nlp =  AipNlp(APP_ID, API_KEY, SECRET_KEY)
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

# 读取文件
def get_file_content(filePath):
    os.system(f"ffmpeg -y  -i {filePath} -acodec pcm_s16le -f s16le -ac 1 -ar 16000 {filePath}.pcm")
    with open(f"{filePath}.pcm", 'rb') as fp:
        return fp.read()

def audio2text(filepath):
    # 识别本地文件
    res = client.asr(get_file_content(filepath), 'pcm', 16000, {
        'dev_pid': 1536,
    })

    print(res.get("result")[0])

    return res.get("result")[0]

def text2audio(text):
    filename = f"{time.time()}.mp3"
    result = client.synthesis(text, 'zh', 1, {
        'vol': 5,
        "spd": 3,
        "pit": 7,
        "per": 4
    })

    # 识别正确返回语音二进制 错误则返回dict 参照下面错误码
    if not isinstance(result, dict):
        with open(filename, 'wb') as f:
            f.write(result)

    return filename

def to_tuling(text):
    import requests

    args = {
        "reqType": 0,
        "perception": {
            "inputText": {
                "text": text
            }
        },
        "userInfo": {
            "apiKey": "9a9a026e2eb64ed6b006ad99d27f6b9e",
            "userId": "1111"
        }
    }

    url = "http://openapi.tuling123.com/openapi/api/v2"

    res = requests.post(url, json=args)

    text = res.json().get("results")[0].get("values").get("text")
    return text

# res = nlp.simnet("你叫什么名字","你的名字是什么")
# print(res)


text = audio2text("bjtq.wma")

if nlp.simnet("你叫什么名字",text).get("score") >= 0.68 :
    text = "我的名字叫银角大王8"
else:
    text = to_tuling(text)

filename = text2audio(text)

os.system(filename)

整合后的项目

from flask import Flask, render_template, request, jsonify, send_file
from uuid import uuid4
import baidu_ai

app = Flask(__name__)


@app.route("/")
def index():
    return render_template("index.html")


@app.route("/ai", methods=["POST"])
def ai():
    # 1.保存录音文件
    audio = request.files.get("record")
    filename = f"{uuid4()}.wav"
    audio.save(filename)
    # 2.将录音文件转换为PCM发送给百度进行语音识别
    q_text = baidu_ai.audio2text(filename)

    # 3.将识别的问题交给图灵或自主处理获取答案
    a_text = baidu_ai.to_tuling(q_text)

    # 4.将答案发送给百度语音合成,合成音频文件
    a_file = baidu_ai.text2audio(a_text)

    # 5.将音频文件发送给前端播放

    return jsonify({"filename": a_file})


@app.route("/get_audio/<filename>")
def get_audio(filename):
    return send_file(filename)


if __name__ == '__main__':
    app.run("0.0.0.0", 9527, debug=True)

猜你喜欢

转载自www.cnblogs.com/zzy7372/p/10274295.html